|
@@ -1017,3 +1017,92 @@ static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
|
|
|
gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
|
|
|
|
|
|
return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
|
|
|
+ struct gpmc_device_timings *dev_t)
|
|
|
+{
|
|
|
+ u32 temp;
|
|
|
+
|
|
|
+ gpmc_t->sync_clk = gpmc_calc_divider(dev_t->clk) *
|
|
|
+ gpmc_get_fclk_period();
|
|
|
+
|
|
|
+ gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
|
|
|
+ dev_t->t_bacc,
|
|
|
+ gpmc_t->sync_clk);
|
|
|
+
|
|
|
+ temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
|
|
|
+ gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
|
|
|
+
|
|
|
+ if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (dev_t->ce_xdelay)
|
|
|
+ gpmc_t->bool_timings.cs_extra_delay = true;
|
|
|
+ if (dev_t->avd_xdelay)
|
|
|
+ gpmc_t->bool_timings.adv_extra_delay = true;
|
|
|
+ if (dev_t->oe_xdelay)
|
|
|
+ gpmc_t->bool_timings.oe_extra_delay = true;
|
|
|
+ if (dev_t->we_xdelay)
|
|
|
+ gpmc_t->bool_timings.we_extra_delay = true;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
|
|
|
+ struct gpmc_device_timings *dev_t)
|
|
|
+{
|
|
|
+ u32 temp;
|
|
|
+
|
|
|
+ /* cs_on */
|
|
|
+ gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
|
|
|
+
|
|
|
+ /* adv_on */
|
|
|
+ temp = dev_t->t_avdasu;
|
|
|
+ if (dev_t->t_ce_avd)
|
|
|
+ temp = max_t(u32, temp,
|
|
|
+ gpmc_t->cs_on + dev_t->t_ce_avd);
|
|
|
+ gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
|
|
|
+
|
|
|
+ if (dev_t->sync_write || dev_t->sync_read)
|
|
|
+ gpmc_calc_sync_common_timings(gpmc_t, dev_t);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/* TODO: remove this function once all peripherals are confirmed to
|
|
|
+ * work with generic timing. Simultaneously gpmc_cs_set_timings()
|
|
|
+ * has to be modified to handle timings in ps instead of ns
|
|
|
+*/
|
|
|
+static void gpmc_convert_ps_to_ns(struct gpmc_timings *t)
|
|
|
+{
|
|
|
+ t->cs_on /= 1000;
|
|
|
+ t->cs_rd_off /= 1000;
|
|
|
+ t->cs_wr_off /= 1000;
|
|
|
+ t->adv_on /= 1000;
|
|
|
+ t->adv_rd_off /= 1000;
|
|
|
+ t->adv_wr_off /= 1000;
|
|
|
+ t->we_on /= 1000;
|
|
|
+ t->we_off /= 1000;
|
|
|
+ t->oe_on /= 1000;
|
|
|
+ t->oe_off /= 1000;
|
|
|
+ t->page_burst_access /= 1000;
|
|
|
+ t->access /= 1000;
|
|
|
+ t->rd_cycle /= 1000;
|
|
|
+ t->wr_cycle /= 1000;
|
|
|
+ t->bus_turnaround /= 1000;
|
|
|
+ t->cycle2cycle_delay /= 1000;
|
|
|
+ t->wait_monitoring /= 1000;
|
|
|
+ t->clk_activation /= 1000;
|
|
|
+ t->wr_access /= 1000;
|
|
|
+ t->wr_data_mux_bus /= 1000;
|
|
|
+}
|
|
|
+
|
|
|
+int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
|
|
|
+ struct gpmc_device_timings *dev_t)
|
|
|
+{
|
|
|
+ memset(gpmc_t, 0, sizeof(*gpmc_t));
|
|
|
+
|
|
|
+ gpmc_calc_common_timings(gpmc_t, dev_t);
|
|
|
+
|
|
|
+ if (dev_t->sync_read)
|