OMAP: OneNAND: let boards determine OneNAND frequency
OneNAND version ID may not give the highest frequency
supported and some OneNAND's have setup times that are
clock dependent. Let the board provide that information.
Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 46786a6..d776ded 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -121,6 +121,47 @@
writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
}
+static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
+ void __iomem *onenand_base, bool *clk_dep)
+{
+ u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
+ int freq = 0;
+
+ if (cfg->get_freq) {
+ struct onenand_freq_info fi;
+
+ fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID);
+ fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID);
+ fi.ver_id = ver;
+ freq = cfg->get_freq(&fi, clk_dep);
+ if (freq)
+ return freq;
+ }
+
+ switch ((ver >> 4) & 0xf) {
+ case 0:
+ freq = 40;
+ break;
+ case 1:
+ freq = 54;
+ break;
+ case 2:
+ freq = 66;
+ break;
+ case 3:
+ freq = 83;
+ break;
+ case 4:
+ freq = 104;
+ break;
+ default:
+ freq = 54;
+ break;
+ }
+
+ return freq;
+}
+
static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
void __iomem *onenand_base,
int *freq_ptr)
@@ -138,6 +179,7 @@
int err, ticks_cez;
int cs = cfg->cs, freq = *freq_ptr;
u32 reg;
+ bool clk_dep = false;
if (cfg->flags & ONENAND_SYNC_READ) {
sync_read = 1;
@@ -152,27 +194,7 @@
err = omap2_onenand_set_async_mode(cs, onenand_base);
if (err)
return err;
- reg = readw(onenand_base + ONENAND_REG_VERSION_ID);
- switch ((reg >> 4) & 0xf) {
- case 0:
- freq = 40;
- break;
- case 1:
- freq = 54;
- break;
- case 2:
- freq = 66;
- break;
- case 3:
- freq = 83;
- break;
- case 4:
- freq = 104;
- break;
- default:
- freq = 54;
- break;
- }
+ freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep);
first_time = 1;
}
@@ -232,6 +254,22 @@
else
latency = 4;
+ if (clk_dep) {
+ if (gpmc_clk_ns < 12) { /* >83Mhz */
+ t_ces = 3;
+ t_avds = 4;
+ } else if (gpmc_clk_ns < 15) { /* >66Mhz */
+ t_ces = 5;
+ t_avds = 4;
+ } else if (gpmc_clk_ns < 25) { /* >40Mhz */
+ t_ces = 6;
+ t_avds = 5;
+ } else {
+ t_ces = 7;
+ t_avds = 7;
+ }
+ }
+
if (first_time)
set_onenand_cfg(onenand_base, latency,
sync_read, sync_write, hf, vhf);