blob: f318f11da2fa53ca07117bf34b00f1156f626f01 [file] [log] [blame]
Juha Yrjolaaa62e902009-05-28 13:23:52 -07001/*
2 * linux/arch/arm/mach-omap2/gpmc-onenand.c
3 *
4 * Copyright (C) 2006 - 2009 Nokia Corporation
5 * Contacts: Juha Yrjola
6 * Tony Lindgren
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
Paul Gortmakerd44b28c2011-07-31 10:52:44 -040013#include <linux/string.h>
Juha Yrjolaaa62e902009-05-28 13:23:52 -070014#include <linux/kernel.h>
15#include <linux/platform_device.h>
16#include <linux/mtd/onenand_regs.h>
17#include <linux/io.h>
Arnd Bergmann22037472012-08-24 15:21:06 +020018#include <linux/platform_data/mtd-onenand-omap2.h>
Afzal Mohammed46376882012-06-05 10:11:48 +053019#include <linux/err.h>
Juha Yrjolaaa62e902009-05-28 13:23:52 -070020
21#include <asm/mach/flash.h>
22
Tony Lindgrence491cf2009-10-20 09:40:47 -070023#include <plat/gpmc.h>
Juha Yrjolaaa62e902009-05-28 13:23:52 -070024
Tony Lindgrendbc04162012-08-31 10:59:07 -070025#include "soc.h"
Afzal Mohammedb6ab13e2012-09-29 10:32:42 +053026#include "gpmc-onenand.h"
Tony Lindgrendbc04162012-08-31 10:59:07 -070027
Afzal Mohammed681988b2012-08-30 12:53:23 -070028#define ONENAND_IO_SIZE SZ_128K
29
Afzal Mohammed46376882012-06-05 10:11:48 +053030#define ONENAND_FLAG_SYNCREAD (1 << 0)
31#define ONENAND_FLAG_SYNCWRITE (1 << 1)
32#define ONENAND_FLAG_HF (1 << 2)
33#define ONENAND_FLAG_VHF (1 << 3)
34
35static unsigned onenand_flags;
36static unsigned latency;
37static int fclk_offset;
38
Juha Yrjolaaa62e902009-05-28 13:23:52 -070039static struct omap_onenand_platform_data *gpmc_onenand_data;
40
Afzal Mohammed681988b2012-08-30 12:53:23 -070041static struct resource gpmc_onenand_resource = {
42 .flags = IORESOURCE_MEM,
43};
44
Juha Yrjolaaa62e902009-05-28 13:23:52 -070045static struct platform_device gpmc_onenand_device = {
46 .name = "omap2-onenand",
47 .id = -1,
Afzal Mohammed681988b2012-08-30 12:53:23 -070048 .num_resources = 1,
49 .resource = &gpmc_onenand_resource,
Juha Yrjolaaa62e902009-05-28 13:23:52 -070050};
51
Afzal Mohammed46376882012-06-05 10:11:48 +053052static struct gpmc_timings omap2_onenand_calc_async_timings(void)
Juha Yrjolaaa62e902009-05-28 13:23:52 -070053{
54 struct gpmc_timings t;
55
56 const int t_cer = 15;
57 const int t_avdp = 12;
58 const int t_aavdh = 7;
59 const int t_ce = 76;
60 const int t_aa = 76;
61 const int t_oe = 20;
62 const int t_cez = 20; /* max of t_cez, t_oez */
63 const int t_ds = 30;
64 const int t_wpl = 40;
65 const int t_wph = 30;
66
67 memset(&t, 0, sizeof(t));
68 t.sync_clk = 0;
69 t.cs_on = 0;
70 t.adv_on = 0;
71
72 /* Read */
73 t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer));
74 t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh);
75 t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa);
76 t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce));
77 t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe));
78 t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
79 t.cs_rd_off = t.oe_off;
80 t.rd_cycle = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez);
81
82 /* Write */
83 t.adv_wr_off = t.adv_rd_off;
84 t.we_on = t.oe_on;
85 if (cpu_is_omap34xx()) {
86 t.wr_data_mux_bus = t.we_on;
87 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
88 }
89 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
90 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
91 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
92
Afzal Mohammed46376882012-06-05 10:11:48 +053093 return t;
94}
95
96static int gpmc_set_async_mode(int cs, struct gpmc_timings *t)
97{
Juha Yrjolaaa62e902009-05-28 13:23:52 -070098 /* Configure GPMC for asynchronous read */
99 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
100 GPMC_CONFIG1_DEVICESIZE_16 |
101 GPMC_CONFIG1_MUXADDDATA);
102
Afzal Mohammed46376882012-06-05 10:11:48 +0530103 return gpmc_cs_set_timings(cs, t);
104}
105
106static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
107{
108 u32 reg;
Adrian Hunter6d453e82009-06-23 13:30:24 +0300109
110 /* Ensure sync read and sync write are disabled */
111 reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
112 reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
113 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700114}
115
Afzal Mohammed46376882012-06-05 10:11:48 +0530116static void set_onenand_cfg(void __iomem *onenand_base)
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700117{
118 u32 reg;
119
120 reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
121 reg &= ~((0x7 << ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7 << 9));
122 reg |= (latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
123 ONENAND_SYS_CFG1_BL_16;
Afzal Mohammed46376882012-06-05 10:11:48 +0530124 if (onenand_flags & ONENAND_FLAG_SYNCREAD)
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700125 reg |= ONENAND_SYS_CFG1_SYNC_READ;
126 else
127 reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
Afzal Mohammed46376882012-06-05 10:11:48 +0530128 if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700129 reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
130 else
131 reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
Afzal Mohammed46376882012-06-05 10:11:48 +0530132 if (onenand_flags & ONENAND_FLAG_HF)
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700133 reg |= ONENAND_SYS_CFG1_HF;
134 else
135 reg &= ~ONENAND_SYS_CFG1_HF;
Afzal Mohammed46376882012-06-05 10:11:48 +0530136 if (onenand_flags & ONENAND_FLAG_VHF)
Adrian Hunter1435ca02011-02-07 10:46:58 +0200137 reg |= ONENAND_SYS_CFG1_VHF;
138 else
139 reg &= ~ONENAND_SYS_CFG1_VHF;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700140 writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
141}
142
Adrian Hunter5714b7e2011-02-07 10:47:00 +0200143static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
Jon Hunter757ef792012-06-28 13:41:29 -0500144 void __iomem *onenand_base)
Adrian Hunter5714b7e2011-02-07 10:47:00 +0200145{
146 u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
Jon Hunter757ef792012-06-28 13:41:29 -0500147 int freq;
Adrian Hunter5714b7e2011-02-07 10:47:00 +0200148
149 switch ((ver >> 4) & 0xf) {
150 case 0:
151 freq = 40;
152 break;
153 case 1:
154 freq = 54;
155 break;
156 case 2:
157 freq = 66;
158 break;
159 case 3:
160 freq = 83;
161 break;
162 case 4:
163 freq = 104;
164 break;
165 default:
166 freq = 54;
167 break;
168 }
169
170 return freq;
171}
172
Afzal Mohammed46376882012-06-05 10:11:48 +0530173static struct gpmc_timings
174omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
Jon Hunter757ef792012-06-28 13:41:29 -0500175 int freq)
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700176{
177 struct gpmc_timings t;
178 const int t_cer = 15;
179 const int t_avdp = 12;
180 const int t_cez = 20; /* max of t_cez, t_oez */
181 const int t_ds = 30;
182 const int t_wpl = 40;
183 const int t_wph = 30;
184 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700185 u32 reg;
Afzal Mohammed46376882012-06-05 10:11:48 +0530186 int div, fclk_offset_ns, gpmc_clk_ns;
187 int ticks_cez;
188 int cs = cfg->cs;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700189
Afzal Mohammed46376882012-06-05 10:11:48 +0530190 if (cfg->flags & ONENAND_SYNC_READ)
191 onenand_flags = ONENAND_FLAG_SYNCREAD;
192 else if (cfg->flags & ONENAND_SYNC_READWRITE)
193 onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700194
195 switch (freq) {
Adrian Hunter49314452010-12-09 11:22:50 +0200196 case 104:
197 min_gpmc_clk_period = 9600; /* 104 MHz */
198 t_ces = 3;
199 t_avds = 4;
200 t_avdh = 2;
201 t_ach = 3;
202 t_aavdh = 6;
Adrian Hunter1435ca02011-02-07 10:46:58 +0200203 t_rdyo = 6;
Adrian Hunter49314452010-12-09 11:22:50 +0200204 break;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700205 case 83:
Adrian Huntera3551f52010-12-09 10:48:27 +0200206 min_gpmc_clk_period = 12000; /* 83 MHz */
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700207 t_ces = 5;
208 t_avds = 4;
209 t_avdh = 2;
210 t_ach = 6;
211 t_aavdh = 6;
212 t_rdyo = 9;
213 break;
214 case 66:
Adrian Huntera3551f52010-12-09 10:48:27 +0200215 min_gpmc_clk_period = 15000; /* 66 MHz */
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700216 t_ces = 6;
217 t_avds = 5;
218 t_avdh = 2;
219 t_ach = 6;
220 t_aavdh = 6;
221 t_rdyo = 11;
222 break;
223 default:
Adrian Huntera3551f52010-12-09 10:48:27 +0200224 min_gpmc_clk_period = 18500; /* 54 MHz */
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700225 t_ces = 7;
226 t_avds = 7;
227 t_avdh = 7;
228 t_ach = 9;
229 t_aavdh = 7;
230 t_rdyo = 15;
Afzal Mohammed46376882012-06-05 10:11:48 +0530231 onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700232 break;
233 }
234
Afzal Mohammed1b47ca12012-08-19 18:29:45 +0530235 div = gpmc_calc_divider(min_gpmc_clk_period);
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700236 gpmc_clk_ns = gpmc_ticks_to_ns(div);
237 if (gpmc_clk_ns < 15) /* >66Mhz */
Afzal Mohammed46376882012-06-05 10:11:48 +0530238 onenand_flags |= ONENAND_FLAG_HF;
239 else
240 onenand_flags &= ~ONENAND_FLAG_HF;
Adrian Hunter1435ca02011-02-07 10:46:58 +0200241 if (gpmc_clk_ns < 12) /* >83Mhz */
Afzal Mohammed46376882012-06-05 10:11:48 +0530242 onenand_flags |= ONENAND_FLAG_VHF;
243 else
244 onenand_flags &= ~ONENAND_FLAG_VHF;
245 if (onenand_flags & ONENAND_FLAG_VHF)
Adrian Hunter1435ca02011-02-07 10:46:58 +0200246 latency = 8;
Afzal Mohammed46376882012-06-05 10:11:48 +0530247 else if (onenand_flags & ONENAND_FLAG_HF)
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700248 latency = 6;
249 else if (gpmc_clk_ns >= 25) /* 40 MHz*/
250 latency = 3;
251 else
252 latency = 4;
253
Afzal Mohammed46376882012-06-05 10:11:48 +0530254 /* Set synchronous read timings */
255 memset(&t, 0, sizeof(t));
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700256
257 if (div == 1) {
258 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
259 reg |= (1 << 7);
260 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
261 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
262 reg |= (1 << 7);
263 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
264 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
265 reg |= (1 << 7);
266 reg |= (1 << 23);
267 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
268 } else {
269 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
270 reg &= ~(1 << 7);
271 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
272 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
273 reg &= ~(1 << 7);
274 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
275 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
276 reg &= ~(1 << 7);
277 reg &= ~(1 << 23);
278 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
279 }
280
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700281 t.sync_clk = min_gpmc_clk_period;
282 t.cs_on = 0;
283 t.adv_on = 0;
284 fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
285 fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
286 t.page_burst_access = gpmc_clk_ns;
287
288 /* Read */
289 t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
290 t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
Adrian Hunter1435ca02011-02-07 10:46:58 +0200291 /* Force at least 1 clk between AVD High to OE Low */
292 if (t.oe_on <= t.adv_rd_off)
293 t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700294 t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
295 t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
296 t.cs_rd_off = t.oe_off;
297 ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
298 t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
299 ticks_cez);
300
301 /* Write */
Afzal Mohammed46376882012-06-05 10:11:48 +0530302 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700303 t.adv_wr_off = t.adv_rd_off;
304 t.we_on = 0;
305 t.we_off = t.cs_rd_off;
306 t.cs_wr_off = t.cs_rd_off;
307 t.wr_cycle = t.rd_cycle;
308 if (cpu_is_omap34xx()) {
309 t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
Adrian Huntera3551f52010-12-09 10:48:27 +0200310 gpmc_ps_to_ticks(min_gpmc_clk_period +
311 t_rdyo * 1000));
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700312 t.wr_access = t.access;
313 }
314 } else {
315 t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int,
316 t_avdp, t_cer));
317 t.we_on = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh);
318 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
319 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
320 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
321 if (cpu_is_omap34xx()) {
322 t.wr_data_mux_bus = t.we_on;
323 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
324 }
325 }
326
Afzal Mohammed46376882012-06-05 10:11:48 +0530327 return t;
328}
329
330static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
331{
332 unsigned sync_read = onenand_flags & ONENAND_FLAG_SYNCREAD;
333 unsigned sync_write = onenand_flags & ONENAND_FLAG_SYNCWRITE;
334
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700335 /* Configure GPMC for synchronous read */
336 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1,
337 GPMC_CONFIG1_WRAPBURST_SUPP |
338 GPMC_CONFIG1_READMULTIPLE_SUPP |
339 (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
340 (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
341 (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
342 GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
343 GPMC_CONFIG1_PAGE_LEN(2) |
344 (cpu_is_omap34xx() ? 0 :
345 (GPMC_CONFIG1_WAIT_READ_MON |
346 GPMC_CONFIG1_WAIT_PIN_SEL(0))) |
347 GPMC_CONFIG1_DEVICESIZE_16 |
348 GPMC_CONFIG1_DEVICETYPE_NOR |
349 GPMC_CONFIG1_MUXADDDATA);
350
Afzal Mohammed46376882012-06-05 10:11:48 +0530351 return gpmc_cs_set_timings(cs, t);
352}
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700353
Afzal Mohammed46376882012-06-05 10:11:48 +0530354static int omap2_onenand_setup_async(void __iomem *onenand_base)
355{
356 struct gpmc_timings t;
357 int ret;
358
359 omap2_onenand_set_async_mode(onenand_base);
360
361 t = omap2_onenand_calc_async_timings();
362
363 ret = gpmc_set_async_mode(gpmc_onenand_data->cs, &t);
364 if (IS_ERR_VALUE(ret))
365 return ret;
366
367 omap2_onenand_set_async_mode(onenand_base);
368
369 return 0;
370}
371
372static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
373{
374 int ret, freq = *freq_ptr;
375 struct gpmc_timings t;
Afzal Mohammed46376882012-06-05 10:11:48 +0530376
377 if (!freq) {
378 /* Very first call freq is not known */
Jon Hunter757ef792012-06-28 13:41:29 -0500379 freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
Afzal Mohammed46376882012-06-05 10:11:48 +0530380 set_onenand_cfg(onenand_base);
381 }
382
Jon Hunter757ef792012-06-28 13:41:29 -0500383 t = omap2_onenand_calc_sync_timings(gpmc_onenand_data, freq);
Afzal Mohammed46376882012-06-05 10:11:48 +0530384
385 ret = gpmc_set_sync_mode(gpmc_onenand_data->cs, &t);
386 if (IS_ERR_VALUE(ret))
387 return ret;
388
389 set_onenand_cfg(onenand_base);
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700390
Adrian Hunter3ad2d862011-02-07 10:46:59 +0200391 *freq_ptr = freq;
392
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700393 return 0;
394}
395
Adrian Hunter3ad2d862011-02-07 10:46:59 +0200396static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700397{
398 struct device *dev = &gpmc_onenand_device.dev;
Afzal Mohammed46376882012-06-05 10:11:48 +0530399 unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
400 int ret;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700401
Afzal Mohammed46376882012-06-05 10:11:48 +0530402 ret = omap2_onenand_setup_async(onenand_base);
403 if (ret) {
404 dev_err(dev, "unable to set to async mode\n");
405 return ret;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700406 }
407
Afzal Mohammed46376882012-06-05 10:11:48 +0530408 if (!(gpmc_onenand_data->flags & l))
409 return 0;
410
411 ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
412 if (ret)
413 dev_err(dev, "unable to set to sync mode\n");
414 return ret;
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700415}
416
417void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
418{
Afzal Mohammed681988b2012-08-30 12:53:23 -0700419 int err;
420
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700421 gpmc_onenand_data = _onenand_data;
422 gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
423 gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
424
425 if (cpu_is_omap24xx() &&
426 (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
427 printk(KERN_ERR "Onenand using only SYNC_READ on 24xx\n");
428 gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
429 gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
430 }
431
Afzal Mohammedeb77b6a2012-10-05 11:39:54 +0530432 if (cpu_is_omap34xx())
433 gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
434 else
435 gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
436
Afzal Mohammed681988b2012-08-30 12:53:23 -0700437 err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
438 (unsigned long *)&gpmc_onenand_resource.start);
439 if (err < 0) {
440 pr_err("%s: Cannot request GPMC CS\n", __func__);
441 return;
442 }
443
444 gpmc_onenand_resource.end = gpmc_onenand_resource.start +
445 ONENAND_IO_SIZE - 1;
446
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700447 if (platform_device_register(&gpmc_onenand_device) < 0) {
Afzal Mohammed681988b2012-08-30 12:53:23 -0700448 pr_err("%s: Unable to register OneNAND device\n", __func__);
449 gpmc_cs_free(gpmc_onenand_data->cs);
Juha Yrjolaaa62e902009-05-28 13:23:52 -0700450 return;
451 }
452}