static int tusb_set_sync_mode(unsigned sysclk_ps) { struct gpmc_device_timings dev_t; struct gpmc_timings t; unsigned t_scsnh_advnh = sysclk_ps + 3000; memset(&dev_t, 0, sizeof(dev_t)); dev_t.clk = 11100; dev_t.t_bacc = 1000; dev_t.t_ces = 1000; dev_t.t_ceasu = 8 * 1000; dev_t.t_avdasu = t_scsnh_advnh - 7000; dev_t.t_ce_avd = 1000; dev_t.t_avdp_r = t_scsnh_advnh; dev_t.cyc_aavdh_oe = 3; dev_t.cyc_oe = 5; dev_t.t_ce_rdyz = 7000; dev_t.t_avdp_w = t_scsnh_advnh; dev_t.cyc_aavdh_we = 3; dev_t.cyc_wpl = 6; dev_t.t_ce_rdyz = 7000; gpmc_calc_timings(&t, &tusb_sync, &dev_t); return gpmc_cs_set_timings(sync_cs, &t); }
static int tusb_set_async_mode(unsigned sysclk_ps) { struct gpmc_device_timings dev_t; struct gpmc_timings t; unsigned t_acsnh_advnh = sysclk_ps + 3000; memset(&dev_t, 0, sizeof(dev_t)); dev_t.t_ceasu = 8 * 1000; dev_t.t_avdasu = t_acsnh_advnh - 7000; dev_t.t_ce_avd = 1000; dev_t.t_avdp_r = t_acsnh_advnh; dev_t.t_oeasu = t_acsnh_advnh + 1000; dev_t.t_oe = 300; dev_t.t_cez_r = 7000; dev_t.t_cez_w = dev_t.t_cez_r; dev_t.t_avdp_w = t_acsnh_advnh; dev_t.t_weasu = t_acsnh_advnh + 1000; dev_t.t_wpl = 300; dev_t.cyc_aavdh_we = 1; gpmc_calc_timings(&t, &tusb_async, &dev_t); return gpmc_cs_set_timings(async_cs, &t); }
static void omap2_onenand_calc_async_timings(struct gpmc_timings *t) { struct gpmc_device_timings dev_t; const int t_cer = 15; const int t_avdp = 12; const int t_aavdh = 7; const int t_ce = 76; const int t_aa = 76; const int t_oe = 20; const int t_cez = 20; /* max of t_cez, t_oez */ const int t_wpl = 40; const int t_wph = 30; memset(&dev_t, 0, sizeof(dev_t)); dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000; dev_t.t_avdp_w = dev_t.t_avdp_r; dev_t.t_aavdh = t_aavdh * 1000; dev_t.t_aa = t_aa * 1000; dev_t.t_ce = t_ce * 1000; dev_t.t_oe = t_oe * 1000; dev_t.t_cez_r = t_cez * 1000; dev_t.t_cez_w = dev_t.t_cez_r; dev_t.t_wpl = t_wpl * 1000; dev_t.t_wph = t_wph * 1000; gpmc_calc_timings(t, &onenand_async, &dev_t); }
/* * Set the gpmc timings for smc91c96. The timings are taken * from the data sheet available at: * http://www.smsc.com/main/catalog/lan91c96.html * REVISIT: Level shifters can add at least to the access latency. */ static int smc91c96_gpmc_retime(void) { struct gpmc_timings t; struct gpmc_device_timings dev_t; const int t3 = 10; /* Figure 12.2 read and 12.4 write */ const int t4_r = 20; /* Figure 12.2 read */ const int t4_w = 5; /* Figure 12.4 write */ const int t5 = 25; /* Figure 12.2 read */ const int t6 = 15; /* Figure 12.2 read */ const int t7 = 5; /* Figure 12.4 write */ const int t8 = 5; /* Figure 12.4 write */ const int t20 = 185; /* Figure 12.2 read and 12.4 write */ /* * FIXME: Calculate the address and data bus muxed timings. * Note that at least adv_rd_off needs to be changed according * to omap3430 TRM Figure 11-11. Are the sdp boards using the * FPGA in between smc91x and omap as the timings are different * from above? */ if (gpmc_cfg->flags & GPMC_MUX_ADD_DATA) return 0; memset(&dev_t, 0, sizeof(dev_t)); dev_t.t_oeasu = t3 * 1000; dev_t.t_oe = t5 * 1000; dev_t.t_cez_r = t4_r * 1000; dev_t.t_oez = t6 * 1000; dev_t.t_rd_cycle = (t20 - t3) * 1000; dev_t.t_weasu = t3 * 1000; dev_t.t_wpl = t7 * 1000; dev_t.t_wph = t8 * 1000; dev_t.t_cez_w = t4_w * 1000; dev_t.t_wr_cycle = (t20 - t3) * 1000; gpmc_calc_timings(&t, &smc91x_settings, &dev_t); return gpmc_cs_set_timings(gpmc_cfg->cs, &t); }
static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t, unsigned int flags, int freq) { struct gpmc_device_timings dev_t; const int t_cer = 15; const int t_avdp = 12; const int t_cez = 20; /* max of t_cez, t_oez */ const int t_wpl = 40; const int t_wph = 30; int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; int div, gpmc_clk_ns; if (flags & ONENAND_SYNC_READ) onenand_flags = ONENAND_FLAG_SYNCREAD; else if (flags & ONENAND_SYNC_READWRITE) onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE; switch (freq) { case 104: min_gpmc_clk_period = 9600; /* 104 MHz */ t_ces = 3; t_avds = 4; t_avdh = 2; t_ach = 3; t_aavdh = 6; t_rdyo = 6; break; case 83: min_gpmc_clk_period = 12000; /* 83 MHz */ t_ces = 5; t_avds = 4; t_avdh = 2; t_ach = 6; t_aavdh = 6; t_rdyo = 9; break; case 66: min_gpmc_clk_period = 15000; /* 66 MHz */ t_ces = 6; t_avds = 5; t_avdh = 2; t_ach = 6; t_aavdh = 6; t_rdyo = 11; break; default: min_gpmc_clk_period = 18500; /* 54 MHz */ t_ces = 7; t_avds = 7; t_avdh = 7; t_ach = 9; t_aavdh = 7; t_rdyo = 15; onenand_flags &= ~ONENAND_FLAG_SYNCWRITE; break; } div = gpmc_calc_divider(min_gpmc_clk_period); gpmc_clk_ns = gpmc_ticks_to_ns(div); if (gpmc_clk_ns < 15) /* >66MHz */ onenand_flags |= ONENAND_FLAG_HF; else onenand_flags &= ~ONENAND_FLAG_HF; if (gpmc_clk_ns < 12) /* >83MHz */ onenand_flags |= ONENAND_FLAG_VHF; else onenand_flags &= ~ONENAND_FLAG_VHF; if (onenand_flags & ONENAND_FLAG_VHF) latency = 8; else if (onenand_flags & ONENAND_FLAG_HF) latency = 6; else if (gpmc_clk_ns >= 25) /* 40 MHz*/ latency = 3; else latency = 4; /* Set synchronous read timings */ memset(&dev_t, 0, sizeof(dev_t)); if (onenand_flags & ONENAND_FLAG_SYNCREAD) onenand_sync.sync_read = true; if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { onenand_sync.sync_write = true; onenand_sync.burst_write = true; } else { dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; dev_t.t_wpl = t_wpl * 1000; dev_t.t_wph = t_wph * 1000; dev_t.t_aavdh = t_aavdh * 1000; } dev_t.ce_xdelay = true; dev_t.avd_xdelay = true; dev_t.oe_xdelay = true; dev_t.we_xdelay = true; dev_t.clk = min_gpmc_clk_period; dev_t.t_bacc = dev_t.clk; dev_t.t_ces = t_ces * 1000; dev_t.t_avds = t_avds * 1000; dev_t.t_avdh = t_avdh * 1000; dev_t.t_ach = t_ach * 1000; dev_t.cyc_iaa = (latency + 1); dev_t.t_cez_r = t_cez * 1000; dev_t.t_cez_w = dev_t.t_cez_r; dev_t.cyc_aavdh_oe = 1; dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; gpmc_calc_timings(t, &onenand_sync, &dev_t); }