Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

OMAP: OneNAND: fix 104MHz support

104MHz needs a latency of 8 clock cycles and the VHF
flag must be set. Also t_rdyo is specified as
"not applicable" so pick a lower value, and force at
least 1 clk between AVD High to OE Low.

Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>

authored by

Adrian Hunter and committed by
Tony Lindgren
1435ca0f f040d332

+18 -6
+17 -6
arch/arm/mach-omap2/gpmc-onenand.c
··· 94 94 } 95 95 96 96 static void set_onenand_cfg(void __iomem *onenand_base, int latency, 97 - int sync_read, int sync_write, int hf) 97 + int sync_read, int sync_write, int hf, int vhf) 98 98 { 99 99 u32 reg; 100 100 ··· 114 114 reg |= ONENAND_SYS_CFG1_HF; 115 115 else 116 116 reg &= ~ONENAND_SYS_CFG1_HF; 117 + if (vhf) 118 + reg |= ONENAND_SYS_CFG1_VHF; 119 + else 120 + reg &= ~ONENAND_SYS_CFG1_VHF; 117 121 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); 118 122 } 119 123 ··· 134 130 const int t_wph = 30; 135 131 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; 136 132 int tick_ns, div, fclk_offset_ns, fclk_offset, gpmc_clk_ns, latency; 137 - int first_time = 0, hf = 0, sync_read = 0, sync_write = 0; 133 + int first_time = 0, hf = 0, vhf = 0, sync_read = 0, sync_write = 0; 138 134 int err, ticks_cez; 139 135 int cs = cfg->cs; 140 136 u32 reg; ··· 184 180 t_avdh = 2; 185 181 t_ach = 3; 186 182 t_aavdh = 6; 187 - t_rdyo = 9; 183 + t_rdyo = 6; 188 184 break; 189 185 case 83: 190 186 min_gpmc_clk_period = 12000; /* 83 MHz */ ··· 221 217 gpmc_clk_ns = gpmc_ticks_to_ns(div); 222 218 if (gpmc_clk_ns < 15) /* >66Mhz */ 223 219 hf = 1; 224 - if (hf) 220 + if (gpmc_clk_ns < 12) /* >83Mhz */ 221 + vhf = 1; 222 + if (vhf) 223 + latency = 8; 224 + else if (hf) 225 225 latency = 6; 226 226 else if (gpmc_clk_ns >= 25) /* 40 MHz*/ 227 227 latency = 3; ··· 234 226 235 227 if (first_time) 236 228 set_onenand_cfg(onenand_base, latency, 237 - sync_read, sync_write, hf); 229 + sync_read, sync_write, hf, vhf); 238 230 239 231 if (div == 1) { 240 232 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2); ··· 272 264 /* Read */ 273 265 t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh)); 274 266 t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach)); 267 + /* Force at least 1 clk between AVD High to OE Low */ 268 + if (t.oe_on <= t.adv_rd_off) 269 + t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1); 275 270 t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div); 276 271 t.oe_off = t.access + gpmc_round_ns_to_ticks(1); 277 272 t.cs_rd_off = t.oe_off; ··· 328 317 if (err) 329 318 return err; 330 319 331 - set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf); 320 + set_onenand_cfg(onenand_base, latency, sync_read, sync_write, hf, vhf); 332 321 333 322 return 0; 334 323 }
+1
include/linux/mtd/onenand_regs.h
··· 168 168 #define ONENAND_SYS_CFG1_INT (1 << 6) 169 169 #define ONENAND_SYS_CFG1_IOBE (1 << 5) 170 170 #define ONENAND_SYS_CFG1_RDY_CONF (1 << 4) 171 + #define ONENAND_SYS_CFG1_VHF (1 << 3) 171 172 #define ONENAND_SYS_CFG1_HF (1 << 2) 172 173 #define ONENAND_SYS_CFG1_SYNC_WRITE (1 << 1) 173 174