aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/gpmc-onenand.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@nokia.com>2011-02-07 03:47:00 -0500
committerTony Lindgren <tony@atomide.com>2011-02-17 18:44:46 -0500
commit5714b7ed6b3e3c00c0d4719bb66757e64c30ecf6 (patch)
treeaaf57838fa11ca7b9c6a4bb5da80b57a5597dfdb /arch/arm/mach-omap2/gpmc-onenand.c
parent3ad2d861362031dac8b2bba78a8f4c575300948f (diff)
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>
Diffstat (limited to 'arch/arm/mach-omap2/gpmc-onenand.c')
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c80
1 files changed, 59 insertions, 21 deletions
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 46786a606e90..d776ded9830d 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -121,6 +121,47 @@ static void set_onenand_cfg(void __iomem *onenand_base, int latency,
121 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1); 121 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
122} 122}
123 123
124static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
125 void __iomem *onenand_base, bool *clk_dep)
126{
127 u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
128 int freq = 0;
129
130 if (cfg->get_freq) {
131 struct onenand_freq_info fi;
132
133 fi.maf_id = readw(onenand_base + ONENAND_REG_MANUFACTURER_ID);
134 fi.dev_id = readw(onenand_base + ONENAND_REG_DEVICE_ID);
135 fi.ver_id = ver;
136 freq = cfg->get_freq(&fi, clk_dep);
137 if (freq)
138 return freq;
139 }
140
141 switch ((ver >> 4) & 0xf) {
142 case 0:
143 freq = 40;
144 break;
145 case 1:
146 freq = 54;
147 break;
148 case 2:
149 freq = 66;
150 break;
151 case 3:
152 freq = 83;
153 break;
154 case 4:
155 freq = 104;
156 break;
157 default:
158 freq = 54;
159 break;
160 }
161
162 return freq;
163}
164
124static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg, 165static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
125 void __iomem *onenand_base, 166 void __iomem *onenand_base,
126 int *freq_ptr) 167 int *freq_ptr)
@@ -138,6 +179,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
138 int err, ticks_cez; 179 int err, ticks_cez;
139 int cs = cfg->cs, freq = *freq_ptr; 180 int cs = cfg->cs, freq = *freq_ptr;
140 u32 reg; 181 u32 reg;
182 bool clk_dep = false;
141 183
142 if (cfg->flags & ONENAND_SYNC_READ) { 184 if (cfg->flags & ONENAND_SYNC_READ) {
143 sync_read = 1; 185 sync_read = 1;
@@ -152,27 +194,7 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
152 err = omap2_onenand_set_async_mode(cs, onenand_base); 194 err = omap2_onenand_set_async_mode(cs, onenand_base);
153 if (err) 195 if (err)
154 return err; 196 return err;
155 reg = readw(onenand_base + ONENAND_REG_VERSION_ID); 197 freq = omap2_onenand_get_freq(cfg, onenand_base, &clk_dep);
156 switch ((reg >> 4) & 0xf) {
157 case 0:
158 freq = 40;
159 break;
160 case 1:
161 freq = 54;
162 break;
163 case 2:
164 freq = 66;
165 break;
166 case 3:
167 freq = 83;
168 break;
169 case 4:
170 freq = 104;
171 break;
172 default:
173 freq = 54;
174 break;
175 }
176 first_time = 1; 198 first_time = 1;
177 } 199 }
178 200
@@ -232,6 +254,22 @@ static int omap2_onenand_set_sync_mode(struct omap_onenand_platform_data *cfg,
232 else 254 else
233 latency = 4; 255 latency = 4;
234 256
257 if (clk_dep) {
258 if (gpmc_clk_ns < 12) { /* >83Mhz */
259 t_ces = 3;
260 t_avds = 4;
261 } else if (gpmc_clk_ns < 15) { /* >66Mhz */
262 t_ces = 5;
263 t_avds = 4;
264 } else if (gpmc_clk_ns < 25) { /* >40Mhz */
265 t_ces = 6;
266 t_avds = 5;
267 } else {
268 t_ces = 7;
269 t_avds = 7;
270 }
271 }
272
235 if (first_time) 273 if (first_time)
236 set_onenand_cfg(onenand_base, latency, 274 set_onenand_cfg(onenand_base, latency,
237 sync_read, sync_write, hf, vhf); 275 sync_read, sync_write, hf, vhf);