kernel: update 3.14 to 3.14.18
[openwrt.git] / target / linux / ipq806x / patches / 0150-mtd-nand-Add-Qualcomm-NAND-controller.patch
1 From d2981ca1343b837fc574c4e46806d041b258720d Mon Sep 17 00:00:00 2001
2 From: Andy Gross <agross@codeaurora.org>
3 Date: Mon, 16 Jun 2014 17:13:22 -0500
4 Subject: [PATCH 150/182] mtd: nand: Add Qualcomm NAND controller
5
6 This patch adds the Qualcomm NAND controller and required infrastructure.
7
8 Signed-off-by: Andy Gross <agross@codeaurora.org>
9 ---
10  drivers/mtd/nand/Kconfig        |   18 +
11  drivers/mtd/nand/Makefile       |    2 +
12  drivers/mtd/nand/qcom_adm_dma.c |  797 +++++
13  drivers/mtd/nand/qcom_adm_dma.h |  268 ++
14  drivers/mtd/nand/qcom_nand.c    | 7455 +++++++++++++++++++++++++++++++++++++++
15  drivers/mtd/nand/qcom_nand.h    |  196 +
16  6 files changed, 8736 insertions(+)
17  create mode 100644 drivers/mtd/nand/qcom_adm_dma.c
18  create mode 100644 drivers/mtd/nand/qcom_adm_dma.h
19  create mode 100644 drivers/mtd/nand/qcom_nand.c
20  create mode 100644 drivers/mtd/nand/qcom_nand.h
21
22 --- a/drivers/mtd/nand/Kconfig
23 +++ b/drivers/mtd/nand/Kconfig
24 @@ -510,4 +510,22 @@ config MTD_NAND_XWAY
25           Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
26           to the External Bus Unit (EBU).
27  
28 +config MTD_QCOM_DMA
29 +       tristate "QCMO NAND DMA Support"
30 +       depends on ARCH_QCOM && MTD_QCOM_NAND
31 +       default n
32 +       help
33 +         DMA support for QCOM NAND
34 +
35 +config MTD_QCOM_NAND
36 +       tristate "QCOM NAND Device Support"
37 +       depends on MTD && ARCH_QCOM
38 +       select CRC16
39 +       select BITREVERSE
40 +       select MTD_NAND_IDS
41 +       select MTD_QCOM_DMA
42 +       default y
43 +       help
44 +         Support for some NAND chips connected to the QCOM NAND controller.
45 +
46  endif # MTD_NAND
47 --- a/drivers/mtd/nand/Makefile
48 +++ b/drivers/mtd/nand/Makefile
49 @@ -49,5 +49,7 @@ obj-$(CONFIG_MTD_NAND_JZ4740)         += jz4740
50  obj-$(CONFIG_MTD_NAND_GPMI_NAND)       += gpmi-nand/
51  obj-$(CONFIG_MTD_NAND_XWAY)            += xway_nand.o
52  obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH)   += bcm47xxnflash/
53 +obj-$(CONFIG_MTD_QCOM_NAND)    += qcom_nand.o
54 +obj-$(CONFIG_MTD_QCOM_DMA)     += qcom_adm_dma.o
55  
56  nand-objs := nand_base.o nand_bbt.o
57 --- /dev/null
58 +++ b/drivers/mtd/nand/qcom_adm_dma.c
59 @@ -0,0 +1,797 @@
60 +/* * Copyright (c) 2012 The Linux Foundation. All rights reserved.* */
61 +/* linux/arch/arm/mach-msm/dma.c
62 + *
63 + * Copyright (C) 2007 Google, Inc.
64 + * Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
65 + *
66 + * This software is licensed under the terms of the GNU General Public
67 + * License version 2, as published by the Free Software Foundation, and
68 + * may be copied, distributed, and modified under those terms.
69 + *
70 + * This program is distributed in the hope that it will be useful,
71 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
72 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
73 + * GNU General Public License for more details.
74 + *
75 + */
76 +
77 +#include <linux/clk.h>
78 +#include <linux/err.h>
79 +#include <linux/io.h>
80 +#include <linux/interrupt.h>
81 +#include <linux/module.h>
82 +#include <linux/platform_device.h>
83 +#include <linux/spinlock.h>
84 +#include <linux/pm_runtime.h>
85 +#include <linux/reset.h>
86 +#include <linux/reset-controller.h>
87 +#include "qcom_adm_dma.h"
88 +
89 +#define MODULE_NAME "msm_dmov"
90 +
91 +#define MSM_DMOV_CHANNEL_COUNT 16
92 +#define MSM_DMOV_CRCI_COUNT 16
93 +
94 +enum {
95 +       CLK_DIS,
96 +       CLK_TO_BE_DIS,
97 +       CLK_EN
98 +};
99 +
100 +struct msm_dmov_ci_conf {
101 +       int start;
102 +       int end;
103 +       int burst;
104 +};
105 +
106 +struct msm_dmov_crci_conf {
107 +       int sd;
108 +       int blk_size;
109 +};
110 +
111 +struct msm_dmov_chan_conf {
112 +       int sd;
113 +       int block;
114 +       int priority;
115 +};
116 +
117 +struct msm_dmov_conf {
118 +       void *base;
119 +       struct msm_dmov_crci_conf *crci_conf;
120 +       struct msm_dmov_chan_conf *chan_conf;
121 +       int channel_active;
122 +       int sd;
123 +       size_t sd_size;
124 +       struct list_head staged_commands[MSM_DMOV_CHANNEL_COUNT];
125 +       struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
126 +       struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
127 +       struct mutex lock;
128 +       spinlock_t list_lock;
129 +       unsigned int irq;
130 +       struct clk *clk;
131 +       struct clk *pclk;
132 +       struct clk *ebiclk;
133 +       unsigned int clk_ctl;
134 +       struct delayed_work work;
135 +       struct workqueue_struct *cmd_wq;
136 +
137 +       struct reset_control *adm_reset;
138 +       struct reset_control *pbus_reset;
139 +       struct reset_control *c0_reset;
140 +       struct reset_control *c1_reset;
141 +       struct reset_control *c2_reset;
142 +       
143 +};
144 +
145 +static void msm_dmov_clock_work(struct work_struct *);
146 +
147 +#define DMOV_CRCI_DEFAULT_CONF { .sd = 0, .blk_size = 0 }
148 +#define DMOV_CRCI_CONF(secd, blk) { .sd = secd, .blk_size = blk }
149 +
150 +static struct msm_dmov_crci_conf adm_crci_conf[] = {
151 +       DMOV_CRCI_DEFAULT_CONF,
152 +       DMOV_CRCI_DEFAULT_CONF,
153 +       DMOV_CRCI_DEFAULT_CONF,
154 +       DMOV_CRCI_DEFAULT_CONF,
155 +       DMOV_CRCI_DEFAULT_CONF,
156 +       DMOV_CRCI_DEFAULT_CONF,
157 +       DMOV_CRCI_DEFAULT_CONF,
158 +       DMOV_CRCI_DEFAULT_CONF,
159 +       DMOV_CRCI_DEFAULT_CONF,
160 +       DMOV_CRCI_DEFAULT_CONF,
161 +       DMOV_CRCI_CONF(0, 1),
162 +       DMOV_CRCI_DEFAULT_CONF,
163 +       DMOV_CRCI_DEFAULT_CONF,
164 +       DMOV_CRCI_DEFAULT_CONF,
165 +       DMOV_CRCI_DEFAULT_CONF,
166 +       DMOV_CRCI_DEFAULT_CONF,
167 +};
168 +
169 +#define DMOV_CHANNEL_DEFAULT_CONF { .sd = 0, .block = 0, .priority = 1 }
170 +
171 +static struct msm_dmov_chan_conf adm_chan_conf[] = {
172 +       DMOV_CHANNEL_DEFAULT_CONF,
173 +       DMOV_CHANNEL_DEFAULT_CONF,
174 +       DMOV_CHANNEL_DEFAULT_CONF,
175 +       DMOV_CHANNEL_DEFAULT_CONF,
176 +       DMOV_CHANNEL_DEFAULT_CONF,
177 +       DMOV_CHANNEL_DEFAULT_CONF,
178 +       DMOV_CHANNEL_DEFAULT_CONF,
179 +       DMOV_CHANNEL_DEFAULT_CONF,
180 +       DMOV_CHANNEL_DEFAULT_CONF,
181 +       DMOV_CHANNEL_DEFAULT_CONF,
182 +       DMOV_CHANNEL_DEFAULT_CONF,
183 +       DMOV_CHANNEL_DEFAULT_CONF,
184 +       DMOV_CHANNEL_DEFAULT_CONF,
185 +       DMOV_CHANNEL_DEFAULT_CONF,
186 +       DMOV_CHANNEL_DEFAULT_CONF,
187 +       DMOV_CHANNEL_DEFAULT_CONF,
188 +};
189 +
190 +#define DMOV_IRQ_TO_ADM(irq) 0
191 +
192 +static struct msm_dmov_conf dmov_conf[] = {
193 +       {
194 +               .crci_conf = adm_crci_conf,
195 +               .chan_conf = adm_chan_conf,
196 +               .lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
197 +               .list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
198 +               .clk_ctl = CLK_EN,
199 +               .work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
200 +                               msm_dmov_clock_work,0),
201 +       }
202 +};
203 +
204 +#define MSM_DMOV_ID_COUNT (MSM_DMOV_CHANNEL_COUNT * ARRAY_SIZE(dmov_conf))
205 +#define DMOV_REG(name, adm)    ((name) + (dmov_conf[adm].base) +\
206 +       (dmov_conf[adm].sd * dmov_conf[adm].sd_size))
207 +#define DMOV_ID_TO_ADM(id)   ((id) / MSM_DMOV_CHANNEL_COUNT)
208 +#define DMOV_ID_TO_CHAN(id)   ((id) % MSM_DMOV_CHANNEL_COUNT)
209 +#define DMOV_CHAN_ADM_TO_ID(ch, adm) ((ch) + (adm) * MSM_DMOV_CHANNEL_COUNT)
210 +
211 +enum {
212 +       MSM_DMOV_PRINT_ERRORS = 1,
213 +       MSM_DMOV_PRINT_IO = 2,
214 +       MSM_DMOV_PRINT_FLOW = 4
215 +};
216 +
217 +unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
218 +
219 +#define MSM_DMOV_DPRINTF(mask, format, args...) \
220 +       do { \
221 +               if ((mask) & msm_dmov_print_mask) \
222 +                       printk(KERN_ERR format, args); \
223 +       } while (0)
224 +#define PRINT_ERROR(format, args...) \
225 +       MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_ERRORS, format, args);
226 +#define PRINT_IO(format, args...) \
227 +       MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_IO, format, args);
228 +#define PRINT_FLOW(format, args...) \
229 +       MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
230 +
231 +static int msm_dmov_clk_on(int adm)
232 +{
233 +       int ret;
234 +
235 +return 0;
236 +       ret = clk_prepare_enable(dmov_conf[adm].clk);
237 +       if (ret)
238 +               return ret;
239 +       if (dmov_conf[adm].pclk) {
240 +               ret = clk_prepare_enable(dmov_conf[adm].pclk);
241 +               if (ret) {
242 +                       clk_disable_unprepare(dmov_conf[adm].clk);
243 +                       return ret;
244 +               }
245 +       }
246 +       if (dmov_conf[adm].ebiclk) {
247 +               ret = clk_prepare_enable(dmov_conf[adm].ebiclk);
248 +               if (ret) {
249 +                       if (dmov_conf[adm].pclk)
250 +                               clk_disable_unprepare(dmov_conf[adm].pclk);
251 +                       clk_disable_unprepare(dmov_conf[adm].clk);
252 +               }
253 +       }
254 +       return ret;
255 +}
256 +
257 +static void msm_dmov_clk_off(int adm)
258 +{
259 +#if 0
260 +       if (dmov_conf[adm].ebiclk)
261 +               clk_disable_unprepare(dmov_conf[adm].ebiclk);
262 +       if (dmov_conf[adm].pclk)
263 +               clk_disable_unprepare(dmov_conf[adm].pclk);
264 +       clk_disable_unprepare(dmov_conf[adm].clk);
265 +#endif
266 +}
267 +
268 +static void msm_dmov_clock_work(struct work_struct *work)
269 +{
270 +       struct msm_dmov_conf *conf =
271 +               container_of(to_delayed_work(work), struct msm_dmov_conf, work);
272 +       int adm = DMOV_IRQ_TO_ADM(conf->irq);
273 +       mutex_lock(&conf->lock);
274 +       if (conf->clk_ctl == CLK_TO_BE_DIS) {
275 +               BUG_ON(conf->channel_active);
276 +               msm_dmov_clk_off(adm);
277 +               conf->clk_ctl = CLK_DIS;
278 +       }
279 +       mutex_unlock(&conf->lock);
280 +}
281 +
282 +enum {
283 +       NOFLUSH = 0,
284 +       GRACEFUL,
285 +       NONGRACEFUL,
286 +};
287 +
288 +/* Caller must hold the list lock */
289 +static struct msm_dmov_cmd *start_ready_cmd(unsigned ch, int adm)
290 +{
291 +       struct msm_dmov_cmd *cmd;
292 +
293 +       if (list_empty(&dmov_conf[adm].ready_commands[ch])) {
294 +               return NULL;
295 +       }
296 +
297 +       cmd = list_entry(dmov_conf[adm].ready_commands[ch].next, typeof(*cmd),
298 +                        list);
299 +       list_del(&cmd->list);
300 +       if (cmd->exec_func)
301 +               cmd->exec_func(cmd);
302 +       list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
303 +       if (!dmov_conf[adm].channel_active) {
304 +               enable_irq(dmov_conf[adm].irq);
305 +       }
306 +       dmov_conf[adm].channel_active |= BIT(ch);
307 +       PRINT_IO("msm dmov enqueue command, %x, ch %d\n", cmd->cmdptr, ch);
308 +       writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
309 +
310 +       return cmd;
311 +}
312 +
313 +static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
314 +{
315 +       struct msm_dmov_cmd *cmd =
316 +               container_of(work, struct msm_dmov_cmd, work);
317 +       unsigned id = cmd->id;
318 +       unsigned status;
319 +       unsigned long flags;
320 +       int adm = DMOV_ID_TO_ADM(id);
321 +       int ch = DMOV_ID_TO_CHAN(id);
322 +
323 +       mutex_lock(&dmov_conf[adm].lock);
324 +       if (dmov_conf[adm].clk_ctl == CLK_DIS) {
325 +               status = msm_dmov_clk_on(adm);
326 +               if (status != 0)
327 +                       goto error;
328 +       }
329 +       dmov_conf[adm].clk_ctl = CLK_EN;
330 +
331 +       spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
332 +
333 +       cmd = list_entry(dmov_conf[adm].staged_commands[ch].next, typeof(*cmd),
334 +                        list);
335 +       list_del(&cmd->list);
336 +       list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
337 +       status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
338 +       if (status & DMOV_STATUS_CMD_PTR_RDY) {
339 +               PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
340 +                       id, status);
341 +               cmd = start_ready_cmd(ch, adm);
342 +               /*
343 +                * We added something to the ready list, and still hold the
344 +                * list lock. Thus, no need to check for cmd == NULL
345 +                */
346 +               if (cmd->toflush) {
347 +                       int flush = (cmd->toflush == GRACEFUL) ? 1 << 31 : 0;
348 +                       writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
349 +               }
350 +       } else {
351 +               cmd->toflush = 0;
352 +               if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
353 +                   !list_empty(&dmov_conf[adm].ready_commands[ch]))
354 +                       PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
355 +                               "status %x\n", id, status);
356 +               PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
357 +                   "%x\n", id, status);
358 +       }
359 +       if (!dmov_conf[adm].channel_active) {
360 +               dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
361 +               schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
362 +       }
363 +       spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
364 +error:
365 +       mutex_unlock(&dmov_conf[adm].lock);
366 +}
367 +
368 +static void __msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
369 +{
370 +       int adm = DMOV_ID_TO_ADM(id);
371 +       int ch = DMOV_ID_TO_CHAN(id);
372 +       unsigned long flags;
373 +       cmd->id = id;
374 +       cmd->toflush = 0;
375 +
376 +       spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
377 +       list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
378 +       spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
379 +
380 +       queue_work(dmov_conf[adm].cmd_wq, &cmd->work);
381 +}
382 +
383 +void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
384 +{
385 +       INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
386 +       __msm_dmov_enqueue_cmd_ext(id, cmd);
387 +}
388 +EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
389 +
390 +void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
391 +{
392 +       /* Disable callback function (for backwards compatibility) */
393 +       cmd->exec_func = NULL;
394 +       INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
395 +       __msm_dmov_enqueue_cmd_ext(id, cmd);
396 +}
397 +EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
398 +
399 +void msm_dmov_flush(unsigned int id, int graceful)
400 +{
401 +       unsigned long irq_flags;
402 +       int ch = DMOV_ID_TO_CHAN(id);
403 +       int adm = DMOV_ID_TO_ADM(id);
404 +       int flush = graceful ? DMOV_FLUSH_TYPE : 0;
405 +       struct msm_dmov_cmd *cmd;
406 +
407 +       spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
408 +       /* XXX not checking if flush cmd sent already */
409 +       if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
410 +               PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
411 +               writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
412 +       }
413 +       list_for_each_entry(cmd, &dmov_conf[adm].staged_commands[ch], list)
414 +               cmd->toflush = graceful ? GRACEFUL : NONGRACEFUL;
415 +       /* spin_unlock_irqrestore has the necessary barrier */
416 +       spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
417 +}
418 +EXPORT_SYMBOL(msm_dmov_flush);
419 +
420 +struct msm_dmov_exec_cmdptr_cmd {
421 +       struct msm_dmov_cmd dmov_cmd;
422 +       struct completion complete;
423 +       unsigned id;
424 +       unsigned int result;
425 +       struct msm_dmov_errdata err;
426 +};
427 +
428 +static void
429 +dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
430 +                              unsigned int result,
431 +                              struct msm_dmov_errdata *err)
432 +{
433 +       struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
434 +       cmd->result = result;
435 +       if (result != 0x80000002 && err)
436 +               memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
437 +
438 +       complete(&cmd->complete);
439 +}
440 +
441 +int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
442 +{
443 +       struct msm_dmov_exec_cmdptr_cmd cmd;
444 +
445 +       PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
446 +
447 +       cmd.dmov_cmd.cmdptr = cmdptr;
448 +       cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
449 +       cmd.dmov_cmd.exec_func = NULL;
450 +       cmd.id = id;
451 +       cmd.result = 0;
452 +       INIT_WORK_ONSTACK(&cmd.dmov_cmd.work, msm_dmov_enqueue_cmd_ext_work);
453 +       init_completion(&cmd.complete);
454 +
455 +       __msm_dmov_enqueue_cmd_ext(id, &cmd.dmov_cmd);
456 +       wait_for_completion_timeout(&cmd.complete, msecs_to_jiffies(1000));
457 +
458 +       if (cmd.result != 0x80000002) {
459 +               PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
460 +               PRINT_ERROR("dmov_exec_cmdptr(%d):  flush: %x %x %x %x\n",
461 +                       id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
462 +               return -EIO;
463 +       }
464 +       PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
465 +       return 0;
466 +}
467 +EXPORT_SYMBOL(msm_dmov_exec_cmd);
468 +
469 +static void fill_errdata(struct msm_dmov_errdata *errdata, int ch, int adm)
470 +{
471 +       errdata->flush[0] = readl_relaxed(DMOV_REG(DMOV_FLUSH0(ch), adm));
472 +       errdata->flush[1] = readl_relaxed(DMOV_REG(DMOV_FLUSH1(ch), adm));
473 +       errdata->flush[2] = 0;
474 +       errdata->flush[3] = readl_relaxed(DMOV_REG(DMOV_FLUSH3(ch), adm));
475 +       errdata->flush[4] = readl_relaxed(DMOV_REG(DMOV_FLUSH4(ch), adm));
476 +       errdata->flush[5] = readl_relaxed(DMOV_REG(DMOV_FLUSH5(ch), adm));
477 +}
478 +
479 +static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
480 +{
481 +        unsigned int int_status;
482 +       unsigned int mask;
483 +       unsigned int id;
484 +       unsigned int ch;
485 +       unsigned long irq_flags;
486 +       unsigned int ch_status;
487 +       unsigned int ch_result;
488 +       unsigned int valid = 0;
489 +       struct msm_dmov_cmd *cmd;
490 +       int adm = DMOV_IRQ_TO_ADM(irq);
491 +
492 +       mutex_lock(&dmov_conf[adm].lock);
493 +       /* read and clear isr */
494 +       int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
495 +       PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
496 +
497 +       spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
498 +       while (int_status) {
499 +               mask = int_status & -int_status;
500 +               ch = fls(mask) - 1;
501 +               id = DMOV_CHAN_ADM_TO_ID(ch, adm);
502 +               PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
503 +               int_status &= ~mask;
504 +               ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
505 +               if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
506 +                       PRINT_FLOW("msm_datamover_irq_handler id %d, "
507 +                               "result not valid %x\n", id, ch_status);
508 +                       continue;
509 +               }
510 +               do {
511 +                       valid = 1;
512 +                       ch_result = readl_relaxed(DMOV_REG(DMOV_RSLT(ch), adm));
513 +                       if (list_empty(&dmov_conf[adm].active_commands[ch])) {
514 +                               PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
515 +                                       "with no active command, status %x, result %x\n",
516 +                                       id, ch_status, ch_result);
517 +                               cmd = NULL;
518 +                       } else {
519 +                               cmd = list_entry(dmov_conf[adm].
520 +                                       active_commands[ch].next, typeof(*cmd),
521 +                                       list);
522 +                       }
523 +                       PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
524 +                       if (ch_result & DMOV_RSLT_DONE) {
525 +                               PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
526 +                                       id, ch_status);
527 +                               PRINT_IO("msm_datamover_irq_handler id %d, got result "
528 +                                       "for %p, result %x\n", id, cmd, ch_result);
529 +                               if (cmd) {
530 +                                       list_del(&cmd->list);
531 +                                       cmd->complete_func(cmd, ch_result, NULL);
532 +                               }
533 +                       }
534 +                       if (ch_result & DMOV_RSLT_FLUSH) {
535 +                               struct msm_dmov_errdata errdata;
536 +
537 +                               fill_errdata(&errdata, ch, adm);
538 +                               PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
539 +                               PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
540 +                               if (cmd) {
541 +                                       list_del(&cmd->list);
542 +                                       cmd->complete_func(cmd, ch_result, &errdata);
543 +                               }
544 +                       }
545 +                       if (ch_result & DMOV_RSLT_ERROR) {
546 +                               struct msm_dmov_errdata errdata;
547 +
548 +                               fill_errdata(&errdata, ch, adm);
549 +
550 +                               PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
551 +                               PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
552 +                               if (cmd) {
553 +                                       list_del(&cmd->list);
554 +                                       cmd->complete_func(cmd, ch_result, &errdata);
555 +                               }
556 +                               /* this does not seem to work, once we get an error */
557 +                               /* the datamover will no longer accept commands */
558 +                               writel_relaxed(0, DMOV_REG(DMOV_FLUSH0(ch),
559 +                                              adm));
560 +                       }
561 +                       rmb();
562 +                       ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
563 +                                                 adm));
564 +                       PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
565 +                       if (ch_status & DMOV_STATUS_CMD_PTR_RDY)
566 +                               start_ready_cmd(ch, adm);
567 +               } while (ch_status & DMOV_STATUS_RSLT_VALID);
568 +               if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
569 +                   list_empty(&dmov_conf[adm].ready_commands[ch]))
570 +                       dmov_conf[adm].channel_active &= ~(1U << ch);
571 +               PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
572 +       }
573 +       spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
574 +
575 +       if (!dmov_conf[adm].channel_active && valid) {
576 +               disable_irq_nosync(dmov_conf[adm].irq);
577 +               dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
578 +               schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
579 +       }
580 +
581 +       mutex_unlock(&dmov_conf[adm].lock);
582 +
583 +       return valid ? IRQ_HANDLED : IRQ_NONE;
584 +}
585 +
586 +static int msm_dmov_suspend_late(struct device *dev)
587 +{
588 +       struct platform_device *pdev = to_platform_device(dev);
589 +       int adm = (pdev->id >= 0) ? pdev->id : 0;
590 +       mutex_lock(&dmov_conf[adm].lock);
591 +       if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
592 +               BUG_ON(dmov_conf[adm].channel_active);
593 +               msm_dmov_clk_off(adm);
594 +               dmov_conf[adm].clk_ctl = CLK_DIS;
595 +       }
596 +       mutex_unlock(&dmov_conf[adm].lock);
597 +       return 0;
598 +}
599 +
600 +static int msm_dmov_runtime_suspend(struct device *dev)
601 +{
602 +       dev_dbg(dev, "pm_runtime: suspending...\n");
603 +       return 0;
604 +}
605 +
606 +static int msm_dmov_runtime_resume(struct device *dev)
607 +{
608 +       dev_dbg(dev, "pm_runtime: resuming...\n");
609 +       return 0;
610 +}
611 +
612 +static int msm_dmov_runtime_idle(struct device *dev)
613 +{
614 +       dev_dbg(dev, "pm_runtime: idling...\n");
615 +       return 0;
616 +}
617 +
618 +static struct dev_pm_ops msm_dmov_dev_pm_ops = {
619 +       .runtime_suspend = msm_dmov_runtime_suspend,
620 +       .runtime_resume = msm_dmov_runtime_resume,
621 +       .runtime_idle = msm_dmov_runtime_idle,
622 +       .suspend = msm_dmov_suspend_late,
623 +};
624 +
625 +static int msm_dmov_init_clocks(struct platform_device *pdev)
626 +{
627 +       int adm = (pdev->id >= 0) ? pdev->id : 0;
628 +       int ret;
629 +
630 +       dmov_conf[adm].clk = devm_clk_get(&pdev->dev, "core_clk");
631 +       if (IS_ERR(dmov_conf[adm].clk)) {
632 +               printk(KERN_ERR "%s: Error getting adm_clk\n", __func__);
633 +               dmov_conf[adm].clk = NULL;
634 +               return -ENOENT;
635 +       }
636 +
637 +       dmov_conf[adm].pclk = devm_clk_get(&pdev->dev, "iface_clk");
638 +       if (IS_ERR(dmov_conf[adm].pclk)) {
639 +               dmov_conf[adm].pclk = NULL;
640 +               /* pclk not present on all SoCs, don't bail on failure */
641 +       }
642 +
643 +       dmov_conf[adm].ebiclk = devm_clk_get(&pdev->dev, "mem_clk");
644 +       if (IS_ERR(dmov_conf[adm].ebiclk)) {
645 +               dmov_conf[adm].ebiclk = NULL;
646 +               /* ebiclk not present on all SoCs, don't bail on failure */
647 +       } else {
648 +               ret = clk_set_rate(dmov_conf[adm].ebiclk, 27000000);
649 +               if (ret)
650 +                       return -ENOENT;
651 +       }
652 +
653 +       return 0;
654 +}
655 +
656 +static void config_datamover(int adm)
657 +{
658 +       int i;
659 +
660 +       /* Reset the ADM */
661 +       reset_control_assert(dmov_conf[adm].adm_reset);
662 +       reset_control_assert(dmov_conf[adm].c0_reset);
663 +       reset_control_assert(dmov_conf[adm].c1_reset);
664 +       reset_control_assert(dmov_conf[adm].c2_reset);
665 +
666 +       reset_control_deassert(dmov_conf[adm].c2_reset);
667 +       reset_control_deassert(dmov_conf[adm].c1_reset);
668 +       reset_control_deassert(dmov_conf[adm].c0_reset);
669 +       reset_control_deassert(dmov_conf[adm].adm_reset);
670 +
671 +       for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
672 +               struct msm_dmov_chan_conf *chan_conf =
673 +                       dmov_conf[adm].chan_conf;
674 +               unsigned conf;
675 +               /* Only configure scorpion channels */
676 +               if (chan_conf[i].sd <= 1) {
677 +                       conf = readl_relaxed(DMOV_REG(DMOV_CONF(i), adm));
678 +                       conf |= DMOV_CONF_MPU_DISABLE |
679 +                               DMOV_CONF_PERM_MPU_CONF |
680 +                               DMOV_CONF_FLUSH_RSLT_EN |
681 +                               DMOV_CONF_FORCE_RSLT_EN |
682 +                               DMOV_CONF_IRQ_EN |
683 +                               DMOV_CONF_PRIORITY(chan_conf[i].priority);
684 +
685 +                       conf &= ~DMOV_CONF_SD(7);
686 +                       conf |= DMOV_CONF_SD(chan_conf[i].sd);
687 +                       writel_relaxed(conf, DMOV_REG(DMOV_CONF(i), adm));
688 +               }
689 +       }
690 +
691 +       for (i = 0; i < MSM_DMOV_CRCI_COUNT; i++) {
692 +               writel_relaxed(DMOV_CRCI_CTL_RST,
693 +                      DMOV_REG(DMOV_CRCI_CTL(i), adm));
694 +       }
695 +
696 +       /* NAND CRCI Enable */
697 +       writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_NAND_CRCI_DATA), adm));
698 +       writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_NAND_CRCI_CMD), adm));
699 +
700 +       /* GSBI5 CRCI Enable */
701 +       writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_SPI_GSBI5_RX_CRCI), adm));
702 +       writel_relaxed(0, DMOV_REG(DMOV_CRCI_CTL(DMOV_SPI_GSBI5_TX_CRCI), adm));
703 +
704 +       writel_relaxed(DMOV_CI_CONF_RANGE_START(0x40) | /* EBI1 */
705 +                       DMOV_CI_CONF_RANGE_END(0xb0) |
706 +                       DMOV_CI_CONF_MAX_BURST(0x8),
707 +                      DMOV_REG(DMOV_CI_CONF(0), adm));
708 +
709 +       writel_relaxed(DMOV_CI_CONF_RANGE_START(0x2a) | /* IMEM */
710 +                       DMOV_CI_CONF_RANGE_END(0x2c) |
711 +                       DMOV_CI_CONF_MAX_BURST(0x8),
712 +                      DMOV_REG(DMOV_CI_CONF(1), adm));
713 +
714 +       writel_relaxed(DMOV_CI_CONF_RANGE_START(0x12) | /* CPSS/SPS */
715 +                       DMOV_CI_CONF_RANGE_END(0x28) |
716 +                       DMOV_CI_CONF_MAX_BURST(0x8),
717 +                      DMOV_REG(DMOV_CI_CONF(2), adm));
718 +
719 +       writel_relaxed(DMOV_HI_GP_CTL_CORE_CLK_LP_EN | /* will disable LP */
720 +                       DMOV_HI_GP_CTL_LP_CNT(0xf),
721 +                      DMOV_REG(DMOV_HI_GP_CTL, adm));
722 +
723 +}
724 +
725 +static int msm_dmov_probe(struct platform_device *pdev)
726 +{
727 +       
728 +        int adm = (pdev->id >= 0) ? pdev->id : 0;
729 +       int i;
730 +       int ret;
731 +       struct resource *irqres =
732 +               platform_get_resource(pdev, IORESOURCE_IRQ, 0);
733 +       struct resource *mres =
734 +               platform_get_resource(pdev, IORESOURCE_MEM, 0);
735 +
736 +        dmov_conf[adm].sd=0;
737 +        dmov_conf[adm].sd_size=0x800;
738 +          
739 +       dmov_conf[adm].irq = irqres->start;
740 +
741 +       dmov_conf[adm].base = devm_ioremap_resource(&pdev->dev, mres);
742 +       if (!dmov_conf[adm].base)
743 +               return -ENOMEM;
744 +
745 +       dmov_conf[adm].cmd_wq = alloc_ordered_workqueue("dmov%d_wq", 0, adm);
746 +       if (!dmov_conf[adm].cmd_wq) {
747 +               PRINT_ERROR("Couldn't allocate ADM%d workqueue.\n", adm);
748 +               return -ENOMEM;
749 +       }
750 +
751 +       /* get resets */
752 +       dmov_conf[adm].adm_reset = devm_reset_control_get(&pdev->dev, "adm");
753 +       if (IS_ERR(dmov_conf[adm].adm_reset)) {
754 +               dev_err(&pdev->dev, "failed to get adm reset\n");
755 +               ret = PTR_ERR(dmov_conf[adm].adm_reset);
756 +               goto out_wq;
757 +       }
758 +
759 +       dmov_conf[adm].pbus_reset = devm_reset_control_get(&pdev->dev, "pbus");
760 +       if (IS_ERR(dmov_conf[adm].pbus_reset)) {
761 +               dev_err(&pdev->dev, "failed to get pbus reset\n");
762 +               ret = PTR_ERR(dmov_conf[adm].pbus_reset);
763 +               goto out_wq;
764 +       }
765 +
766 +       dmov_conf[adm].c0_reset = devm_reset_control_get(&pdev->dev, "c0");
767 +       if (IS_ERR(dmov_conf[adm].c0_reset)) {
768 +               dev_err(&pdev->dev, "failed to get c0 reset\n");
769 +               ret = PTR_ERR(dmov_conf[adm].c0_reset);
770 +               goto out_wq;
771 +       }
772 +
773 +       dmov_conf[adm].c1_reset = devm_reset_control_get(&pdev->dev, "c1");
774 +       if (IS_ERR(dmov_conf[adm].c1_reset)) {
775 +               dev_err(&pdev->dev, "failed to get c1 reset\n");
776 +               ret = PTR_ERR(dmov_conf[adm].c1_reset);
777 +               goto out_wq;
778 +       }
779 +
780 +       dmov_conf[adm].c2_reset = devm_reset_control_get(&pdev->dev, "c2");
781 +       if (IS_ERR(dmov_conf[adm].c2_reset)) {
782 +               dev_err(&pdev->dev, "failed to get c2 reset\n");
783 +               ret = PTR_ERR(dmov_conf[adm].c2_reset);
784 +               goto out_wq;
785 +       }
786 +
787 +       ret = devm_request_threaded_irq(&pdev->dev, dmov_conf[adm].irq, NULL,
788 +               msm_dmov_isr, IRQF_ONESHOT, "msmdatamover", NULL);
789 +
790 +       if (ret) {
791 +               PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
792 +                       dmov_conf[adm].irq);
793 +               goto out_wq;
794 +       }
795 +
796 +       disable_irq(dmov_conf[adm].irq);
797 +       ret = msm_dmov_init_clocks(pdev);
798 +       if (ret) {
799 +               PRINT_ERROR("Requesting ADM%d clocks failed\n", adm);
800 +               goto out_wq;
801 +       }
802 +       clk_prepare_enable(dmov_conf[adm].clk);
803 +       clk_prepare_enable(dmov_conf[adm].pclk);
804 +
805 +//     ret = msm_dmov_clk_on(adm);
806 +//     if (ret) {
807 +//             PRINT_ERROR("Enabling ADM%d clocks failed\n", adm);
808 +//             goto out_wq;
809 +//     }
810 +
811 +       config_datamover(adm);
812 +       for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
813 +               INIT_LIST_HEAD(&dmov_conf[adm].staged_commands[i]);
814 +               INIT_LIST_HEAD(&dmov_conf[adm].ready_commands[i]);
815 +               INIT_LIST_HEAD(&dmov_conf[adm].active_commands[i]);
816 +
817 +               writel_relaxed(DMOV_RSLT_CONF_IRQ_EN
818 +                    | DMOV_RSLT_CONF_FORCE_FLUSH_RSLT,
819 +                    DMOV_REG(DMOV_RSLT_CONF(i), adm));
820 +       }
821 +       wmb();
822 +//     msm_dmov_clk_off(adm);
823 +       return ret;
824 +out_wq:
825 +       destroy_workqueue(dmov_conf[adm].cmd_wq);
826 +       return ret;
827 +}
828 +
829 +#ifdef CONFIG_OF
830 +static const struct of_device_id adm_of_match[] = {
831 +        { .compatible = "qcom,adm", },
832 +        {},
833 +};
834 +MODULE_DEVICE_TABLE(of, adm_of_match);
835 +#endif
836 +
837 +static struct platform_driver msm_dmov_driver = {
838 +       .probe = msm_dmov_probe,
839 +       .driver = {
840 +               .name = MODULE_NAME,
841 +               .owner = THIS_MODULE,
842 +                .of_match_table = adm_of_match,
843 +               .pm = &msm_dmov_dev_pm_ops,
844 +       },
845 +};
846 +
847 +/* static int __init */
848 +static int __init msm_init_datamover(void)
849 +{
850 +       int ret;
851 +       ret = platform_driver_register(&msm_dmov_driver);
852 +       if (ret)
853 +               return ret;
854 +       return 0;
855 +}
856 +arch_initcall(msm_init_datamover);
857 --- /dev/null
858 +++ b/drivers/mtd/nand/qcom_adm_dma.h
859 @@ -0,0 +1,268 @@
860 +/* * Copyright (c) 2012 The Linux Foundation. All rights reserved.* */
861 +/* linux/include/asm-arm/arch-msm/dma.h
862 + *
863 + * Copyright (C) 2007 Google, Inc.
864 + * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
865 + *
866 + * This software is licensed under the terms of the GNU General Public
867 + * License version 2, as published by the Free Software Foundation, and
868 + * may be copied, distributed, and modified under those terms.
869 + *
870 + * This program is distributed in the hope that it will be useful,
871 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
872 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
873 + * GNU General Public License for more details.
874 + *
875 + */
876 +
877 +#ifndef __ASM_ARCH_MSM_DMA_H
878 +#define __ASM_ARCH_MSM_DMA_H
879 +#include <linux/list.h>
880 +
881 +struct msm_dmov_errdata {
882 +       uint32_t flush[6];
883 +};
884 +
885 +struct msm_dmov_cmd {
886 +       struct list_head list;
887 +       unsigned int cmdptr;
888 +       void (*complete_func)(struct msm_dmov_cmd *cmd,
889 +                             unsigned int result,
890 +                             struct msm_dmov_errdata *err);
891 +       void (*exec_func)(struct msm_dmov_cmd *cmd);
892 +       struct work_struct work;
893 +       unsigned id;    /* For internal use */
894 +       void *user;     /* Pointer for caller's reference */
895 +       u8 toflush;
896 +};
897 +
898 +struct msm_dmov_pdata {
899 +       int sd;
900 +       size_t sd_size;
901 +};
902 +
903 +void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
904 +void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd);
905 +void msm_dmov_flush(unsigned int id, int graceful);
906 +int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
907 +
908 +#define DMOV_CRCIS_PER_CONF 10
909 +
910 +#define DMOV_ADDR(off, ch) ((off) + ((ch) << 2))
911 +
912 +#define DMOV_CMD_PTR(ch)      DMOV_ADDR(0x000, ch)
913 +#define DMOV_CMD_LIST         (0 << 29) /* does not work */
914 +#define DMOV_CMD_PTR_LIST     (1 << 29) /* works */
915 +#define DMOV_CMD_INPUT_CFG    (2 << 29) /* untested */
916 +#define DMOV_CMD_OUTPUT_CFG   (3 << 29) /* untested */
917 +#define DMOV_CMD_ADDR(addr)   ((addr) >> 3)
918 +
919 +#define DMOV_RSLT(ch)         DMOV_ADDR(0x040, ch)
920 +#define DMOV_RSLT_VALID       (1 << 31) /* 0 == host has empties result fifo */
921 +#define DMOV_RSLT_ERROR       (1 << 3)
922 +#define DMOV_RSLT_FLUSH       (1 << 2)
923 +#define DMOV_RSLT_DONE        (1 << 1)  /* top pointer done */
924 +#define DMOV_RSLT_USER        (1 << 0)  /* command with FR force result */
925 +
926 +#define DMOV_FLUSH0(ch)       DMOV_ADDR(0x080, ch)
927 +#define DMOV_FLUSH1(ch)       DMOV_ADDR(0x0C0, ch)
928 +#define DMOV_FLUSH2(ch)       DMOV_ADDR(0x100, ch)
929 +#define DMOV_FLUSH3(ch)       DMOV_ADDR(0x140, ch)
930 +#define DMOV_FLUSH4(ch)       DMOV_ADDR(0x180, ch)
931 +#define DMOV_FLUSH5(ch)       DMOV_ADDR(0x1C0, ch)
932 +#define DMOV_FLUSH_TYPE       (1 << 31)
933 +
934 +#define DMOV_STATUS(ch)       DMOV_ADDR(0x200, ch)
935 +#define DMOV_STATUS_RSLT_COUNT(n)    (((n) >> 29))
936 +#define DMOV_STATUS_CMD_COUNT(n)     (((n) >> 27) & 3)
937 +#define DMOV_STATUS_RSLT_VALID       (1 << 1)
938 +#define DMOV_STATUS_CMD_PTR_RDY      (1 << 0)
939 +
940 +#define DMOV_CONF(ch)         DMOV_ADDR(0x240, ch)
941 +#define DMOV_CONF_SD(sd)               (((sd & 4) << 11) | ((sd & 3) << 4))
942 +#define DMOV_CONF_OTHER_CH_BLK_MASK(m) ((m << 0x10) & 0xffff0000)
943 +#define DMOV_CONF_SHADOW_EN            (1 << 12)
944 +#define DMOV_CONF_MPU_DISABLE          (1 << 11)
945 +#define DMOV_CONF_PERM_MPU_CONF                (1 << 9)
946 +#define DMOV_CONF_FLUSH_RSLT_EN                (1 << 8)
947 +#define DMOV_CONF_IRQ_EN               (1 << 6)
948 +#define DMOV_CONF_FORCE_RSLT_EN                (1 << 7)
949 +#define DMOV_CONF_PRIORITY(n)          (n << 0)
950 +
951 +#define DMOV_DBG_ERR(ci)      DMOV_ADDR(0x280, ci)
952 +
953 +#define DMOV_RSLT_CONF(ch)    DMOV_ADDR(0x300, ch)
954 +#define DMOV_RSLT_CONF_FORCE_TOP_PTR_RSLT (1 << 2)
955 +#define DMOV_RSLT_CONF_FORCE_FLUSH_RSLT   (1 << 1)
956 +#define DMOV_RSLT_CONF_IRQ_EN             (1 << 0)
957 +
958 +#define DMOV_ISR              DMOV_ADDR(0x380, 0)
959 +
960 +#define DMOV_CI_CONF(ci)      DMOV_ADDR(0x390, ci)
961 +#define DMOV_CI_CONF_RANGE_END(n)      ((n) << 24)
962 +#define DMOV_CI_CONF_RANGE_START(n)    ((n) << 16)
963 +#define DMOV_CI_CONF_MAX_BURST(n)      ((n) << 0)
964 +
965 +#define DMOV_CI_DBG_ERR(ci)   DMOV_ADDR(0x3B0, ci)
966 +
967 +#define DMOV_CRCI_CONF0       DMOV_ADDR(0x3D0, 0)
968 +#define DMOV_CRCI_CONF0_CRCI9_SD       (2 << 0x1b)
969 +
970 +#define DMOV_CRCI_CONF1       DMOV_ADDR(0x3D4, 0)
971 +#define DMOV_CRCI_CONF0_SD(crci, sd) (sd << (crci*3))
972 +#define DMOV_CRCI_CONF1_SD(crci, sd) (sd << ((crci-DMOV_CRCIS_PER_CONF)*3))
973 +
974 +#define DMOV_HI_GP_CTL                 DMOV_ADDR(0x3D8, 0)
975 +#define DMOV_HI_GP_CTL_CORE_CLK_LP_EN  (1 << 12)
976 +#define DMOV_HI_GP_CTL_LP_CNT(x)       (((x) & 0xf) << 8)
977 +#define DMOV_HI_GP_CTL_CI3_CLK_LP_EN   (1 << 7)
978 +#define DMOV_HI_GP_CTL_CI2_CLK_LP_EN   (1 << 6)
979 +#define DMOV_HI_GP_CTL_CI1_CLK_LP_EN   (1 << 5)
980 +#define DMOV_HI_GP_CTL_CI0_CLK_LP_EN   (1 << 4)
981 +
982 +#define DMOV_CRCI_CTL(crci)   DMOV_ADDR(0x400, crci)
983 +#define DMOV_CRCI_CTL_BLK_SZ(n)        ((n) << 0)
984 +#define DMOV_CRCI_CTL_RST              (1 << 17)
985 +#define DMOV_CRCI_MUX                  (1 << 18)
986 +
987 +/* channel assignments */
988 +
989 +/*
990 + * Format of CRCI numbers: crci number + (muxsel << 4)
991 + */
992 +
993 +#define DMOV_GP_CHAN           9
994 +
995 +#define DMOV_CE_IN_CHAN        0
996 +#define DMOV_CE_IN_CRCI        2
997 +
998 +#define DMOV_CE_OUT_CHAN       1
999 +#define DMOV_CE_OUT_CRCI       3
1000 +
1001 +#define DMOV_TSIF_CHAN         2
1002 +#define DMOV_TSIF_CRCI         11
1003 +
1004 +#define DMOV_HSUART_GSBI6_TX_CHAN      7
1005 +#define DMOV_HSUART_GSBI6_TX_CRCI      6
1006 +
1007 +#define DMOV_HSUART_GSBI6_RX_CHAN      8
1008 +#define DMOV_HSUART_GSBI6_RX_CRCI      11
1009 +
1010 +#define DMOV_HSUART_GSBI8_TX_CHAN      7
1011 +#define DMOV_HSUART_GSBI8_TX_CRCI      10
1012 +
1013 +#define DMOV_HSUART_GSBI8_RX_CHAN      8
1014 +#define DMOV_HSUART_GSBI8_RX_CRCI      9
1015 +
1016 +#define DMOV_HSUART_GSBI9_TX_CHAN      4
1017 +#define DMOV_HSUART_GSBI9_TX_CRCI      13
1018 +
1019 +#define DMOV_HSUART_GSBI9_RX_CHAN      3
1020 +#define DMOV_HSUART_GSBI9_RX_CRCI      12
1021 +
1022 +#define DMOV_NAND_CHAN                 3
1023 +#define DMOV_NAND_CRCI_CMD             15
1024 +#define DMOV_NAND_CRCI_DATA            3
1025 +
1026 +#define DMOV_SPI_GSBI5_RX_CRCI         9
1027 +#define DMOV_SPI_GSBI5_TX_CRCI         10
1028 +#define DMOV_SPI_GSBI5_RX_CHAN         6
1029 +#define DMOV_SPI_GSBI5_TX_CHAN         5
1030 +
1031 +/* channels for APQ8064 */
1032 +#define DMOV8064_CE_IN_CHAN        0
1033 +#define DMOV8064_CE_IN_CRCI       14
1034 +
1035 +#define DMOV8064_CE_OUT_CHAN       1
1036 +#define DMOV8064_CE_OUT_CRCI       15
1037 +
1038 +#define DMOV8064_TSIF_CHAN         2
1039 +#define DMOV8064_TSIF_CRCI         1
1040 +
1041 +/* channels for APQ8064 SGLTE*/
1042 +#define DMOV_APQ8064_HSUART_GSBI4_TX_CHAN      11
1043 +#define DMOV_APQ8064_HSUART_GSBI4_TX_CRCI      8
1044 +
1045 +#define DMOV_APQ8064_HSUART_GSBI4_RX_CHAN      10
1046 +#define DMOV_APQ8064_HSUART_GSBI4_RX_CRCI      7
1047 +
1048 +/* channels for MPQ8064 */
1049 +#define DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN      7
1050 +#define DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI      6
1051 +
1052 +#define DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN      6
1053 +#define DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI      11
1054 +
1055 +#define DMOV_IPQ806X_HSUART_GSBI6_TX_CHAN      DMOV_MPQ8064_HSUART_GSBI6_TX_CHAN
1056 +#define DMOV_IPQ806X_HSUART_GSBI6_TX_CRCI      DMOV_MPQ8064_HSUART_GSBI6_TX_CRCI
1057 +
1058 +#define DMOV_IPQ806X_HSUART_GSBI6_RX_CHAN      DMOV_MPQ8064_HSUART_GSBI6_RX_CHAN
1059 +#define DMOV_IPQ806X_HSUART_GSBI6_RX_CRCI      DMOV_MPQ8064_HSUART_GSBI6_RX_CRCI
1060 +
1061 +/* no client rate control ifc (eg, ram) */
1062 +#define DMOV_NONE_CRCI        0
1063 +
1064 +
1065 +/* If the CMD_PTR register has CMD_PTR_LIST selected, the data mover
1066 + * is going to walk a list of 32bit pointers as described below.  Each
1067 + * pointer points to a *array* of dmov_s, etc structs.  The last pointer
1068 + * in the list is marked with CMD_PTR_LP.  The last struct in each array
1069 + * is marked with CMD_LC (see below).
1070 + */
1071 +#define CMD_PTR_ADDR(addr)  ((addr) >> 3)
1072 +#define CMD_PTR_LP          (1 << 31) /* last pointer */
1073 +#define CMD_PTR_PT          (3 << 29) /* ? */
1074 +
1075 +/* Single Item Mode */
1076 +typedef struct {
1077 +       unsigned cmd;
1078 +       unsigned src;
1079 +       unsigned dst;
1080 +       unsigned len;
1081 +} dmov_s;
1082 +
1083 +/* Scatter/Gather Mode */
1084 +typedef struct {
1085 +       unsigned cmd;
1086 +       unsigned src_dscr;
1087 +       unsigned dst_dscr;
1088 +       unsigned _reserved;
1089 +} dmov_sg;
1090 +
1091 +/* Box mode */
1092 +typedef struct {
1093 +       uint32_t cmd;
1094 +       uint32_t src_row_addr;
1095 +       uint32_t dst_row_addr;
1096 +       uint32_t src_dst_len;
1097 +       uint32_t num_rows;
1098 +       uint32_t row_offset;
1099 +} dmov_box;
1100 +
1101 +/* bits for the cmd field of the above structures */
1102 +
1103 +#define CMD_LC      (1 << 31)  /* last command */
1104 +#define CMD_FR      (1 << 22)  /* force result -- does not work? */
1105 +#define CMD_OCU     (1 << 21)  /* other channel unblock */
1106 +#define CMD_OCB     (1 << 20)  /* other channel block */
1107 +#define CMD_TCB     (1 << 19)  /* ? */
1108 +#define CMD_DAH     (1 << 18)  /* destination address hold -- does not work?*/
1109 +#define CMD_SAH     (1 << 17)  /* source address hold -- does not work? */
1110 +
1111 +#define CMD_MODE_SINGLE     (0 << 0) /* dmov_s structure used */
1112 +#define CMD_MODE_SG         (1 << 0) /* untested */
1113 +#define CMD_MODE_IND_SG     (2 << 0) /* untested */
1114 +#define CMD_MODE_BOX        (3 << 0) /* untested */
1115 +
1116 +#define CMD_DST_SWAP_BYTES  (1 << 14) /* exchange each byte n with byte n+1 */
1117 +#define CMD_DST_SWAP_SHORTS (1 << 15) /* exchange each short n with short n+1 */
1118 +#define CMD_DST_SWAP_WORDS  (1 << 16) /* exchange each word n with word n+1 */
1119 +
1120 +#define CMD_SRC_SWAP_BYTES  (1 << 11) /* exchange each byte n with byte n+1 */
1121 +#define CMD_SRC_SWAP_SHORTS (1 << 12) /* exchange each short n with short n+1 */
1122 +#define CMD_SRC_SWAP_WORDS  (1 << 13) /* exchange each word n with word n+1 */
1123 +
1124 +#define CMD_DST_CRCI(n)     (((n) & 15) << 7)
1125 +#define CMD_SRC_CRCI(n)     (((n) & 15) << 3)
1126 +
1127 +#endif
1128 --- /dev/null
1129 +++ b/drivers/mtd/nand/qcom_nand.c
1130 @@ -0,0 +1,7455 @@
1131 +/*
1132 + * Copyright (C) 2007 Google, Inc.
1133 + * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
1134 + *
1135 + * This software is licensed under the terms of the GNU General Public
1136 + * License version 2, as published by the Free Software Foundation, and
1137 + * may be copied, distributed, and modified under those terms.
1138 + *
1139 + * This program is distributed in the hope that it will be useful,
1140 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1141 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1142 + * GNU General Public License for more details.
1143 + *
1144 + */
1145 +
1146 +#include <linux/slab.h>
1147 +#include <linux/kernel.h>
1148 +#include <linux/module.h>
1149 +#include <linux/mtd/mtd.h>
1150 +#include <linux/mtd/nand.h>
1151 +#include <linux/mtd/partitions.h>
1152 +#include <linux/platform_device.h>
1153 +#include <linux/sched.h>
1154 +#include <linux/dma-mapping.h>
1155 +#include <linux/io.h>
1156 +#include <linux/crc16.h>
1157 +#include <linux/bitrev.h>
1158 +#include <linux/clk.h>
1159 +
1160 +#include <asm/dma.h>
1161 +#include <asm/mach/flash.h>
1162 +
1163 +#include "qcom_adm_dma.h"
1164 +
1165 +#include "qcom_nand.h"
1166 +unsigned long msm_nand_phys = 0;
1167 +unsigned long msm_nandc01_phys = 0;
1168 +unsigned long msm_nandc10_phys = 0;
1169 +unsigned long msm_nandc11_phys = 0;
1170 +unsigned long ebi2_register_base = 0;
1171 +static uint32_t dual_nand_ctlr_present;
1172 +static uint32_t interleave_enable;
1173 +static uint32_t enable_bch_ecc;
1174 +static uint32_t boot_layout;
1175 +
1176 +
1177 +#define MSM_NAND_DMA_BUFFER_SIZE SZ_8K
1178 +#define MSM_NAND_DMA_BUFFER_SLOTS \
1179 +       (MSM_NAND_DMA_BUFFER_SIZE / (sizeof(((atomic_t *)0)->counter) * 8))
1180 +
1181 +#define MSM_NAND_CFG0_RAW_ONFI_IDENTIFIER 0x88000800
1182 +#define MSM_NAND_CFG0_RAW_ONFI_PARAM_INFO 0x88040000
1183 +#define MSM_NAND_CFG1_RAW_ONFI_IDENTIFIER 0x0005045d
1184 +#define MSM_NAND_CFG1_RAW_ONFI_PARAM_INFO 0x0005045d
1185 +
1186 +#define ONFI_IDENTIFIER_LENGTH 0x0004
1187 +#define ONFI_PARAM_INFO_LENGTH 0x0200
1188 +#define ONFI_PARAM_PAGE_LENGTH 0x0100
1189 +
1190 +#define ONFI_PARAMETER_PAGE_SIGNATURE 0x49464E4F
1191 +
1192 +#define FLASH_READ_ONFI_IDENTIFIER_COMMAND 0x90
1193 +#define FLASH_READ_ONFI_IDENTIFIER_ADDRESS 0x20
1194 +#define FLASH_READ_ONFI_PARAMETERS_COMMAND 0xEC
1195 +#define FLASH_READ_ONFI_PARAMETERS_ADDRESS 0x00
1196 +
1197 +#define UD_SIZE_BYTES_MASK     (0x3FF << 9)
1198 +#define SPARE_SIZE_BYTES_MASK  (0xF << 23)
1199 +#define ECC_NUM_DATA_BYTES_MASK        (0x3FF << 16)
1200 +
1201 +#define VERBOSE 0
1202 +
1203 +struct msm_nand_chip {
1204 +       struct device *dev;
1205 +       wait_queue_head_t wait_queue;
1206 +       atomic_t dma_buffer_busy;
1207 +       unsigned dma_channel;
1208 +       uint8_t *dma_buffer;
1209 +       dma_addr_t dma_addr;
1210 +       unsigned CFG0, CFG1, CFG0_RAW, CFG1_RAW;
1211 +       uint32_t ecc_buf_cfg;
1212 +       uint32_t ecc_bch_cfg;
1213 +       uint32_t ecc_parity_bytes;
1214 +       unsigned cw_size;
1215 +       unsigned int uncorrectable_bit_mask;
1216 +       unsigned int num_err_mask;
1217 +};
1218 +
1219 +#define CFG1_WIDE_FLASH (1U << 1)
1220 +
1221 +/* TODO: move datamover code out */
1222 +
1223 +#define SRC_CRCI_NAND_CMD  CMD_SRC_CRCI(DMOV_NAND_CRCI_CMD)
1224 +#define DST_CRCI_NAND_CMD  CMD_DST_CRCI(DMOV_NAND_CRCI_CMD)
1225 +#define SRC_CRCI_NAND_DATA CMD_SRC_CRCI(DMOV_NAND_CRCI_DATA)
1226 +#define DST_CRCI_NAND_DATA CMD_DST_CRCI(DMOV_NAND_CRCI_DATA)
1227 +
1228 +#define msm_virt_to_dma(chip, vaddr) \
1229 +       ((chip)->dma_addr + \
1230 +        ((uint8_t *)(vaddr) - (chip)->dma_buffer))
1231 +
1232 +/**
1233 + * msm_nand_oob_64 - oob info for 2KB page
1234 + */
1235 +static struct nand_ecclayout msm_nand_oob_64 = {
1236 +       .eccbytes       = 40,
1237 +       .eccpos         = {
1238 +               0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
1239 +               10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
1240 +               20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
1241 +               46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
1242 +               },
1243 +       .oobavail       = 16,
1244 +       .oobfree        = {
1245 +               {30, 16},
1246 +       }
1247 +};
1248 +
1249 +/**
1250 + * msm_nand_oob_128 - oob info for 4KB page
1251 + */
1252 +static struct nand_ecclayout msm_nand_oob_128 = {
1253 +       .eccbytes       = 80,
1254 +       .eccpos         = {
1255 +                 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
1256 +                10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
1257 +                20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
1258 +                30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
1259 +                40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
1260 +                50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
1261 +                60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
1262 +               102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
1263 +               },
1264 +       .oobavail       = 32,
1265 +       .oobfree        = {
1266 +               {70, 32},
1267 +       }
1268 +};
1269 +
1270 +/**
1271 + * msm_nand_oob_224 - oob info for 4KB page 8Bit interface
1272 + */
1273 +static struct nand_ecclayout msm_nand_oob_224_x8 = {
1274 +       .eccbytes       = 104,
1275 +       .eccpos         = {
1276 +                 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,
1277 +                13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,
1278 +                26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,
1279 +                39,  40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,
1280 +                52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,
1281 +                65,  66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,
1282 +                78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,
1283 +               123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
1284 +               },
1285 +       .oobavail       = 32,
1286 +       .oobfree        = {
1287 +               {91, 32},
1288 +       }
1289 +};
1290 +
1291 +/**
1292 + * msm_nand_oob_224 - oob info for 4KB page 16Bit interface
1293 + */
1294 +static struct nand_ecclayout msm_nand_oob_224_x16 = {
1295 +       .eccbytes       = 112,
1296 +       .eccpos         = {
1297 +         0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,
1298 +        14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
1299 +        28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
1300 +        42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
1301 +        56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
1302 +        70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
1303 +        84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
1304 +       130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
1305 +       },
1306 +       .oobavail       = 32,
1307 +       .oobfree        = {
1308 +               {98, 32},
1309 +       }
1310 +};
1311 +
1312 +/**
1313 + * msm_nand_oob_256 - oob info for 8KB page
1314 + */
1315 +static struct nand_ecclayout msm_nand_oob_256 = {
1316 +       .eccbytes       = 160,
1317 +       .eccpos         = {
1318 +                 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,
1319 +                10,  11,  12,  13,  14,  15,  16,  17,  18,  19,
1320 +                20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
1321 +                30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
1322 +                40,  41,  42,  43,  44,  45,  46,  47,  48,  49,
1323 +                50,  51,  52,  53,  54,  55,  56,  57,  58,  59,
1324 +                60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
1325 +                70,  71,  72,  73,  74,  75,  76,  77,  78,  79,
1326 +                80,  81,  82,  83,  84,  85,  86,  87,  88,  89,
1327 +                90,  91,  92,  93,  94,  96,  97,  98 , 99, 100,
1328 +               101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
1329 +               111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
1330 +               121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
1331 +               131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
1332 +               141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
1333 +               215, 216, 217, 218, 219, 220, 221, 222, 223, 224,
1334 +               },
1335 +       .oobavail       = 64,
1336 +       .oobfree        = {
1337 +               {151, 64},
1338 +       }
1339 +};
1340 +
1341 +/**
1342 + * msm_onenand_oob_64 - oob info for large (2KB) page
1343 + */
1344 +static struct nand_ecclayout msm_onenand_oob_64 = {
1345 +       .eccbytes       = 20,
1346 +       .eccpos         = {
1347 +               8, 9, 10, 11, 12,
1348 +               24, 25, 26, 27, 28,
1349 +               40, 41, 42, 43, 44,
1350 +               56, 57, 58, 59, 60,
1351 +               },
1352 +       .oobavail       = 20,
1353 +       .oobfree        = {
1354 +               {2, 3}, {14, 2}, {18, 3}, {30, 2},
1355 +               {34, 3}, {46, 2}, {50, 3}, {62, 2}
1356 +       }
1357 +};
1358 +
1359 +static void *msm_nand_get_dma_buffer(struct msm_nand_chip *chip, size_t size)
1360 +{
1361 +       unsigned int bitmask, free_bitmask, old_bitmask;
1362 +       unsigned int need_mask, current_need_mask;
1363 +       int free_index;
1364 +
1365 +       need_mask = (1UL << DIV_ROUND_UP(size, MSM_NAND_DMA_BUFFER_SLOTS)) - 1;
1366 +       bitmask = atomic_read(&chip->dma_buffer_busy);
1367 +       free_bitmask = ~bitmask;
1368 +       while (free_bitmask) {
1369 +               free_index = __ffs(free_bitmask);
1370 +               current_need_mask = need_mask << free_index;
1371 +
1372 +               if (size + free_index * MSM_NAND_DMA_BUFFER_SLOTS >=
1373 +                                                MSM_NAND_DMA_BUFFER_SIZE)
1374 +                       return NULL;
1375 +
1376 +               if ((bitmask & current_need_mask) == 0) {
1377 +                       old_bitmask =
1378 +                               atomic_cmpxchg(&chip->dma_buffer_busy,
1379 +                                              bitmask,
1380 +                                              bitmask | current_need_mask);
1381 +                       if (old_bitmask == bitmask)
1382 +                               return chip->dma_buffer +
1383 +                                       free_index * MSM_NAND_DMA_BUFFER_SLOTS;
1384 +                       free_bitmask = 0; /* force return */
1385 +               }
1386 +               /* current free range was too small, clear all free bits */
1387 +               /* below the top busy bit within current_need_mask */
1388 +               free_bitmask &=
1389 +                       ~(~0U >> (32 - fls(bitmask & current_need_mask)));
1390 +       }
1391 +
1392 +       return NULL;
1393 +}
1394 +
1395 +static void msm_nand_release_dma_buffer(struct msm_nand_chip *chip,
1396 +                                       void *buffer, size_t size)
1397 +{
1398 +       int index;
1399 +       unsigned int used_mask;
1400 +
1401 +       used_mask = (1UL << DIV_ROUND_UP(size, MSM_NAND_DMA_BUFFER_SLOTS)) - 1;
1402 +       index = ((uint8_t *)buffer - chip->dma_buffer) /
1403 +               MSM_NAND_DMA_BUFFER_SLOTS;
1404 +       atomic_sub(used_mask << index, &chip->dma_buffer_busy);
1405 +
1406 +       wake_up(&chip->wait_queue);
1407 +}
1408 +
1409 +
1410 +unsigned flash_rd_reg(struct msm_nand_chip *chip, unsigned addr)
1411 +{
1412 +       struct {
1413 +               dmov_s cmd;
1414 +               unsigned cmdptr;
1415 +               unsigned data;
1416 +       } *dma_buffer;
1417 +       unsigned rv;
1418 +
1419 +       wait_event(chip->wait_queue,
1420 +                  (dma_buffer = msm_nand_get_dma_buffer(
1421 +                           chip, sizeof(*dma_buffer))));
1422 +
1423 +       dma_buffer->cmd.cmd = CMD_LC | CMD_OCB | CMD_OCU;
1424 +       dma_buffer->cmd.src = addr;
1425 +       dma_buffer->cmd.dst = msm_virt_to_dma(chip, &dma_buffer->data);
1426 +       dma_buffer->cmd.len = 4;
1427 +
1428 +       dma_buffer->cmdptr =
1429 +               (msm_virt_to_dma(chip, &dma_buffer->cmd) >> 3) | CMD_PTR_LP;
1430 +       dma_buffer->data = 0xeeeeeeee;
1431 +
1432 +       mb();
1433 +       msm_dmov_exec_cmd(
1434 +               chip->dma_channel, DMOV_CMD_PTR_LIST |
1435 +               DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
1436 +       mb();
1437 +
1438 +       rv = dma_buffer->data;
1439 +
1440 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
1441 +
1442 +       return rv;
1443 +}
1444 +
1445 +void flash_wr_reg(struct msm_nand_chip *chip, unsigned addr, unsigned val)
1446 +{
1447 +       struct {
1448 +               dmov_s cmd;
1449 +               unsigned cmdptr;
1450 +               unsigned data;
1451 +       } *dma_buffer;
1452 +
1453 +       wait_event(chip->wait_queue,
1454 +                  (dma_buffer = msm_nand_get_dma_buffer(
1455 +                           chip, sizeof(*dma_buffer))));
1456 +
1457 +       dma_buffer->cmd.cmd = CMD_LC | CMD_OCB | CMD_OCU;
1458 +       dma_buffer->cmd.src = msm_virt_to_dma(chip, &dma_buffer->data);
1459 +       dma_buffer->cmd.dst = addr;
1460 +       dma_buffer->cmd.len = 4;
1461 +
1462 +       dma_buffer->cmdptr =
1463 +               (msm_virt_to_dma(chip, &dma_buffer->cmd) >> 3) | CMD_PTR_LP;
1464 +       dma_buffer->data = val;
1465 +
1466 +       mb();
1467 +       msm_dmov_exec_cmd(
1468 +               chip->dma_channel, DMOV_CMD_PTR_LIST |
1469 +               DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
1470 +       mb();
1471 +
1472 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
1473 +}
1474 +
1475 +/*
1476 + * Allocates a bounce buffer, and stores the buffer address in
1477 + * variable pointed to by bounce_buf. bounce_buf should point to a
1478 + * stack variable, to avoid SMP issues.
1479 + */
1480 +static int msm_nand_alloc_bounce(void *addr, size_t size,
1481 +                                enum dma_data_direction dir,
1482 +                                uint8_t **bounce_buf)
1483 +{
1484 +       if (bounce_buf == NULL) {
1485 +               printk(KERN_ERR "not allocating bounce buffer\n");
1486 +               return -EINVAL;
1487 +       }
1488 +
1489 +       *bounce_buf = kmalloc(size, GFP_KERNEL | GFP_NOFS | GFP_DMA);
1490 +       if (*bounce_buf == NULL) {
1491 +               printk(KERN_ERR "error alloc bounce buffer %zu\n", size);
1492 +               return -ENOMEM;
1493 +       }
1494 +
1495 +       if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL)
1496 +               memcpy(*bounce_buf, addr, size);
1497 +
1498 +       return 0;
1499 +}
1500 +
1501 +/*
1502 + * Maps the user buffer for DMA. If the buffer is vmalloced and the
1503 + * buffer crosses a page boundary, then we kmalloc a bounce buffer and
1504 + * copy the data into it. The bounce buffer is stored in the variable
1505 + * pointed to by bounce_buf, for freeing up later on.  The bounce_buf
1506 + * should point to a stack variable, to avoid SMP issues.
1507 + */
1508 +static dma_addr_t
1509 +msm_nand_dma_map(struct device *dev, void *addr, size_t size,
1510 +                enum dma_data_direction dir, uint8_t **bounce_buf)
1511 +{
1512 +       int ret;
1513 +       struct page *page;
1514 +       unsigned long offset = (unsigned long)addr & ~PAGE_MASK;
1515 +
1516 +       if (virt_addr_valid(addr)) {
1517 +               page = virt_to_page(addr);
1518 +       } else {
1519 +               if (size + offset > PAGE_SIZE) {
1520 +                       ret = msm_nand_alloc_bounce(addr, size, dir, bounce_buf);
1521 +                       if (ret < 0)
1522 +                               return DMA_ERROR_CODE;
1523 +
1524 +                       offset = (unsigned long)*bounce_buf & ~PAGE_MASK;
1525 +                       page = virt_to_page(*bounce_buf);
1526 +               } else {
1527 +                       page = vmalloc_to_page(addr);
1528 +               }
1529 +       }
1530 +
1531 +       return dma_map_page(dev, page, offset, size, dir);
1532 +}
1533 +
1534 +static void msm_nand_dma_unmap(struct device *dev, dma_addr_t addr, size_t size,
1535 +                              enum dma_data_direction dir,
1536 +                              void *orig_buf, void *bounce_buf)
1537 +{
1538 +       dma_unmap_page(dev, addr, size, dir);
1539 +
1540 +       if (bounce_buf != NULL) {
1541 +               if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
1542 +                       memcpy(orig_buf, bounce_buf, size);
1543 +
1544 +               kfree(bounce_buf);
1545 +       }
1546 +}
1547 +
1548 +uint32_t flash_read_id(struct msm_nand_chip *chip)
1549 +{
1550 +       struct {
1551 +               dmov_s cmd[9];
1552 +               unsigned cmdptr;
1553 +               unsigned data[7];
1554 +       } *dma_buffer;
1555 +       uint32_t rv;
1556 +       dmov_s *cmd;
1557 +
1558 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
1559 +                               (chip, sizeof(*dma_buffer))));
1560 +
1561 +       dma_buffer->data[0] = 0 | 4;
1562 +       dma_buffer->data[1] = MSM_NAND_CMD_FETCH_ID;
1563 +       dma_buffer->data[2] = 1;
1564 +       dma_buffer->data[3] = 0xeeeeeeee;
1565 +       dma_buffer->data[4] = 0xeeeeeeee;
1566 +       dma_buffer->data[5] = flash_rd_reg(chip, MSM_NAND_SFLASHC_BURST_CFG);
1567 +       dma_buffer->data[6] = 0x00000000;
1568 +       BUILD_BUG_ON(6 != ARRAY_SIZE(dma_buffer->data) - 1);
1569 +
1570 +       cmd = dma_buffer->cmd;
1571 +
1572 +       cmd->cmd = 0 | CMD_OCB;
1573 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
1574 +       cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
1575 +       cmd->len = 4;
1576 +       cmd++;
1577 +
1578 +       cmd->cmd = 0;
1579 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
1580 +       cmd->dst = MSM_NAND_ADDR0;
1581 +       cmd->len = 4;
1582 +       cmd++;
1583 +
1584 +       cmd->cmd = 0;
1585 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[6]);
1586 +       cmd->dst = MSM_NAND_ADDR1;
1587 +       cmd->len = 4;
1588 +       cmd++;
1589 +
1590 +       cmd->cmd = 0;
1591 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[0]);
1592 +       cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
1593 +       cmd->len = 4;
1594 +       cmd++;
1595 +
1596 +       cmd->cmd = DST_CRCI_NAND_CMD;
1597 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[1]);
1598 +       cmd->dst = MSM_NAND_FLASH_CMD;
1599 +       cmd->len = 4;
1600 +       cmd++;
1601 +
1602 +       cmd->cmd = 0;
1603 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[2]);
1604 +       cmd->dst = MSM_NAND_EXEC_CMD;
1605 +       cmd->len = 4;
1606 +       cmd++;
1607 +
1608 +       cmd->cmd = SRC_CRCI_NAND_DATA;
1609 +       cmd->src = MSM_NAND_FLASH_STATUS;
1610 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data[3]);
1611 +       cmd->len = 4;
1612 +       cmd++;
1613 +
1614 +       cmd->cmd = 0;
1615 +       cmd->src = MSM_NAND_READ_ID;
1616 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data[4]);
1617 +       cmd->len = 4;
1618 +       cmd++;
1619 +
1620 +       cmd->cmd = CMD_OCU | CMD_LC;
1621 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data[5]);
1622 +       cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
1623 +       cmd->len = 4;
1624 +       cmd++;
1625 +
1626 +       BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->cmd) - 1);
1627 +
1628 +       dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3
1629 +                       ) | CMD_PTR_LP;
1630 +
1631 +       mb();
1632 +       msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
1633 +               DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
1634 +       mb();
1635 +
1636 +       pr_info("status: %x\n", dma_buffer->data[3]);
1637 +       pr_info("nandid: %x maker %02x device %02x\n",
1638 +              dma_buffer->data[4], dma_buffer->data[4] & 0xff,
1639 +              (dma_buffer->data[4] >> 8) & 0xff);
1640 +       rv = dma_buffer->data[4];
1641 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
1642 +       return rv;
1643 +}
1644 +
1645 +struct flash_identification {
1646 +       uint32_t flash_id;
1647 +       uint32_t density;
1648 +       uint32_t widebus;
1649 +       uint32_t pagesize;
1650 +       uint32_t blksize;
1651 +       uint32_t oobsize;
1652 +       uint32_t ecc_correctability;
1653 +} supported_flash;
1654 +
1655 +uint16_t flash_onfi_crc_check(uint8_t *buffer, uint16_t count)
1656 +{
1657 +       int i;
1658 +       uint16_t result;
1659 +
1660 +       for (i = 0; i < count; i++)
1661 +               buffer[i] = bitrev8(buffer[i]);
1662 +
1663 +       result = bitrev16(crc16(bitrev16(0x4f4e), buffer, count));
1664 +
1665 +       for (i = 0; i < count; i++)
1666 +               buffer[i] = bitrev8(buffer[i]);
1667 +
1668 +       return result;
1669 +}
1670 +
1671 +static void flash_reset(struct msm_nand_chip *chip)
1672 +{
1673 +       struct {
1674 +               dmov_s cmd[6];
1675 +               unsigned cmdptr;
1676 +               struct {
1677 +                       uint32_t cmd;
1678 +                       uint32_t exec;
1679 +                       uint32_t flash_status;
1680 +                       uint32_t sflash_bcfg_orig;
1681 +                       uint32_t sflash_bcfg_mod;
1682 +                       uint32_t chip_select;
1683 +               } data;
1684 +       } *dma_buffer;
1685 +       dmov_s *cmd;
1686 +       dma_addr_t dma_cmd;
1687 +       dma_addr_t dma_cmdptr;
1688 +
1689 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
1690 +                                     (chip, sizeof(*dma_buffer))));
1691 +
1692 +       dma_buffer->data.sflash_bcfg_orig
1693 +               = flash_rd_reg(chip, MSM_NAND_SFLASHC_BURST_CFG);
1694 +       dma_buffer->data.sflash_bcfg_mod = 0x00000000;
1695 +       dma_buffer->data.chip_select = 4;
1696 +       dma_buffer->data.cmd = MSM_NAND_CMD_RESET;
1697 +       dma_buffer->data.exec = 1;
1698 +       dma_buffer->data.flash_status = 0xeeeeeeee;
1699 +
1700 +       cmd = dma_buffer->cmd;
1701 +
1702 +       /* Put the Nand ctlr in Async mode and disable SFlash ctlr */
1703 +       cmd->cmd = 0;
1704 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sflash_bcfg_mod);
1705 +       cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
1706 +       cmd->len = 4;
1707 +       cmd++;
1708 +
1709 +       cmd->cmd = 0;
1710 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chip_select);
1711 +       cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
1712 +       cmd->len = 4;
1713 +       cmd++;
1714 +
1715 +       /* Block on cmd ready, & write Reset command */
1716 +       cmd->cmd = DST_CRCI_NAND_CMD;
1717 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
1718 +       cmd->dst = MSM_NAND_FLASH_CMD;
1719 +       cmd->len = 4;
1720 +       cmd++;
1721 +
1722 +       cmd->cmd = 0;
1723 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
1724 +       cmd->dst = MSM_NAND_EXEC_CMD;
1725 +       cmd->len = 4;
1726 +       cmd++;
1727 +
1728 +       cmd->cmd = SRC_CRCI_NAND_DATA;
1729 +       cmd->src = MSM_NAND_FLASH_STATUS;
1730 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status);
1731 +       cmd->len = 4;
1732 +       cmd++;
1733 +
1734 +       /* Restore the SFLASH_BURST_CONFIG register */
1735 +       cmd->cmd = 0;
1736 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sflash_bcfg_orig);
1737 +       cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
1738 +       cmd->len = 4;
1739 +       cmd++;
1740 +
1741 +       BUILD_BUG_ON(6 != ARRAY_SIZE(dma_buffer->cmd));
1742 +
1743 +       dma_buffer->cmd[0].cmd |= CMD_OCB;
1744 +       cmd[-1].cmd |= CMD_OCU | CMD_LC;
1745 +
1746 +       dma_cmd = msm_virt_to_dma(chip, dma_buffer->cmd);
1747 +       dma_buffer->cmdptr = (dma_cmd >> 3) | CMD_PTR_LP;
1748 +
1749 +       mb();
1750 +       dma_cmdptr = msm_virt_to_dma(chip, &dma_buffer->cmdptr);
1751 +       msm_dmov_exec_cmd(chip->dma_channel,
1752 +                         DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(dma_cmdptr));
1753 +       mb();
1754 +
1755 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
1756 +}
1757 +
1758 +uint32_t flash_onfi_probe(struct msm_nand_chip *chip)
1759 +{
1760 +
1761 +
1762 +               struct onfi_param_page {
1763 +               uint32_t parameter_page_signature;
1764 +               uint16_t revision_number;
1765 +               uint16_t features_supported;
1766 +               uint16_t optional_commands_supported;
1767 +               uint8_t  reserved0[22];
1768 +               uint8_t  device_manufacturer[12];
1769 +               uint8_t  device_model[20];
1770 +               uint8_t  jedec_manufacturer_id;
1771 +               uint16_t date_code;
1772 +               uint8_t  reserved1[13];
1773 +               uint32_t number_of_data_bytes_per_page;
1774 +               uint16_t number_of_spare_bytes_per_page;
1775 +               uint32_t number_of_data_bytes_per_partial_page;
1776 +               uint16_t number_of_spare_bytes_per_partial_page;
1777 +               uint32_t number_of_pages_per_block;
1778 +               uint32_t number_of_blocks_per_logical_unit;
1779 +               uint8_t  number_of_logical_units;
1780 +               uint8_t  number_of_address_cycles;
1781 +               uint8_t  number_of_bits_per_cell;
1782 +               uint16_t maximum_bad_blocks_per_logical_unit;
1783 +               uint16_t block_endurance;
1784 +               uint8_t  guaranteed_valid_begin_blocks;
1785 +               uint16_t guaranteed_valid_begin_blocks_endurance;
1786 +               uint8_t  number_of_programs_per_page;
1787 +               uint8_t  partial_program_attributes;
1788 +               uint8_t  number_of_bits_ecc_correctability;
1789 +               uint8_t  number_of_interleaved_address_bits;
1790 +               uint8_t  interleaved_operation_attributes;
1791 +               uint8_t  reserved2[13];
1792 +               uint8_t  io_pin_capacitance;
1793 +               uint16_t timing_mode_support;
1794 +               uint16_t program_cache_timing_mode_support;
1795 +               uint16_t maximum_page_programming_time;
1796 +               uint16_t maximum_block_erase_time;
1797 +               uint16_t maximum_page_read_time;
1798 +               uint16_t maximum_change_column_setup_time;
1799 +               uint8_t  reserved3[23];
1800 +               uint16_t vendor_specific_revision_number;
1801 +               uint8_t  vendor_specific[88];
1802 +               uint16_t integrity_crc;
1803 +
1804 +       } __attribute__((__packed__));
1805 +
1806 +       struct onfi_param_page *onfi_param_page_ptr;
1807 +       uint8_t *onfi_identifier_buf = NULL;
1808 +       uint8_t *onfi_param_info_buf = NULL;
1809 +
1810 +       struct {
1811 +               dmov_s cmd[12];
1812 +               unsigned cmdptr;
1813 +               struct {
1814 +                       uint32_t cmd;
1815 +                       uint32_t addr0;
1816 +                       uint32_t addr1;
1817 +                       uint32_t cfg0;
1818 +                       uint32_t cfg1;
1819 +                       uint32_t exec;
1820 +                       uint32_t flash_status;
1821 +                       uint32_t devcmd1_orig;
1822 +                       uint32_t devcmdvld_orig;
1823 +                       uint32_t devcmd1_mod;
1824 +                       uint32_t devcmdvld_mod;
1825 +                       uint32_t sflash_bcfg_orig;
1826 +                       uint32_t sflash_bcfg_mod;
1827 +                       uint32_t chip_select;
1828 +               } data;
1829 +       } *dma_buffer;
1830 +       dmov_s *cmd;
1831 +
1832 +       unsigned page_address = 0;
1833 +       int err = 0;
1834 +       dma_addr_t dma_addr_param_info = 0;
1835 +       dma_addr_t dma_addr_identifier = 0;
1836 +       unsigned cmd_set_count = 2;
1837 +       unsigned crc_chk_count = 0;
1838 +
1839 +       /*if (msm_nand_data.nr_parts) {
1840 +               page_address = ((msm_nand_data.parts[0]).offset << 6);
1841 +       } else {
1842 +               pr_err("flash_onfi_probe: "
1843 +                               "No partition info available\n");
1844 +               err = -EIO;
1845 +               return err;
1846 +       }*/
1847 +
1848 +       wait_event(chip->wait_queue, (onfi_identifier_buf =
1849 +               msm_nand_get_dma_buffer(chip, ONFI_IDENTIFIER_LENGTH)));
1850 +       dma_addr_identifier = msm_virt_to_dma(chip, onfi_identifier_buf);
1851 +
1852 +       wait_event(chip->wait_queue, (onfi_param_info_buf =
1853 +               msm_nand_get_dma_buffer(chip, ONFI_PARAM_INFO_LENGTH)));
1854 +       dma_addr_param_info = msm_virt_to_dma(chip, onfi_param_info_buf);
1855 +
1856 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
1857 +                               (chip, sizeof(*dma_buffer))));
1858 +
1859 +       dma_buffer->data.sflash_bcfg_orig = flash_rd_reg
1860 +                               (chip, MSM_NAND_SFLASHC_BURST_CFG);
1861 +       dma_buffer->data.devcmd1_orig = flash_rd_reg(chip, MSM_NAND_DEV_CMD1);
1862 +       dma_buffer->data.devcmdvld_orig = flash_rd_reg(chip,
1863 +                                                MSM_NAND_DEV_CMD_VLD);
1864 +       dma_buffer->data.chip_select = 4;
1865 +
1866 +       while (cmd_set_count-- > 0) {
1867 +               cmd = dma_buffer->cmd;
1868 +
1869 +               dma_buffer->data.devcmd1_mod = (dma_buffer->data.devcmd1_orig &
1870 +                               0xFFFFFF00) | (cmd_set_count
1871 +                               ? FLASH_READ_ONFI_IDENTIFIER_COMMAND
1872 +                               : FLASH_READ_ONFI_PARAMETERS_COMMAND);
1873 +               dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
1874 +               dma_buffer->data.addr0 = (page_address << 16) | (cmd_set_count
1875 +                               ? FLASH_READ_ONFI_IDENTIFIER_ADDRESS
1876 +                               : FLASH_READ_ONFI_PARAMETERS_ADDRESS);
1877 +               dma_buffer->data.addr1 = (page_address >> 16) & 0xFF;
1878 +               dma_buffer->data.cfg0 = (cmd_set_count
1879 +                               ? MSM_NAND_CFG0_RAW_ONFI_IDENTIFIER
1880 +                               : MSM_NAND_CFG0_RAW_ONFI_PARAM_INFO);
1881 +               dma_buffer->data.cfg1 = (cmd_set_count
1882 +                               ? MSM_NAND_CFG1_RAW_ONFI_IDENTIFIER
1883 +                               : MSM_NAND_CFG1_RAW_ONFI_PARAM_INFO);
1884 +               dma_buffer->data.sflash_bcfg_mod = 0x00000000;
1885 +               dma_buffer->data.devcmdvld_mod = (dma_buffer->
1886 +                               data.devcmdvld_orig & 0xFFFFFFFE);
1887 +               dma_buffer->data.exec = 1;
1888 +               dma_buffer->data.flash_status = 0xeeeeeeee;
1889 +
1890 +               /* Put the Nand ctlr in Async mode and disable SFlash ctlr */
1891 +               cmd->cmd = 0;
1892 +               cmd->src = msm_virt_to_dma(chip,
1893 +                               &dma_buffer->data.sflash_bcfg_mod);
1894 +               cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
1895 +               cmd->len = 4;
1896 +               cmd++;
1897 +
1898 +               cmd->cmd = 0;
1899 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chip_select);
1900 +               cmd->dst = MSM_NAND_FLASH_CHIP_SELECT;
1901 +               cmd->len = 4;
1902 +               cmd++;
1903 +
1904 +               /* Block on cmd ready, & write CMD,ADDR0,ADDR1,CHIPSEL regs */
1905 +               cmd->cmd = DST_CRCI_NAND_CMD;
1906 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
1907 +               cmd->dst = MSM_NAND_FLASH_CMD;
1908 +               cmd->len = 12;
1909 +               cmd++;
1910 +
1911 +               /* Configure the CFG0 and CFG1 registers */
1912 +               cmd->cmd = 0;
1913 +               cmd->src = msm_virt_to_dma(chip,
1914 +                               &dma_buffer->data.cfg0);
1915 +               cmd->dst = MSM_NAND_DEV0_CFG0;
1916 +               cmd->len = 8;
1917 +               cmd++;
1918 +
1919 +               /* Configure the DEV_CMD_VLD register */
1920 +               cmd->cmd = 0;
1921 +               cmd->src = msm_virt_to_dma(chip,
1922 +                               &dma_buffer->data.devcmdvld_mod);
1923 +               cmd->dst = MSM_NAND_DEV_CMD_VLD;
1924 +               cmd->len = 4;
1925 +               cmd++;
1926 +
1927 +               /* Configure the DEV_CMD1 register */
1928 +               cmd->cmd = 0;
1929 +               cmd->src = msm_virt_to_dma(chip,
1930 +                               &dma_buffer->data.devcmd1_mod);
1931 +               cmd->dst = MSM_NAND_DEV_CMD1;
1932 +               cmd->len = 4;
1933 +               cmd++;
1934 +
1935 +               /* Kick the execute command */
1936 +               cmd->cmd = 0;
1937 +               cmd->src = msm_virt_to_dma(chip,
1938 +                               &dma_buffer->data.exec);
1939 +               cmd->dst = MSM_NAND_EXEC_CMD;
1940 +               cmd->len = 4;
1941 +               cmd++;
1942 +
1943 +               /* Block on data ready, and read the two status registers */
1944 +               cmd->cmd = SRC_CRCI_NAND_DATA;
1945 +               cmd->src = MSM_NAND_FLASH_STATUS;
1946 +               cmd->dst = msm_virt_to_dma(chip,
1947 +                               &dma_buffer->data.flash_status);
1948 +               cmd->len = 4;
1949 +               cmd++;
1950 +
1951 +               /* Read data block - valid only if status says success */
1952 +               cmd->cmd = 0;
1953 +               cmd->src = MSM_NAND_FLASH_BUFFER;
1954 +               cmd->dst = (cmd_set_count ? dma_addr_identifier :
1955 +                               dma_addr_param_info);
1956 +               cmd->len = (cmd_set_count ? ONFI_IDENTIFIER_LENGTH :
1957 +                               ONFI_PARAM_INFO_LENGTH);
1958 +               cmd++;
1959 +
1960 +               /* Restore the DEV_CMD1 register */
1961 +               cmd->cmd = 0 ;
1962 +               cmd->src = msm_virt_to_dma(chip,
1963 +                               &dma_buffer->data.devcmd1_orig);
1964 +               cmd->dst = MSM_NAND_DEV_CMD1;
1965 +               cmd->len = 4;
1966 +               cmd++;
1967 +
1968 +               /* Restore the DEV_CMD_VLD register */
1969 +               cmd->cmd = 0;
1970 +               cmd->src = msm_virt_to_dma(chip,
1971 +                               &dma_buffer->data.devcmdvld_orig);
1972 +               cmd->dst = MSM_NAND_DEV_CMD_VLD;
1973 +               cmd->len = 4;
1974 +               cmd++;
1975 +
1976 +               /* Restore the SFLASH_BURST_CONFIG register */
1977 +               cmd->cmd = 0;
1978 +               cmd->src = msm_virt_to_dma(chip,
1979 +                               &dma_buffer->data.sflash_bcfg_orig);
1980 +               cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
1981 +               cmd->len = 4;
1982 +               cmd++;
1983 +
1984 +               BUILD_BUG_ON(12 != ARRAY_SIZE(dma_buffer->cmd));
1985 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
1986 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
1987 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
1988 +
1989 +               dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
1990 +                               >> 3) | CMD_PTR_LP;
1991 +
1992 +               mb();
1993 +               msm_dmov_exec_cmd(chip->dma_channel,
1994 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
1995 +                       &dma_buffer->cmdptr)));
1996 +               mb();
1997 +
1998 +               /* Check for errors, protection violations etc */
1999 +               if (dma_buffer->data.flash_status & 0x110) {
2000 +                       pr_info("MPU/OP error (0x%x) during "
2001 +                                       "ONFI probe\n",
2002 +                                       dma_buffer->data.flash_status);
2003 +                       err = -EIO;
2004 +                       break;
2005 +               }
2006 +
2007 +               if (cmd_set_count) {
2008 +                       onfi_param_page_ptr = (struct onfi_param_page *)
2009 +                               (&(onfi_identifier_buf[0]));
2010 +                       if (onfi_param_page_ptr->parameter_page_signature !=
2011 +                                       ONFI_PARAMETER_PAGE_SIGNATURE) {
2012 +                               pr_info("ONFI probe : Found a non"
2013 +                                               "ONFI Compliant device \n");
2014 +                               err = -EIO;
2015 +                               break;
2016 +                       }
2017 +               } else {
2018 +                       for (crc_chk_count = 0; crc_chk_count <
2019 +                                       ONFI_PARAM_INFO_LENGTH
2020 +                                       / ONFI_PARAM_PAGE_LENGTH;
2021 +                                       crc_chk_count++) {
2022 +                               onfi_param_page_ptr =
2023 +                                       (struct onfi_param_page *)
2024 +                                       (&(onfi_param_info_buf
2025 +                                       [ONFI_PARAM_PAGE_LENGTH *
2026 +                                       crc_chk_count]));
2027 +                               if (flash_onfi_crc_check(
2028 +                                       (uint8_t *)onfi_param_page_ptr,
2029 +                                       ONFI_PARAM_PAGE_LENGTH - 2) ==
2030 +                                       onfi_param_page_ptr->integrity_crc) {
2031 +                                       break;
2032 +                               }
2033 +                       }
2034 +                       if (crc_chk_count >= ONFI_PARAM_INFO_LENGTH
2035 +                                       / ONFI_PARAM_PAGE_LENGTH) {
2036 +                               pr_info("ONFI probe : CRC Check "
2037 +                                               "failed on ONFI Parameter "
2038 +                                               "data \n");
2039 +                               err = -EIO;
2040 +                               break;
2041 +                       } else {
2042 +                               supported_flash.flash_id =
2043 +                                       flash_read_id(chip);
2044 +                               supported_flash.widebus  =
2045 +                                       onfi_param_page_ptr->
2046 +                                       features_supported & 0x01;
2047 +                               supported_flash.pagesize =
2048 +                                       onfi_param_page_ptr->
2049 +                                       number_of_data_bytes_per_page;
2050 +                               supported_flash.blksize  =
2051 +                                       onfi_param_page_ptr->
2052 +                                       number_of_pages_per_block *
2053 +                                       supported_flash.pagesize;
2054 +                               supported_flash.oobsize  =
2055 +                                       onfi_param_page_ptr->
2056 +                                       number_of_spare_bytes_per_page;
2057 +                               supported_flash.density  =
2058 +                                       onfi_param_page_ptr->
2059 +                                       number_of_blocks_per_logical_unit
2060 +                                       * supported_flash.blksize;
2061 +                               supported_flash.ecc_correctability =
2062 +                                       onfi_param_page_ptr->
2063 +                                       number_of_bits_ecc_correctability;
2064 +
2065 +                               pr_info("ONFI probe : Found an ONFI "
2066 +                                       "compliant device %s\n",
2067 +                                       onfi_param_page_ptr->device_model);
2068 +
2069 +                               /* Temporary hack for MT29F4G08ABC device.
2070 +                                * Since the device is not properly adhering
2071 +                                * to ONFi specification it is reporting
2072 +                                * as 16 bit device though it is 8 bit device!!!
2073 +                                */
2074 +                               if (!strncmp(onfi_param_page_ptr->device_model,
2075 +                                       "MT29F4G08ABC", 12))
2076 +                                       supported_flash.widebus  = 0;
2077 +                       }
2078 +               }
2079 +       }
2080 +
2081 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
2082 +       msm_nand_release_dma_buffer(chip, onfi_param_info_buf,
2083 +                       ONFI_PARAM_INFO_LENGTH);
2084 +       msm_nand_release_dma_buffer(chip, onfi_identifier_buf,
2085 +                       ONFI_IDENTIFIER_LENGTH);
2086 +
2087 +       return err;
2088 +}
2089 +
2090 +static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
2091 +                            struct mtd_oob_ops *ops)
2092 +{
2093 +       struct msm_nand_chip *chip = mtd->priv;
2094 +
2095 +       struct {
2096 +               dmov_s cmd[8 * 5 + 2];
2097 +               unsigned cmdptr;
2098 +               struct {
2099 +                       uint32_t cmd;
2100 +                       uint32_t addr0;
2101 +                       uint32_t addr1;
2102 +                       uint32_t chipsel;
2103 +                       uint32_t cfg0;
2104 +                       uint32_t cfg1;
2105 +                       uint32_t eccbchcfg;
2106 +                       uint32_t exec;
2107 +                       uint32_t ecccfg;
2108 +                       struct {
2109 +                               uint32_t flash_status;
2110 +                               uint32_t buffer_status;
2111 +                       } result[8];
2112 +               } data;
2113 +       } *dma_buffer;
2114 +       dmov_s *cmd;
2115 +       unsigned n;
2116 +       unsigned page = 0;
2117 +       uint32_t oob_len;
2118 +       uint32_t sectordatasize;
2119 +       uint32_t sectoroobsize;
2120 +       int err, pageerr, rawerr;
2121 +       dma_addr_t data_dma_addr = 0;
2122 +       dma_addr_t oob_dma_addr = 0;
2123 +       dma_addr_t data_dma_addr_curr = 0;
2124 +       dma_addr_t oob_dma_addr_curr = 0;
2125 +       uint8_t *dat_bounce_buf = NULL;
2126 +       uint8_t *oob_bounce_buf = NULL;
2127 +       uint32_t oob_col = 0;
2128 +       unsigned page_count;
2129 +       unsigned pages_read = 0;
2130 +       unsigned start_sector = 0;
2131 +       uint32_t ecc_errors;
2132 +       uint32_t total_ecc_errors = 0;
2133 +       unsigned cwperpage;
2134 +#if VERBOSE
2135 +       pr_info("================================================="
2136 +                       "================\n");
2137 +       pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
2138 +                       "\noobbuf 0x%p ooblen 0x%x\n",
2139 +                       __func__, from, ops->mode, ops->datbuf, ops->len,
2140 +                       ops->oobbuf, ops->ooblen);
2141 +#endif
2142 +
2143 +       if (mtd->writesize == 2048)
2144 +               page = from >> 11;
2145 +
2146 +       if (mtd->writesize == 4096)
2147 +               page = from >> 12;
2148 +
2149 +       oob_len = ops->ooblen;
2150 +       cwperpage = (mtd->writesize >> 9);
2151 +
2152 +       if (from & (mtd->writesize - 1)) {
2153 +               pr_err("%s: unsupported from, 0x%llx\n",
2154 +                      __func__, from);
2155 +               return -EINVAL;
2156 +       }
2157 +       if (ops->mode != MTD_OPS_RAW) {
2158 +               if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
2159 +                       /* when ops->datbuf is NULL, ops->len can be ooblen */
2160 +                       pr_err("%s: unsupported ops->len, %d\n",
2161 +                              __func__, ops->len);
2162 +                       return -EINVAL;
2163 +               }
2164 +       } else {
2165 +               if (ops->datbuf != NULL &&
2166 +                       (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
2167 +                       pr_err("%s: unsupported ops->len,"
2168 +                               " %d for MTD_OPS_RAW\n", __func__, ops->len);
2169 +                       return -EINVAL;
2170 +               }
2171 +       }
2172 +
2173 +       if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
2174 +               pr_err("%s: unsupported ops->ooboffs, %d\n",
2175 +                      __func__, ops->ooboffs);
2176 +               return -EINVAL;
2177 +       }
2178 +
2179 +       if (ops->oobbuf && !ops->datbuf && ops->mode == MTD_OPS_AUTO_OOB)
2180 +               start_sector = cwperpage - 1;
2181 +
2182 +       if (ops->oobbuf && !ops->datbuf) {
2183 +               page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
2184 +                       mtd->oobavail : mtd->oobsize);
2185 +               if ((page_count == 0) && (ops->ooblen))
2186 +                       page_count = 1;
2187 +       } else if (ops->mode != MTD_OPS_RAW)
2188 +               page_count = ops->len / mtd->writesize;
2189 +       else
2190 +               page_count = ops->len / (mtd->writesize + mtd->oobsize);
2191 +
2192 +       if (ops->datbuf) {
2193 +               data_dma_addr_curr = data_dma_addr =
2194 +                       msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
2195 +                                        DMA_FROM_DEVICE, &dat_bounce_buf);
2196 +               if (dma_mapping_error(chip->dev, data_dma_addr)) {
2197 +                       pr_err("msm_nand_read_oob: failed to get dma addr "
2198 +                              "for %p\n", ops->datbuf);
2199 +                       return -EIO;
2200 +               }
2201 +       }
2202 +       if (ops->oobbuf) {
2203 +               memset(ops->oobbuf, 0xff, ops->ooblen);
2204 +               oob_dma_addr_curr = oob_dma_addr =
2205 +                       msm_nand_dma_map(chip->dev, ops->oobbuf,
2206 +                                        ops->ooblen, DMA_BIDIRECTIONAL,
2207 +                                        &oob_bounce_buf);
2208 +               if (dma_mapping_error(chip->dev, oob_dma_addr)) {
2209 +                       pr_err("msm_nand_read_oob: failed to get dma addr "
2210 +                              "for %p\n", ops->oobbuf);
2211 +                       err = -EIO;
2212 +                       goto err_dma_map_oobbuf_failed;
2213 +               }
2214 +       }
2215 +
2216 +       wait_event(chip->wait_queue,
2217 +                  (dma_buffer = msm_nand_get_dma_buffer(
2218 +                           chip, sizeof(*dma_buffer))));
2219 +
2220 +       oob_col = start_sector * chip->cw_size;
2221 +       if (chip->CFG1 & CFG1_WIDE_FLASH)
2222 +               oob_col >>= 1;
2223 +
2224 +       err = 0;
2225 +       while (page_count-- > 0) {
2226 +               cmd = dma_buffer->cmd;
2227 +
2228 +               /* CMD / ADDR0 / ADDR1 / CHIPSEL program values */
2229 +               if (ops->mode != MTD_OPS_RAW) {
2230 +                       dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ_ECC;
2231 +                       dma_buffer->data.cfg0 =
2232 +                       (chip->CFG0 & ~(7U << 6))
2233 +                               | (((cwperpage-1) - start_sector) << 6);
2234 +                       dma_buffer->data.cfg1 = chip->CFG1;
2235 +                       if (enable_bch_ecc)
2236 +                               dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
2237 +               } else {
2238 +                       dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
2239 +                       dma_buffer->data.cfg0 = (chip->CFG0_RAW
2240 +                                       & ~(7U << 6)) | ((cwperpage-1) << 6);
2241 +                       dma_buffer->data.cfg1 = chip->CFG1_RAW |
2242 +                                       (chip->CFG1 & CFG1_WIDE_FLASH);
2243 +               }
2244 +
2245 +               dma_buffer->data.addr0 = (page << 16) | oob_col;
2246 +               dma_buffer->data.addr1 = (page >> 16) & 0xff;
2247 +               /* chipsel_0 + enable DM interface */
2248 +               dma_buffer->data.chipsel = 0 | 4;
2249 +
2250 +
2251 +               /* GO bit for the EXEC register */
2252 +               dma_buffer->data.exec = 1;
2253 +
2254 +
2255 +               BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->data.result));
2256 +
2257 +               for (n = start_sector; n < cwperpage; n++) {
2258 +                       /* flash + buffer status return words */
2259 +                       dma_buffer->data.result[n].flash_status = 0xeeeeeeee;
2260 +                       dma_buffer->data.result[n].buffer_status = 0xeeeeeeee;
2261 +
2262 +                       /* block on cmd ready, then
2263 +                        * write CMD / ADDR0 / ADDR1 / CHIPSEL
2264 +                        * regs in a burst
2265 +                        */
2266 +                       cmd->cmd = DST_CRCI_NAND_CMD;
2267 +                       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
2268 +                       cmd->dst = MSM_NAND_FLASH_CMD;
2269 +                       if (n == start_sector)
2270 +                               cmd->len = 16;
2271 +                       else
2272 +                               cmd->len = 4;
2273 +                       cmd++;
2274 +
2275 +                       if (n == start_sector) {
2276 +                               cmd->cmd = 0;
2277 +                               cmd->src = msm_virt_to_dma(chip,
2278 +                                                       &dma_buffer->data.cfg0);
2279 +                               cmd->dst = MSM_NAND_DEV0_CFG0;
2280 +                               if (enable_bch_ecc)
2281 +                                       cmd->len = 12;
2282 +                               else
2283 +                                       cmd->len = 8;
2284 +                               cmd++;
2285 +
2286 +                               dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
2287 +                               cmd->cmd = 0;
2288 +                               cmd->src = msm_virt_to_dma(chip,
2289 +                                               &dma_buffer->data.ecccfg);
2290 +                               cmd->dst = MSM_NAND_EBI2_ECC_BUF_CFG;
2291 +                               cmd->len = 4;
2292 +                               cmd++;
2293 +                       }
2294 +
2295 +                       /* kick the execute register */
2296 +                       cmd->cmd = 0;
2297 +                       cmd->src =
2298 +                               msm_virt_to_dma(chip, &dma_buffer->data.exec);
2299 +                       cmd->dst = MSM_NAND_EXEC_CMD;
2300 +                       cmd->len = 4;
2301 +                       cmd++;
2302 +
2303 +                       /* block on data ready, then
2304 +                        * read the status register
2305 +                        */
2306 +                       cmd->cmd = SRC_CRCI_NAND_DATA;
2307 +                       cmd->src = MSM_NAND_FLASH_STATUS;
2308 +                       cmd->dst = msm_virt_to_dma(chip,
2309 +                                                  &dma_buffer->data.result[n]);
2310 +                       /* MSM_NAND_FLASH_STATUS + MSM_NAND_BUFFER_STATUS */
2311 +                       cmd->len = 8;
2312 +                       cmd++;
2313 +
2314 +                       /* read data block
2315 +                        * (only valid if status says success)
2316 +                        */
2317 +                       if (ops->datbuf) {
2318 +                               if (ops->mode != MTD_OPS_RAW) {
2319 +                                       if (!boot_layout)
2320 +                                               sectordatasize = (n < (cwperpage - 1))
2321 +                                                       ? 516 : (512 - ((cwperpage - 1) << 2));
2322 +                                       else
2323 +                                               sectordatasize = 512;
2324 +                               } else {
2325 +                                       sectordatasize = chip->cw_size;
2326 +                               }
2327 +
2328 +                               cmd->cmd = 0;
2329 +                               cmd->src = MSM_NAND_FLASH_BUFFER;
2330 +                               cmd->dst = data_dma_addr_curr;
2331 +                               data_dma_addr_curr += sectordatasize;
2332 +                               cmd->len = sectordatasize;
2333 +                               cmd++;
2334 +                       }
2335 +
2336 +                       if (ops->oobbuf && (n == (cwperpage - 1)
2337 +                            || ops->mode != MTD_OPS_AUTO_OOB)) {
2338 +                               cmd->cmd = 0;
2339 +                               if (n == (cwperpage - 1)) {
2340 +                                       cmd->src = MSM_NAND_FLASH_BUFFER +
2341 +                                               (512 - ((cwperpage - 1) << 2));
2342 +                                       sectoroobsize = (cwperpage << 2);
2343 +                                       if (ops->mode != MTD_OPS_AUTO_OOB)
2344 +                                               sectoroobsize +=
2345 +                                                       chip->ecc_parity_bytes;
2346 +                               } else {
2347 +                                       cmd->src = MSM_NAND_FLASH_BUFFER + 516;
2348 +                                       sectoroobsize = chip->ecc_parity_bytes;
2349 +                               }
2350 +
2351 +                               cmd->dst = oob_dma_addr_curr;
2352 +                               if (sectoroobsize < oob_len)
2353 +                                       cmd->len = sectoroobsize;
2354 +                               else
2355 +                                       cmd->len = oob_len;
2356 +                               oob_dma_addr_curr += cmd->len;
2357 +                               oob_len -= cmd->len;
2358 +                               if (cmd->len > 0)
2359 +                                       cmd++;
2360 +                       }
2361 +               }
2362 +
2363 +               BUILD_BUG_ON(8 * 5 + 2 != ARRAY_SIZE(dma_buffer->cmd));
2364 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
2365 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
2366 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
2367 +
2368 +               dma_buffer->cmdptr =
2369 +                       (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
2370 +                       | CMD_PTR_LP;
2371 +
2372 +               mb();
2373 +               msm_dmov_exec_cmd(chip->dma_channel,
2374 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
2375 +                       &dma_buffer->cmdptr)));
2376 +               mb();
2377 +
2378 +               /* if any of the writes failed (0x10), or there
2379 +                * was a protection violation (0x100), we lose
2380 +                */
2381 +               pageerr = rawerr = 0;
2382 +               for (n = start_sector; n < cwperpage; n++) {
2383 +                       if (dma_buffer->data.result[n].flash_status & 0x110) {
2384 +                               rawerr = -EIO;
2385 +                               break;
2386 +                       }
2387 +               }
2388 +               if (rawerr) {
2389 +                       if (ops->datbuf && ops->mode != MTD_OPS_RAW) {
2390 +                               uint8_t *datbuf = ops->datbuf +
2391 +                                       pages_read * mtd->writesize;
2392 +
2393 +                               dma_sync_single_for_cpu(chip->dev,
2394 +                                       data_dma_addr_curr-mtd->writesize,
2395 +                                       mtd->writesize, DMA_BIDIRECTIONAL);
2396 +
2397 +                               for (n = 0; n < mtd->writesize; n++) {
2398 +                                       /* empty blocks read 0x54 at
2399 +                                        * these offsets
2400 +                                        */
2401 +                                       if ((n % 516 == 3 || n % 516 == 175)
2402 +                                                       && datbuf[n] == 0x54)
2403 +                                               datbuf[n] = 0xff;
2404 +                                       if (datbuf[n] != 0xff) {
2405 +                                               pageerr = rawerr;
2406 +                                               break;
2407 +                                       }
2408 +                               }
2409 +
2410 +                               dma_sync_single_for_device(chip->dev,
2411 +                                       data_dma_addr_curr-mtd->writesize,
2412 +                                       mtd->writesize, DMA_BIDIRECTIONAL);
2413 +
2414 +                       }
2415 +                       if (ops->oobbuf) {
2416 +                               dma_sync_single_for_cpu(chip->dev,
2417 +                               oob_dma_addr_curr - (ops->ooblen - oob_len),
2418 +                               ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
2419 +
2420 +                               for (n = 0; n < ops->ooblen; n++) {
2421 +                                       if (ops->oobbuf[n] != 0xff) {
2422 +                                               pageerr = rawerr;
2423 +                                               break;
2424 +                                       }
2425 +                               }
2426 +
2427 +                               dma_sync_single_for_device(chip->dev,
2428 +                               oob_dma_addr_curr - (ops->ooblen - oob_len),
2429 +                               ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
2430 +                       }
2431 +               }
2432 +               if (pageerr) {
2433 +                       for (n = start_sector; n < cwperpage; n++) {
2434 +                               if (dma_buffer->data.result[n].buffer_status &
2435 +                                       chip->uncorrectable_bit_mask) {
2436 +                                       /* not thread safe */
2437 +                                       mtd->ecc_stats.failed++;
2438 +                                       pageerr = -EBADMSG;
2439 +                                       break;
2440 +                               }
2441 +                       }
2442 +               }
2443 +               if (!rawerr) { /* check for corretable errors */
2444 +                       for (n = start_sector; n < cwperpage; n++) {
2445 +                               ecc_errors =
2446 +                               (dma_buffer->data.result[n].buffer_status
2447 +                                & chip->num_err_mask);
2448 +                               if (ecc_errors) {
2449 +                                       total_ecc_errors += ecc_errors;
2450 +                                       /* not thread safe */
2451 +                                       mtd->ecc_stats.corrected += ecc_errors;
2452 +                                       if (ecc_errors > 1)
2453 +                                               pageerr = -EUCLEAN;
2454 +                               }
2455 +                       }
2456 +               }
2457 +               if (pageerr && (pageerr != -EUCLEAN || err == 0))
2458 +                       err = pageerr;
2459 +
2460 +#if VERBOSE
2461 +               if (rawerr && !pageerr) {
2462 +                       pr_err("msm_nand_read_oob %llx %x %x empty page\n",
2463 +                              (loff_t)page * mtd->writesize, ops->len,
2464 +                              ops->ooblen);
2465 +               } else {
2466 +                       for (n = start_sector; n < cwperpage; n++)
2467 +                               pr_info("flash_status[%d] = %x,\
2468 +                               buffr_status[%d] = %x\n",
2469 +                               n, dma_buffer->data.result[n].flash_status,
2470 +                               n, dma_buffer->data.result[n].buffer_status);
2471 +               }
2472 +#endif
2473 +               if (err && err != -EUCLEAN && err != -EBADMSG)
2474 +                       break;
2475 +               pages_read++;
2476 +               page++;
2477 +       }
2478 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
2479 +
2480 +       if (ops->oobbuf) {
2481 +               msm_nand_dma_unmap(chip->dev, oob_dma_addr,
2482 +                                  ops->ooblen, DMA_FROM_DEVICE,
2483 +                                  ops->oobbuf, oob_bounce_buf);
2484 +       }
2485 +err_dma_map_oobbuf_failed:
2486 +       if (ops->datbuf) {
2487 +               msm_nand_dma_unmap(chip->dev, data_dma_addr,
2488 +                                  ops->len, DMA_BIDIRECTIONAL,
2489 +                                  ops->datbuf, dat_bounce_buf);
2490 +       }
2491 +
2492 +       if (ops->mode != MTD_OPS_RAW)
2493 +               ops->retlen = mtd->writesize * pages_read;
2494 +       else
2495 +               ops->retlen = (mtd->writesize +  mtd->oobsize) *
2496 +                                                       pages_read;
2497 +       ops->oobretlen = ops->ooblen - oob_len;
2498 +       if (err)
2499 +               pr_err("msm_nand_read_oob %llx %x %x failed %d, corrected %d\n",
2500 +                      from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
2501 +                      total_ecc_errors);
2502 +#if VERBOSE
2503 +       pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
2504 +                       __func__, err, ops->retlen, ops->oobretlen);
2505 +
2506 +       pr_info("==================================================="
2507 +                       "==============\n");
2508 +#endif
2509 +       return err;
2510 +}
2511 +
2512 +static int msm_nand_read_oob_dualnandc(struct mtd_info *mtd, loff_t from,
2513 +                       struct mtd_oob_ops *ops)
2514 +{
2515 +       struct msm_nand_chip *chip = mtd->priv;
2516 +
2517 +       struct {
2518 +               dmov_s cmd[16 * 6 + 20];
2519 +               unsigned cmdptr;
2520 +               struct {
2521 +                       uint32_t cmd;
2522 +                       uint32_t nandc01_addr0;
2523 +                       uint32_t nandc10_addr0;
2524 +                       uint32_t nandc11_addr1;
2525 +                       uint32_t chipsel_cs0;
2526 +                       uint32_t chipsel_cs1;
2527 +                       uint32_t cfg0;
2528 +                       uint32_t cfg1;
2529 +                       uint32_t eccbchcfg;
2530 +                       uint32_t exec;
2531 +                       uint32_t ecccfg;
2532 +                       uint32_t ebi2_chip_select_cfg0;
2533 +                       uint32_t adm_mux_data_ack_req_nc01;
2534 +                       uint32_t adm_mux_cmd_ack_req_nc01;
2535 +                       uint32_t adm_mux_data_ack_req_nc10;
2536 +                       uint32_t adm_mux_cmd_ack_req_nc10;
2537 +                       uint32_t adm_default_mux;
2538 +                       uint32_t default_ebi2_chip_select_cfg0;
2539 +                       uint32_t nc10_flash_dev_cmd_vld;
2540 +                       uint32_t nc10_flash_dev_cmd1;
2541 +                       uint32_t nc10_flash_dev_cmd_vld_default;
2542 +                       uint32_t nc10_flash_dev_cmd1_default;
2543 +                       struct {
2544 +                               uint32_t flash_status;
2545 +                               uint32_t buffer_status;
2546 +                       } result[16];
2547 +               } data;
2548 +       } *dma_buffer;
2549 +       dmov_s *cmd;
2550 +       unsigned n;
2551 +       unsigned page = 0;
2552 +       uint32_t oob_len;
2553 +       uint32_t sectordatasize;
2554 +       uint32_t sectoroobsize;
2555 +       int err, pageerr, rawerr;
2556 +       dma_addr_t data_dma_addr = 0;
2557 +       dma_addr_t oob_dma_addr = 0;
2558 +       dma_addr_t data_dma_addr_curr = 0;
2559 +       dma_addr_t oob_dma_addr_curr = 0;
2560 +       uint32_t oob_col = 0;
2561 +       unsigned page_count;
2562 +       unsigned pages_read = 0;
2563 +       unsigned start_sector = 0;
2564 +       uint32_t ecc_errors;
2565 +       uint32_t total_ecc_errors = 0;
2566 +       unsigned cwperpage;
2567 +       unsigned cw_offset = chip->cw_size;
2568 +#if VERBOSE
2569 +               pr_info("================================================="
2570 +                               "============\n");
2571 +               pr_info("%s:\nfrom 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
2572 +                               "\noobbuf 0x%p ooblen 0x%x\n\n",
2573 +                               __func__, from, ops->mode, ops->datbuf,
2574 +                               ops->len, ops->oobbuf, ops->ooblen);
2575 +#endif
2576 +
2577 +       if (mtd->writesize == 2048)
2578 +               page = from >> 11;
2579 +
2580 +       if (mtd->writesize == 4096)
2581 +               page = from >> 12;
2582 +
2583 +       if (interleave_enable)
2584 +               page = (from >> 1) >> 12;
2585 +
2586 +       oob_len = ops->ooblen;
2587 +       cwperpage = (mtd->writesize >> 9);
2588 +
2589 +       if (from & (mtd->writesize - 1)) {
2590 +               pr_err("%s: unsupported from, 0x%llx\n",
2591 +                      __func__, from);
2592 +               return -EINVAL;
2593 +       }
2594 +       if (ops->mode != MTD_OPS_RAW) {
2595 +               if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
2596 +                       pr_err("%s: unsupported ops->len, %d\n",
2597 +                              __func__, ops->len);
2598 +                       return -EINVAL;
2599 +               }
2600 +       } else {
2601 +               if (ops->datbuf != NULL &&
2602 +                       (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
2603 +                       pr_err("%s: unsupported ops->len,"
2604 +                               " %d for MTD_OPS_RAW\n", __func__, ops->len);
2605 +                       return -EINVAL;
2606 +               }
2607 +       }
2608 +
2609 +       if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
2610 +               pr_err("%s: unsupported ops->ooboffs, %d\n",
2611 +                      __func__, ops->ooboffs);
2612 +               return -EINVAL;
2613 +       }
2614 +
2615 +       if (ops->oobbuf && !ops->datbuf && ops->mode == MTD_OPS_AUTO_OOB)
2616 +               start_sector = cwperpage - 1;
2617 +
2618 +       if (ops->oobbuf && !ops->datbuf) {
2619 +               page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
2620 +                       mtd->oobavail : mtd->oobsize);
2621 +               if ((page_count == 0) && (ops->ooblen))
2622 +                       page_count = 1;
2623 +       } else if (ops->mode != MTD_OPS_RAW)
2624 +               page_count = ops->len / mtd->writesize;
2625 +       else
2626 +               page_count = ops->len / (mtd->writesize + mtd->oobsize);
2627 +
2628 +       if (ops->datbuf) {
2629 +               data_dma_addr_curr = data_dma_addr =
2630 +                       msm_nand_dma_map(chip->dev, ops->datbuf, ops->len,
2631 +                                        DMA_FROM_DEVICE, NULL);
2632 +               if (dma_mapping_error(chip->dev, data_dma_addr)) {
2633 +                       pr_err("msm_nand_read_oob_dualnandc: "
2634 +                               "failed to get dma addr for %p\n",
2635 +                               ops->datbuf);
2636 +                       return -EIO;
2637 +               }
2638 +       }
2639 +       if (ops->oobbuf) {
2640 +               memset(ops->oobbuf, 0xff, ops->ooblen);
2641 +               oob_dma_addr_curr = oob_dma_addr =
2642 +                       msm_nand_dma_map(chip->dev, ops->oobbuf,
2643 +                                        ops->ooblen, DMA_BIDIRECTIONAL, NULL);
2644 +               if (dma_mapping_error(chip->dev, oob_dma_addr)) {
2645 +                       pr_err("msm_nand_read_oob_dualnandc: "
2646 +                               "failed to get dma addr for %p\n",
2647 +                               ops->oobbuf);
2648 +                       err = -EIO;
2649 +                       goto err_dma_map_oobbuf_failed;
2650 +               }
2651 +       }
2652 +
2653 +       wait_event(chip->wait_queue,
2654 +                  (dma_buffer = msm_nand_get_dma_buffer(
2655 +                           chip, sizeof(*dma_buffer))));
2656 +
2657 +       oob_col = start_sector * chip->cw_size;
2658 +       if (chip->CFG1 & CFG1_WIDE_FLASH) {
2659 +               oob_col >>= 1;
2660 +               cw_offset >>= 1;
2661 +       }
2662 +
2663 +       err = 0;
2664 +       while (page_count-- > 0) {
2665 +               cmd = dma_buffer->cmd;
2666 +
2667 +               if (ops->mode != MTD_OPS_RAW) {
2668 +                       dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ_ECC;
2669 +                       if (start_sector == (cwperpage - 1)) {
2670 +                               dma_buffer->data.cfg0 = (chip->CFG0 &
2671 +                                                       ~(7U << 6));
2672 +                       } else {
2673 +                               dma_buffer->data.cfg0 = (chip->CFG0 &
2674 +                               ~(7U << 6))
2675 +                               | (((cwperpage >> 1)-1) << 6);
2676 +                       }
2677 +                       dma_buffer->data.cfg1 = chip->CFG1;
2678 +                       if (enable_bch_ecc)
2679 +                               dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
2680 +               } else {
2681 +                       dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
2682 +                       dma_buffer->data.cfg0 = ((chip->CFG0_RAW &
2683 +                               ~(7U << 6)) | ((((cwperpage >> 1)-1) << 6)));
2684 +                       dma_buffer->data.cfg1 = chip->CFG1_RAW |
2685 +                                       (chip->CFG1 & CFG1_WIDE_FLASH);
2686 +               }
2687 +
2688 +               if (!interleave_enable) {
2689 +                       if (start_sector == (cwperpage - 1)) {
2690 +                               dma_buffer->data.nandc10_addr0 =
2691 +                                                       (page << 16) | oob_col;
2692 +                               dma_buffer->data.nc10_flash_dev_cmd_vld = 0xD;
2693 +                               dma_buffer->data.nc10_flash_dev_cmd1 =
2694 +                                                               0xF00F3000;
2695 +                       } else {
2696 +                               dma_buffer->data.nandc01_addr0 = page << 16;
2697 +                               /* NC10 ADDR0 points to the next code word */
2698 +                               dma_buffer->data.nandc10_addr0 = (page << 16) |
2699 +                                                               cw_offset;
2700 +                               dma_buffer->data.nc10_flash_dev_cmd_vld = 0x1D;
2701 +                               dma_buffer->data.nc10_flash_dev_cmd1 =
2702 +                                                               0xF00FE005;
2703 +                       }
2704 +               } else {
2705 +                       dma_buffer->data.nandc01_addr0 =
2706 +                       dma_buffer->data.nandc10_addr0 =
2707 +                                               (page << 16) | oob_col;
2708 +               }
2709 +               /* ADDR1 */
2710 +               dma_buffer->data.nandc11_addr1 = (page >> 16) & 0xff;
2711 +
2712 +               dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
2713 +               dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
2714 +               dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
2715 +               dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
2716 +               dma_buffer->data.adm_default_mux = 0x00000FC0;
2717 +               dma_buffer->data.nc10_flash_dev_cmd_vld_default = 0x1D;
2718 +               dma_buffer->data.nc10_flash_dev_cmd1_default = 0xF00F3000;
2719 +
2720 +               dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
2721 +               dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
2722 +
2723 +               /* chipsel_0 + enable DM interface */
2724 +               dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
2725 +               /* chipsel_1 + enable DM interface */
2726 +               dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
2727 +
2728 +               /* GO bit for the EXEC register */
2729 +               dma_buffer->data.exec = 1;
2730 +
2731 +               BUILD_BUG_ON(16 != ARRAY_SIZE(dma_buffer->data.result));
2732 +
2733 +               for (n = start_sector; n < cwperpage; n++) {
2734 +                       /* flash + buffer status return words */
2735 +                       dma_buffer->data.result[n].flash_status = 0xeeeeeeee;
2736 +                       dma_buffer->data.result[n].buffer_status = 0xeeeeeeee;
2737 +
2738 +                       if (n == start_sector) {
2739 +                               if (!interleave_enable) {
2740 +                                       cmd->cmd = 0;
2741 +                                       cmd->src = msm_virt_to_dma(chip,
2742 +                                       &dma_buffer->
2743 +                                               data.nc10_flash_dev_cmd_vld);
2744 +                                       cmd->dst = NC10(MSM_NAND_DEV_CMD_VLD);
2745 +                                       cmd->len = 4;
2746 +                                       cmd++;
2747 +
2748 +                                       cmd->cmd = 0;
2749 +                                       cmd->src = msm_virt_to_dma(chip,
2750 +                                       &dma_buffer->data.nc10_flash_dev_cmd1);
2751 +                                       cmd->dst = NC10(MSM_NAND_DEV_CMD1);
2752 +                                       cmd->len = 4;
2753 +                                       cmd++;
2754 +
2755 +                                       /* NC01, NC10 --> ADDR1 */
2756 +                                       cmd->cmd = 0;
2757 +                                       cmd->src = msm_virt_to_dma(chip,
2758 +                                       &dma_buffer->data.nandc11_addr1);
2759 +                                       cmd->dst = NC11(MSM_NAND_ADDR1);
2760 +                                       cmd->len = 8;
2761 +                                       cmd++;
2762 +
2763 +                                       cmd->cmd = 0;
2764 +                                       cmd->src = msm_virt_to_dma(chip,
2765 +                                               &dma_buffer->data.cfg0);
2766 +                                       cmd->dst = NC11(MSM_NAND_DEV0_CFG0);
2767 +                                       if (enable_bch_ecc)
2768 +                                               cmd->len = 12;
2769 +                                       else
2770 +                                               cmd->len = 8;
2771 +                                       cmd++;
2772 +                               } else {
2773 +                                       /* enable CS0 & CS1 */
2774 +                                       cmd->cmd = 0;
2775 +                                       cmd->src = msm_virt_to_dma(chip,
2776 +                                       &dma_buffer->
2777 +                                               data.ebi2_chip_select_cfg0);
2778 +                                       cmd->dst = EBI2_CHIP_SELECT_CFG0;
2779 +                                       cmd->len = 4;
2780 +                                       cmd++;
2781 +
2782 +                                       /* NC01, NC10 --> ADDR1 */
2783 +                                       cmd->cmd = 0;
2784 +                                       cmd->src = msm_virt_to_dma(chip,
2785 +                                       &dma_buffer->data.nandc11_addr1);
2786 +                                       cmd->dst = NC11(MSM_NAND_ADDR1);
2787 +                                       cmd->len = 4;
2788 +                                       cmd++;
2789 +
2790 +                                       /* Enable CS0 for NC01 */
2791 +                                       cmd->cmd = 0;
2792 +                                       cmd->src = msm_virt_to_dma(chip,
2793 +                                       &dma_buffer->data.chipsel_cs0);
2794 +                                       cmd->dst =
2795 +                                       NC01(MSM_NAND_FLASH_CHIP_SELECT);
2796 +                                       cmd->len = 4;
2797 +                                       cmd++;
2798 +
2799 +                                       /* Enable CS1 for NC10 */
2800 +                                       cmd->cmd = 0;
2801 +                                       cmd->src = msm_virt_to_dma(chip,
2802 +                                       &dma_buffer->data.chipsel_cs1);
2803 +                                       cmd->dst =
2804 +                                       NC10(MSM_NAND_FLASH_CHIP_SELECT);
2805 +                                       cmd->len = 4;
2806 +                                       cmd++;
2807 +
2808 +                                       /* config DEV0_CFG0 & CFG1 for CS0 */
2809 +                                       cmd->cmd = 0;
2810 +                                       cmd->src = msm_virt_to_dma(chip,
2811 +                                       &dma_buffer->data.cfg0);
2812 +                                       cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
2813 +                                       cmd->len = 8;
2814 +                                       cmd++;
2815 +
2816 +                                       /* config DEV1_CFG0 & CFG1 for CS1 */
2817 +                                       cmd->cmd = 0;
2818 +                                       cmd->src = msm_virt_to_dma(chip,
2819 +                                       &dma_buffer->data.cfg0);
2820 +                                       cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
2821 +                                       cmd->len = 8;
2822 +                                       cmd++;
2823 +                               }
2824 +
2825 +                               dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
2826 +                               cmd->cmd = 0;
2827 +                               cmd->src = msm_virt_to_dma(chip,
2828 +                                               &dma_buffer->data.ecccfg);
2829 +                               cmd->dst = NC11(MSM_NAND_EBI2_ECC_BUF_CFG);
2830 +                               cmd->len = 4;
2831 +                               cmd++;
2832 +
2833 +                               /* if 'only' the last code word */
2834 +                               if (n == cwperpage - 1) {
2835 +                                       /* MASK CMD ACK/REQ --> NC01 (0x53C)*/
2836 +                                       cmd->cmd = 0;
2837 +                                       cmd->src = msm_virt_to_dma(chip,
2838 +                                       &dma_buffer->
2839 +                                               data.adm_mux_cmd_ack_req_nc01);
2840 +                                       cmd->dst = EBI2_NAND_ADM_MUX;
2841 +                                       cmd->len = 4;
2842 +                                       cmd++;
2843 +
2844 +                                       /* CMD */
2845 +                                       cmd->cmd = DST_CRCI_NAND_CMD;
2846 +                                       cmd->src = msm_virt_to_dma(chip,
2847 +                                                       &dma_buffer->data.cmd);
2848 +                                       cmd->dst = NC10(MSM_NAND_FLASH_CMD);
2849 +                                       cmd->len = 4;
2850 +                                       cmd++;
2851 +
2852 +                                       /* NC10 --> ADDR0 ( 0x0 ) */
2853 +                                       cmd->cmd = 0;
2854 +                                       cmd->src = msm_virt_to_dma(chip,
2855 +                                       &dma_buffer->data.nandc10_addr0);
2856 +                                       cmd->dst = NC10(MSM_NAND_ADDR0);
2857 +                                       cmd->len = 4;
2858 +                                       cmd++;
2859 +
2860 +                                       /* kick the execute reg for NC10 */
2861 +                                       cmd->cmd = 0;
2862 +                                       cmd->src = msm_virt_to_dma(chip,
2863 +                                               &dma_buffer->data.exec);
2864 +                                       cmd->dst = NC10(MSM_NAND_EXEC_CMD);
2865 +                                       cmd->len = 4;
2866 +                                       cmd++;
2867 +
2868 +                                       /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
2869 +                                       cmd->cmd = 0;
2870 +                                       cmd->src = msm_virt_to_dma(chip,
2871 +                                       &dma_buffer->
2872 +                                       data.adm_mux_data_ack_req_nc01);
2873 +                                       cmd->dst = EBI2_NAND_ADM_MUX;
2874 +                                       cmd->len = 4;
2875 +                                       cmd++;
2876 +
2877 +                                       /* block on data ready from NC10, then
2878 +                                        * read the status register
2879 +                                        */
2880 +                                       cmd->cmd = SRC_CRCI_NAND_DATA;
2881 +                                       cmd->src = NC10(MSM_NAND_FLASH_STATUS);
2882 +                                       cmd->dst = msm_virt_to_dma(chip,
2883 +                                               &dma_buffer->data.result[n]);
2884 +                                       /* MSM_NAND_FLASH_STATUS +
2885 +                                        * MSM_NAND_BUFFER_STATUS
2886 +                                        */
2887 +                                       cmd->len = 8;
2888 +                                       cmd++;
2889 +                               } else {
2890 +                                       /* NC01 --> ADDR0 */
2891 +                                       cmd->cmd = 0;
2892 +                                       cmd->src = msm_virt_to_dma(chip,
2893 +                                       &dma_buffer->data.nandc01_addr0);
2894 +                                       cmd->dst = NC01(MSM_NAND_ADDR0);
2895 +                                       cmd->len = 4;
2896 +                                       cmd++;
2897 +
2898 +                                       /* NC10 --> ADDR1 */
2899 +                                       cmd->cmd = 0;
2900 +                                       cmd->src = msm_virt_to_dma(chip,
2901 +                                       &dma_buffer->data.nandc10_addr0);
2902 +                                       cmd->dst = NC10(MSM_NAND_ADDR0);
2903 +                                       cmd->len = 4;
2904 +                                       cmd++;
2905 +
2906 +                                       /* MASK CMD ACK/REQ --> NC10 (0xF14)*/
2907 +                                       cmd->cmd = 0;
2908 +                                       cmd->src = msm_virt_to_dma(chip,
2909 +                                       &dma_buffer->
2910 +                                               data.adm_mux_cmd_ack_req_nc10);
2911 +                                       cmd->dst = EBI2_NAND_ADM_MUX;
2912 +                                       cmd->len = 4;
2913 +                                       cmd++;
2914 +
2915 +                                       /* CMD */
2916 +                                       cmd->cmd = DST_CRCI_NAND_CMD;
2917 +                                       cmd->src = msm_virt_to_dma(chip,
2918 +                                                       &dma_buffer->data.cmd);
2919 +                                       cmd->dst = NC01(MSM_NAND_FLASH_CMD);
2920 +                                       cmd->len = 4;
2921 +                                       cmd++;
2922 +
2923 +                                       /* kick the execute register for NC01*/
2924 +                                       cmd->cmd = 0;
2925 +                                       cmd->src = msm_virt_to_dma(chip,
2926 +                                                &dma_buffer->data.exec);
2927 +                                       cmd->dst = NC01(MSM_NAND_EXEC_CMD);
2928 +                                       cmd->len = 4;
2929 +                                       cmd++;
2930 +                               }
2931 +                       }
2932 +
2933 +                       /* read data block
2934 +                        * (only valid if status says success)
2935 +                        */
2936 +                       if (ops->datbuf || (ops->oobbuf &&
2937 +                                                ops->mode != MTD_OPS_AUTO_OOB)) {
2938 +                               if (ops->mode != MTD_OPS_RAW)
2939 +                                       sectordatasize = (n < (cwperpage - 1))
2940 +                                       ? 516 : (512 - ((cwperpage - 1) << 2));
2941 +                               else
2942 +                                       sectordatasize = chip->cw_size;
2943 +
2944 +                               if (n % 2 == 0) {
2945 +                                       /* MASK DATA ACK/REQ --> NC10 (0xF28)*/
2946 +                                       cmd->cmd = 0;
2947 +                                       cmd->src = msm_virt_to_dma(chip,
2948 +                                       &dma_buffer->
2949 +                                       data.adm_mux_data_ack_req_nc10);
2950 +                                       cmd->dst = EBI2_NAND_ADM_MUX;
2951 +                                       cmd->len = 4;
2952 +                                       cmd++;
2953 +
2954 +                                       /* block on data ready from NC01, then
2955 +                                        * read the status register
2956 +                                        */
2957 +                                       cmd->cmd = SRC_CRCI_NAND_DATA;
2958 +                                       cmd->src = NC01(MSM_NAND_FLASH_STATUS);
2959 +                                       cmd->dst = msm_virt_to_dma(chip,
2960 +                                               &dma_buffer->data.result[n]);
2961 +                                       /* MSM_NAND_FLASH_STATUS +
2962 +                                        * MSM_NAND_BUFFER_STATUS
2963 +                                        */
2964 +                                       cmd->len = 8;
2965 +                                       cmd++;
2966 +
2967 +                                       /* MASK CMD ACK/REQ --> NC01 (0x53C)*/
2968 +                                       cmd->cmd = 0;
2969 +                                       cmd->src = msm_virt_to_dma(chip,
2970 +                                       &dma_buffer->
2971 +                                               data.adm_mux_cmd_ack_req_nc01);
2972 +                                       cmd->dst = EBI2_NAND_ADM_MUX;
2973 +                                       cmd->len = 4;
2974 +                                       cmd++;
2975 +
2976 +                                       /* CMD */
2977 +                                       cmd->cmd = DST_CRCI_NAND_CMD;
2978 +                                       cmd->src = msm_virt_to_dma(chip,
2979 +                                                       &dma_buffer->data.cmd);
2980 +                                       cmd->dst = NC10(MSM_NAND_FLASH_CMD);
2981 +                                       cmd->len = 4;
2982 +                                       cmd++;
2983 +
2984 +                                       /* kick the execute register for NC10 */
2985 +                                       cmd->cmd = 0;
2986 +                                       cmd->src = msm_virt_to_dma(chip,
2987 +                                               &dma_buffer->data.exec);
2988 +                                       cmd->dst = NC10(MSM_NAND_EXEC_CMD);
2989 +                                       cmd->len = 4;
2990 +                                       cmd++;
2991 +
2992 +                                       /* Read only when there is data
2993 +                                        * buffer
2994 +                                        */
2995 +                                       if (ops->datbuf) {
2996 +                                               cmd->cmd = 0;
2997 +                                               cmd->src =
2998 +                                               NC01(MSM_NAND_FLASH_BUFFER);
2999 +                                               cmd->dst = data_dma_addr_curr;
3000 +                                               data_dma_addr_curr +=
3001 +                                               sectordatasize;
3002 +                                               cmd->len = sectordatasize;
3003 +                                               cmd++;
3004 +                                       }
3005 +                               } else {
3006 +                                       /* MASK DATA ACK/REQ -->
3007 +                                        * NC01 (0xA3C)
3008 +                                        */
3009 +                                       cmd->cmd = 0;
3010 +                                       cmd->src = msm_virt_to_dma(chip,
3011 +                                       &dma_buffer->
3012 +                                       data.adm_mux_data_ack_req_nc01);
3013 +                                       cmd->dst = EBI2_NAND_ADM_MUX;
3014 +                                       cmd->len = 4;
3015 +                                       cmd++;
3016 +
3017 +                                       /* block on data ready from NC10
3018 +                                        * then read the status register
3019 +                                        */
3020 +                                       cmd->cmd = SRC_CRCI_NAND_DATA;
3021 +                                       cmd->src =
3022 +                                       NC10(MSM_NAND_FLASH_STATUS);
3023 +                                       cmd->dst = msm_virt_to_dma(chip,
3024 +                                          &dma_buffer->data.result[n]);
3025 +                                       /* MSM_NAND_FLASH_STATUS +
3026 +                                        * MSM_NAND_BUFFER_STATUS
3027 +                                        */
3028 +                                       cmd->len = 8;
3029 +                                       cmd++;
3030 +                                       if (n != cwperpage - 1) {
3031 +                                               /* MASK CMD ACK/REQ -->
3032 +                                                * NC10 (0xF14)
3033 +                                                */
3034 +                                               cmd->cmd = 0;
3035 +                                               cmd->src =
3036 +                                               msm_virt_to_dma(chip,
3037 +                                               &dma_buffer->
3038 +                                               data.adm_mux_cmd_ack_req_nc10);
3039 +                                               cmd->dst = EBI2_NAND_ADM_MUX;
3040 +                                               cmd->len = 4;
3041 +                                               cmd++;
3042 +
3043 +                                               /* CMD */
3044 +                                               cmd->cmd = DST_CRCI_NAND_CMD;
3045 +                                               cmd->src = msm_virt_to_dma(chip,
3046 +                                                       &dma_buffer->data.cmd);
3047 +                                               cmd->dst =
3048 +                                               NC01(MSM_NAND_FLASH_CMD);
3049 +                                               cmd->len = 4;
3050 +                                               cmd++;
3051 +
3052 +                                               /* EXEC */
3053 +                                               cmd->cmd = 0;
3054 +                                               cmd->src = msm_virt_to_dma(chip,
3055 +                                                       &dma_buffer->data.exec);
3056 +                                               cmd->dst =
3057 +                                               NC01(MSM_NAND_EXEC_CMD);
3058 +                                               cmd->len = 4;
3059 +                                               cmd++;
3060 +                                       }
3061 +
3062 +                                       /* Read only when there is data
3063 +                                        * buffer
3064 +                                        */
3065 +                                       if (ops->datbuf) {
3066 +                                               cmd->cmd = 0;
3067 +                                               cmd->src =
3068 +                                               NC10(MSM_NAND_FLASH_BUFFER);
3069 +                                               cmd->dst = data_dma_addr_curr;
3070 +                                               data_dma_addr_curr +=
3071 +                                               sectordatasize;
3072 +                                               cmd->len = sectordatasize;
3073 +                                               cmd++;
3074 +                                       }
3075 +                               }
3076 +                       }
3077 +
3078 +                       if (ops->oobbuf && (n == (cwperpage - 1)
3079 +                            || ops->mode != MTD_OPS_AUTO_OOB)) {
3080 +                               cmd->cmd = 0;
3081 +                               if (n == (cwperpage - 1)) {
3082 +                                       /* Use NC10 for reading the
3083 +                                        * last codeword!!!
3084 +                                        */
3085 +                                       cmd->src = NC10(MSM_NAND_FLASH_BUFFER) +
3086 +                                               (512 - ((cwperpage - 1) << 2));
3087 +                                       sectoroobsize = (cwperpage << 2);
3088 +                                       if (ops->mode != MTD_OPS_AUTO_OOB)
3089 +                                               sectoroobsize +=
3090 +                                                       chip->ecc_parity_bytes;
3091 +                               } else {
3092 +                                       if (n % 2 == 0)
3093 +                                               cmd->src =
3094 +                                               NC01(MSM_NAND_FLASH_BUFFER)
3095 +                                               + 516;
3096 +                                       else
3097 +                                               cmd->src =
3098 +                                               NC10(MSM_NAND_FLASH_BUFFER)
3099 +                                               + 516;
3100 +                                       sectoroobsize = chip->ecc_parity_bytes;
3101 +                               }
3102 +                               cmd->dst = oob_dma_addr_curr;
3103 +                               if (sectoroobsize < oob_len)
3104 +                                       cmd->len = sectoroobsize;
3105 +                               else
3106 +                                       cmd->len = oob_len;
3107 +                               oob_dma_addr_curr += cmd->len;
3108 +                               oob_len -= cmd->len;
3109 +                               if (cmd->len > 0)
3110 +                                       cmd++;
3111 +                       }
3112 +               }
3113 +               /* ADM --> Default mux state (0xFC0) */
3114 +               cmd->cmd = 0;
3115 +               cmd->src = msm_virt_to_dma(chip,
3116 +                       &dma_buffer->data.adm_default_mux);
3117 +               cmd->dst = EBI2_NAND_ADM_MUX;
3118 +               cmd->len = 4;
3119 +               cmd++;
3120 +
3121 +               if (!interleave_enable) {
3122 +                       cmd->cmd = 0;
3123 +                       cmd->src = msm_virt_to_dma(chip,
3124 +                       &dma_buffer->data.nc10_flash_dev_cmd_vld_default);
3125 +                       cmd->dst = NC10(MSM_NAND_DEV_CMD_VLD);
3126 +                       cmd->len = 4;
3127 +                       cmd++;
3128 +
3129 +                       cmd->cmd = 0;
3130 +                       cmd->src = msm_virt_to_dma(chip,
3131 +                       &dma_buffer->data.nc10_flash_dev_cmd1_default);
3132 +                       cmd->dst = NC10(MSM_NAND_DEV_CMD1);
3133 +                       cmd->len = 4;
3134 +                       cmd++;
3135 +               } else {
3136 +                       /* disable CS1 */
3137 +                       cmd->cmd = 0;
3138 +                       cmd->src = msm_virt_to_dma(chip,
3139 +                       &dma_buffer->data.default_ebi2_chip_select_cfg0);
3140 +                       cmd->dst = EBI2_CHIP_SELECT_CFG0;
3141 +                       cmd->len = 4;
3142 +                       cmd++;
3143 +               }
3144 +
3145 +               BUILD_BUG_ON(16 * 6 + 20 != ARRAY_SIZE(dma_buffer->cmd));
3146 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
3147 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
3148 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
3149 +
3150 +               dma_buffer->cmdptr =
3151 +                       (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
3152 +                       | CMD_PTR_LP;
3153 +
3154 +               mb();
3155 +               msm_dmov_exec_cmd(chip->dma_channel,
3156 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
3157 +                       &dma_buffer->cmdptr)));
3158 +               mb();
3159 +
3160 +               /* if any of the writes failed (0x10), or there
3161 +                * was a protection violation (0x100), we lose
3162 +                */
3163 +               pageerr = rawerr = 0;
3164 +               for (n = start_sector; n < cwperpage; n++) {
3165 +                       if (dma_buffer->data.result[n].flash_status & 0x110) {
3166 +                               rawerr = -EIO;
3167 +                               break;
3168 +                       }
3169 +               }
3170 +               if (rawerr) {
3171 +                       if (ops->datbuf && ops->mode != MTD_OPS_RAW) {
3172 +                               uint8_t *datbuf = ops->datbuf +
3173 +                                       pages_read * mtd->writesize;
3174 +
3175 +                               dma_sync_single_for_cpu(chip->dev,
3176 +                                       data_dma_addr_curr-mtd->writesize,
3177 +                                       mtd->writesize, DMA_BIDIRECTIONAL);
3178 +
3179 +                               for (n = 0; n < mtd->writesize; n++) {
3180 +                                       /* empty blocks read 0x54 at
3181 +                                        * these offsets
3182 +                                        */
3183 +                                       if ((n % 516 == 3 || n % 516 == 175)
3184 +                                                       && datbuf[n] == 0x54)
3185 +                                               datbuf[n] = 0xff;
3186 +                                       if (datbuf[n] != 0xff) {
3187 +                                               pageerr = rawerr;
3188 +                                               break;
3189 +                                       }
3190 +                               }
3191 +
3192 +                               dma_sync_single_for_device(chip->dev,
3193 +                                       data_dma_addr_curr-mtd->writesize,
3194 +                                       mtd->writesize, DMA_BIDIRECTIONAL);
3195 +
3196 +                       }
3197 +                       if (ops->oobbuf) {
3198 +                               dma_sync_single_for_cpu(chip->dev,
3199 +                               oob_dma_addr_curr - (ops->ooblen - oob_len),
3200 +                               ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
3201 +
3202 +                               for (n = 0; n < ops->ooblen; n++) {
3203 +                                       if (ops->oobbuf[n] != 0xff) {
3204 +                                               pageerr = rawerr;
3205 +                                               break;
3206 +                                       }
3207 +                               }
3208 +
3209 +                               dma_sync_single_for_device(chip->dev,
3210 +                               oob_dma_addr_curr - (ops->ooblen - oob_len),
3211 +                               ops->ooblen - oob_len, DMA_BIDIRECTIONAL);
3212 +                       }
3213 +               }
3214 +               if (pageerr) {
3215 +                       for (n = start_sector; n < cwperpage; n++) {
3216 +                               if (dma_buffer->data.result[n].buffer_status
3217 +                                       & chip->uncorrectable_bit_mask) {
3218 +                                       /* not thread safe */
3219 +                                       mtd->ecc_stats.failed++;
3220 +                                       pageerr = -EBADMSG;
3221 +                                       break;
3222 +                               }
3223 +                       }
3224 +               }
3225 +               if (!rawerr) { /* check for corretable errors */
3226 +                       for (n = start_sector; n < cwperpage; n++) {
3227 +                               ecc_errors = dma_buffer->data.
3228 +                                       result[n].buffer_status
3229 +                                       & chip->num_err_mask;
3230 +                               if (ecc_errors) {
3231 +                                       total_ecc_errors += ecc_errors;
3232 +                                       /* not thread safe */
3233 +                                       mtd->ecc_stats.corrected += ecc_errors;
3234 +                                       if (ecc_errors > 1)
3235 +                                               pageerr = -EUCLEAN;
3236 +                               }
3237 +                       }
3238 +               }
3239 +               if (pageerr && (pageerr != -EUCLEAN || err == 0))
3240 +                       err = pageerr;
3241 +
3242 +#if VERBOSE
3243 +               if (rawerr && !pageerr) {
3244 +                       pr_err("msm_nand_read_oob_dualnandc "
3245 +                               "%llx %x %x empty page\n",
3246 +                              (loff_t)page * mtd->writesize, ops->len,
3247 +                              ops->ooblen);
3248 +               } else {
3249 +                       for (n = start_sector; n < cwperpage; n++) {
3250 +                               if (n%2) {
3251 +                                       pr_info("NC10: flash_status[%d] = %x, "
3252 +                                        "buffr_status[%d] = %x\n",
3253 +                                       n, dma_buffer->
3254 +                                               data.result[n].flash_status,
3255 +                                       n, dma_buffer->
3256 +                                               data.result[n].buffer_status);
3257 +                               } else {
3258 +                                       pr_info("NC01: flash_status[%d] = %x, "
3259 +                                        "buffr_status[%d] = %x\n",
3260 +                                       n, dma_buffer->
3261 +                                               data.result[n].flash_status,
3262 +                                       n, dma_buffer->
3263 +                                               data.result[n].buffer_status);
3264 +                               }
3265 +                       }
3266 +               }
3267 +#endif
3268 +               if (err && err != -EUCLEAN && err != -EBADMSG)
3269 +                       break;
3270 +               pages_read++;
3271 +               page++;
3272 +       }
3273 +
3274 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
3275 +
3276 +       if (ops->oobbuf) {
3277 +               dma_unmap_page(chip->dev, oob_dma_addr,
3278 +                                ops->ooblen, DMA_FROM_DEVICE);
3279 +       }
3280 +err_dma_map_oobbuf_failed:
3281 +       if (ops->datbuf) {
3282 +               dma_unmap_page(chip->dev, data_dma_addr,
3283 +                                ops->len, DMA_BIDIRECTIONAL);
3284 +       }
3285 +
3286 +       if (ops->mode != MTD_OPS_RAW)
3287 +               ops->retlen = mtd->writesize * pages_read;
3288 +       else
3289 +               ops->retlen = (mtd->writesize +  mtd->oobsize) *
3290 +                                                       pages_read;
3291 +       ops->oobretlen = ops->ooblen - oob_len;
3292 +       if (err)
3293 +               pr_err("msm_nand_read_oob_dualnandc "
3294 +                       "%llx %x %x failed %d, corrected %d\n",
3295 +                       from, ops->datbuf ? ops->len : 0, ops->ooblen, err,
3296 +                       total_ecc_errors);
3297 +#if VERBOSE
3298 +       pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
3299 +                       __func__, err, ops->retlen, ops->oobretlen);
3300 +
3301 +       pr_info("==================================================="
3302 +                       "==========\n");
3303 +#endif
3304 +       return err;
3305 +}
3306 +
3307 +static int
3308 +msm_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
3309 +             size_t *retlen, u_char *buf)
3310 +{
3311 +       int ret;
3312 +       struct mtd_ecc_stats stats;
3313 +       struct mtd_oob_ops ops;
3314 +       int (*read_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
3315 +
3316 +       if (!dual_nand_ctlr_present)
3317 +               read_oob = msm_nand_read_oob;
3318 +       else
3319 +               read_oob = msm_nand_read_oob_dualnandc;
3320 +
3321 +       ops.mode = MTD_OPS_PLACE_OOB;
3322 +       ops.retlen = 0;
3323 +       ops.ooblen = 0;
3324 +       ops.oobbuf = NULL;
3325 +       ret = 0;
3326 +       *retlen = 0;
3327 +       stats = mtd->ecc_stats;
3328 +
3329 +       if ((from & (mtd->writesize - 1)) == 0 && len == mtd->writesize) {
3330 +               /* reading a page on page boundary */
3331 +               ops.len = len;
3332 +               ops.datbuf = buf;
3333 +               ret = read_oob(mtd, from, &ops);
3334 +               *retlen = ops.retlen;
3335 +       } else if (len > 0) {
3336 +               /* reading any size on any offset. partial page is supported */
3337 +               u8 *bounce_buf;
3338 +               loff_t aligned_from;
3339 +               loff_t offset;
3340 +               size_t actual_len;
3341 +
3342 +               bounce_buf = kmalloc(mtd->writesize, GFP_KERNEL);
3343 +               if (!bounce_buf) {
3344 +                       pr_err("%s: could not allocate memory\n", __func__);
3345 +                       ret = -ENOMEM;
3346 +                       goto out;
3347 +               }
3348 +
3349 +               ops.len = mtd->writesize;
3350 +               offset = from & (mtd->writesize - 1);
3351 +               aligned_from = from - offset;
3352 +
3353 +               for (;;) {
3354 +                       int no_copy;
3355 +
3356 +                       actual_len = mtd->writesize - offset;
3357 +                       if (actual_len > len)
3358 +                               actual_len = len;
3359 +
3360 +                       no_copy = (offset == 0 && actual_len == mtd->writesize);
3361 +                       ops.datbuf = (no_copy) ? buf : bounce_buf;
3362 +
3363 +                       /*
3364 +                        * MTD API requires that all the pages are to
3365 +                        * be read even if uncorrectable or
3366 +                        * correctable ECC errors occur.
3367 +                        */
3368 +                       ret = read_oob(mtd, aligned_from, &ops);
3369 +                       if (ret == -EBADMSG || ret == -EUCLEAN)
3370 +                               ret = 0;
3371 +
3372 +                       if (ret < 0)
3373 +                               break;
3374 +
3375 +                       if (!no_copy)
3376 +                               memcpy(buf, bounce_buf + offset, actual_len);
3377 +
3378 +                       len -= actual_len;
3379 +                       *retlen += actual_len;
3380 +                       if (len == 0)
3381 +                               break;
3382 +
3383 +                       buf += actual_len;
3384 +                       offset = 0;
3385 +                       aligned_from += mtd->writesize;
3386 +               }
3387 +
3388 +               kfree(bounce_buf);
3389 +       }
3390 +
3391 +out:
3392 +       if (ret)
3393 +               return ret;
3394 +
3395 +       if (mtd->ecc_stats.failed - stats.failed)
3396 +               return -EBADMSG;
3397 +
3398 +       if (mtd->ecc_stats.corrected - stats.corrected)
3399 +               return -EUCLEAN;
3400 +
3401 +       return 0;
3402 +}
3403 +
3404 +static int
3405 +msm_nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
3406 +{
3407 +        struct msm_nand_chip *chip = mtd->priv;
3408 +       struct {
3409 +               dmov_s cmd[8 * 7 + 2];
3410 +               unsigned cmdptr;
3411 +               struct {
3412 +                       uint32_t cmd;
3413 +                       uint32_t addr0;
3414 +                       uint32_t addr1;
3415 +                       uint32_t chipsel;
3416 +                       uint32_t cfg0;
3417 +                       uint32_t cfg1;
3418 +                       uint32_t eccbchcfg;
3419 +                       uint32_t exec;
3420 +                       uint32_t ecccfg;
3421 +                       uint32_t clrfstatus;
3422 +                       uint32_t clrrstatus;
3423 +                       uint32_t flash_status[8];
3424 +               } data;
3425 +       } *dma_buffer;
3426 +       dmov_s *cmd;
3427 +       unsigned n;
3428 +       unsigned page = 0;
3429 +       uint32_t oob_len;
3430 +       uint32_t sectordatawritesize;
3431 +       int err = 0;
3432 +       dma_addr_t data_dma_addr = 0;
3433 +       dma_addr_t oob_dma_addr = 0;
3434 +       dma_addr_t data_dma_addr_curr = 0;
3435 +       dma_addr_t oob_dma_addr_curr = 0;
3436 +       uint8_t *dat_bounce_buf = NULL;
3437 +       uint8_t *oob_bounce_buf = NULL;
3438 +       unsigned page_count;
3439 +       unsigned pages_written = 0;
3440 +       unsigned cwperpage;
3441 +#if VERBOSE
3442 +       pr_info("================================================="
3443 +                       "================\n");
3444 +       pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
3445 +                       "\noobbuf 0x%p ooblen 0x%x\n",
3446 +                       __func__, to, ops->mode, ops->datbuf, ops->len,
3447 +                       ops->oobbuf, ops->ooblen);
3448 +#endif
3449 +
3450 +       if (mtd->writesize == 2048)
3451 +               page = to >> 11;
3452 +
3453 +       if (mtd->writesize == 4096)
3454 +               page = to >> 12;
3455 +
3456 +       oob_len = ops->ooblen;
3457 +       cwperpage = (mtd->writesize >> 9);
3458 +
3459 +       if (to & (mtd->writesize - 1)) {
3460 +               pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
3461 +               return -EINVAL;
3462 +       }
3463 +
3464 +       if (ops->mode != MTD_OPS_RAW) {
3465 +               if (ops->ooblen != 0 && ops->mode != MTD_OPS_AUTO_OOB) {
3466 +                       pr_err("%s: unsupported ops->mode,%d\n",
3467 +                                        __func__, ops->mode);
3468 +                       return -EINVAL;
3469 +               }
3470 +               if ((ops->len % mtd->writesize) != 0) {
3471 +                       pr_err("%s: unsupported ops->len, %d\n",
3472 +                                       __func__, ops->len);
3473 +                       return -EINVAL;
3474 +               }
3475 +       } else {
3476 +               if ((ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
3477 +                       pr_err("%s: unsupported ops->len, "
3478 +                               "%d for MTD_OPS_RAW mode\n",
3479 +                                __func__, ops->len);
3480 +                       return -EINVAL;
3481 +               }
3482 +       }
3483 +
3484 +       if (ops->datbuf == NULL) {
3485 +               pr_err("%s: unsupported ops->datbuf == NULL\n", __func__);
3486 +               return -EINVAL;
3487 +       }
3488 +       if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
3489 +               pr_err("%s: unsupported ops->ooboffs, %d\n",
3490 +                      __func__, ops->ooboffs);
3491 +               return -EINVAL;
3492 +       }
3493 +
3494 +       if (ops->datbuf) {
3495 +               data_dma_addr_curr = data_dma_addr =
3496 +                       msm_nand_dma_map(chip->dev, ops->datbuf,
3497 +                                        ops->len, DMA_TO_DEVICE,
3498 +                                        &dat_bounce_buf);
3499 +               if (dma_mapping_error(chip->dev, data_dma_addr)) {
3500 +                       pr_err("msm_nand_write_oob: failed to get dma addr "
3501 +                              "for %p\n", ops->datbuf);
3502 +                       return -EIO;
3503 +               }
3504 +       }
3505 +       if (ops->oobbuf) {
3506 +               oob_dma_addr_curr = oob_dma_addr =
3507 +                       msm_nand_dma_map(chip->dev, ops->oobbuf,
3508 +                                        ops->ooblen, DMA_TO_DEVICE,
3509 +                                        &oob_bounce_buf);
3510 +               if (dma_mapping_error(chip->dev, oob_dma_addr)) {
3511 +                       pr_err("msm_nand_write_oob: failed to get dma addr "
3512 +                              "for %p\n", ops->oobbuf);
3513 +                       err = -EIO;
3514 +                       goto err_dma_map_oobbuf_failed;
3515 +               }
3516 +       }
3517 +       if (ops->mode != MTD_OPS_RAW)
3518 +               page_count = ops->len / mtd->writesize;
3519 +       else
3520 +               page_count = ops->len / (mtd->writesize + mtd->oobsize);
3521 +
3522 +       wait_event(chip->wait_queue, (dma_buffer =
3523 +                       msm_nand_get_dma_buffer(chip, sizeof(*dma_buffer))));
3524 +
3525 +       while (page_count-- > 0) {
3526 +               cmd = dma_buffer->cmd;
3527 +
3528 +               if (ops->mode != MTD_OPS_RAW) {
3529 +                       dma_buffer->data.cfg0 = chip->CFG0;
3530 +                       dma_buffer->data.cfg1 = chip->CFG1;
3531 +                       if (enable_bch_ecc)
3532 +                               dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
3533 +               } else {
3534 +                       dma_buffer->data.cfg0 = (chip->CFG0_RAW &
3535 +                                       ~(7U << 6)) | ((cwperpage-1) << 6);
3536 +                       dma_buffer->data.cfg1 = chip->CFG1_RAW |
3537 +                                               (chip->CFG1 & CFG1_WIDE_FLASH);
3538 +               }
3539 +
3540 +               /* CMD / ADDR0 / ADDR1 / CHIPSEL program values */
3541 +               dma_buffer->data.cmd = MSM_NAND_CMD_PRG_PAGE;
3542 +               dma_buffer->data.addr0 = page << 16;
3543 +               dma_buffer->data.addr1 = (page >> 16) & 0xff;
3544 +               /* chipsel_0 + enable DM interface */
3545 +               dma_buffer->data.chipsel = 0 | 4;
3546 +
3547 +
3548 +               /* GO bit for the EXEC register */
3549 +               dma_buffer->data.exec = 1;
3550 +               dma_buffer->data.clrfstatus = 0x00000020;
3551 +               dma_buffer->data.clrrstatus = 0x000000C0;
3552 +
3553 +               BUILD_BUG_ON(8 != ARRAY_SIZE(dma_buffer->data.flash_status));
3554 +
3555 +               for (n = 0; n < cwperpage ; n++) {
3556 +                       /* status return words */
3557 +                       dma_buffer->data.flash_status[n] = 0xeeeeeeee;
3558 +                       /* block on cmd ready, then
3559 +                        * write CMD / ADDR0 / ADDR1 / CHIPSEL regs in a burst
3560 +                        */
3561 +                       cmd->cmd = DST_CRCI_NAND_CMD;
3562 +                       cmd->src =
3563 +                               msm_virt_to_dma(chip, &dma_buffer->data.cmd);
3564 +                       cmd->dst = MSM_NAND_FLASH_CMD;
3565 +                       if (n == 0)
3566 +                               cmd->len = 16;
3567 +                       else
3568 +                               cmd->len = 4;
3569 +                       cmd++;
3570 +
3571 +                       if (n == 0) {
3572 +                               cmd->cmd = 0;
3573 +                               cmd->src = msm_virt_to_dma(chip,
3574 +                                                       &dma_buffer->data.cfg0);
3575 +                               cmd->dst = MSM_NAND_DEV0_CFG0;
3576 +                               if (enable_bch_ecc)
3577 +                                       cmd->len = 12;
3578 +                               else
3579 +                                       cmd->len = 8;
3580 +                               cmd++;
3581 +
3582 +                               dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
3583 +                               cmd->cmd = 0;
3584 +                               cmd->src = msm_virt_to_dma(chip,
3585 +                                                &dma_buffer->data.ecccfg);
3586 +                               cmd->dst = MSM_NAND_EBI2_ECC_BUF_CFG;
3587 +                               cmd->len = 4;
3588 +                               cmd++;
3589 +                       }
3590 +
3591 +                       /* write data block */
3592 +                       if (ops->mode != MTD_OPS_RAW) {
3593 +                               if (!boot_layout)
3594 +                                       sectordatawritesize = (n < (cwperpage - 1)) ?
3595 +                                               516 : (512 - ((cwperpage - 1) << 2));
3596 +                               else
3597 +                                       sectordatawritesize = 512;
3598 +                       } else {
3599 +                               sectordatawritesize = chip->cw_size;
3600 +                       }
3601 +
3602 +                       cmd->cmd = 0;
3603 +                       cmd->src = data_dma_addr_curr;
3604 +                       data_dma_addr_curr += sectordatawritesize;
3605 +                       cmd->dst = MSM_NAND_FLASH_BUFFER;
3606 +                       cmd->len = sectordatawritesize;
3607 +                       cmd++;
3608 +
3609 +                       if (ops->oobbuf) {
3610 +                               if (n == (cwperpage - 1)) {
3611 +                                       cmd->cmd = 0;
3612 +                                       cmd->src = oob_dma_addr_curr;
3613 +                                       cmd->dst = MSM_NAND_FLASH_BUFFER +
3614 +                                               (512 - ((cwperpage - 1) << 2));
3615 +                                       if ((cwperpage << 2) < oob_len)
3616 +                                               cmd->len = (cwperpage << 2);
3617 +                                       else
3618 +                                               cmd->len = oob_len;
3619 +                                       oob_dma_addr_curr += cmd->len;
3620 +                                       oob_len -= cmd->len;
3621 +                                       if (cmd->len > 0)
3622 +                                               cmd++;
3623 +                               }
3624 +                               if (ops->mode != MTD_OPS_AUTO_OOB) {
3625 +                                       /* skip ecc bytes in oobbuf */
3626 +                                       if (oob_len < chip->ecc_parity_bytes) {
3627 +                                               oob_dma_addr_curr +=
3628 +                                                       chip->ecc_parity_bytes;
3629 +                                               oob_len -=
3630 +                                                       chip->ecc_parity_bytes;
3631 +                                       } else {
3632 +                                               oob_dma_addr_curr += oob_len;
3633 +                                               oob_len = 0;
3634 +                                       }
3635 +                               }
3636 +                       }
3637 +
3638 +                       /* kick the execute register */
3639 +                       cmd->cmd = 0;
3640 +                       cmd->src =
3641 +                               msm_virt_to_dma(chip, &dma_buffer->data.exec);
3642 +                       cmd->dst = MSM_NAND_EXEC_CMD;
3643 +                       cmd->len = 4;
3644 +                       cmd++;
3645 +
3646 +                       /* block on data ready, then
3647 +                        * read the status register
3648 +                        */
3649 +                       cmd->cmd = SRC_CRCI_NAND_DATA;
3650 +                       cmd->src = MSM_NAND_FLASH_STATUS;
3651 +                       cmd->dst = msm_virt_to_dma(chip,
3652 +                                            &dma_buffer->data.flash_status[n]);
3653 +                       cmd->len = 4;
3654 +                       cmd++;
3655 +
3656 +                       cmd->cmd = 0;
3657 +                       cmd->src = msm_virt_to_dma(chip,
3658 +                                               &dma_buffer->data.clrfstatus);
3659 +                       cmd->dst = MSM_NAND_FLASH_STATUS;
3660 +                       cmd->len = 4;
3661 +                       cmd++;
3662 +
3663 +                       cmd->cmd = 0;
3664 +                       cmd->src = msm_virt_to_dma(chip,
3665 +                                               &dma_buffer->data.clrrstatus);
3666 +                       cmd->dst = MSM_NAND_READ_STATUS;
3667 +                       cmd->len = 4;
3668 +                       cmd++;
3669 +
3670 +               }
3671 +
3672 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
3673 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
3674 +               BUILD_BUG_ON(8 * 7 + 2 != ARRAY_SIZE(dma_buffer->cmd));
3675 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
3676 +               dma_buffer->cmdptr =
3677 +                       (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) |
3678 +                       CMD_PTR_LP;
3679 +
3680 +               mb();
3681 +               msm_dmov_exec_cmd(chip->dma_channel,
3682 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
3683 +                               msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
3684 +               mb();
3685 +
3686 +               /* if any of the writes failed (0x10), or there was a
3687 +                * protection violation (0x100), or the program success
3688 +                * bit (0x80) is unset, we lose
3689 +                */
3690 +               err = 0;
3691 +               for (n = 0; n < cwperpage; n++) {
3692 +                       if (dma_buffer->data.flash_status[n] & 0x110) {
3693 +                               err = -EIO;
3694 +                               break;
3695 +                       }
3696 +                       if (!(dma_buffer->data.flash_status[n] & 0x80)) {
3697 +                               err = -EIO;
3698 +                               break;
3699 +                       }
3700 +               }
3701 +
3702 +#if VERBOSE
3703 +               for (n = 0; n < cwperpage; n++)
3704 +                       pr_info("write pg %d: flash_status[%d] = %x\n", page,
3705 +                               n, dma_buffer->data.flash_status[n]);
3706 +
3707 +#endif
3708 +               if (err)
3709 +                       break;
3710 +               pages_written++;
3711 +               page++;
3712 +       }
3713 +       if (ops->mode != MTD_OPS_RAW)
3714 +               ops->retlen = mtd->writesize * pages_written;
3715 +       else
3716 +               ops->retlen = (mtd->writesize + mtd->oobsize) * pages_written;
3717 +
3718 +       ops->oobretlen = ops->ooblen - oob_len;
3719 +
3720 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
3721 +
3722 +       if (ops->oobbuf) {
3723 +               msm_nand_dma_unmap(chip->dev, oob_dma_addr,
3724 +                                  ops->ooblen, DMA_TO_DEVICE,
3725 +                                  ops->oobbuf, oob_bounce_buf);
3726 +       }
3727 +err_dma_map_oobbuf_failed:
3728 +       if (ops->datbuf) {
3729 +               msm_nand_dma_unmap(chip->dev, data_dma_addr, ops->len,
3730 +                                  DMA_TO_DEVICE, ops->datbuf,
3731 +                                  dat_bounce_buf);
3732 +       }
3733 +       if (err)
3734 +               pr_err("msm_nand_write_oob %llx %x %x failed %d\n",
3735 +                      to, ops->len, ops->ooblen, err);
3736 +
3737 +#if VERBOSE
3738 +               pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
3739 +                               __func__, err, ops->retlen, ops->oobretlen);
3740 +
3741 +               pr_info("==================================================="
3742 +                               "==============\n");
3743 +#endif
3744 +       return err;
3745 +}
3746 +
3747 +static int
3748 +msm_nand_write_oob_dualnandc(struct mtd_info *mtd, loff_t to,
3749 +                               struct mtd_oob_ops *ops)
3750 +{
3751 +       struct msm_nand_chip *chip = mtd->priv;
3752 +       struct {
3753 +               dmov_s cmd[16 * 6 + 18];
3754 +               unsigned cmdptr;
3755 +               struct {
3756 +                       uint32_t cmd;
3757 +                       uint32_t nandc01_addr0;
3758 +                       uint32_t nandc10_addr0;
3759 +                       uint32_t nandc11_addr1;
3760 +                       uint32_t chipsel_cs0;
3761 +                       uint32_t chipsel_cs1;
3762 +                       uint32_t cfg0;
3763 +                       uint32_t cfg1;
3764 +                       uint32_t eccbchcfg;
3765 +                       uint32_t exec;
3766 +                       uint32_t ecccfg;
3767 +                       uint32_t cfg0_nc01;
3768 +                       uint32_t ebi2_chip_select_cfg0;
3769 +                       uint32_t adm_mux_data_ack_req_nc01;
3770 +                       uint32_t adm_mux_cmd_ack_req_nc01;
3771 +                       uint32_t adm_mux_data_ack_req_nc10;
3772 +                       uint32_t adm_mux_cmd_ack_req_nc10;
3773 +                       uint32_t adm_default_mux;
3774 +                       uint32_t default_ebi2_chip_select_cfg0;
3775 +                       uint32_t nc01_flash_dev_cmd_vld;
3776 +                       uint32_t nc10_flash_dev_cmd0;
3777 +                       uint32_t nc01_flash_dev_cmd_vld_default;
3778 +                       uint32_t nc10_flash_dev_cmd0_default;
3779 +                       uint32_t flash_status[16];
3780 +                       uint32_t clrfstatus;
3781 +                       uint32_t clrrstatus;
3782 +               } data;
3783 +       } *dma_buffer;
3784 +       dmov_s *cmd;
3785 +       unsigned n;
3786 +       unsigned page = 0;
3787 +       uint32_t oob_len;
3788 +       uint32_t sectordatawritesize;
3789 +       int err = 0;
3790 +       dma_addr_t data_dma_addr = 0;
3791 +       dma_addr_t oob_dma_addr = 0;
3792 +       dma_addr_t data_dma_addr_curr = 0;
3793 +       dma_addr_t oob_dma_addr_curr = 0;
3794 +       unsigned page_count;
3795 +       unsigned pages_written = 0;
3796 +       unsigned cwperpage;
3797 +       unsigned cw_offset = chip->cw_size;
3798 +#if VERBOSE
3799 +               pr_info("================================================="
3800 +                               "============\n");
3801 +               pr_info("%s:\nto 0x%llx mode %d\ndatbuf 0x%p datlen 0x%x"
3802 +                               "\noobbuf 0x%p ooblen 0x%x\n\n",
3803 +                               __func__, to, ops->mode, ops->datbuf, ops->len,
3804 +                               ops->oobbuf, ops->ooblen);
3805 +#endif
3806 +
3807 +       if (mtd->writesize == 2048)
3808 +               page = to >> 11;
3809 +
3810 +       if (mtd->writesize == 4096)
3811 +               page = to >> 12;
3812 +
3813 +       if (interleave_enable)
3814 +               page = (to >> 1) >> 12;
3815 +
3816 +       oob_len = ops->ooblen;
3817 +       cwperpage = (mtd->writesize >> 9);
3818 +
3819 +       if (to & (mtd->writesize - 1)) {
3820 +               pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
3821 +               return -EINVAL;
3822 +       }
3823 +
3824 +       if (ops->mode != MTD_OPS_RAW) {
3825 +               if (ops->ooblen != 0 && ops->mode != MTD_OPS_AUTO_OOB) {
3826 +                       pr_err("%s: unsupported ops->mode,%d\n",
3827 +                                        __func__, ops->mode);
3828 +                       return -EINVAL;
3829 +               }
3830 +               if ((ops->len % mtd->writesize) != 0) {
3831 +                       pr_err("%s: unsupported ops->len, %d\n",
3832 +                                       __func__, ops->len);
3833 +                       return -EINVAL;
3834 +               }
3835 +       } else {
3836 +               if ((ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
3837 +                       pr_err("%s: unsupported ops->len, "
3838 +                               "%d for MTD_OPS_RAW mode\n",
3839 +                                __func__, ops->len);
3840 +                       return -EINVAL;
3841 +               }
3842 +       }
3843 +
3844 +       if (ops->datbuf == NULL) {
3845 +               pr_err("%s: unsupported ops->datbuf == NULL\n", __func__);
3846 +               return -EINVAL;
3847 +       }
3848 +
3849 +       if (ops->mode != MTD_OPS_RAW && ops->ooblen != 0 && ops->ooboffs != 0) {
3850 +               pr_err("%s: unsupported ops->ooboffs, %d\n",
3851 +                      __func__, ops->ooboffs);
3852 +               return -EINVAL;
3853 +       }
3854 +
3855 +       if (ops->datbuf) {
3856 +               data_dma_addr_curr = data_dma_addr =
3857 +                       msm_nand_dma_map(chip->dev, ops->datbuf,
3858 +                                        ops->len, DMA_TO_DEVICE, NULL);
3859 +               if (dma_mapping_error(chip->dev, data_dma_addr)) {
3860 +                       pr_err("msm_nand_write_oob_dualnandc:"
3861 +                               "failed to get dma addr "
3862 +                              "for %p\n", ops->datbuf);
3863 +                       return -EIO;
3864 +               }
3865 +       }
3866 +       if (ops->oobbuf) {
3867 +               oob_dma_addr_curr = oob_dma_addr =
3868 +                       msm_nand_dma_map(chip->dev, ops->oobbuf,
3869 +                                        ops->ooblen, DMA_TO_DEVICE, NULL);
3870 +               if (dma_mapping_error(chip->dev, oob_dma_addr)) {
3871 +                       pr_err("msm_nand_write_oob_dualnandc:"
3872 +                               "failed to get dma addr "
3873 +                              "for %p\n", ops->oobbuf);
3874 +                       err = -EIO;
3875 +                       goto err_dma_map_oobbuf_failed;
3876 +               }
3877 +       }
3878 +       if (ops->mode != MTD_OPS_RAW)
3879 +               page_count = ops->len / mtd->writesize;
3880 +       else
3881 +               page_count = ops->len / (mtd->writesize + mtd->oobsize);
3882 +
3883 +       wait_event(chip->wait_queue, (dma_buffer =
3884 +                       msm_nand_get_dma_buffer(chip, sizeof(*dma_buffer))));
3885 +
3886 +       if (chip->CFG1 & CFG1_WIDE_FLASH)
3887 +               cw_offset >>= 1;
3888 +
3889 +       dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
3890 +       dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
3891 +       dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
3892 +       dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
3893 +       dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
3894 +       dma_buffer->data.adm_default_mux = 0x00000FC0;
3895 +       dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
3896 +       dma_buffer->data.nc01_flash_dev_cmd_vld = 0x9;
3897 +       dma_buffer->data.nc10_flash_dev_cmd0 = 0x1085D060;
3898 +       dma_buffer->data.nc01_flash_dev_cmd_vld_default = 0x1D;
3899 +       dma_buffer->data.nc10_flash_dev_cmd0_default = 0x1080D060;
3900 +       dma_buffer->data.clrfstatus = 0x00000020;
3901 +       dma_buffer->data.clrrstatus = 0x000000C0;
3902 +
3903 +       while (page_count-- > 0) {
3904 +               cmd = dma_buffer->cmd;
3905 +
3906 +               if (ops->mode != MTD_OPS_RAW) {
3907 +                       dma_buffer->data.cfg0 = ((chip->CFG0 & ~(7U << 6))
3908 +                               & ~(1 << 4)) | ((((cwperpage >> 1)-1)) << 6);
3909 +                       dma_buffer->data.cfg1 = chip->CFG1;
3910 +                       if (enable_bch_ecc)
3911 +                               dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
3912 +               } else {
3913 +                       dma_buffer->data.cfg0 = ((chip->CFG0_RAW &
3914 +                       ~(7U << 6)) & ~(1 << 4)) | (((cwperpage >> 1)-1) << 6);
3915 +                       dma_buffer->data.cfg1 = chip->CFG1_RAW |
3916 +                                       (chip->CFG1 & CFG1_WIDE_FLASH);
3917 +               }
3918 +
3919 +               /* Disables the automatic issuing of the read
3920 +                * status command for first NAND controller.
3921 +                */
3922 +               if (!interleave_enable)
3923 +                       dma_buffer->data.cfg0_nc01 = dma_buffer->data.cfg0
3924 +                                                       | (1 << 4);
3925 +               else
3926 +                       dma_buffer->data.cfg0 |= (1 << 4);
3927 +
3928 +               dma_buffer->data.cmd = MSM_NAND_CMD_PRG_PAGE;
3929 +               dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
3930 +               dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
3931 +
3932 +               /* GO bit for the EXEC register */
3933 +               dma_buffer->data.exec = 1;
3934 +
3935 +               if (!interleave_enable) {
3936 +                       dma_buffer->data.nandc01_addr0 = (page << 16) | 0x0;
3937 +                       /* NC10 ADDR0 points to the next code word */
3938 +                       dma_buffer->data.nandc10_addr0 =
3939 +                                       (page << 16) | cw_offset;
3940 +               } else {
3941 +                       dma_buffer->data.nandc01_addr0 =
3942 +                       dma_buffer->data.nandc10_addr0 = (page << 16) | 0x0;
3943 +               }
3944 +               /* ADDR1 */
3945 +               dma_buffer->data.nandc11_addr1 = (page >> 16) & 0xff;
3946 +
3947 +               BUILD_BUG_ON(16 != ARRAY_SIZE(dma_buffer->data.flash_status));
3948 +
3949 +               for (n = 0; n < cwperpage; n++) {
3950 +                       /* status return words */
3951 +                       dma_buffer->data.flash_status[n] = 0xeeeeeeee;
3952 +
3953 +                       if (n == 0) {
3954 +                               if (!interleave_enable) {
3955 +                                       cmd->cmd = 0;
3956 +                                       cmd->src = msm_virt_to_dma(chip,
3957 +                                       &dma_buffer->
3958 +                                       data.nc01_flash_dev_cmd_vld);
3959 +                                       cmd->dst = NC01(MSM_NAND_DEV_CMD_VLD);
3960 +                                       cmd->len = 4;
3961 +                                       cmd++;
3962 +
3963 +                                       cmd->cmd = 0;
3964 +                                       cmd->src = msm_virt_to_dma(chip,
3965 +                                       &dma_buffer->data.nc10_flash_dev_cmd0);
3966 +                                       cmd->dst = NC10(MSM_NAND_DEV_CMD0);
3967 +                                       cmd->len = 4;
3968 +                                       cmd++;
3969 +
3970 +                                       /* common settings for both NC01 & NC10
3971 +                                        * NC01, NC10 --> ADDR1 / CHIPSEL
3972 +                                        */
3973 +                                       cmd->cmd = 0;
3974 +                                       cmd->src = msm_virt_to_dma(chip,
3975 +                                       &dma_buffer->data.nandc11_addr1);
3976 +                                       cmd->dst = NC11(MSM_NAND_ADDR1);
3977 +                                       cmd->len = 8;
3978 +                                       cmd++;
3979 +
3980 +                                       /* Disables the automatic issue of the
3981 +                                        * read status command after the write
3982 +                                        * operation.
3983 +                                        */
3984 +                                       cmd->cmd = 0;
3985 +                                       cmd->src = msm_virt_to_dma(chip,
3986 +                                               &dma_buffer->data.cfg0_nc01);
3987 +                                       cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
3988 +                                       cmd->len = 4;
3989 +                                       cmd++;
3990 +
3991 +                                       cmd->cmd = 0;
3992 +                                       cmd->src = msm_virt_to_dma(chip,
3993 +                                               &dma_buffer->data.cfg0);
3994 +                                       cmd->dst = NC10(MSM_NAND_DEV0_CFG0);
3995 +                                       cmd->len = 4;
3996 +                                       cmd++;
3997 +
3998 +                                       cmd->cmd = 0;
3999 +                                       cmd->src = msm_virt_to_dma(chip,
4000 +                                               &dma_buffer->data.cfg1);
4001 +                                       cmd->dst = NC11(MSM_NAND_DEV0_CFG1);
4002 +                                       if (enable_bch_ecc)
4003 +                                               cmd->len = 8;
4004 +                                       else
4005 +                                               cmd->len = 4;
4006 +                                       cmd++;
4007 +                               } else {
4008 +                                       /* enable CS1 */
4009 +                                       cmd->cmd = 0;
4010 +                                       cmd->src = msm_virt_to_dma(chip,
4011 +                                       &dma_buffer->
4012 +                                       data.ebi2_chip_select_cfg0);
4013 +                                       cmd->dst = EBI2_CHIP_SELECT_CFG0;
4014 +                                       cmd->len = 4;
4015 +                                       cmd++;
4016 +
4017 +                                       /* NC11 --> ADDR1 */
4018 +                                       cmd->cmd = 0;
4019 +                                       cmd->src = msm_virt_to_dma(chip,
4020 +                                       &dma_buffer->data.nandc11_addr1);
4021 +                                       cmd->dst = NC11(MSM_NAND_ADDR1);
4022 +                                       cmd->len = 4;
4023 +                                       cmd++;
4024 +
4025 +                                       /* Enable CS0 for NC01 */
4026 +                                       cmd->cmd = 0;
4027 +                                       cmd->src = msm_virt_to_dma(chip,
4028 +                                       &dma_buffer->data.chipsel_cs0);
4029 +                                       cmd->dst =
4030 +                                       NC01(MSM_NAND_FLASH_CHIP_SELECT);
4031 +                                       cmd->len = 4;
4032 +                                       cmd++;
4033 +
4034 +                                       /* Enable CS1 for NC10 */
4035 +                                       cmd->cmd = 0;
4036 +                                       cmd->src = msm_virt_to_dma(chip,
4037 +                                       &dma_buffer->data.chipsel_cs1);
4038 +                                       cmd->dst =
4039 +                                       NC10(MSM_NAND_FLASH_CHIP_SELECT);
4040 +                                       cmd->len = 4;
4041 +                                       cmd++;
4042 +
4043 +                                       /* config DEV0_CFG0 & CFG1 for CS0 */
4044 +                                       cmd->cmd = 0;
4045 +                                       cmd->src = msm_virt_to_dma(chip,
4046 +                                               &dma_buffer->data.cfg0);
4047 +                                       cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
4048 +                                       cmd->len = 8;
4049 +                                       cmd++;
4050 +
4051 +                                       /* config DEV1_CFG0 & CFG1 for CS1 */
4052 +                                       cmd->cmd = 0;
4053 +                                       cmd->src = msm_virt_to_dma(chip,
4054 +                                       &dma_buffer->data.cfg0);
4055 +                                       cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
4056 +                                       cmd->len = 8;
4057 +                                       cmd++;
4058 +                               }
4059 +
4060 +                               dma_buffer->data.ecccfg = chip->ecc_buf_cfg;
4061 +                               cmd->cmd = 0;
4062 +                               cmd->src = msm_virt_to_dma(chip,
4063 +                                               &dma_buffer->data.ecccfg);
4064 +                               cmd->dst = NC11(MSM_NAND_EBI2_ECC_BUF_CFG);
4065 +                               cmd->len = 4;
4066 +                               cmd++;
4067 +
4068 +                               /* NC01 --> ADDR0 */
4069 +                               cmd->cmd = 0;
4070 +                               cmd->src = msm_virt_to_dma(chip,
4071 +                                       &dma_buffer->data.nandc01_addr0);
4072 +                               cmd->dst = NC01(MSM_NAND_ADDR0);
4073 +                               cmd->len = 4;
4074 +                               cmd++;
4075 +
4076 +                               /* NC10 --> ADDR0 */
4077 +                               cmd->cmd = 0;
4078 +                               cmd->src = msm_virt_to_dma(chip,
4079 +                               &dma_buffer->data.nandc10_addr0);
4080 +                               cmd->dst = NC10(MSM_NAND_ADDR0);
4081 +                               cmd->len = 4;
4082 +                               cmd++;
4083 +                       }
4084 +
4085 +                       if (n % 2 == 0) {
4086 +                               /* MASK CMD ACK/REQ --> NC10 (0xF14)*/
4087 +                               cmd->cmd = 0;
4088 +                               cmd->src = msm_virt_to_dma(chip,
4089 +                               &dma_buffer->data.adm_mux_cmd_ack_req_nc10);
4090 +                               cmd->dst = EBI2_NAND_ADM_MUX;
4091 +                               cmd->len = 4;
4092 +                               cmd++;
4093 +
4094 +                               /* CMD */
4095 +                               cmd->cmd = DST_CRCI_NAND_CMD;
4096 +                               cmd->src = msm_virt_to_dma(chip,
4097 +                                               &dma_buffer->data.cmd);
4098 +                               cmd->dst = NC01(MSM_NAND_FLASH_CMD);
4099 +                               cmd->len = 4;
4100 +                               cmd++;
4101 +                       } else {
4102 +                               /* MASK CMD ACK/REQ --> NC01 (0x53C)*/
4103 +                               cmd->cmd = 0;
4104 +                               cmd->src = msm_virt_to_dma(chip,
4105 +                               &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
4106 +                               cmd->dst = EBI2_NAND_ADM_MUX;
4107 +                               cmd->len = 4;
4108 +                               cmd++;
4109 +
4110 +                               /* CMD */
4111 +                               cmd->cmd = DST_CRCI_NAND_CMD;
4112 +                               cmd->src = msm_virt_to_dma(chip,
4113 +                                               &dma_buffer->data.cmd);
4114 +                               cmd->dst = NC10(MSM_NAND_FLASH_CMD);
4115 +                               cmd->len = 4;
4116 +                               cmd++;
4117 +                       }
4118 +
4119 +                       if (ops->mode != MTD_OPS_RAW)
4120 +                               sectordatawritesize = (n < (cwperpage - 1)) ?
4121 +                                       516 : (512 - ((cwperpage - 1) << 2));
4122 +                       else
4123 +                               sectordatawritesize = chip->cw_size;
4124 +
4125 +                       cmd->cmd = 0;
4126 +                       cmd->src = data_dma_addr_curr;
4127 +                       data_dma_addr_curr += sectordatawritesize;
4128 +
4129 +                       if (n % 2 == 0)
4130 +                               cmd->dst = NC01(MSM_NAND_FLASH_BUFFER);
4131 +                       else
4132 +                               cmd->dst = NC10(MSM_NAND_FLASH_BUFFER);
4133 +                       cmd->len = sectordatawritesize;
4134 +                       cmd++;
4135 +
4136 +                       if (ops->oobbuf) {
4137 +                               if (n == (cwperpage - 1)) {
4138 +                                       cmd->cmd = 0;
4139 +                                       cmd->src = oob_dma_addr_curr;
4140 +                                       cmd->dst = NC10(MSM_NAND_FLASH_BUFFER) +
4141 +                                               (512 - ((cwperpage - 1) << 2));
4142 +                                       if ((cwperpage << 2) < oob_len)
4143 +                                               cmd->len = (cwperpage << 2);
4144 +                                       else
4145 +                                               cmd->len = oob_len;
4146 +                                       oob_dma_addr_curr += cmd->len;
4147 +                                       oob_len -= cmd->len;
4148 +                                       if (cmd->len > 0)
4149 +                                               cmd++;
4150 +                               }
4151 +                               if (ops->mode != MTD_OPS_AUTO_OOB) {
4152 +                                       /* skip ecc bytes in oobbuf */
4153 +                                       if (oob_len < chip->ecc_parity_bytes) {
4154 +                                               oob_dma_addr_curr +=
4155 +                                                       chip->ecc_parity_bytes;
4156 +                                               oob_len -=
4157 +                                                       chip->ecc_parity_bytes;
4158 +                                       } else {
4159 +                                               oob_dma_addr_curr += oob_len;
4160 +                                               oob_len = 0;
4161 +                                       }
4162 +                               }
4163 +                       }
4164 +
4165 +                       if (n % 2 == 0) {
4166 +                               if (n != 0) {
4167 +                                       /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
4168 +                                       cmd->cmd = 0;
4169 +                                       cmd->src = msm_virt_to_dma(chip,
4170 +                                       &dma_buffer->
4171 +                                       data.adm_mux_data_ack_req_nc01);
4172 +                                       cmd->dst = EBI2_NAND_ADM_MUX;
4173 +                                       cmd->len = 4;
4174 +                                       cmd++;
4175 +
4176 +                                       /* block on data ready from NC10, then
4177 +                                       * read the status register
4178 +                                       */
4179 +                                       cmd->cmd = SRC_CRCI_NAND_DATA;
4180 +                                       cmd->src = NC10(MSM_NAND_FLASH_STATUS);
4181 +                                       cmd->dst = msm_virt_to_dma(chip,
4182 +                                       &dma_buffer->data.flash_status[n-1]);
4183 +                                       cmd->len = 4;
4184 +                                       cmd++;
4185 +                               }
4186 +                               /* kick the NC01 execute register */
4187 +                               cmd->cmd = 0;
4188 +                               cmd->src = msm_virt_to_dma(chip,
4189 +                                               &dma_buffer->data.exec);
4190 +                               cmd->dst = NC01(MSM_NAND_EXEC_CMD);
4191 +                               cmd->len = 4;
4192 +                               cmd++;
4193 +                       } else {
4194 +                               /* MASK DATA ACK/REQ --> NC10 (0xF28)*/
4195 +                               cmd->cmd = 0;
4196 +                               cmd->src = msm_virt_to_dma(chip,
4197 +                               &dma_buffer->data.adm_mux_data_ack_req_nc10);
4198 +                               cmd->dst = EBI2_NAND_ADM_MUX;
4199 +                               cmd->len = 4;
4200 +                               cmd++;
4201 +
4202 +                               /* block on data ready from NC01, then
4203 +                                * read the status register
4204 +                                */
4205 +                               cmd->cmd = SRC_CRCI_NAND_DATA;
4206 +                               cmd->src = NC01(MSM_NAND_FLASH_STATUS);
4207 +                               cmd->dst = msm_virt_to_dma(chip,
4208 +                               &dma_buffer->data.flash_status[n-1]);
4209 +                               cmd->len = 4;
4210 +                               cmd++;
4211 +
4212 +                               /* kick the execute register */
4213 +                               cmd->cmd = 0;
4214 +                               cmd->src =
4215 +                               msm_virt_to_dma(chip, &dma_buffer->data.exec);
4216 +                               cmd->dst = NC10(MSM_NAND_EXEC_CMD);
4217 +                               cmd->len = 4;
4218 +                               cmd++;
4219 +                       }
4220 +               }
4221 +
4222 +               /* MASK DATA ACK/REQ --> NC01 (0xA3C)*/
4223 +               cmd->cmd = 0;
4224 +               cmd->src = msm_virt_to_dma(chip,
4225 +                               &dma_buffer->data.adm_mux_data_ack_req_nc01);
4226 +               cmd->dst = EBI2_NAND_ADM_MUX;
4227 +               cmd->len = 4;
4228 +               cmd++;
4229 +
4230 +               /* we should process outstanding request */
4231 +               /* block on data ready, then
4232 +                * read the status register
4233 +                */
4234 +               cmd->cmd = SRC_CRCI_NAND_DATA;
4235 +               cmd->src = NC10(MSM_NAND_FLASH_STATUS);
4236 +               cmd->dst = msm_virt_to_dma(chip,
4237 +                            &dma_buffer->data.flash_status[n-1]);
4238 +               cmd->len = 4;
4239 +               cmd++;
4240 +
4241 +               cmd->cmd = 0;
4242 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
4243 +               cmd->dst = NC11(MSM_NAND_FLASH_STATUS);
4244 +               cmd->len = 4;
4245 +               cmd++;
4246 +
4247 +               cmd->cmd = 0;
4248 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
4249 +               cmd->dst = NC11(MSM_NAND_READ_STATUS);
4250 +               cmd->len = 4;
4251 +               cmd++;
4252 +
4253 +               /* MASK DATA ACK/REQ --> NC01 (0xFC0)*/
4254 +               cmd->cmd = 0;
4255 +               cmd->src = msm_virt_to_dma(chip,
4256 +                               &dma_buffer->data.adm_default_mux);
4257 +               cmd->dst = EBI2_NAND_ADM_MUX;
4258 +               cmd->len = 4;
4259 +               cmd++;
4260 +
4261 +               if (!interleave_enable) {
4262 +                       /* setting to defalut values back */
4263 +                       cmd->cmd = 0;
4264 +                       cmd->src = msm_virt_to_dma(chip,
4265 +                       &dma_buffer->data.nc01_flash_dev_cmd_vld_default);
4266 +                       cmd->dst = NC01(MSM_NAND_DEV_CMD_VLD);
4267 +                       cmd->len = 4;
4268 +                       cmd++;
4269 +
4270 +                       cmd->cmd = 0;
4271 +                       cmd->src = msm_virt_to_dma(chip,
4272 +                       &dma_buffer->data.nc10_flash_dev_cmd0_default);
4273 +                       cmd->dst = NC10(MSM_NAND_DEV_CMD0);
4274 +                       cmd->len = 4;
4275 +                       cmd++;
4276 +               } else {
4277 +                       /* disable CS1 */
4278 +                       cmd->cmd = 0;
4279 +                       cmd->src = msm_virt_to_dma(chip,
4280 +                       &dma_buffer->data.default_ebi2_chip_select_cfg0);
4281 +                       cmd->dst = EBI2_CHIP_SELECT_CFG0;
4282 +                       cmd->len = 4;
4283 +                       cmd++;
4284 +               }
4285 +
4286 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
4287 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
4288 +               BUILD_BUG_ON(16 * 6 + 18 != ARRAY_SIZE(dma_buffer->cmd));
4289 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
4290 +               dma_buffer->cmdptr =
4291 +               ((msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP);
4292 +
4293 +               mb();
4294 +               msm_dmov_exec_cmd(chip->dma_channel,
4295 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
4296 +                               msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
4297 +               mb();
4298 +
4299 +               /* if any of the writes failed (0x10), or there was a
4300 +                * protection violation (0x100), or the program success
4301 +                * bit (0x80) is unset, we lose
4302 +                */
4303 +               err = 0;
4304 +               for (n = 0; n < cwperpage; n++) {
4305 +                       if (dma_buffer->data.flash_status[n] & 0x110) {
4306 +                               err = -EIO;
4307 +                               break;
4308 +                       }
4309 +                       if (!(dma_buffer->data.flash_status[n] & 0x80)) {
4310 +                               err = -EIO;
4311 +                               break;
4312 +                       }
4313 +               }
4314 +               /* check for flash status busy for the last codeword */
4315 +               if (!interleave_enable)
4316 +                       if (!(dma_buffer->data.flash_status[cwperpage - 1]
4317 +                                                               & 0x20)) {
4318 +                               err = -EIO;
4319 +                               break;
4320 +                       }
4321 +#if VERBOSE
4322 +       for (n = 0; n < cwperpage; n++) {
4323 +               if (n%2) {
4324 +                       pr_info("NC10: write pg %d: flash_status[%d] = %x\n",
4325 +                               page, n, dma_buffer->data.flash_status[n]);
4326 +               } else {
4327 +                       pr_info("NC01: write pg %d: flash_status[%d] = %x\n",
4328 +                               page, n, dma_buffer->data.flash_status[n]);
4329 +               }
4330 +       }
4331 +#endif
4332 +               if (err)
4333 +                       break;
4334 +               pages_written++;
4335 +               page++;
4336 +       }
4337 +       if (ops->mode != MTD_OPS_RAW)
4338 +               ops->retlen = mtd->writesize * pages_written;
4339 +       else
4340 +               ops->retlen = (mtd->writesize + mtd->oobsize) * pages_written;
4341 +
4342 +       ops->oobretlen = ops->ooblen - oob_len;
4343 +
4344 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
4345 +
4346 +       if (ops->oobbuf)
4347 +               dma_unmap_page(chip->dev, oob_dma_addr,
4348 +                                ops->ooblen, DMA_TO_DEVICE);
4349 +err_dma_map_oobbuf_failed:
4350 +       if (ops->datbuf)
4351 +               dma_unmap_page(chip->dev, data_dma_addr, ops->len,
4352 +                               DMA_TO_DEVICE);
4353 +       if (err)
4354 +               pr_err("msm_nand_write_oob_dualnandc %llx %x %x failed %d\n",
4355 +                      to, ops->len, ops->ooblen, err);
4356 +
4357 +#if VERBOSE
4358 +       pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
4359 +                       __func__, err, ops->retlen, ops->oobretlen);
4360 +
4361 +       pr_info("==================================================="
4362 +                       "==========\n");
4363 +#endif
4364 +       return err;
4365 +}
4366 +
4367 +static int msm_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
4368 +                         size_t *retlen, const u_char *buf)
4369 +{
4370 +        int ret;
4371 +       struct mtd_oob_ops ops;
4372 +       int (*write_oob)(struct mtd_info *, loff_t, struct mtd_oob_ops *);
4373 +
4374 +       if (!dual_nand_ctlr_present)
4375 +               write_oob = msm_nand_write_oob;
4376 +       else
4377 +               write_oob = msm_nand_write_oob_dualnandc;
4378 +
4379 +       ops.mode = MTD_OPS_PLACE_OOB;
4380 +       ops.retlen = 0;
4381 +       ops.ooblen = 0;
4382 +       ops.oobbuf = NULL;
4383 +       ret = 0;
4384 +       *retlen = 0;
4385 +
4386 +       if (!virt_addr_valid(buf) &&
4387 +           ((to | len) & (mtd->writesize - 1)) == 0 &&
4388 +           ((unsigned long) buf & ~PAGE_MASK) + len > PAGE_SIZE) {
4389 +               /*
4390 +                * Handle writing of large size write buffer in vmalloc
4391 +                * address space that does not fit in an MMU page.
4392 +                * The destination address must be on page boundary,
4393 +                * and the size must be multiple of NAND page size.
4394 +                * Writing partial page is not supported.
4395 +                */
4396 +               ops.len = mtd->writesize;
4397 +
4398 +               for (;;) {
4399 +                       ops.datbuf = (uint8_t *) buf;
4400 +
4401 +                       ret = write_oob(mtd, to, &ops);
4402 +                       if (ret < 0)
4403 +                               break;
4404 +
4405 +                       len -= mtd->writesize;
4406 +                       *retlen += mtd->writesize;
4407 +                       if (len == 0)
4408 +                               break;
4409 +
4410 +                       buf += mtd->writesize;
4411 +                       to += mtd->writesize;
4412 +               }
4413 +       } else {
4414 +               ops.len = len;
4415 +               ops.datbuf = (uint8_t *) buf;
4416 +               ret = write_oob(mtd, to, &ops);
4417 +               *retlen = ops.retlen;
4418 +       }
4419 +
4420 +       return ret;
4421 +}
4422 +
4423 +static int
4424 +msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr)
4425 +{
4426 +       int err;
4427 +       struct msm_nand_chip *chip = mtd->priv;
4428 +       struct {
4429 +               dmov_s cmd[6];
4430 +               unsigned cmdptr;
4431 +               struct {
4432 +                       uint32_t cmd;
4433 +                       uint32_t addr0;
4434 +                       uint32_t addr1;
4435 +                       uint32_t chipsel;
4436 +                       uint32_t cfg0;
4437 +                       uint32_t cfg1;
4438 +                       uint32_t exec;
4439 +                       uint32_t flash_status;
4440 +                       uint32_t clrfstatus;
4441 +                       uint32_t clrrstatus;
4442 +               } data;
4443 +       } *dma_buffer;
4444 +       dmov_s *cmd;
4445 +       unsigned page = 0;
4446 +
4447 +       if (mtd->writesize == 2048)
4448 +               page = instr->addr >> 11;
4449 +
4450 +       if (mtd->writesize == 4096)
4451 +               page = instr->addr >> 12;
4452 +
4453 +       if (instr->addr & (mtd->erasesize - 1)) {
4454 +               pr_err("%s: unsupported erase address, 0x%llx\n",
4455 +                      __func__, instr->addr);
4456 +               return -EINVAL;
4457 +       }
4458 +       if (instr->len != mtd->erasesize) {
4459 +               pr_err("%s: unsupported erase len, %lld\n",
4460 +                      __func__, instr->len);
4461 +               return -EINVAL;
4462 +       }
4463 +
4464 +       wait_event(chip->wait_queue,
4465 +                  (dma_buffer = msm_nand_get_dma_buffer(
4466 +                           chip, sizeof(*dma_buffer))));
4467 +
4468 +       cmd = dma_buffer->cmd;
4469 +
4470 +       dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
4471 +       dma_buffer->data.addr0 = page;
4472 +       dma_buffer->data.addr1 = 0;
4473 +       dma_buffer->data.chipsel = 0 | 4;
4474 +       dma_buffer->data.exec = 1;
4475 +       dma_buffer->data.flash_status = 0xeeeeeeee;
4476 +       dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6));  /* CW_PER_PAGE = 0 */
4477 +       dma_buffer->data.cfg1 = chip->CFG1;
4478 +       dma_buffer->data.clrfstatus = 0x00000020;
4479 +       dma_buffer->data.clrrstatus = 0x000000C0;
4480 +
4481 +       cmd->cmd = DST_CRCI_NAND_CMD | CMD_OCB;
4482 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
4483 +       cmd->dst = MSM_NAND_FLASH_CMD;
4484 +       cmd->len = 16;
4485 +       cmd++;
4486 +
4487 +       cmd->cmd = 0;
4488 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
4489 +       cmd->dst = MSM_NAND_DEV0_CFG0;
4490 +       cmd->len = 8;
4491 +       cmd++;
4492 +
4493 +       cmd->cmd = 0;
4494 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
4495 +       cmd->dst = MSM_NAND_EXEC_CMD;
4496 +       cmd->len = 4;
4497 +       cmd++;
4498 +
4499 +       cmd->cmd = SRC_CRCI_NAND_DATA;
4500 +       cmd->src = MSM_NAND_FLASH_STATUS;
4501 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status);
4502 +       cmd->len = 4;
4503 +       cmd++;
4504 +
4505 +       cmd->cmd = 0;
4506 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
4507 +       cmd->dst = MSM_NAND_FLASH_STATUS;
4508 +       cmd->len = 4;
4509 +       cmd++;
4510 +
4511 +       cmd->cmd = CMD_OCU | CMD_LC;
4512 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
4513 +       cmd->dst = MSM_NAND_READ_STATUS;
4514 +       cmd->len = 4;
4515 +       cmd++;
4516 +
4517 +       BUILD_BUG_ON(5 != ARRAY_SIZE(dma_buffer->cmd) - 1);
4518 +       BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
4519 +       dma_buffer->cmdptr =
4520 +               (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
4521 +
4522 +       mb();
4523 +       msm_dmov_exec_cmd(
4524 +               chip->dma_channel, DMOV_CMD_PTR_LIST |
4525 +               DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
4526 +       mb();
4527 +
4528 +       /* we fail if there was an operation error, a mpu error, or the
4529 +        * erase success bit was not set.
4530 +        */
4531 +
4532 +       if (dma_buffer->data.flash_status & 0x110 ||
4533 +                       !(dma_buffer->data.flash_status & 0x80))
4534 +               err = -EIO;
4535 +       else
4536 +               err = 0;
4537 +
4538 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
4539 +       if (err) {
4540 +               pr_err("%s: erase failed, 0x%llx\n", __func__, instr->addr);
4541 +               instr->fail_addr = instr->addr;
4542 +               instr->state = MTD_ERASE_FAILED;
4543 +       } else {
4544 +               instr->state = MTD_ERASE_DONE;
4545 +               instr->fail_addr = 0xffffffff;
4546 +               mtd_erase_callback(instr);
4547 +       }
4548 +       return err;
4549 +}
4550 +
4551 +static int
4552 +msm_nand_erase_dualnandc(struct mtd_info *mtd, struct erase_info *instr)
4553 +{
4554 +       int err;
4555 +       struct msm_nand_chip *chip = mtd->priv;
4556 +       struct {
4557 +               dmov_s cmd[18];
4558 +               unsigned cmdptr;
4559 +               struct {
4560 +                       uint32_t cmd;
4561 +                       uint32_t addr0;
4562 +                       uint32_t addr1;
4563 +                       uint32_t chipsel_cs0;
4564 +                       uint32_t chipsel_cs1;
4565 +                       uint32_t cfg0;
4566 +                       uint32_t cfg1;
4567 +                       uint32_t exec;
4568 +                       uint32_t ecccfg;
4569 +                       uint32_t ebi2_chip_select_cfg0;
4570 +                       uint32_t adm_mux_data_ack_req_nc01;
4571 +                       uint32_t adm_mux_cmd_ack_req_nc01;
4572 +                       uint32_t adm_mux_data_ack_req_nc10;
4573 +                       uint32_t adm_mux_cmd_ack_req_nc10;
4574 +                       uint32_t adm_default_mux;
4575 +                       uint32_t default_ebi2_chip_select_cfg0;
4576 +                       uint32_t nc01_flash_dev_cmd0;
4577 +                       uint32_t nc01_flash_dev_cmd0_default;
4578 +                       uint32_t flash_status[2];
4579 +                       uint32_t clrfstatus;
4580 +                       uint32_t clrrstatus;
4581 +               } data;
4582 +       } *dma_buffer;
4583 +       dmov_s *cmd;
4584 +       unsigned page = 0;
4585 +
4586 +       if (mtd->writesize == 2048)
4587 +               page = instr->addr >> 11;
4588 +
4589 +       if (mtd->writesize == 4096)
4590 +               page = instr->addr >> 12;
4591 +
4592 +       if (mtd->writesize == 8192)
4593 +               page = (instr->addr >> 1) >> 12;
4594 +
4595 +       if (instr->addr & (mtd->erasesize - 1)) {
4596 +               pr_err("%s: unsupported erase address, 0x%llx\n",
4597 +                      __func__, instr->addr);
4598 +               return -EINVAL;
4599 +       }
4600 +       if (instr->len != mtd->erasesize) {
4601 +               pr_err("%s: unsupported erase len, %lld\n",
4602 +                      __func__, instr->len);
4603 +               return -EINVAL;
4604 +       }
4605 +
4606 +       wait_event(chip->wait_queue,
4607 +                  (dma_buffer = msm_nand_get_dma_buffer(
4608 +                           chip, sizeof(*dma_buffer))));
4609 +
4610 +       cmd = dma_buffer->cmd;
4611 +
4612 +       dma_buffer->data.cmd = MSM_NAND_CMD_BLOCK_ERASE;
4613 +       dma_buffer->data.addr0 = page;
4614 +       dma_buffer->data.addr1 = 0;
4615 +       dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
4616 +       dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
4617 +       dma_buffer->data.exec = 1;
4618 +       dma_buffer->data.flash_status[0] = 0xeeeeeeee;
4619 +       dma_buffer->data.flash_status[1] = 0xeeeeeeee;
4620 +       dma_buffer->data.cfg0 = chip->CFG0 & (~(7 << 6));  /* CW_PER_PAGE = 0 */
4621 +       dma_buffer->data.cfg1 = chip->CFG1;
4622 +       dma_buffer->data.clrfstatus = 0x00000020;
4623 +       dma_buffer->data.clrrstatus = 0x000000C0;
4624 +
4625 +       dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
4626 +       dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
4627 +       dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
4628 +       dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
4629 +       dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
4630 +       dma_buffer->data.adm_default_mux = 0x00000FC0;
4631 +       dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
4632 +
4633 +       /* enable CS1 */
4634 +       cmd->cmd = 0 | CMD_OCB;
4635 +       cmd->src = msm_virt_to_dma(chip,
4636 +                       &dma_buffer->data.ebi2_chip_select_cfg0);
4637 +       cmd->dst = EBI2_CHIP_SELECT_CFG0;
4638 +       cmd->len = 4;
4639 +       cmd++;
4640 +
4641 +       /* erase CS0 block now !!! */
4642 +       /* 0xF14 */
4643 +       cmd->cmd = 0;
4644 +       cmd->src = msm_virt_to_dma(chip,
4645 +                       &dma_buffer->data.adm_mux_cmd_ack_req_nc10);
4646 +       cmd->dst = EBI2_NAND_ADM_MUX;
4647 +       cmd->len = 4;
4648 +       cmd++;
4649 +
4650 +       cmd->cmd = DST_CRCI_NAND_CMD;
4651 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
4652 +       cmd->dst = NC01(MSM_NAND_FLASH_CMD);
4653 +       cmd->len = 16;
4654 +       cmd++;
4655 +
4656 +       cmd->cmd = 0;
4657 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
4658 +       cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
4659 +       cmd->len = 8;
4660 +       cmd++;
4661 +
4662 +       cmd->cmd = 0;
4663 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
4664 +       cmd->dst = NC01(MSM_NAND_EXEC_CMD);
4665 +       cmd->len = 4;
4666 +       cmd++;
4667 +
4668 +       /* 0xF28 */
4669 +       cmd->cmd = 0;
4670 +       cmd->src = msm_virt_to_dma(chip,
4671 +                       &dma_buffer->data.adm_mux_data_ack_req_nc10);
4672 +       cmd->dst = EBI2_NAND_ADM_MUX;
4673 +       cmd->len = 4;
4674 +       cmd++;
4675 +
4676 +       cmd->cmd = SRC_CRCI_NAND_DATA;
4677 +       cmd->src = NC01(MSM_NAND_FLASH_STATUS);
4678 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[0]);
4679 +       cmd->len = 4;
4680 +       cmd++;
4681 +
4682 +       /* erase CS1 block now !!! */
4683 +       /* 0x53C */
4684 +       cmd->cmd = 0;
4685 +       cmd->src = msm_virt_to_dma(chip,
4686 +                              &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
4687 +       cmd->dst = EBI2_NAND_ADM_MUX;
4688 +       cmd->len = 4;
4689 +       cmd++;
4690 +
4691 +       cmd->cmd = DST_CRCI_NAND_CMD;
4692 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
4693 +       cmd->dst = NC10(MSM_NAND_FLASH_CMD);
4694 +       cmd->len = 12;
4695 +       cmd++;
4696 +
4697 +       cmd->cmd = 0;
4698 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chipsel_cs1);
4699 +       cmd->dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
4700 +       cmd->len = 4;
4701 +       cmd++;
4702 +
4703 +       cmd->cmd = 0;
4704 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
4705 +       cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
4706 +       cmd->len = 8;
4707 +
4708 +       cmd->cmd = 0;
4709 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
4710 +       cmd->dst = NC10(MSM_NAND_EXEC_CMD);
4711 +       cmd->len = 4;
4712 +       cmd++;
4713 +
4714 +       /* 0xA3C */
4715 +       cmd->cmd = 0;
4716 +       cmd->src = msm_virt_to_dma(chip,
4717 +                            &dma_buffer->data.adm_mux_data_ack_req_nc01);
4718 +       cmd->dst = EBI2_NAND_ADM_MUX;
4719 +       cmd->len = 4;
4720 +       cmd++;
4721 +
4722 +       cmd->cmd = SRC_CRCI_NAND_DATA;
4723 +       cmd->src = NC10(MSM_NAND_FLASH_STATUS);
4724 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.flash_status[1]);
4725 +       cmd->len = 4;
4726 +       cmd++;
4727 +
4728 +       cmd->cmd = 0;
4729 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrfstatus);
4730 +       cmd->dst = NC11(MSM_NAND_FLASH_STATUS);
4731 +       cmd->len = 4;
4732 +       cmd++;
4733 +
4734 +       cmd->cmd = 0;
4735 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.clrrstatus);
4736 +       cmd->dst = NC11(MSM_NAND_READ_STATUS);
4737 +       cmd->len = 4;
4738 +       cmd++;
4739 +
4740 +       cmd->cmd = 0;
4741 +       cmd->src = msm_virt_to_dma(chip,
4742 +                       &dma_buffer->data.adm_default_mux);
4743 +       cmd->dst = EBI2_NAND_ADM_MUX;
4744 +       cmd->len = 4;
4745 +       cmd++;
4746 +
4747 +       /* disable CS1 */
4748 +       cmd->cmd = CMD_OCU | CMD_LC;
4749 +       cmd->src = msm_virt_to_dma(chip,
4750 +                       &dma_buffer->data.default_ebi2_chip_select_cfg0);
4751 +       cmd->dst = EBI2_CHIP_SELECT_CFG0;
4752 +       cmd->len = 4;
4753 +       cmd++;
4754 +
4755 +       BUILD_BUG_ON(17 != ARRAY_SIZE(dma_buffer->cmd) - 1);
4756 +       BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
4757 +
4758 +       dma_buffer->cmdptr =
4759 +               (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
4760 +
4761 +       mb();
4762 +       msm_dmov_exec_cmd(
4763 +               chip->dma_channel, DMOV_CMD_PTR_LIST |
4764 +               DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
4765 +       mb();
4766 +
4767 +       /* we fail if there was an operation error, a mpu error, or the
4768 +        * erase success bit was not set.
4769 +        */
4770 +
4771 +       if (dma_buffer->data.flash_status[0] & 0x110 ||
4772 +                       !(dma_buffer->data.flash_status[0] & 0x80) ||
4773 +                       dma_buffer->data.flash_status[1] & 0x110 ||
4774 +                       !(dma_buffer->data.flash_status[1] & 0x80))
4775 +               err = -EIO;
4776 +       else
4777 +               err = 0;
4778 +
4779 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
4780 +       if (err) {
4781 +               pr_err("%s: erase failed, 0x%llx\n", __func__, instr->addr);
4782 +               instr->fail_addr = instr->addr;
4783 +               instr->state = MTD_ERASE_FAILED;
4784 +       } else {
4785 +               instr->state = MTD_ERASE_DONE;
4786 +               instr->fail_addr = 0xffffffff;
4787 +               mtd_erase_callback(instr);
4788 +       }
4789 +       return err;
4790 +}
4791 +
4792 +static int
4793 +msm_nand_block_isbad(struct mtd_info *mtd, loff_t ofs)
4794 +{
4795 +       struct msm_nand_chip *chip = mtd->priv;
4796 +       int ret;
4797 +       struct {
4798 +               dmov_s cmd[5];
4799 +               unsigned cmdptr;
4800 +               struct {
4801 +                       uint32_t cmd;
4802 +                       uint32_t addr0;
4803 +                       uint32_t addr1;
4804 +                       uint32_t chipsel;
4805 +                       uint32_t cfg0;
4806 +                       uint32_t cfg1;
4807 +                       uint32_t eccbchcfg;
4808 +                       uint32_t exec;
4809 +                       uint32_t ecccfg;
4810 +                       struct {
4811 +                               uint32_t flash_status;
4812 +                               uint32_t buffer_status;
4813 +                       } result;
4814 +               } data;
4815 +       } *dma_buffer;
4816 +       dmov_s *cmd;
4817 +       uint8_t *buf;
4818 +       unsigned page = 0;
4819 +       unsigned cwperpage;
4820 +
4821 +       if (mtd->writesize == 2048)
4822 +               page = ofs >> 11;
4823 +
4824 +       if (mtd->writesize == 4096)
4825 +               page = ofs >> 12;
4826 +
4827 +       cwperpage = (mtd->writesize >> 9);
4828 +
4829 +       /* Check for invalid offset */
4830 +       if (ofs > mtd->size)
4831 +               return -EINVAL;
4832 +       if (ofs & (mtd->erasesize - 1)) {
4833 +               pr_err("%s: unsupported block address, 0x%x\n",
4834 +                        __func__, (uint32_t)ofs);
4835 +               return -EINVAL;
4836 +       }
4837 +
4838 +       wait_event(chip->wait_queue,
4839 +               (dma_buffer = msm_nand_get_dma_buffer(chip ,
4840 +                                        sizeof(*dma_buffer) + 4)));
4841 +       buf = (uint8_t *)dma_buffer + sizeof(*dma_buffer);
4842 +
4843 +       /* Read 4 bytes starting from the bad block marker location
4844 +        * in the last code word of the page
4845 +        */
4846 +
4847 +       cmd = dma_buffer->cmd;
4848 +
4849 +       dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
4850 +       dma_buffer->data.cfg0 = chip->CFG0_RAW & ~(7U << 6);
4851 +       dma_buffer->data.cfg1 = chip->CFG1_RAW |
4852 +                               (chip->CFG1 & CFG1_WIDE_FLASH);
4853 +       if (enable_bch_ecc)
4854 +               dma_buffer->data.eccbchcfg = chip->ecc_bch_cfg;
4855 +
4856 +       if (chip->CFG1 & CFG1_WIDE_FLASH)
4857 +               dma_buffer->data.addr0 = (page << 16) |
4858 +                       ((chip->cw_size * (cwperpage-1)) >> 1);
4859 +       else
4860 +               dma_buffer->data.addr0 = (page << 16) |
4861 +                       (chip->cw_size * (cwperpage-1));
4862 +
4863 +       dma_buffer->data.addr1 = (page >> 16) & 0xff;
4864 +       dma_buffer->data.chipsel = 0 | 4;
4865 +
4866 +       dma_buffer->data.exec = 1;
4867 +
4868 +       dma_buffer->data.result.flash_status = 0xeeeeeeee;
4869 +       dma_buffer->data.result.buffer_status = 0xeeeeeeee;
4870 +
4871 +       cmd->cmd = DST_CRCI_NAND_CMD;
4872 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
4873 +       cmd->dst = MSM_NAND_FLASH_CMD;
4874 +       cmd->len = 16;
4875 +       cmd++;
4876 +
4877 +       cmd->cmd = 0;
4878 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
4879 +       cmd->dst = MSM_NAND_DEV0_CFG0;
4880 +       if (enable_bch_ecc)
4881 +               cmd->len = 12;
4882 +       else
4883 +               cmd->len = 8;
4884 +       cmd++;
4885 +
4886 +       cmd->cmd = 0;
4887 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
4888 +       cmd->dst = MSM_NAND_EXEC_CMD;
4889 +       cmd->len = 4;
4890 +       cmd++;
4891 +
4892 +       cmd->cmd = SRC_CRCI_NAND_DATA;
4893 +       cmd->src = MSM_NAND_FLASH_STATUS;
4894 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result);
4895 +       cmd->len = 8;
4896 +       cmd++;
4897 +
4898 +       cmd->cmd = 0;
4899 +       cmd->src = MSM_NAND_FLASH_BUFFER +
4900 +       (mtd->writesize - (chip->cw_size * (cwperpage-1)));
4901 +       cmd->dst = msm_virt_to_dma(chip, buf);
4902 +       cmd->len = 4;
4903 +       cmd++;
4904 +
4905 +       BUILD_BUG_ON(5 != ARRAY_SIZE(dma_buffer->cmd));
4906 +       BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
4907 +       dma_buffer->cmd[0].cmd |= CMD_OCB;
4908 +       cmd[-1].cmd |= CMD_OCU | CMD_LC;
4909 +
4910 +       dma_buffer->cmdptr = (msm_virt_to_dma(chip,
4911 +                               dma_buffer->cmd) >> 3) | CMD_PTR_LP;
4912 +
4913 +       mb();
4914 +       msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
4915 +               DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
4916 +       mb();
4917 +
4918 +       ret = 0;
4919 +       if (dma_buffer->data.result.flash_status & 0x110)
4920 +               ret = -EIO;
4921 +
4922 +       if (!ret) {
4923 +               /* Check for bad block marker byte */
4924 +               if (chip->CFG1 & CFG1_WIDE_FLASH) {
4925 +                       if (buf[0] != 0xFF || buf[1] != 0xFF)
4926 +                               ret = 1;
4927 +               } else {
4928 +                       if (buf[0] != 0xFF)
4929 +                               ret = 1;
4930 +               }
4931 +       }
4932 +
4933 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer) + 4);
4934 +       return ret;
4935 +}
4936 +
4937 +static int
4938 +msm_nand_block_isbad_dualnandc(struct mtd_info *mtd, loff_t ofs)
4939 +{
4940 +       struct msm_nand_chip *chip = mtd->priv;
4941 +       int ret;
4942 +       struct {
4943 +               dmov_s cmd[18];
4944 +               unsigned cmdptr;
4945 +               struct {
4946 +                       uint32_t cmd;
4947 +                       uint32_t addr0;
4948 +                       uint32_t addr1;
4949 +                       uint32_t chipsel_cs0;
4950 +                       uint32_t chipsel_cs1;
4951 +                       uint32_t cfg0;
4952 +                       uint32_t cfg1;
4953 +                       uint32_t exec;
4954 +                       uint32_t ecccfg;
4955 +                       uint32_t ebi2_chip_select_cfg0;
4956 +                       uint32_t adm_mux_data_ack_req_nc01;
4957 +                       uint32_t adm_mux_cmd_ack_req_nc01;
4958 +                       uint32_t adm_mux_data_ack_req_nc10;
4959 +                       uint32_t adm_mux_cmd_ack_req_nc10;
4960 +                       uint32_t adm_default_mux;
4961 +                       uint32_t default_ebi2_chip_select_cfg0;
4962 +                       struct {
4963 +                               uint32_t flash_status;
4964 +                               uint32_t buffer_status;
4965 +                       } result[2];
4966 +               } data;
4967 +       } *dma_buffer;
4968 +       dmov_s *cmd;
4969 +       uint8_t *buf01;
4970 +       uint8_t *buf10;
4971 +       unsigned page = 0;
4972 +       unsigned cwperpage;
4973 +
4974 +       if (mtd->writesize == 2048)
4975 +               page = ofs >> 11;
4976 +
4977 +       if (mtd->writesize == 4096)
4978 +               page = ofs >> 12;
4979 +
4980 +       if (mtd->writesize == 8192)
4981 +               page = (ofs >> 1) >> 12;
4982 +
4983 +       cwperpage = ((mtd->writesize >> 1) >> 9);
4984 +
4985 +       /* Check for invalid offset */
4986 +       if (ofs > mtd->size)
4987 +               return -EINVAL;
4988 +       if (ofs & (mtd->erasesize - 1)) {
4989 +               pr_err("%s: unsupported block address, 0x%x\n",
4990 +                        __func__, (uint32_t)ofs);
4991 +               return -EINVAL;
4992 +       }
4993 +
4994 +       wait_event(chip->wait_queue,
4995 +               (dma_buffer = msm_nand_get_dma_buffer(chip ,
4996 +                                        sizeof(*dma_buffer) + 8)));
4997 +       buf01 = (uint8_t *)dma_buffer + sizeof(*dma_buffer);
4998 +       buf10 = buf01 + 4;
4999 +
5000 +       /* Read 4 bytes starting from the bad block marker location
5001 +        * in the last code word of the page
5002 +        */
5003 +       cmd = dma_buffer->cmd;
5004 +
5005 +       dma_buffer->data.cmd = MSM_NAND_CMD_PAGE_READ;
5006 +       dma_buffer->data.cfg0 = chip->CFG0_RAW & ~(7U << 6);
5007 +       dma_buffer->data.cfg1 = chip->CFG1_RAW |
5008 +                               (chip->CFG1 & CFG1_WIDE_FLASH);
5009 +
5010 +       if (chip->CFG1 & CFG1_WIDE_FLASH)
5011 +               dma_buffer->data.addr0 = (page << 16) |
5012 +                       ((528*(cwperpage-1)) >> 1);
5013 +       else
5014 +               dma_buffer->data.addr0 = (page << 16) |
5015 +                       (528*(cwperpage-1));
5016 +
5017 +       dma_buffer->data.addr1 = (page >> 16) & 0xff;
5018 +       dma_buffer->data.chipsel_cs0 = (1<<4) | 4;
5019 +       dma_buffer->data.chipsel_cs1 = (1<<4) | 5;
5020 +
5021 +       dma_buffer->data.exec = 1;
5022 +
5023 +       dma_buffer->data.result[0].flash_status = 0xeeeeeeee;
5024 +       dma_buffer->data.result[0].buffer_status = 0xeeeeeeee;
5025 +       dma_buffer->data.result[1].flash_status = 0xeeeeeeee;
5026 +       dma_buffer->data.result[1].buffer_status = 0xeeeeeeee;
5027 +
5028 +       dma_buffer->data.ebi2_chip_select_cfg0 = 0x00000805;
5029 +       dma_buffer->data.adm_mux_data_ack_req_nc01 = 0x00000A3C;
5030 +       dma_buffer->data.adm_mux_cmd_ack_req_nc01  = 0x0000053C;
5031 +       dma_buffer->data.adm_mux_data_ack_req_nc10 = 0x00000F28;
5032 +       dma_buffer->data.adm_mux_cmd_ack_req_nc10  = 0x00000F14;
5033 +       dma_buffer->data.adm_default_mux = 0x00000FC0;
5034 +       dma_buffer->data.default_ebi2_chip_select_cfg0 = 0x00000801;
5035 +
5036 +       /* Reading last code word from NC01 */
5037 +       /* enable CS1 */
5038 +       cmd->cmd = 0;
5039 +       cmd->src = msm_virt_to_dma(chip,
5040 +                       &dma_buffer->data.ebi2_chip_select_cfg0);
5041 +       cmd->dst = EBI2_CHIP_SELECT_CFG0;
5042 +       cmd->len = 4;
5043 +       cmd++;
5044 +
5045 +       /* 0xF14 */
5046 +       cmd->cmd = 0;
5047 +       cmd->src = msm_virt_to_dma(chip,
5048 +                       &dma_buffer->data.adm_mux_cmd_ack_req_nc10);
5049 +       cmd->dst = EBI2_NAND_ADM_MUX;
5050 +       cmd->len = 4;
5051 +       cmd++;
5052 +
5053 +       cmd->cmd = DST_CRCI_NAND_CMD;
5054 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
5055 +       cmd->dst = NC01(MSM_NAND_FLASH_CMD);
5056 +       cmd->len = 16;
5057 +       cmd++;
5058 +
5059 +       cmd->cmd = 0;
5060 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
5061 +       cmd->dst = NC01(MSM_NAND_DEV0_CFG0);
5062 +       cmd->len = 8;
5063 +       cmd++;
5064 +
5065 +       cmd->cmd = 0;
5066 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
5067 +       cmd->dst = NC01(MSM_NAND_EXEC_CMD);
5068 +       cmd->len = 4;
5069 +       cmd++;
5070 +
5071 +       /* 0xF28 */
5072 +       cmd->cmd = 0;
5073 +       cmd->src = msm_virt_to_dma(chip,
5074 +                       &dma_buffer->data.adm_mux_data_ack_req_nc10);
5075 +       cmd->dst = EBI2_NAND_ADM_MUX;
5076 +       cmd->len = 4;
5077 +       cmd++;
5078 +
5079 +       cmd->cmd = SRC_CRCI_NAND_DATA;
5080 +       cmd->src = NC01(MSM_NAND_FLASH_STATUS);
5081 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result[0]);
5082 +       cmd->len = 8;
5083 +       cmd++;
5084 +
5085 +       cmd->cmd = 0;
5086 +       cmd->src = NC01(MSM_NAND_FLASH_BUFFER) + ((mtd->writesize >> 1) -
5087 +                                                       (528*(cwperpage-1)));
5088 +       cmd->dst = msm_virt_to_dma(chip, buf01);
5089 +       cmd->len = 4;
5090 +       cmd++;
5091 +
5092 +       /* Reading last code word from NC10 */
5093 +       /* 0x53C */
5094 +       cmd->cmd = 0;
5095 +       cmd->src = msm_virt_to_dma(chip,
5096 +       &dma_buffer->data.adm_mux_cmd_ack_req_nc01);
5097 +       cmd->dst = EBI2_NAND_ADM_MUX;
5098 +       cmd->len = 4;
5099 +       cmd++;
5100 +
5101 +       cmd->cmd = DST_CRCI_NAND_CMD;
5102 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
5103 +       cmd->dst = NC10(MSM_NAND_FLASH_CMD);
5104 +       cmd->len = 12;
5105 +       cmd++;
5106 +
5107 +       cmd->cmd = 0;
5108 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.chipsel_cs1);
5109 +       cmd->dst = NC10(MSM_NAND_FLASH_CHIP_SELECT);
5110 +       cmd->len = 4;
5111 +       cmd++;
5112 +
5113 +       cmd->cmd = 0;
5114 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cfg0);
5115 +       cmd->dst = NC10(MSM_NAND_DEV1_CFG0);
5116 +       cmd->len = 8;
5117 +       cmd++;
5118 +
5119 +       cmd->cmd = 0;
5120 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
5121 +       cmd->dst = NC10(MSM_NAND_EXEC_CMD);
5122 +       cmd->len = 4;
5123 +       cmd++;
5124 +
5125 +       /* A3C */
5126 +       cmd->cmd = 0;
5127 +       cmd->src = msm_virt_to_dma(chip,
5128 +                       &dma_buffer->data.adm_mux_data_ack_req_nc01);
5129 +       cmd->dst = EBI2_NAND_ADM_MUX;
5130 +       cmd->len = 4;
5131 +       cmd++;
5132 +
5133 +       cmd->cmd = SRC_CRCI_NAND_DATA;
5134 +       cmd->src = NC10(MSM_NAND_FLASH_STATUS);
5135 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.result[1]);
5136 +       cmd->len = 8;
5137 +       cmd++;
5138 +
5139 +       cmd->cmd = 0;
5140 +       cmd->src = NC10(MSM_NAND_FLASH_BUFFER) + ((mtd->writesize >> 1) -
5141 +                                                       (528*(cwperpage-1)));
5142 +       cmd->dst = msm_virt_to_dma(chip, buf10);
5143 +       cmd->len = 4;
5144 +       cmd++;
5145 +
5146 +       /* FC0 */
5147 +       cmd->cmd = 0;
5148 +       cmd->src = msm_virt_to_dma(chip,
5149 +                       &dma_buffer->data.adm_default_mux);
5150 +       cmd->dst = EBI2_NAND_ADM_MUX;
5151 +       cmd->len = 4;
5152 +       cmd++;
5153 +
5154 +       /* disble CS1 */
5155 +       cmd->cmd = 0;
5156 +       cmd->src = msm_virt_to_dma(chip,
5157 +                       &dma_buffer->data.ebi2_chip_select_cfg0);
5158 +       cmd->dst = EBI2_CHIP_SELECT_CFG0;
5159 +       cmd->len = 4;
5160 +       cmd++;
5161 +
5162 +       BUILD_BUG_ON(18 != ARRAY_SIZE(dma_buffer->cmd));
5163 +       BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
5164 +       dma_buffer->cmd[0].cmd |= CMD_OCB;
5165 +       cmd[-1].cmd |= CMD_OCU | CMD_LC;
5166 +
5167 +       dma_buffer->cmdptr = (msm_virt_to_dma(chip,
5168 +                               dma_buffer->cmd) >> 3) | CMD_PTR_LP;
5169 +
5170 +       mb();
5171 +       msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
5172 +               DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
5173 +       mb();
5174 +
5175 +       ret = 0;
5176 +       if ((dma_buffer->data.result[0].flash_status & 0x110) ||
5177 +                       (dma_buffer->data.result[1].flash_status & 0x110))
5178 +               ret = -EIO;
5179 +
5180 +       if (!ret) {
5181 +               /* Check for bad block marker byte for NC01 & NC10 */
5182 +               if (chip->CFG1 & CFG1_WIDE_FLASH) {
5183 +                       if ((buf01[0] != 0xFF || buf01[1] != 0xFF) ||
5184 +                               (buf10[0] != 0xFF || buf10[1] != 0xFF))
5185 +                               ret = 1;
5186 +               } else {
5187 +                       if (buf01[0] != 0xFF || buf10[0] != 0xFF)
5188 +                               ret = 1;
5189 +               }
5190 +       }
5191 +
5192 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer) + 8);
5193 +       return ret;
5194 +}
5195 +
5196 +static int
5197 +msm_nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
5198 +{
5199 +       struct mtd_oob_ops ops;
5200 +       int ret;
5201 +       uint8_t *buf;
5202 +
5203 +       /* Check for invalid offset */
5204 +       if (ofs > mtd->size)
5205 +               return -EINVAL;
5206 +       if (ofs & (mtd->erasesize - 1)) {
5207 +               pr_err("%s: unsupported block address, 0x%x\n",
5208 +                                __func__, (uint32_t)ofs);
5209 +               return -EINVAL;
5210 +       }
5211 +
5212 +       /*
5213 +       Write all 0s to the first page
5214 +       This will set the BB marker to 0
5215 +       */
5216 +       buf = page_address(ZERO_PAGE());
5217 +
5218 +       ops.mode = MTD_OPS_RAW;
5219 +       ops.len = mtd->writesize + mtd->oobsize;
5220 +       ops.retlen = 0;
5221 +       ops.ooblen = 0;
5222 +       ops.datbuf = buf;
5223 +       ops.oobbuf = NULL;
5224 +       if (!interleave_enable)
5225 +               ret =  msm_nand_write_oob(mtd, ofs, &ops);
5226 +       else
5227 +               ret = msm_nand_write_oob_dualnandc(mtd, ofs, &ops);
5228 +
5229 +       return ret;
5230 +}
5231 +
5232 +/**
5233 + * msm_nand_suspend - [MTD Interface] Suspend the msm_nand flash
5234 + * @param mtd          MTD device structure
5235 + */
5236 +static int msm_nand_suspend(struct mtd_info *mtd)
5237 +{
5238 +       return 0;
5239 +}
5240 +
5241 +/**
5242 + * msm_nand_resume - [MTD Interface] Resume the msm_nand flash
5243 + * @param mtd          MTD device structure
5244 + */
5245 +static void msm_nand_resume(struct mtd_info *mtd)
5246 +{
5247 +}
5248 +
5249 +struct onenand_information {
5250 +       uint16_t manufacturer_id;
5251 +       uint16_t device_id;
5252 +       uint16_t version_id;
5253 +       uint16_t data_buf_size;
5254 +       uint16_t boot_buf_size;
5255 +       uint16_t num_of_buffers;
5256 +       uint16_t technology;
5257 +};
5258 +
5259 +static struct onenand_information onenand_info;
5260 +static uint32_t nand_sfcmd_mode;
5261 +
5262 +uint32_t flash_onenand_probe(struct msm_nand_chip *chip)
5263 +{
5264 +               struct {
5265 +               dmov_s cmd[7];
5266 +               unsigned cmdptr;
5267 +               struct {
5268 +                       uint32_t bcfg;
5269 +                       uint32_t cmd;
5270 +                       uint32_t exec;
5271 +                       uint32_t status;
5272 +                       uint32_t addr0;
5273 +                       uint32_t addr1;
5274 +                       uint32_t addr2;
5275 +                       uint32_t addr3;
5276 +                       uint32_t addr4;
5277 +                       uint32_t addr5;
5278 +                       uint32_t addr6;
5279 +                       uint32_t data0;
5280 +                       uint32_t data1;
5281 +                       uint32_t data2;
5282 +                       uint32_t data3;
5283 +                       uint32_t data4;
5284 +                       uint32_t data5;
5285 +                       uint32_t data6;
5286 +               } data;
5287 +       } *dma_buffer;
5288 +       dmov_s *cmd;
5289 +
5290 +       int err = 0;
5291 +       uint32_t initialsflashcmd = 0;
5292 +
5293 +       initialsflashcmd = flash_rd_reg(chip, MSM_NAND_SFLASHC_CMD);
5294 +
5295 +       if ((initialsflashcmd & 0x10) == 0x10)
5296 +               nand_sfcmd_mode = MSM_NAND_SFCMD_ASYNC;
5297 +       else
5298 +               nand_sfcmd_mode = MSM_NAND_SFCMD_BURST;
5299 +
5300 +       printk(KERN_INFO "SFLASHC Async Mode bit: %x \n", nand_sfcmd_mode);
5301 +
5302 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
5303 +                               (chip, sizeof(*dma_buffer))));
5304 +
5305 +       cmd = dma_buffer->cmd;
5306 +
5307 +       dma_buffer->data.bcfg = SFLASH_BCFG |
5308 +                                       (nand_sfcmd_mode ? 0 : (1 << 24));
5309 +       dma_buffer->data.cmd = SFLASH_PREPCMD(7, 0, 0,
5310 +                                               MSM_NAND_SFCMD_DATXS,
5311 +                                               nand_sfcmd_mode,
5312 +                                               MSM_NAND_SFCMD_REGRD);
5313 +       dma_buffer->data.exec = 1;
5314 +       dma_buffer->data.status = CLEAN_DATA_32;
5315 +       dma_buffer->data.addr0 = (ONENAND_DEVICE_ID << 16) |
5316 +                                               (ONENAND_MANUFACTURER_ID);
5317 +       dma_buffer->data.addr1 = (ONENAND_DATA_BUFFER_SIZE << 16) |
5318 +                                               (ONENAND_VERSION_ID);
5319 +       dma_buffer->data.addr2 = (ONENAND_AMOUNT_OF_BUFFERS << 16) |
5320 +                                               (ONENAND_BOOT_BUFFER_SIZE);
5321 +       dma_buffer->data.addr3 = (CLEAN_DATA_16 << 16) |
5322 +                                               (ONENAND_TECHNOLOGY << 0);
5323 +       dma_buffer->data.data0 = CLEAN_DATA_32;
5324 +       dma_buffer->data.data1 = CLEAN_DATA_32;
5325 +       dma_buffer->data.data2 = CLEAN_DATA_32;
5326 +       dma_buffer->data.data3 = CLEAN_DATA_32;
5327 +
5328 +       /* Enable and configure the SFlash controller */
5329 +       cmd->cmd = 0;
5330 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.bcfg);
5331 +       cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
5332 +       cmd->len = 4;
5333 +       cmd++;
5334 +
5335 +       /* Block on cmd ready and write CMD register */
5336 +       cmd->cmd = DST_CRCI_NAND_CMD;
5337 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.cmd);
5338 +       cmd->dst = MSM_NAND_SFLASHC_CMD;
5339 +       cmd->len = 4;
5340 +       cmd++;
5341 +
5342 +       /* Configure the ADDR0 and ADDR1 registers */
5343 +       cmd->cmd = 0;
5344 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
5345 +       cmd->dst = MSM_NAND_ADDR0;
5346 +       cmd->len = 8;
5347 +       cmd++;
5348 +
5349 +       /* Configure the ADDR2 and ADDR3 registers */
5350 +       cmd->cmd = 0;
5351 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
5352 +       cmd->dst = MSM_NAND_ADDR2;
5353 +       cmd->len = 8;
5354 +       cmd++;
5355 +
5356 +       /* Kick the execute command */
5357 +       cmd->cmd = 0;
5358 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.exec);
5359 +       cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5360 +       cmd->len = 4;
5361 +       cmd++;
5362 +
5363 +       /* Block on data ready, and read the two status registers */
5364 +       cmd->cmd = SRC_CRCI_NAND_DATA;
5365 +       cmd->src = MSM_NAND_SFLASHC_STATUS;
5366 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.status);
5367 +       cmd->len = 4;
5368 +       cmd++;
5369 +
5370 +       /* Read data registers - valid only if status says success */
5371 +       cmd->cmd = 0;
5372 +       cmd->src = MSM_NAND_GENP_REG0;
5373 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data0);
5374 +       cmd->len = 16;
5375 +       cmd++;
5376 +
5377 +       BUILD_BUG_ON(7 != ARRAY_SIZE(dma_buffer->cmd));
5378 +       BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
5379 +       dma_buffer->cmd[0].cmd |= CMD_OCB;
5380 +       cmd[-1].cmd |= CMD_OCU | CMD_LC;
5381 +
5382 +       dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
5383 +                       >> 3) | CMD_PTR_LP;
5384 +
5385 +       mb();
5386 +       msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
5387 +                       | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
5388 +                       &dma_buffer->cmdptr)));
5389 +       mb();
5390 +
5391 +       /* Check for errors, protection violations etc */
5392 +       if (dma_buffer->data.status & 0x110) {
5393 +               pr_info("%s: MPU/OP error"
5394 +                               "(0x%x) during Onenand probe\n",
5395 +                               __func__, dma_buffer->data.status);
5396 +               err = -EIO;
5397 +       } else {
5398 +
5399 +               onenand_info.manufacturer_id =
5400 +                       (dma_buffer->data.data0 >> 0) & 0x0000FFFF;
5401 +               onenand_info.device_id =
5402 +                       (dma_buffer->data.data0 >> 16) & 0x0000FFFF;
5403 +               onenand_info.version_id =
5404 +                       (dma_buffer->data.data1 >> 0) & 0x0000FFFF;
5405 +               onenand_info.data_buf_size =
5406 +                       (dma_buffer->data.data1 >> 16) & 0x0000FFFF;
5407 +               onenand_info.boot_buf_size =
5408 +                       (dma_buffer->data.data2 >> 0) & 0x0000FFFF;
5409 +               onenand_info.num_of_buffers =
5410 +                       (dma_buffer->data.data2 >> 16) & 0x0000FFFF;
5411 +               onenand_info.technology =
5412 +                       (dma_buffer->data.data3 >> 0) & 0x0000FFFF;
5413 +
5414 +
5415 +               pr_info("======================================="
5416 +                               "==========================\n");
5417 +
5418 +               pr_info("%s: manufacturer_id = 0x%x\n"
5419 +                               , __func__, onenand_info.manufacturer_id);
5420 +               pr_info("%s: device_id = 0x%x\n"
5421 +                               , __func__, onenand_info.device_id);
5422 +               pr_info("%s: version_id = 0x%x\n"
5423 +                               , __func__, onenand_info.version_id);
5424 +               pr_info("%s: data_buf_size = 0x%x\n"
5425 +                               , __func__, onenand_info.data_buf_size);
5426 +               pr_info("%s: boot_buf_size = 0x%x\n"
5427 +                               , __func__, onenand_info.boot_buf_size);
5428 +               pr_info("%s: num_of_buffers = 0x%x\n"
5429 +                               , __func__, onenand_info.num_of_buffers);
5430 +               pr_info("%s: technology = 0x%x\n"
5431 +                               , __func__, onenand_info.technology);
5432 +
5433 +               pr_info("======================================="
5434 +                               "==========================\n");
5435 +
5436 +               if ((onenand_info.manufacturer_id != 0x00EC)
5437 +                       || ((onenand_info.device_id & 0x0040) != 0x0040)
5438 +                       || (onenand_info.data_buf_size != 0x0800)
5439 +                       || (onenand_info.boot_buf_size != 0x0200)
5440 +                       || (onenand_info.num_of_buffers != 0x0201)
5441 +                       || (onenand_info.technology != 0)) {
5442 +
5443 +                       pr_info("%s: Detected an unsupported device\n"
5444 +                               , __func__);
5445 +                       err = -EIO;
5446 +               }
5447 +       }
5448 +
5449 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
5450 +
5451 +       return err;
5452 +}
5453 +
5454 +int msm_onenand_read_oob(struct mtd_info *mtd,
5455 +               loff_t from, struct mtd_oob_ops *ops)
5456 +{
5457 +       struct msm_nand_chip *chip = mtd->priv;
5458 +
5459 +       struct {
5460 +               dmov_s cmd[53];
5461 +               unsigned cmdptr;
5462 +               struct {
5463 +                       uint32_t sfbcfg;
5464 +                       uint32_t sfcmd[9];
5465 +                       uint32_t sfexec;
5466 +                       uint32_t sfstat[9];
5467 +                       uint32_t addr0;
5468 +                       uint32_t addr1;
5469 +                       uint32_t addr2;
5470 +                       uint32_t addr3;
5471 +                       uint32_t addr4;
5472 +                       uint32_t addr5;
5473 +                       uint32_t addr6;
5474 +                       uint32_t data0;
5475 +                       uint32_t data1;
5476 +                       uint32_t data2;
5477 +                       uint32_t data3;
5478 +                       uint32_t data4;
5479 +                       uint32_t data5;
5480 +                       uint32_t data6;
5481 +                       uint32_t macro[5];
5482 +               } data;
5483 +       } *dma_buffer;
5484 +       dmov_s *cmd;
5485 +
5486 +       int err = 0;
5487 +       int i;
5488 +       dma_addr_t data_dma_addr = 0;
5489 +       dma_addr_t oob_dma_addr = 0;
5490 +       dma_addr_t data_dma_addr_curr = 0;
5491 +       dma_addr_t oob_dma_addr_curr = 0;
5492 +
5493 +       loff_t from_curr = 0;
5494 +       unsigned page_count;
5495 +       unsigned pages_read = 0;
5496 +
5497 +       uint16_t onenand_startaddr1;
5498 +       uint16_t onenand_startaddr8;
5499 +       uint16_t onenand_startaddr2;
5500 +       uint16_t onenand_startbuffer;
5501 +       uint16_t onenand_sysconfig1;
5502 +       uint16_t controller_status;
5503 +       uint16_t interrupt_status;
5504 +       uint16_t ecc_status;
5505 +#if VERBOSE
5506 +       pr_info("================================================="
5507 +                       "================\n");
5508 +       pr_info("%s: from 0x%llx mode %d \ndatbuf 0x%p datlen 0x%x"
5509 +                       "\noobbuf 0x%p ooblen 0x%x\n",
5510 +                       __func__, from, ops->mode, ops->datbuf, ops->len,
5511 +                       ops->oobbuf, ops->ooblen);
5512 +#endif
5513 +       if (!mtd) {
5514 +               pr_err("%s: invalid mtd pointer, 0x%x\n", __func__,
5515 +                               (uint32_t)mtd);
5516 +               return -EINVAL;
5517 +       }
5518 +       if (from & (mtd->writesize - 1)) {
5519 +               pr_err("%s: unsupported from, 0x%llx\n", __func__,
5520 +                               from);
5521 +               return -EINVAL;
5522 +       }
5523 +
5524 +       if ((ops->mode != MTD_OPS_PLACE_OOB) && (ops->mode != MTD_OPS_AUTO_OOB) &&
5525 +                       (ops->mode != MTD_OPS_RAW)) {
5526 +               pr_err("%s: unsupported ops->mode, %d\n", __func__,
5527 +                               ops->mode);
5528 +               return -EINVAL;
5529 +       }
5530 +
5531 +       if (((ops->datbuf == NULL) || (ops->len == 0)) &&
5532 +                       ((ops->oobbuf == NULL) || (ops->ooblen == 0))) {
5533 +               pr_err("%s: incorrect ops fields - nothing to do\n",
5534 +                               __func__);
5535 +               return -EINVAL;
5536 +       }
5537 +
5538 +       if ((ops->datbuf != NULL) && (ops->len == 0)) {
5539 +               pr_err("%s: data buffer passed but length 0\n",
5540 +                               __func__);
5541 +               return -EINVAL;
5542 +       }
5543 +
5544 +       if ((ops->oobbuf != NULL) && (ops->ooblen == 0)) {
5545 +               pr_err("%s: oob buffer passed but length 0\n",
5546 +                               __func__);
5547 +               return -EINVAL;
5548 +       }
5549 +
5550 +       if (ops->mode != MTD_OPS_RAW) {
5551 +               if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
5552 +                       /* when ops->datbuf is NULL, ops->len can be ooblen */
5553 +                       pr_err("%s: unsupported ops->len, %d\n", __func__,
5554 +                                       ops->len);
5555 +                       return -EINVAL;
5556 +               }
5557 +       } else {
5558 +               if (ops->datbuf != NULL &&
5559 +                       (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
5560 +                       pr_err("%s: unsupported ops->len,"
5561 +                               " %d for MTD_OPS_RAW\n", __func__, ops->len);
5562 +                       return -EINVAL;
5563 +               }
5564 +       }
5565 +
5566 +       if ((ops->mode == MTD_OPS_RAW) && (ops->oobbuf)) {
5567 +               pr_err("%s: unsupported operation, oobbuf pointer "
5568 +                               "passed in for RAW mode, %x\n", __func__,
5569 +                               (uint32_t)ops->oobbuf);
5570 +               return -EINVAL;
5571 +       }
5572 +
5573 +       if (ops->oobbuf && !ops->datbuf) {
5574 +               page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
5575 +                       mtd->oobavail : mtd->oobsize);
5576 +               if ((page_count == 0) && (ops->ooblen))
5577 +                       page_count = 1;
5578 +       } else if (ops->mode != MTD_OPS_RAW)
5579 +                       page_count = ops->len / mtd->writesize;
5580 +               else
5581 +                       page_count = ops->len / (mtd->writesize + mtd->oobsize);
5582 +
5583 +       if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->oobbuf != NULL)) {
5584 +               if (page_count * mtd->oobsize > ops->ooblen) {
5585 +                       pr_err("%s: unsupported ops->ooblen for "
5586 +                               "PLACE, %d\n", __func__, ops->ooblen);
5587 +                       return -EINVAL;
5588 +               }
5589 +       }
5590 +
5591 +       if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->ooblen != 0) &&
5592 +                                                       (ops->ooboffs != 0)) {
5593 +               pr_err("%s: unsupported ops->ooboffs, %d\n", __func__,
5594 +                               ops->ooboffs);
5595 +               return -EINVAL;
5596 +       }
5597 +
5598 +       if (ops->datbuf) {
5599 +               memset(ops->datbuf, 0x55, ops->len);
5600 +               data_dma_addr_curr = data_dma_addr = msm_nand_dma_map(chip->dev,
5601 +                               ops->datbuf, ops->len, DMA_FROM_DEVICE, NULL);
5602 +               if (dma_mapping_error(chip->dev, data_dma_addr)) {
5603 +                       pr_err("%s: failed to get dma addr for %p\n",
5604 +                                       __func__, ops->datbuf);
5605 +                       return -EIO;
5606 +               }
5607 +       }
5608 +       if (ops->oobbuf) {
5609 +               memset(ops->oobbuf, 0x55, ops->ooblen);
5610 +               oob_dma_addr_curr = oob_dma_addr = msm_nand_dma_map(chip->dev,
5611 +                               ops->oobbuf, ops->ooblen, DMA_FROM_DEVICE, NULL);
5612 +               if (dma_mapping_error(chip->dev, oob_dma_addr)) {
5613 +                       pr_err("%s: failed to get dma addr for %p\n",
5614 +                                       __func__, ops->oobbuf);
5615 +                       err = -EIO;
5616 +                       goto err_dma_map_oobbuf_failed;
5617 +               }
5618 +       }
5619 +
5620 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
5621 +                               (chip, sizeof(*dma_buffer))));
5622 +
5623 +       from_curr = from;
5624 +
5625 +       while (page_count-- > 0) {
5626 +
5627 +               cmd = dma_buffer->cmd;
5628 +
5629 +               if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
5630 +                       && (from_curr >= (mtd->size>>1))) { /* DDP Device */
5631 +                               onenand_startaddr1 = DEVICE_FLASHCORE_1 |
5632 +                                       (((uint32_t)(from_curr-(mtd->size>>1))
5633 +                                       / mtd->erasesize));
5634 +                               onenand_startaddr2 = DEVICE_BUFFERRAM_1;
5635 +               } else {
5636 +                               onenand_startaddr1 = DEVICE_FLASHCORE_0 |
5637 +                               ((uint32_t)from_curr / mtd->erasesize) ;
5638 +                               onenand_startaddr2 = DEVICE_BUFFERRAM_0;
5639 +               }
5640 +
5641 +               onenand_startaddr8 = (((uint32_t)from_curr &
5642 +                               (mtd->erasesize - 1)) / mtd->writesize) << 2;
5643 +               onenand_startbuffer = DATARAM0_0 << 8;
5644 +               onenand_sysconfig1 = (ops->mode == MTD_OPS_RAW) ?
5645 +                       ONENAND_SYSCFG1_ECCDIS(nand_sfcmd_mode) :
5646 +                       ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);
5647 +
5648 +               dma_buffer->data.sfbcfg = SFLASH_BCFG |
5649 +                                       (nand_sfcmd_mode ? 0 : (1 << 24));
5650 +               dma_buffer->data.sfcmd[0] =  SFLASH_PREPCMD(7, 0, 0,
5651 +                                                       MSM_NAND_SFCMD_CMDXS,
5652 +                                                       nand_sfcmd_mode,
5653 +                                                       MSM_NAND_SFCMD_REGWR);
5654 +               dma_buffer->data.sfcmd[1] =  SFLASH_PREPCMD(0, 0, 32,
5655 +                                                       MSM_NAND_SFCMD_CMDXS,
5656 +                                                       nand_sfcmd_mode,
5657 +                                                       MSM_NAND_SFCMD_INTHI);
5658 +               dma_buffer->data.sfcmd[2] =  SFLASH_PREPCMD(3, 7, 0,
5659 +                                                       MSM_NAND_SFCMD_DATXS,
5660 +                                                       nand_sfcmd_mode,
5661 +                                                       MSM_NAND_SFCMD_REGRD);
5662 +               dma_buffer->data.sfcmd[3] =  SFLASH_PREPCMD(256, 0, 0,
5663 +                                                       MSM_NAND_SFCMD_DATXS,
5664 +                                                       nand_sfcmd_mode,
5665 +                                                       MSM_NAND_SFCMD_DATRD);
5666 +               dma_buffer->data.sfcmd[4] =  SFLASH_PREPCMD(256, 0, 0,
5667 +                                                       MSM_NAND_SFCMD_DATXS,
5668 +                                                       nand_sfcmd_mode,
5669 +                                                       MSM_NAND_SFCMD_DATRD);
5670 +               dma_buffer->data.sfcmd[5] =  SFLASH_PREPCMD(256, 0, 0,
5671 +                                                       MSM_NAND_SFCMD_DATXS,
5672 +                                                       nand_sfcmd_mode,
5673 +                                                       MSM_NAND_SFCMD_DATRD);
5674 +               dma_buffer->data.sfcmd[6] =  SFLASH_PREPCMD(256, 0, 0,
5675 +                                                       MSM_NAND_SFCMD_DATXS,
5676 +                                                       nand_sfcmd_mode,
5677 +                                                       MSM_NAND_SFCMD_DATRD);
5678 +               dma_buffer->data.sfcmd[7] =  SFLASH_PREPCMD(32, 0, 0,
5679 +                                                       MSM_NAND_SFCMD_DATXS,
5680 +                                                       nand_sfcmd_mode,
5681 +                                                       MSM_NAND_SFCMD_DATRD);
5682 +               dma_buffer->data.sfcmd[8] =  SFLASH_PREPCMD(4, 10, 0,
5683 +                                                       MSM_NAND_SFCMD_CMDXS,
5684 +                                                       nand_sfcmd_mode,
5685 +                                                       MSM_NAND_SFCMD_REGWR);
5686 +               dma_buffer->data.sfexec = 1;
5687 +               dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
5688 +               dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
5689 +               dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
5690 +               dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
5691 +               dma_buffer->data.sfstat[4] = CLEAN_DATA_32;
5692 +               dma_buffer->data.sfstat[5] = CLEAN_DATA_32;
5693 +               dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
5694 +               dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
5695 +               dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
5696 +               dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
5697 +                                               (ONENAND_SYSTEM_CONFIG_1);
5698 +               dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
5699 +                                               (ONENAND_START_ADDRESS_1);
5700 +               dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
5701 +                                               (ONENAND_START_ADDRESS_2);
5702 +               dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
5703 +                                               (ONENAND_COMMAND);
5704 +               dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
5705 +                                               (ONENAND_INTERRUPT_STATUS);
5706 +               dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
5707 +                                               (ONENAND_SYSTEM_CONFIG_1);
5708 +               dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
5709 +                                               (ONENAND_START_ADDRESS_1);
5710 +               dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
5711 +                                               (onenand_sysconfig1);
5712 +               dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
5713 +                                               (onenand_startaddr1);
5714 +               dma_buffer->data.data2 = (onenand_startbuffer << 16) |
5715 +                                               (onenand_startaddr2);
5716 +               dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
5717 +                                               (ONENAND_CMDLOADSPARE);
5718 +               dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
5719 +                                               (CLEAN_DATA_16);
5720 +               dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
5721 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
5722 +               dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
5723 +                                               (ONENAND_STARTADDR1_RES);
5724 +               dma_buffer->data.macro[0] = 0x0200;
5725 +               dma_buffer->data.macro[1] = 0x0300;
5726 +               dma_buffer->data.macro[2] = 0x0400;
5727 +               dma_buffer->data.macro[3] = 0x0500;
5728 +               dma_buffer->data.macro[4] = 0x8010;
5729 +
5730 +               /*************************************************************/
5731 +               /* Write necessary address registers in the onenand device   */
5732 +               /*************************************************************/
5733 +
5734 +               /* Enable and configure the SFlash controller */
5735 +               cmd->cmd = 0;
5736 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
5737 +               cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
5738 +               cmd->len = 4;
5739 +               cmd++;
5740 +
5741 +               /* Block on cmd ready and write CMD register */
5742 +               cmd->cmd = DST_CRCI_NAND_CMD;
5743 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
5744 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
5745 +               cmd->len = 4;
5746 +               cmd++;
5747 +
5748 +               /* Write the ADDR0 and ADDR1 registers */
5749 +               cmd->cmd = 0;
5750 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
5751 +               cmd->dst = MSM_NAND_ADDR0;
5752 +               cmd->len = 8;
5753 +               cmd++;
5754 +
5755 +               /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
5756 +               cmd->cmd = 0;
5757 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
5758 +               cmd->dst = MSM_NAND_ADDR2;
5759 +               cmd->len = 16;
5760 +               cmd++;
5761 +
5762 +               /* Write the ADDR6 registers */
5763 +               cmd->cmd = 0;
5764 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
5765 +               cmd->dst = MSM_NAND_ADDR6;
5766 +               cmd->len = 4;
5767 +               cmd++;
5768 +
5769 +               /* Write the GENP0, GENP1, GENP2, GENP3 registers */
5770 +               cmd->cmd = 0;
5771 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
5772 +               cmd->dst = MSM_NAND_GENP_REG0;
5773 +               cmd->len = 16;
5774 +               cmd++;
5775 +
5776 +               /* Write the FLASH_DEV_CMD4,5,6 registers */
5777 +               cmd->cmd = 0;
5778 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
5779 +               cmd->dst = MSM_NAND_DEV_CMD4;
5780 +               cmd->len = 12;
5781 +               cmd++;
5782 +
5783 +               /* Kick the execute command */
5784 +               cmd->cmd = 0;
5785 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
5786 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5787 +               cmd->len = 4;
5788 +               cmd++;
5789 +
5790 +               /* Block on data ready, and read the status register */
5791 +               cmd->cmd = SRC_CRCI_NAND_DATA;
5792 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
5793 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
5794 +               cmd->len = 4;
5795 +               cmd++;
5796 +
5797 +               /*************************************************************/
5798 +               /* Wait for the interrupt from the Onenand device controller */
5799 +               /*************************************************************/
5800 +
5801 +               /* Block on cmd ready and write CMD register */
5802 +               cmd->cmd = DST_CRCI_NAND_CMD;
5803 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
5804 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
5805 +               cmd->len = 4;
5806 +               cmd++;
5807 +
5808 +               /* Kick the execute command */
5809 +               cmd->cmd = 0;
5810 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
5811 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5812 +               cmd->len = 4;
5813 +               cmd++;
5814 +
5815 +               /* Block on data ready, and read the status register */
5816 +               cmd->cmd = SRC_CRCI_NAND_DATA;
5817 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
5818 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
5819 +               cmd->len = 4;
5820 +               cmd++;
5821 +
5822 +               /*************************************************************/
5823 +               /* Read necessary status registers from the onenand device   */
5824 +               /*************************************************************/
5825 +
5826 +               /* Block on cmd ready and write CMD register */
5827 +               cmd->cmd = DST_CRCI_NAND_CMD;
5828 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
5829 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
5830 +               cmd->len = 4;
5831 +               cmd++;
5832 +
5833 +               /* Kick the execute command */
5834 +               cmd->cmd = 0;
5835 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
5836 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5837 +               cmd->len = 4;
5838 +               cmd++;
5839 +
5840 +               /* Block on data ready, and read the status register */
5841 +               cmd->cmd = SRC_CRCI_NAND_DATA;
5842 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
5843 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
5844 +               cmd->len = 4;
5845 +               cmd++;
5846 +
5847 +               /* Read the GENP3 register */
5848 +               cmd->cmd = 0;
5849 +               cmd->src = MSM_NAND_GENP_REG3;
5850 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
5851 +               cmd->len = 4;
5852 +               cmd++;
5853 +
5854 +               /* Read the DEVCMD4 register */
5855 +               cmd->cmd = 0;
5856 +               cmd->src = MSM_NAND_DEV_CMD4;
5857 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
5858 +               cmd->len = 4;
5859 +               cmd++;
5860 +
5861 +               /*************************************************************/
5862 +               /* Read the data ram area from the onenand buffer ram        */
5863 +               /*************************************************************/
5864 +
5865 +               if (ops->datbuf) {
5866 +
5867 +                       dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
5868 +                                                       (ONENAND_CMDLOAD);
5869 +
5870 +                       for (i = 0; i < 4; i++) {
5871 +
5872 +                               /* Block on cmd ready and write CMD register */
5873 +                               cmd->cmd = DST_CRCI_NAND_CMD;
5874 +                               cmd->src = msm_virt_to_dma(chip,
5875 +                                               &dma_buffer->data.sfcmd[3+i]);
5876 +                               cmd->dst = MSM_NAND_SFLASHC_CMD;
5877 +                               cmd->len = 4;
5878 +                               cmd++;
5879 +
5880 +                               /* Write the MACRO1 register */
5881 +                               cmd->cmd = 0;
5882 +                               cmd->src = msm_virt_to_dma(chip,
5883 +                                               &dma_buffer->data.macro[i]);
5884 +                               cmd->dst = MSM_NAND_MACRO1_REG;
5885 +                               cmd->len = 4;
5886 +                               cmd++;
5887 +
5888 +                               /* Kick the execute command */
5889 +                               cmd->cmd = 0;
5890 +                               cmd->src = msm_virt_to_dma(chip,
5891 +                                               &dma_buffer->data.sfexec);
5892 +                               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5893 +                               cmd->len = 4;
5894 +                               cmd++;
5895 +
5896 +                               /* Block on data rdy, & read status register */
5897 +                               cmd->cmd = SRC_CRCI_NAND_DATA;
5898 +                               cmd->src = MSM_NAND_SFLASHC_STATUS;
5899 +                               cmd->dst = msm_virt_to_dma(chip,
5900 +                                               &dma_buffer->data.sfstat[3+i]);
5901 +                               cmd->len = 4;
5902 +                               cmd++;
5903 +
5904 +                               /* Transfer nand ctlr buf contents to usr buf */
5905 +                               cmd->cmd = 0;
5906 +                               cmd->src = MSM_NAND_FLASH_BUFFER;
5907 +                               cmd->dst = data_dma_addr_curr;
5908 +                               cmd->len = 512;
5909 +                               data_dma_addr_curr += 512;
5910 +                               cmd++;
5911 +                       }
5912 +               }
5913 +
5914 +               if ((ops->oobbuf) || (ops->mode == MTD_OPS_RAW)) {
5915 +
5916 +                       /* Block on cmd ready and write CMD register */
5917 +                       cmd->cmd = DST_CRCI_NAND_CMD;
5918 +                       cmd->src = msm_virt_to_dma(chip,
5919 +                                       &dma_buffer->data.sfcmd[7]);
5920 +                       cmd->dst = MSM_NAND_SFLASHC_CMD;
5921 +                       cmd->len = 4;
5922 +                       cmd++;
5923 +
5924 +                       /* Write the MACRO1 register */
5925 +                       cmd->cmd = 0;
5926 +                       cmd->src = msm_virt_to_dma(chip,
5927 +                                       &dma_buffer->data.macro[4]);
5928 +                       cmd->dst = MSM_NAND_MACRO1_REG;
5929 +                       cmd->len = 4;
5930 +                       cmd++;
5931 +
5932 +                       /* Kick the execute command */
5933 +                       cmd->cmd = 0;
5934 +                       cmd->src = msm_virt_to_dma(chip,
5935 +                                       &dma_buffer->data.sfexec);
5936 +                       cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5937 +                       cmd->len = 4;
5938 +                       cmd++;
5939 +
5940 +                       /* Block on data ready, and read status register */
5941 +                       cmd->cmd = SRC_CRCI_NAND_DATA;
5942 +                       cmd->src = MSM_NAND_SFLASHC_STATUS;
5943 +                       cmd->dst = msm_virt_to_dma(chip,
5944 +                                       &dma_buffer->data.sfstat[7]);
5945 +                       cmd->len = 4;
5946 +                       cmd++;
5947 +
5948 +                       /* Transfer nand ctlr buffer contents into usr buf */
5949 +                       if (ops->mode == MTD_OPS_AUTO_OOB) {
5950 +                               for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++) {
5951 +                                       cmd->cmd = 0;
5952 +                                       cmd->src = MSM_NAND_FLASH_BUFFER +
5953 +                                       mtd->ecclayout->oobfree[i].offset;
5954 +                                       cmd->dst = oob_dma_addr_curr;
5955 +                                       cmd->len =
5956 +                                       mtd->ecclayout->oobfree[i].length;
5957 +                                       oob_dma_addr_curr +=
5958 +                                       mtd->ecclayout->oobfree[i].length;
5959 +                                       cmd++;
5960 +                               }
5961 +                       }
5962 +                       if (ops->mode == MTD_OPS_PLACE_OOB) {
5963 +                                       cmd->cmd = 0;
5964 +                                       cmd->src = MSM_NAND_FLASH_BUFFER;
5965 +                                       cmd->dst = oob_dma_addr_curr;
5966 +                                       cmd->len = mtd->oobsize;
5967 +                                       oob_dma_addr_curr += mtd->oobsize;
5968 +                                       cmd++;
5969 +                       }
5970 +                       if (ops->mode == MTD_OPS_RAW) {
5971 +                                       cmd->cmd = 0;
5972 +                                       cmd->src = MSM_NAND_FLASH_BUFFER;
5973 +                                       cmd->dst = data_dma_addr_curr;
5974 +                                       cmd->len = mtd->oobsize;
5975 +                                       data_dma_addr_curr += mtd->oobsize;
5976 +                                       cmd++;
5977 +                       }
5978 +               }
5979 +
5980 +               /*************************************************************/
5981 +               /* Restore the necessary registers to proper values          */
5982 +               /*************************************************************/
5983 +
5984 +               /* Block on cmd ready and write CMD register */
5985 +               cmd->cmd = DST_CRCI_NAND_CMD;
5986 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
5987 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
5988 +               cmd->len = 4;
5989 +               cmd++;
5990 +
5991 +               /* Kick the execute command */
5992 +               cmd->cmd = 0;
5993 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
5994 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
5995 +               cmd->len = 4;
5996 +               cmd++;
5997 +
5998 +               /* Block on data ready, and read the status register */
5999 +               cmd->cmd = SRC_CRCI_NAND_DATA;
6000 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
6001 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
6002 +               cmd->len = 4;
6003 +               cmd++;
6004 +
6005 +
6006 +               BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
6007 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
6008 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
6009 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
6010 +
6011 +               dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
6012 +                               >> 3) | CMD_PTR_LP;
6013 +
6014 +               mb();
6015 +               msm_dmov_exec_cmd(chip->dma_channel,
6016 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
6017 +                               &dma_buffer->cmdptr)));
6018 +               mb();
6019 +
6020 +               ecc_status = (dma_buffer->data.data3 >> 16) &
6021 +                                                       0x0000FFFF;
6022 +               interrupt_status = (dma_buffer->data.data4 >> 0) &
6023 +                                                       0x0000FFFF;
6024 +               controller_status = (dma_buffer->data.data4 >> 16) &
6025 +                                                       0x0000FFFF;
6026 +
6027 +#if VERBOSE
6028 +               pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
6029 +                               "%x %x\n", __func__,
6030 +                                       dma_buffer->data.sfstat[0],
6031 +                                       dma_buffer->data.sfstat[1],
6032 +                                       dma_buffer->data.sfstat[2],
6033 +                                       dma_buffer->data.sfstat[3],
6034 +                                       dma_buffer->data.sfstat[4],
6035 +                                       dma_buffer->data.sfstat[5],
6036 +                                       dma_buffer->data.sfstat[6],
6037 +                                       dma_buffer->data.sfstat[7],
6038 +                                       dma_buffer->data.sfstat[8]);
6039 +
6040 +               pr_info("%s: controller_status = %x\n", __func__,
6041 +                                       controller_status);
6042 +               pr_info("%s: interrupt_status = %x\n", __func__,
6043 +                                       interrupt_status);
6044 +               pr_info("%s: ecc_status = %x\n", __func__,
6045 +                                       ecc_status);
6046 +#endif
6047 +               /* Check for errors, protection violations etc */
6048 +               if ((controller_status != 0)
6049 +                               || (dma_buffer->data.sfstat[0] & 0x110)
6050 +                               || (dma_buffer->data.sfstat[1] & 0x110)
6051 +                               || (dma_buffer->data.sfstat[2] & 0x110)
6052 +                               || (dma_buffer->data.sfstat[8] & 0x110)
6053 +                               || ((dma_buffer->data.sfstat[3] & 0x110) &&
6054 +                                                               (ops->datbuf))
6055 +                               || ((dma_buffer->data.sfstat[4] & 0x110) &&
6056 +                                                               (ops->datbuf))
6057 +                               || ((dma_buffer->data.sfstat[5] & 0x110) &&
6058 +                                                               (ops->datbuf))
6059 +                               || ((dma_buffer->data.sfstat[6] & 0x110) &&
6060 +                                                               (ops->datbuf))
6061 +                               || ((dma_buffer->data.sfstat[7] & 0x110) &&
6062 +                                                               ((ops->oobbuf)
6063 +                                       || (ops->mode == MTD_OPS_RAW)))) {
6064 +                       pr_info("%s: ECC/MPU/OP error\n", __func__);
6065 +                       err = -EIO;
6066 +               }
6067 +
6068 +               if (err)
6069 +                       break;
6070 +               pages_read++;
6071 +               from_curr += mtd->writesize;
6072 +       }
6073 +
6074 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
6075 +
6076 +       if (ops->oobbuf) {
6077 +               dma_unmap_page(chip->dev, oob_dma_addr, ops->ooblen,
6078 +                               DMA_FROM_DEVICE);
6079 +       }
6080 +err_dma_map_oobbuf_failed:
6081 +       if (ops->datbuf) {
6082 +               dma_unmap_page(chip->dev, data_dma_addr, ops->len,
6083 +                               DMA_FROM_DEVICE);
6084 +       }
6085 +
6086 +       if (err) {
6087 +               pr_err("%s: %llx %x %x failed\n", __func__, from_curr,
6088 +                               ops->datbuf ? ops->len : 0, ops->ooblen);
6089 +       } else {
6090 +               ops->retlen = ops->oobretlen = 0;
6091 +               if (ops->datbuf != NULL) {
6092 +                       if (ops->mode != MTD_OPS_RAW)
6093 +                               ops->retlen = mtd->writesize * pages_read;
6094 +                       else
6095 +                               ops->retlen = (mtd->writesize +  mtd->oobsize)
6096 +                                                       * pages_read;
6097 +               }
6098 +               if (ops->oobbuf != NULL) {
6099 +                       if (ops->mode == MTD_OPS_AUTO_OOB)
6100 +                               ops->oobretlen = mtd->oobavail * pages_read;
6101 +                       else
6102 +                               ops->oobretlen = mtd->oobsize * pages_read;
6103 +               }
6104 +       }
6105 +
6106 +#if VERBOSE
6107 +       pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
6108 +                       __func__, err, ops->retlen, ops->oobretlen);
6109 +
6110 +       pr_info("==================================================="
6111 +                       "==============\n");
6112 +#endif
6113 +       return err;
6114 +}
6115 +
6116 +int msm_onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
6117 +               size_t *retlen, u_char *buf)
6118 +{
6119 +       int ret;
6120 +       struct mtd_oob_ops ops;
6121 +
6122 +       ops.mode = MTD_OPS_PLACE_OOB;
6123 +       ops.datbuf = buf;
6124 +       ops.len = len;
6125 +       ops.retlen = 0;
6126 +       ops.oobbuf = NULL;
6127 +       ops.ooblen = 0;
6128 +       ops.oobretlen = 0;
6129 +       ret =  msm_onenand_read_oob(mtd, from, &ops);
6130 +       *retlen = ops.retlen;
6131 +
6132 +       return ret;
6133 +}
6134 +
6135 +static int msm_onenand_write_oob(struct mtd_info *mtd, loff_t to,
6136 +               struct mtd_oob_ops *ops)
6137 +{
6138 +       struct msm_nand_chip *chip = mtd->priv;
6139 +
6140 +       struct {
6141 +               dmov_s cmd[53];
6142 +               unsigned cmdptr;
6143 +               struct {
6144 +                       uint32_t sfbcfg;
6145 +                       uint32_t sfcmd[10];
6146 +                       uint32_t sfexec;
6147 +                       uint32_t sfstat[10];
6148 +                       uint32_t addr0;
6149 +                       uint32_t addr1;
6150 +                       uint32_t addr2;
6151 +                       uint32_t addr3;
6152 +                       uint32_t addr4;
6153 +                       uint32_t addr5;
6154 +                       uint32_t addr6;
6155 +                       uint32_t data0;
6156 +                       uint32_t data1;
6157 +                       uint32_t data2;
6158 +                       uint32_t data3;
6159 +                       uint32_t data4;
6160 +                       uint32_t data5;
6161 +                       uint32_t data6;
6162 +                       uint32_t macro[5];
6163 +               } data;
6164 +       } *dma_buffer;
6165 +       dmov_s *cmd;
6166 +
6167 +       int err = 0;
6168 +       int i, j, k;
6169 +       dma_addr_t data_dma_addr = 0;
6170 +       dma_addr_t oob_dma_addr = 0;
6171 +       dma_addr_t init_dma_addr = 0;
6172 +       dma_addr_t data_dma_addr_curr = 0;
6173 +       dma_addr_t oob_dma_addr_curr = 0;
6174 +       uint8_t *init_spare_bytes;
6175 +
6176 +       loff_t to_curr = 0;
6177 +       unsigned page_count;
6178 +       unsigned pages_written = 0;
6179 +
6180 +       uint16_t onenand_startaddr1;
6181 +       uint16_t onenand_startaddr8;
6182 +       uint16_t onenand_startaddr2;
6183 +       uint16_t onenand_startbuffer;
6184 +       uint16_t onenand_sysconfig1;
6185 +
6186 +       uint16_t controller_status;
6187 +       uint16_t interrupt_status;
6188 +       uint16_t ecc_status;
6189 +
6190 +#if VERBOSE
6191 +       pr_info("================================================="
6192 +                       "================\n");
6193 +       pr_info("%s: to 0x%llx mode %d \ndatbuf 0x%p datlen 0x%x"
6194 +                       "\noobbuf 0x%p ooblen 0x%x\n",
6195 +                       __func__, to, ops->mode, ops->datbuf, ops->len,
6196 +                       ops->oobbuf, ops->ooblen);
6197 +#endif
6198 +       if (!mtd) {
6199 +               pr_err("%s: invalid mtd pointer, 0x%x\n", __func__,
6200 +                               (uint32_t)mtd);
6201 +               return -EINVAL;
6202 +       }
6203 +       if (to & (mtd->writesize - 1)) {
6204 +               pr_err("%s: unsupported to, 0x%llx\n", __func__, to);
6205 +               return -EINVAL;
6206 +       }
6207 +
6208 +       if ((ops->mode != MTD_OPS_PLACE_OOB) && (ops->mode != MTD_OPS_AUTO_OOB) &&
6209 +                       (ops->mode != MTD_OPS_RAW)) {
6210 +               pr_err("%s: unsupported ops->mode, %d\n", __func__,
6211 +                               ops->mode);
6212 +               return -EINVAL;
6213 +       }
6214 +
6215 +       if (((ops->datbuf == NULL) || (ops->len == 0)) &&
6216 +                       ((ops->oobbuf == NULL) || (ops->ooblen == 0))) {
6217 +               pr_err("%s: incorrect ops fields - nothing to do\n",
6218 +                               __func__);
6219 +               return -EINVAL;
6220 +       }
6221 +
6222 +       if ((ops->datbuf != NULL) && (ops->len == 0)) {
6223 +               pr_err("%s: data buffer passed but length 0\n",
6224 +                               __func__);
6225 +               return -EINVAL;
6226 +       }
6227 +
6228 +       if ((ops->oobbuf != NULL) && (ops->ooblen == 0)) {
6229 +               pr_err("%s: oob buffer passed but length 0\n",
6230 +                               __func__);
6231 +               return -EINVAL;
6232 +       }
6233 +
6234 +       if (ops->mode != MTD_OPS_RAW) {
6235 +               if (ops->datbuf != NULL && (ops->len % mtd->writesize) != 0) {
6236 +                       /* when ops->datbuf is NULL, ops->len can be ooblen */
6237 +                       pr_err("%s: unsupported ops->len, %d\n", __func__,
6238 +                                       ops->len);
6239 +                       return -EINVAL;
6240 +               }
6241 +       } else {
6242 +               if (ops->datbuf != NULL &&
6243 +                       (ops->len % (mtd->writesize + mtd->oobsize)) != 0) {
6244 +                       pr_err("%s: unsupported ops->len,"
6245 +                               " %d for MTD_OPS_RAW\n", __func__, ops->len);
6246 +                       return -EINVAL;
6247 +               }
6248 +       }
6249 +
6250 +       if ((ops->mode == MTD_OPS_RAW) && (ops->oobbuf)) {
6251 +               pr_err("%s: unsupported operation, oobbuf pointer "
6252 +                               "passed in for RAW mode, %x\n", __func__,
6253 +                               (uint32_t)ops->oobbuf);
6254 +               return -EINVAL;
6255 +       }
6256 +
6257 +       if (ops->oobbuf && !ops->datbuf) {
6258 +               page_count = ops->ooblen / ((ops->mode == MTD_OPS_AUTO_OOB) ?
6259 +                       mtd->oobavail : mtd->oobsize);
6260 +               if ((page_count == 0) && (ops->ooblen))
6261 +                       page_count = 1;
6262 +       } else if (ops->mode != MTD_OPS_RAW)
6263 +                       page_count = ops->len / mtd->writesize;
6264 +               else
6265 +                       page_count = ops->len / (mtd->writesize + mtd->oobsize);
6266 +
6267 +       if ((ops->mode == MTD_OPS_AUTO_OOB) && (ops->oobbuf != NULL)) {
6268 +               if (page_count > 1) {
6269 +                       pr_err("%s: unsupported ops->ooblen for"
6270 +                               "AUTO, %d\n", __func__, ops->ooblen);
6271 +                       return -EINVAL;
6272 +               }
6273 +       }
6274 +
6275 +       if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->oobbuf != NULL)) {
6276 +               if (page_count * mtd->oobsize > ops->ooblen) {
6277 +                       pr_err("%s: unsupported ops->ooblen for"
6278 +                               "PLACE, %d\n", __func__, ops->ooblen);
6279 +                       return -EINVAL;
6280 +               }
6281 +       }
6282 +
6283 +       if ((ops->mode == MTD_OPS_PLACE_OOB) && (ops->ooblen != 0) &&
6284 +                                               (ops->ooboffs != 0)) {
6285 +               pr_err("%s: unsupported ops->ooboffs, %d\n",
6286 +                               __func__, ops->ooboffs);
6287 +               return -EINVAL;
6288 +       }
6289 +
6290 +       init_spare_bytes = kmalloc(64, GFP_KERNEL);
6291 +       if (!init_spare_bytes) {
6292 +               pr_err("%s: failed to alloc init_spare_bytes buffer\n",
6293 +                               __func__);
6294 +               return -ENOMEM;
6295 +       }
6296 +       for (i = 0; i < 64; i++)
6297 +               init_spare_bytes[i] = 0xFF;
6298 +
6299 +       if ((ops->oobbuf) && (ops->mode == MTD_OPS_AUTO_OOB)) {
6300 +               for (i = 0, k = 0; i < MTD_MAX_OOBFREE_ENTRIES; i++)
6301 +                       for (j = 0; j < mtd->ecclayout->oobfree[i].length;
6302 +                                       j++) {
6303 +                               init_spare_bytes[j +
6304 +                                       mtd->ecclayout->oobfree[i].offset]
6305 +                                               = (ops->oobbuf)[k];
6306 +                               k++;
6307 +                       }
6308 +       }
6309 +
6310 +       if (ops->datbuf) {
6311 +               data_dma_addr_curr = data_dma_addr = msm_nand_dma_map(chip->dev,
6312 +                               ops->datbuf, ops->len, DMA_TO_DEVICE, NULL);
6313 +               if (dma_mapping_error(chip->dev, data_dma_addr)) {
6314 +                       pr_err("%s: failed to get dma addr for %p\n",
6315 +                                       __func__, ops->datbuf);
6316 +                       return -EIO;
6317 +               }
6318 +       }
6319 +       if (ops->oobbuf) {
6320 +               oob_dma_addr_curr = oob_dma_addr = msm_nand_dma_map(chip->dev,
6321 +                               ops->oobbuf, ops->ooblen, DMA_TO_DEVICE, NULL);
6322 +               if (dma_mapping_error(chip->dev, oob_dma_addr)) {
6323 +                       pr_err("%s: failed to get dma addr for %p\n",
6324 +                                       __func__, ops->oobbuf);
6325 +                       err = -EIO;
6326 +                       goto err_dma_map_oobbuf_failed;
6327 +               }
6328 +       }
6329 +
6330 +       init_dma_addr = msm_nand_dma_map(chip->dev, init_spare_bytes, 64,
6331 +                                        DMA_TO_DEVICE, NULL);
6332 +       if (dma_mapping_error(chip->dev, init_dma_addr)) {
6333 +               pr_err("%s: failed to get dma addr for %p\n",
6334 +                               __func__, init_spare_bytes);
6335 +               err = -EIO;
6336 +               goto err_dma_map_initbuf_failed;
6337 +       }
6338 +
6339 +
6340 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
6341 +                               (chip, sizeof(*dma_buffer))));
6342 +
6343 +       to_curr = to;
6344 +
6345 +       while (page_count-- > 0) {
6346 +               cmd = dma_buffer->cmd;
6347 +
6348 +               if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
6349 +                       && (to_curr >= (mtd->size>>1))) { /* DDP Device */
6350 +                               onenand_startaddr1 = DEVICE_FLASHCORE_1 |
6351 +                                       (((uint32_t)(to_curr-(mtd->size>>1))
6352 +                                       / mtd->erasesize));
6353 +                               onenand_startaddr2 = DEVICE_BUFFERRAM_1;
6354 +               } else {
6355 +                               onenand_startaddr1 = DEVICE_FLASHCORE_0 |
6356 +                                       ((uint32_t)to_curr / mtd->erasesize) ;
6357 +                               onenand_startaddr2 = DEVICE_BUFFERRAM_0;
6358 +               }
6359 +
6360 +               onenand_startaddr8 = (((uint32_t)to_curr &
6361 +                               (mtd->erasesize - 1)) / mtd->writesize) << 2;
6362 +               onenand_startbuffer = DATARAM0_0 << 8;
6363 +               onenand_sysconfig1 = (ops->mode == MTD_OPS_RAW) ?
6364 +                       ONENAND_SYSCFG1_ECCDIS(nand_sfcmd_mode) :
6365 +                       ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode);
6366 +
6367 +               dma_buffer->data.sfbcfg = SFLASH_BCFG |
6368 +                                       (nand_sfcmd_mode ? 0 : (1 << 24));
6369 +               dma_buffer->data.sfcmd[0] =  SFLASH_PREPCMD(6, 0, 0,
6370 +                                                       MSM_NAND_SFCMD_CMDXS,
6371 +                                                       nand_sfcmd_mode,
6372 +                                                       MSM_NAND_SFCMD_REGWR);
6373 +               dma_buffer->data.sfcmd[1] =  SFLASH_PREPCMD(256, 0, 0,
6374 +                                                       MSM_NAND_SFCMD_CMDXS,
6375 +                                                       nand_sfcmd_mode,
6376 +                                                       MSM_NAND_SFCMD_DATWR);
6377 +               dma_buffer->data.sfcmd[2] =  SFLASH_PREPCMD(256, 0, 0,
6378 +                                                       MSM_NAND_SFCMD_CMDXS,
6379 +                                                       nand_sfcmd_mode,
6380 +                                                       MSM_NAND_SFCMD_DATWR);
6381 +               dma_buffer->data.sfcmd[3] =  SFLASH_PREPCMD(256, 0, 0,
6382 +                                                       MSM_NAND_SFCMD_CMDXS,
6383 +                                                       nand_sfcmd_mode,
6384 +                                                       MSM_NAND_SFCMD_DATWR);
6385 +               dma_buffer->data.sfcmd[4] =  SFLASH_PREPCMD(256, 0, 0,
6386 +                                                       MSM_NAND_SFCMD_CMDXS,
6387 +                                                       nand_sfcmd_mode,
6388 +                                                       MSM_NAND_SFCMD_DATWR);
6389 +               dma_buffer->data.sfcmd[5] =  SFLASH_PREPCMD(32, 0, 0,
6390 +                                                       MSM_NAND_SFCMD_CMDXS,
6391 +                                                       nand_sfcmd_mode,
6392 +                                                       MSM_NAND_SFCMD_DATWR);
6393 +               dma_buffer->data.sfcmd[6] =  SFLASH_PREPCMD(1, 6, 0,
6394 +                                                       MSM_NAND_SFCMD_CMDXS,
6395 +                                                       nand_sfcmd_mode,
6396 +                                                       MSM_NAND_SFCMD_REGWR);
6397 +               dma_buffer->data.sfcmd[7] =  SFLASH_PREPCMD(0, 0, 32,
6398 +                                                       MSM_NAND_SFCMD_CMDXS,
6399 +                                                       nand_sfcmd_mode,
6400 +                                                       MSM_NAND_SFCMD_INTHI);
6401 +               dma_buffer->data.sfcmd[8] =  SFLASH_PREPCMD(3, 7, 0,
6402 +                                                       MSM_NAND_SFCMD_DATXS,
6403 +                                                       nand_sfcmd_mode,
6404 +                                                       MSM_NAND_SFCMD_REGRD);
6405 +               dma_buffer->data.sfcmd[9] =  SFLASH_PREPCMD(4, 10, 0,
6406 +                                                       MSM_NAND_SFCMD_CMDXS,
6407 +                                                       nand_sfcmd_mode,
6408 +                                                       MSM_NAND_SFCMD_REGWR);
6409 +               dma_buffer->data.sfexec = 1;
6410 +               dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
6411 +               dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
6412 +               dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
6413 +               dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
6414 +               dma_buffer->data.sfstat[4] = CLEAN_DATA_32;
6415 +               dma_buffer->data.sfstat[5] = CLEAN_DATA_32;
6416 +               dma_buffer->data.sfstat[6] = CLEAN_DATA_32;
6417 +               dma_buffer->data.sfstat[7] = CLEAN_DATA_32;
6418 +               dma_buffer->data.sfstat[8] = CLEAN_DATA_32;
6419 +               dma_buffer->data.sfstat[9] = CLEAN_DATA_32;
6420 +               dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
6421 +                                               (ONENAND_SYSTEM_CONFIG_1);
6422 +               dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
6423 +                                               (ONENAND_START_ADDRESS_1);
6424 +               dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
6425 +                                               (ONENAND_START_ADDRESS_2);
6426 +               dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
6427 +                                               (ONENAND_COMMAND);
6428 +               dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
6429 +                                               (ONENAND_INTERRUPT_STATUS);
6430 +               dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
6431 +                                               (ONENAND_SYSTEM_CONFIG_1);
6432 +               dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
6433 +                                               (ONENAND_START_ADDRESS_1);
6434 +               dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
6435 +                                               (onenand_sysconfig1);
6436 +               dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
6437 +                                               (onenand_startaddr1);
6438 +               dma_buffer->data.data2 = (onenand_startbuffer << 16) |
6439 +                                               (onenand_startaddr2);
6440 +               dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
6441 +                                               (ONENAND_CMDPROGSPARE);
6442 +               dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
6443 +                                               (CLEAN_DATA_16);
6444 +               dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
6445 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
6446 +               dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
6447 +                                               (ONENAND_STARTADDR1_RES);
6448 +               dma_buffer->data.macro[0] = 0x0200;
6449 +               dma_buffer->data.macro[1] = 0x0300;
6450 +               dma_buffer->data.macro[2] = 0x0400;
6451 +               dma_buffer->data.macro[3] = 0x0500;
6452 +               dma_buffer->data.macro[4] = 0x8010;
6453 +
6454 +
6455 +               /*************************************************************/
6456 +               /* Write necessary address registers in the onenand device   */
6457 +               /*************************************************************/
6458 +
6459 +               /* Enable and configure the SFlash controller */
6460 +               cmd->cmd = 0;
6461 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
6462 +               cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
6463 +               cmd->len = 4;
6464 +               cmd++;
6465 +
6466 +               /* Block on cmd ready and write CMD register */
6467 +               cmd->cmd = DST_CRCI_NAND_CMD;
6468 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
6469 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
6470 +               cmd->len = 4;
6471 +               cmd++;
6472 +
6473 +               /* Write the ADDR0 and ADDR1 registers */
6474 +               cmd->cmd = 0;
6475 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
6476 +               cmd->dst = MSM_NAND_ADDR0;
6477 +               cmd->len = 8;
6478 +               cmd++;
6479 +
6480 +               /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
6481 +               cmd->cmd = 0;
6482 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
6483 +               cmd->dst = MSM_NAND_ADDR2;
6484 +               cmd->len = 16;
6485 +               cmd++;
6486 +
6487 +               /* Write the ADDR6 registers */
6488 +               cmd->cmd = 0;
6489 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
6490 +               cmd->dst = MSM_NAND_ADDR6;
6491 +               cmd->len = 4;
6492 +               cmd++;
6493 +
6494 +               /* Write the GENP0, GENP1, GENP2, GENP3 registers */
6495 +               cmd->cmd = 0;
6496 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
6497 +               cmd->dst = MSM_NAND_GENP_REG0;
6498 +               cmd->len = 16;
6499 +               cmd++;
6500 +
6501 +               /* Write the FLASH_DEV_CMD4,5,6 registers */
6502 +               cmd->cmd = 0;
6503 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
6504 +               cmd->dst = MSM_NAND_DEV_CMD4;
6505 +               cmd->len = 12;
6506 +               cmd++;
6507 +
6508 +               /* Kick the execute command */
6509 +               cmd->cmd = 0;
6510 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
6511 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
6512 +               cmd->len = 4;
6513 +               cmd++;
6514 +
6515 +               /* Block on data ready, and read the status register */
6516 +               cmd->cmd = SRC_CRCI_NAND_DATA;
6517 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
6518 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
6519 +               cmd->len = 4;
6520 +               cmd++;
6521 +
6522 +               /*************************************************************/
6523 +               /* Write the data ram area in the onenand buffer ram         */
6524 +               /*************************************************************/
6525 +
6526 +               if (ops->datbuf) {
6527 +                       dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
6528 +                                                       (ONENAND_CMDPROG);
6529 +
6530 +                       for (i = 0; i < 4; i++) {
6531 +
6532 +                               /* Block on cmd ready and write CMD register */
6533 +                               cmd->cmd = DST_CRCI_NAND_CMD;
6534 +                               cmd->src = msm_virt_to_dma(chip,
6535 +                                               &dma_buffer->data.sfcmd[1+i]);
6536 +                               cmd->dst = MSM_NAND_SFLASHC_CMD;
6537 +                               cmd->len = 4;
6538 +                               cmd++;
6539 +
6540 +                               /* Trnsfr usr buf contents to nand ctlr buf */
6541 +                               cmd->cmd = 0;
6542 +                               cmd->src = data_dma_addr_curr;
6543 +                               cmd->dst = MSM_NAND_FLASH_BUFFER;
6544 +                               cmd->len = 512;
6545 +                               data_dma_addr_curr += 512;
6546 +                               cmd++;
6547 +
6548 +                               /* Write the MACRO1 register */
6549 +                               cmd->cmd = 0;
6550 +                               cmd->src = msm_virt_to_dma(chip,
6551 +                                               &dma_buffer->data.macro[i]);
6552 +                               cmd->dst = MSM_NAND_MACRO1_REG;
6553 +                               cmd->len = 4;
6554 +                               cmd++;
6555 +
6556 +                               /* Kick the execute command */
6557 +                               cmd->cmd = 0;
6558 +                               cmd->src = msm_virt_to_dma(chip,
6559 +                                               &dma_buffer->data.sfexec);
6560 +                               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
6561 +                               cmd->len = 4;
6562 +                               cmd++;
6563 +
6564 +                               /* Block on data rdy, & read status register */
6565 +                               cmd->cmd = SRC_CRCI_NAND_DATA;
6566 +                               cmd->src = MSM_NAND_SFLASHC_STATUS;
6567 +                               cmd->dst = msm_virt_to_dma(chip,
6568 +                                               &dma_buffer->data.sfstat[1+i]);
6569 +                               cmd->len = 4;
6570 +                               cmd++;
6571 +
6572 +                       }
6573 +               }
6574 +
6575 +               /* Block on cmd ready and write CMD register */
6576 +               cmd->cmd = DST_CRCI_NAND_CMD;
6577 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[5]);
6578 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
6579 +               cmd->len = 4;
6580 +               cmd++;
6581 +
6582 +               if ((ops->oobbuf) || (ops->mode == MTD_OPS_RAW)) {
6583 +
6584 +                       /* Transfer user buf contents into nand ctlr buffer */
6585 +                       if (ops->mode == MTD_OPS_AUTO_OOB) {
6586 +                               cmd->cmd = 0;
6587 +                               cmd->src = init_dma_addr;
6588 +                               cmd->dst = MSM_NAND_FLASH_BUFFER;
6589 +                               cmd->len = mtd->oobsize;
6590 +                               cmd++;
6591 +                       }
6592 +                       if (ops->mode == MTD_OPS_PLACE_OOB) {
6593 +                               cmd->cmd = 0;
6594 +                               cmd->src = oob_dma_addr_curr;
6595 +                               cmd->dst = MSM_NAND_FLASH_BUFFER;
6596 +                               cmd->len = mtd->oobsize;
6597 +                               oob_dma_addr_curr += mtd->oobsize;
6598 +                               cmd++;
6599 +                       }
6600 +                       if (ops->mode == MTD_OPS_RAW) {
6601 +                               cmd->cmd = 0;
6602 +                               cmd->src = data_dma_addr_curr;
6603 +                               cmd->dst = MSM_NAND_FLASH_BUFFER;
6604 +                               cmd->len = mtd->oobsize;
6605 +                               data_dma_addr_curr += mtd->oobsize;
6606 +                               cmd++;
6607 +                       }
6608 +               } else {
6609 +                               cmd->cmd = 0;
6610 +                               cmd->src = init_dma_addr;
6611 +                               cmd->dst = MSM_NAND_FLASH_BUFFER;
6612 +                               cmd->len = mtd->oobsize;
6613 +                               cmd++;
6614 +               }
6615 +
6616 +               /* Write the MACRO1 register */
6617 +               cmd->cmd = 0;
6618 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.macro[4]);
6619 +               cmd->dst = MSM_NAND_MACRO1_REG;
6620 +               cmd->len = 4;
6621 +               cmd++;
6622 +
6623 +               /* Kick the execute command */
6624 +               cmd->cmd = 0;
6625 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
6626 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
6627 +               cmd->len = 4;
6628 +               cmd++;
6629 +
6630 +               /* Block on data ready, and read the status register */
6631 +               cmd->cmd = SRC_CRCI_NAND_DATA;
6632 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
6633 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[5]);
6634 +               cmd->len = 4;
6635 +               cmd++;
6636 +
6637 +               /*********************************************************/
6638 +               /* Issuing write command                                 */
6639 +               /*********************************************************/
6640 +
6641 +               /* Block on cmd ready and write CMD register */
6642 +               cmd->cmd = DST_CRCI_NAND_CMD;
6643 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[6]);
6644 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
6645 +               cmd->len = 4;
6646 +               cmd++;
6647 +
6648 +               /* Kick the execute command */
6649 +               cmd->cmd = 0;
6650 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
6651 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
6652 +               cmd->len = 4;
6653 +               cmd++;
6654 +
6655 +               /* Block on data ready, and read the status register */
6656 +               cmd->cmd = SRC_CRCI_NAND_DATA;
6657 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
6658 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[6]);
6659 +               cmd->len = 4;
6660 +               cmd++;
6661 +
6662 +               /*************************************************************/
6663 +               /* Wait for the interrupt from the Onenand device controller */
6664 +               /*************************************************************/
6665 +
6666 +               /* Block on cmd ready and write CMD register */
6667 +               cmd->cmd = DST_CRCI_NAND_CMD;
6668 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[7]);
6669 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
6670 +               cmd->len = 4;
6671 +               cmd++;
6672 +
6673 +               /* Kick the execute command */
6674 +               cmd->cmd = 0;
6675 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
6676 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
6677 +               cmd->len = 4;
6678 +               cmd++;
6679 +
6680 +               /* Block on data ready, and read the status register */
6681 +               cmd->cmd = SRC_CRCI_NAND_DATA;
6682 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
6683 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[7]);
6684 +               cmd->len = 4;
6685 +               cmd++;
6686 +
6687 +               /*************************************************************/
6688 +               /* Read necessary status registers from the onenand device   */
6689 +               /*************************************************************/
6690 +
6691 +               /* Block on cmd ready and write CMD register */
6692 +               cmd->cmd = DST_CRCI_NAND_CMD;
6693 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[8]);
6694 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
6695 +               cmd->len = 4;
6696 +               cmd++;
6697 +
6698 +               /* Kick the execute command */
6699 +               cmd->cmd = 0;
6700 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
6701 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
6702 +               cmd->len = 4;
6703 +               cmd++;
6704 +
6705 +               /* Block on data ready, and read the status register */
6706 +               cmd->cmd = SRC_CRCI_NAND_DATA;
6707 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
6708 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[8]);
6709 +               cmd->len = 4;
6710 +               cmd++;
6711 +
6712 +               /* Read the GENP3 register */
6713 +               cmd->cmd = 0;
6714 +               cmd->src = MSM_NAND_GENP_REG3;
6715 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
6716 +               cmd->len = 4;
6717 +               cmd++;
6718 +
6719 +               /* Read the DEVCMD4 register */
6720 +               cmd->cmd = 0;
6721 +               cmd->src = MSM_NAND_DEV_CMD4;
6722 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
6723 +               cmd->len = 4;
6724 +               cmd++;
6725 +
6726 +               /*************************************************************/
6727 +               /* Restore the necessary registers to proper values          */
6728 +               /*************************************************************/
6729 +
6730 +               /* Block on cmd ready and write CMD register */
6731 +               cmd->cmd = DST_CRCI_NAND_CMD;
6732 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[9]);
6733 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
6734 +               cmd->len = 4;
6735 +               cmd++;
6736 +
6737 +               /* Kick the execute command */
6738 +               cmd->cmd = 0;
6739 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
6740 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
6741 +               cmd->len = 4;
6742 +               cmd++;
6743 +
6744 +               /* Block on data ready, and read the status register */
6745 +               cmd->cmd = SRC_CRCI_NAND_DATA;
6746 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
6747 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[9]);
6748 +               cmd->len = 4;
6749 +               cmd++;
6750 +
6751 +
6752 +               BUILD_BUG_ON(53 != ARRAY_SIZE(dma_buffer->cmd));
6753 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
6754 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
6755 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
6756 +
6757 +               dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
6758 +                               >> 3) | CMD_PTR_LP;
6759 +
6760 +               mb();
6761 +               msm_dmov_exec_cmd(chip->dma_channel,
6762 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
6763 +                               &dma_buffer->cmdptr)));
6764 +               mb();
6765 +
6766 +               ecc_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
6767 +               interrupt_status = (dma_buffer->data.data4 >> 0)&0x0000FFFF;
6768 +               controller_status = (dma_buffer->data.data4 >> 16)&0x0000FFFF;
6769 +
6770 +#if VERBOSE
6771 +               pr_info("\n%s: sflash status %x %x %x %x %x %x %x"
6772 +                               " %x %x %x\n", __func__,
6773 +                                       dma_buffer->data.sfstat[0],
6774 +                                       dma_buffer->data.sfstat[1],
6775 +                                       dma_buffer->data.sfstat[2],
6776 +                                       dma_buffer->data.sfstat[3],
6777 +                                       dma_buffer->data.sfstat[4],
6778 +                                       dma_buffer->data.sfstat[5],
6779 +                                       dma_buffer->data.sfstat[6],
6780 +                                       dma_buffer->data.sfstat[7],
6781 +                                       dma_buffer->data.sfstat[8],
6782 +                                       dma_buffer->data.sfstat[9]);
6783 +
6784 +               pr_info("%s: controller_status = %x\n", __func__,
6785 +                                       controller_status);
6786 +               pr_info("%s: interrupt_status = %x\n", __func__,
6787 +                                       interrupt_status);
6788 +               pr_info("%s: ecc_status = %x\n", __func__,
6789 +                                       ecc_status);
6790 +#endif
6791 +               /* Check for errors, protection violations etc */
6792 +               if ((controller_status != 0)
6793 +                               || (dma_buffer->data.sfstat[0] & 0x110)
6794 +                               || (dma_buffer->data.sfstat[6] & 0x110)
6795 +                               || (dma_buffer->data.sfstat[7] & 0x110)
6796 +                               || (dma_buffer->data.sfstat[8] & 0x110)
6797 +                               || (dma_buffer->data.sfstat[9] & 0x110)
6798 +                               || ((dma_buffer->data.sfstat[1] & 0x110) &&
6799 +                                                               (ops->datbuf))
6800 +                               || ((dma_buffer->data.sfstat[2] & 0x110) &&
6801 +                                                               (ops->datbuf))
6802 +                               || ((dma_buffer->data.sfstat[3] & 0x110) &&
6803 +                                                               (ops->datbuf))
6804 +                               || ((dma_buffer->data.sfstat[4] & 0x110) &&
6805 +                                                               (ops->datbuf))
6806 +                               || ((dma_buffer->data.sfstat[5] & 0x110) &&
6807 +                                                               ((ops->oobbuf)
6808 +                                       || (ops->mode == MTD_OPS_RAW)))) {
6809 +                       pr_info("%s: ECC/MPU/OP error\n", __func__);
6810 +                       err = -EIO;
6811 +               }
6812 +
6813 +               if (err)
6814 +                       break;
6815 +               pages_written++;
6816 +               to_curr += mtd->writesize;
6817 +       }
6818 +
6819 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
6820 +
6821 +       dma_unmap_page(chip->dev, init_dma_addr, 64, DMA_TO_DEVICE);
6822 +
6823 +err_dma_map_initbuf_failed:
6824 +       if (ops->oobbuf) {
6825 +               dma_unmap_page(chip->dev, oob_dma_addr, ops->ooblen,
6826 +                                                       DMA_TO_DEVICE);
6827 +       }
6828 +err_dma_map_oobbuf_failed:
6829 +       if (ops->datbuf) {
6830 +               dma_unmap_page(chip->dev, data_dma_addr, ops->len,
6831 +                                                       DMA_TO_DEVICE);
6832 +       }
6833 +
6834 +       if (err) {
6835 +               pr_err("%s: %llx %x %x failed\n", __func__, to_curr,
6836 +                               ops->datbuf ? ops->len : 0, ops->ooblen);
6837 +       } else {
6838 +               ops->retlen = ops->oobretlen = 0;
6839 +               if (ops->datbuf != NULL) {
6840 +                       if (ops->mode != MTD_OPS_RAW)
6841 +                               ops->retlen = mtd->writesize * pages_written;
6842 +                       else
6843 +                               ops->retlen = (mtd->writesize +  mtd->oobsize)
6844 +                                                       * pages_written;
6845 +               }
6846 +               if (ops->oobbuf != NULL) {
6847 +                       if (ops->mode == MTD_OPS_AUTO_OOB)
6848 +                               ops->oobretlen = mtd->oobavail * pages_written;
6849 +                       else
6850 +                               ops->oobretlen = mtd->oobsize * pages_written;
6851 +               }
6852 +       }
6853 +
6854 +#if VERBOSE
6855 +       pr_info("\n%s: ret %d, retlen %d oobretlen %d\n",
6856 +                       __func__, err, ops->retlen, ops->oobretlen);
6857 +
6858 +       pr_info("================================================="
6859 +                       "================\n");
6860 +#endif
6861 +       kfree(init_spare_bytes);
6862 +       return err;
6863 +}
6864 +
6865 +static int msm_onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
6866 +               size_t *retlen, const u_char *buf)
6867 +{
6868 +       int ret;
6869 +       struct mtd_oob_ops ops;
6870 +
6871 +       ops.mode = MTD_OPS_PLACE_OOB;
6872 +       ops.datbuf = (uint8_t *)buf;
6873 +       ops.len = len;
6874 +       ops.retlen = 0;
6875 +       ops.oobbuf = NULL;
6876 +       ops.ooblen = 0;
6877 +       ops.oobretlen = 0;
6878 +       ret =  msm_onenand_write_oob(mtd, to, &ops);
6879 +       *retlen = ops.retlen;
6880 +
6881 +       return ret;
6882 +}
6883 +
6884 +static int msm_onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
6885 +{
6886 +       struct msm_nand_chip *chip = mtd->priv;
6887 +
6888 +       struct {
6889 +               dmov_s cmd[20];
6890 +               unsigned cmdptr;
6891 +               struct {
6892 +                       uint32_t sfbcfg;
6893 +                       uint32_t sfcmd[4];
6894 +                       uint32_t sfexec;
6895 +                       uint32_t sfstat[4];
6896 +                       uint32_t addr0;
6897 +                       uint32_t addr1;
6898 +                       uint32_t addr2;
6899 +                       uint32_t addr3;
6900 +                       uint32_t addr4;
6901 +                       uint32_t addr5;
6902 +                       uint32_t addr6;
6903 +                       uint32_t data0;
6904 +                       uint32_t data1;
6905 +                       uint32_t data2;
6906 +                       uint32_t data3;
6907 +                       uint32_t data4;
6908 +                       uint32_t data5;
6909 +                       uint32_t data6;
6910 +               } data;
6911 +       } *dma_buffer;
6912 +       dmov_s *cmd;
6913 +
6914 +       int err = 0;
6915 +
6916 +       uint16_t onenand_startaddr1;
6917 +       uint16_t onenand_startaddr8;
6918 +       uint16_t onenand_startaddr2;
6919 +       uint16_t onenand_startbuffer;
6920 +
6921 +       uint16_t controller_status;
6922 +       uint16_t interrupt_status;
6923 +       uint16_t ecc_status;
6924 +
6925 +       uint64_t temp;
6926 +
6927 +#if VERBOSE
6928 +       pr_info("================================================="
6929 +                       "================\n");
6930 +       pr_info("%s: addr 0x%llx len 0x%llx\n",
6931 +                       __func__, instr->addr, instr->len);
6932 +#endif
6933 +       if (instr->addr & (mtd->erasesize - 1)) {
6934 +               pr_err("%s: Unsupported erase address, 0x%llx\n",
6935 +                               __func__, instr->addr);
6936 +               return -EINVAL;
6937 +       }
6938 +       if (instr->len != mtd->erasesize) {
6939 +               pr_err("%s: Unsupported erase len, %lld\n",
6940 +                               __func__, instr->len);
6941 +               return -EINVAL;
6942 +       }
6943 +
6944 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
6945 +                               (chip, sizeof(*dma_buffer))));
6946 +
6947 +       cmd = dma_buffer->cmd;
6948 +
6949 +       temp = instr->addr;
6950 +
6951 +       if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
6952 +               && (temp >= (mtd->size>>1))) { /* DDP Device */
6953 +                       onenand_startaddr1 = DEVICE_FLASHCORE_1 |
6954 +                               (((uint32_t)(temp-(mtd->size>>1))
6955 +                                               / mtd->erasesize));
6956 +                       onenand_startaddr2 = DEVICE_BUFFERRAM_1;
6957 +       } else {
6958 +               onenand_startaddr1 = DEVICE_FLASHCORE_0 |
6959 +                       ((uint32_t)temp / mtd->erasesize) ;
6960 +               onenand_startaddr2 = DEVICE_BUFFERRAM_0;
6961 +       }
6962 +
6963 +       onenand_startaddr8 = 0x0000;
6964 +       onenand_startbuffer = DATARAM0_0 << 8;
6965 +
6966 +       dma_buffer->data.sfbcfg = SFLASH_BCFG |
6967 +                                       (nand_sfcmd_mode ? 0 : (1 << 24));
6968 +       dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
6969 +                                               MSM_NAND_SFCMD_CMDXS,
6970 +                                               nand_sfcmd_mode,
6971 +                                               MSM_NAND_SFCMD_REGWR);
6972 +       dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
6973 +                                               MSM_NAND_SFCMD_CMDXS,
6974 +                                               nand_sfcmd_mode,
6975 +                                               MSM_NAND_SFCMD_INTHI);
6976 +       dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
6977 +                                               MSM_NAND_SFCMD_DATXS,
6978 +                                               nand_sfcmd_mode,
6979 +                                               MSM_NAND_SFCMD_REGRD);
6980 +       dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
6981 +                                               MSM_NAND_SFCMD_CMDXS,
6982 +                                               nand_sfcmd_mode,
6983 +                                               MSM_NAND_SFCMD_REGWR);
6984 +       dma_buffer->data.sfexec = 1;
6985 +       dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
6986 +       dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
6987 +       dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
6988 +       dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
6989 +       dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
6990 +                                               (ONENAND_SYSTEM_CONFIG_1);
6991 +       dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
6992 +                                               (ONENAND_START_ADDRESS_1);
6993 +       dma_buffer->data.addr2 = (ONENAND_START_BUFFER << 16) |
6994 +                                               (ONENAND_START_ADDRESS_2);
6995 +       dma_buffer->data.addr3 = (ONENAND_ECC_STATUS << 16) |
6996 +                                               (ONENAND_COMMAND);
6997 +       dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
6998 +                                               (ONENAND_INTERRUPT_STATUS);
6999 +       dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
7000 +                                               (ONENAND_SYSTEM_CONFIG_1);
7001 +       dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
7002 +                                               (ONENAND_START_ADDRESS_1);
7003 +       dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
7004 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
7005 +       dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
7006 +                                               (onenand_startaddr1);
7007 +       dma_buffer->data.data2 = (onenand_startbuffer << 16) |
7008 +                                               (onenand_startaddr2);
7009 +       dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
7010 +                                               (ONENAND_CMDERAS);
7011 +       dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
7012 +                                               (CLEAN_DATA_16);
7013 +       dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
7014 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
7015 +       dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
7016 +                                               (ONENAND_STARTADDR1_RES);
7017 +
7018 +       /***************************************************************/
7019 +       /* Write the necessary address registers in the onenand device */
7020 +       /***************************************************************/
7021 +
7022 +       /* Enable and configure the SFlash controller */
7023 +       cmd->cmd = 0;
7024 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
7025 +       cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
7026 +       cmd->len = 4;
7027 +       cmd++;
7028 +
7029 +       /* Block on cmd ready and write CMD register */
7030 +       cmd->cmd = DST_CRCI_NAND_CMD;
7031 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
7032 +       cmd->dst = MSM_NAND_SFLASHC_CMD;
7033 +       cmd->len = 4;
7034 +       cmd++;
7035 +
7036 +       /* Write the ADDR0 and ADDR1 registers */
7037 +       cmd->cmd = 0;
7038 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
7039 +       cmd->dst = MSM_NAND_ADDR0;
7040 +       cmd->len = 8;
7041 +       cmd++;
7042 +
7043 +       /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
7044 +       cmd->cmd = 0;
7045 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
7046 +       cmd->dst = MSM_NAND_ADDR2;
7047 +       cmd->len = 16;
7048 +       cmd++;
7049 +
7050 +       /* Write the ADDR6 registers */
7051 +       cmd->cmd = 0;
7052 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
7053 +       cmd->dst = MSM_NAND_ADDR6;
7054 +       cmd->len = 4;
7055 +       cmd++;
7056 +
7057 +       /* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
7058 +       cmd->cmd = 0;
7059 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
7060 +       cmd->dst = MSM_NAND_GENP_REG0;
7061 +       cmd->len = 16;
7062 +       cmd++;
7063 +
7064 +       /* Write the FLASH_DEV_CMD4,5,6 registers */
7065 +       cmd->cmd = 0;
7066 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
7067 +       cmd->dst = MSM_NAND_DEV_CMD4;
7068 +       cmd->len = 12;
7069 +       cmd++;
7070 +
7071 +       /* Kick the execute command */
7072 +       cmd->cmd = 0;
7073 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7074 +       cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7075 +       cmd->len = 4;
7076 +       cmd++;
7077 +
7078 +       /* Block on data ready, and read the status register */
7079 +       cmd->cmd = SRC_CRCI_NAND_DATA;
7080 +       cmd->src = MSM_NAND_SFLASHC_STATUS;
7081 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
7082 +       cmd->len = 4;
7083 +       cmd++;
7084 +
7085 +       /***************************************************************/
7086 +       /* Wait for the interrupt from the Onenand device controller   */
7087 +       /***************************************************************/
7088 +
7089 +       /* Block on cmd ready and write CMD register */
7090 +       cmd->cmd = DST_CRCI_NAND_CMD;
7091 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
7092 +       cmd->dst = MSM_NAND_SFLASHC_CMD;
7093 +       cmd->len = 4;
7094 +       cmd++;
7095 +
7096 +       /* Kick the execute command */
7097 +       cmd->cmd = 0;
7098 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7099 +       cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7100 +       cmd->len = 4;
7101 +       cmd++;
7102 +
7103 +       /* Block on data ready, and read the status register */
7104 +       cmd->cmd = SRC_CRCI_NAND_DATA;
7105 +       cmd->src = MSM_NAND_SFLASHC_STATUS;
7106 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
7107 +       cmd->len = 4;
7108 +       cmd++;
7109 +
7110 +       /***************************************************************/
7111 +       /* Read the necessary status registers from the onenand device */
7112 +       /***************************************************************/
7113 +
7114 +       /* Block on cmd ready and write CMD register */
7115 +       cmd->cmd = DST_CRCI_NAND_CMD;
7116 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
7117 +       cmd->dst = MSM_NAND_SFLASHC_CMD;
7118 +       cmd->len = 4;
7119 +       cmd++;
7120 +
7121 +       /* Kick the execute command */
7122 +       cmd->cmd = 0;
7123 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7124 +       cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7125 +       cmd->len = 4;
7126 +       cmd++;
7127 +
7128 +       /* Block on data ready, and read the status register */
7129 +       cmd->cmd = SRC_CRCI_NAND_DATA;
7130 +       cmd->src = MSM_NAND_SFLASHC_STATUS;
7131 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
7132 +       cmd->len = 4;
7133 +       cmd++;
7134 +
7135 +       /* Read the GENP3 register */
7136 +       cmd->cmd = 0;
7137 +       cmd->src = MSM_NAND_GENP_REG3;
7138 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
7139 +       cmd->len = 4;
7140 +       cmd++;
7141 +
7142 +       /* Read the DEVCMD4 register */
7143 +       cmd->cmd = 0;
7144 +       cmd->src = MSM_NAND_DEV_CMD4;
7145 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
7146 +       cmd->len = 4;
7147 +       cmd++;
7148 +
7149 +       /***************************************************************/
7150 +       /* Restore the necessary registers to proper values            */
7151 +       /***************************************************************/
7152 +
7153 +       /* Block on cmd ready and write CMD register */
7154 +       cmd->cmd = DST_CRCI_NAND_CMD;
7155 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
7156 +       cmd->dst = MSM_NAND_SFLASHC_CMD;
7157 +       cmd->len = 4;
7158 +       cmd++;
7159 +
7160 +       /* Kick the execute command */
7161 +       cmd->cmd = 0;
7162 +       cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7163 +       cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7164 +       cmd->len = 4;
7165 +       cmd++;
7166 +
7167 +       /* Block on data ready, and read the status register */
7168 +       cmd->cmd = SRC_CRCI_NAND_DATA;
7169 +       cmd->src = MSM_NAND_SFLASHC_STATUS;
7170 +       cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
7171 +       cmd->len = 4;
7172 +       cmd++;
7173 +
7174 +
7175 +       BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
7176 +       BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
7177 +       dma_buffer->cmd[0].cmd |= CMD_OCB;
7178 +       cmd[-1].cmd |= CMD_OCU | CMD_LC;
7179 +
7180 +       dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
7181 +                       >> 3) | CMD_PTR_LP;
7182 +
7183 +       mb();
7184 +       msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
7185 +                       | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
7186 +                       &dma_buffer->cmdptr)));
7187 +       mb();
7188 +
7189 +       ecc_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
7190 +       interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
7191 +       controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
7192 +
7193 +#if VERBOSE
7194 +       pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
7195 +                               dma_buffer->data.sfstat[0],
7196 +                               dma_buffer->data.sfstat[1],
7197 +                               dma_buffer->data.sfstat[2],
7198 +                               dma_buffer->data.sfstat[3]);
7199 +
7200 +       pr_info("%s: controller_status = %x\n", __func__,
7201 +                               controller_status);
7202 +       pr_info("%s: interrupt_status = %x\n", __func__,
7203 +                               interrupt_status);
7204 +       pr_info("%s: ecc_status = %x\n", __func__,
7205 +                               ecc_status);
7206 +#endif
7207 +       /* Check for errors, protection violations etc */
7208 +       if ((controller_status != 0)
7209 +                       || (dma_buffer->data.sfstat[0] & 0x110)
7210 +                       || (dma_buffer->data.sfstat[1] & 0x110)
7211 +                       || (dma_buffer->data.sfstat[2] & 0x110)
7212 +                       || (dma_buffer->data.sfstat[3] & 0x110)) {
7213 +               pr_err("%s: ECC/MPU/OP error\n", __func__);
7214 +               err = -EIO;
7215 +       }
7216 +
7217 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
7218 +
7219 +       if (err) {
7220 +               pr_err("%s: Erase failed, 0x%llx\n", __func__,
7221 +                               instr->addr);
7222 +               instr->fail_addr = instr->addr;
7223 +               instr->state = MTD_ERASE_FAILED;
7224 +       } else {
7225 +               instr->state = MTD_ERASE_DONE;
7226 +               instr->fail_addr = 0xffffffff;
7227 +               mtd_erase_callback(instr);
7228 +       }
7229 +
7230 +#if VERBOSE
7231 +       pr_info("\n%s: ret %d\n", __func__, err);
7232 +       pr_info("===================================================="
7233 +                       "=============\n");
7234 +#endif
7235 +       return err;
7236 +}
7237 +
7238 +static int msm_onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
7239 +{
7240 +       struct mtd_oob_ops ops;
7241 +       int rval, i;
7242 +       int ret = 0;
7243 +       uint8_t *buffer;
7244 +       uint8_t *oobptr;
7245 +
7246 +       if ((ofs > mtd->size) || (ofs & (mtd->erasesize - 1))) {
7247 +               pr_err("%s: unsupported block address, 0x%x\n",
7248 +                        __func__, (uint32_t)ofs);
7249 +               return -EINVAL;
7250 +       }
7251 +
7252 +       buffer = kmalloc(2112, GFP_KERNEL|GFP_DMA);
7253 +       if (buffer == 0) {
7254 +               pr_err("%s: Could not kmalloc for buffer\n",
7255 +                               __func__);
7256 +               return -ENOMEM;
7257 +       }
7258 +
7259 +       memset(buffer, 0x00, 2112);
7260 +       oobptr = &(buffer[2048]);
7261 +
7262 +       ops.mode = MTD_OPS_RAW;
7263 +       ops.len = 2112;
7264 +       ops.retlen = 0;
7265 +       ops.ooblen = 0;
7266 +       ops.oobretlen = 0;
7267 +       ops.ooboffs = 0;
7268 +       ops.datbuf = buffer;
7269 +       ops.oobbuf = NULL;
7270 +
7271 +       for (i = 0; i < 2; i++) {
7272 +               ofs = ofs + i*mtd->writesize;
7273 +               rval = msm_onenand_read_oob(mtd, ofs, &ops);
7274 +               if (rval) {
7275 +                       pr_err("%s: Error in reading bad blk info\n",
7276 +                                       __func__);
7277 +                       ret = rval;
7278 +                       break;
7279 +               }
7280 +               if ((oobptr[0] != 0xFF) || (oobptr[1] != 0xFF) ||
7281 +                   (oobptr[16] != 0xFF) || (oobptr[17] != 0xFF) ||
7282 +                   (oobptr[32] != 0xFF) || (oobptr[33] != 0xFF) ||
7283 +                   (oobptr[48] != 0xFF) || (oobptr[49] != 0xFF)
7284 +                  ) {
7285 +                       ret = 1;
7286 +                       break;
7287 +               }
7288 +       }
7289 +
7290 +       kfree(buffer);
7291 +
7292 +#if VERBOSE
7293 +       if (ret == 1)
7294 +               pr_info("%s : Block containing 0x%x is bad\n",
7295 +                               __func__, (unsigned int)ofs);
7296 +#endif
7297 +       return ret;
7298 +}
7299 +
7300 +static int msm_onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
7301 +{
7302 +       struct mtd_oob_ops ops;
7303 +       int rval, i;
7304 +       int ret = 0;
7305 +       uint8_t *buffer;
7306 +
7307 +       if ((ofs > mtd->size) || (ofs & (mtd->erasesize - 1))) {
7308 +               pr_err("%s: unsupported block address, 0x%x\n",
7309 +                        __func__, (uint32_t)ofs);
7310 +               return -EINVAL;
7311 +       }
7312 +
7313 +       buffer = page_address(ZERO_PAGE());
7314 +
7315 +       ops.mode = MTD_OPS_RAW;
7316 +       ops.len = 2112;
7317 +       ops.retlen = 0;
7318 +       ops.ooblen = 0;
7319 +       ops.oobretlen = 0;
7320 +       ops.ooboffs = 0;
7321 +       ops.datbuf = buffer;
7322 +       ops.oobbuf = NULL;
7323 +
7324 +       for (i = 0; i < 2; i++) {
7325 +               ofs = ofs + i*mtd->writesize;
7326 +               rval = msm_onenand_write_oob(mtd, ofs, &ops);
7327 +               if (rval) {
7328 +                       pr_err("%s: Error in writing bad blk info\n",
7329 +                                       __func__);
7330 +                       ret = rval;
7331 +                       break;
7332 +               }
7333 +       }
7334 +
7335 +       return ret;
7336 +}
7337 +
7338 +static int msm_onenand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
7339 +{
7340 +       struct msm_nand_chip *chip = mtd->priv;
7341 +
7342 +       struct {
7343 +               dmov_s cmd[20];
7344 +               unsigned cmdptr;
7345 +               struct {
7346 +                       uint32_t sfbcfg;
7347 +                       uint32_t sfcmd[4];
7348 +                       uint32_t sfexec;
7349 +                       uint32_t sfstat[4];
7350 +                       uint32_t addr0;
7351 +                       uint32_t addr1;
7352 +                       uint32_t addr2;
7353 +                       uint32_t addr3;
7354 +                       uint32_t addr4;
7355 +                       uint32_t addr5;
7356 +                       uint32_t addr6;
7357 +                       uint32_t data0;
7358 +                       uint32_t data1;
7359 +                       uint32_t data2;
7360 +                       uint32_t data3;
7361 +                       uint32_t data4;
7362 +                       uint32_t data5;
7363 +                       uint32_t data6;
7364 +               } data;
7365 +       } *dma_buffer;
7366 +       dmov_s *cmd;
7367 +
7368 +       int err = 0;
7369 +
7370 +       uint16_t onenand_startaddr1;
7371 +       uint16_t onenand_startaddr8;
7372 +       uint16_t onenand_startaddr2;
7373 +       uint16_t onenand_startblock;
7374 +
7375 +       uint16_t controller_status;
7376 +       uint16_t interrupt_status;
7377 +       uint16_t write_prot_status;
7378 +
7379 +       uint64_t start_ofs;
7380 +
7381 +#if VERBOSE
7382 +       pr_info("===================================================="
7383 +                       "=============\n");
7384 +       pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
7385 +#endif
7386 +       /* 'ofs' & 'len' should align to block size */
7387 +       if (ofs&(mtd->erasesize - 1)) {
7388 +               pr_err("%s: Unsupported ofs address, 0x%llx\n",
7389 +                               __func__, ofs);
7390 +               return -EINVAL;
7391 +       }
7392 +
7393 +       if (len&(mtd->erasesize - 1)) {
7394 +               pr_err("%s: Unsupported len, %lld\n",
7395 +                               __func__, len);
7396 +               return -EINVAL;
7397 +       }
7398 +
7399 +       if (ofs+len > mtd->size) {
7400 +               pr_err("%s: Maximum chip size exceeded\n", __func__);
7401 +               return -EINVAL;
7402 +       }
7403 +
7404 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
7405 +                               (chip, sizeof(*dma_buffer))));
7406 +
7407 +       for (start_ofs = ofs; ofs < start_ofs+len; ofs = ofs+mtd->erasesize) {
7408 +#if VERBOSE
7409 +               pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
7410 +#endif
7411 +
7412 +               cmd = dma_buffer->cmd;
7413 +               if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
7414 +                       && (ofs >= (mtd->size>>1))) { /* DDP Device */
7415 +                       onenand_startaddr1 = DEVICE_FLASHCORE_1 |
7416 +                               (((uint32_t)(ofs - (mtd->size>>1))
7417 +                                               / mtd->erasesize));
7418 +                       onenand_startaddr2 = DEVICE_BUFFERRAM_1;
7419 +                       onenand_startblock = ((uint32_t)(ofs - (mtd->size>>1))
7420 +                                               / mtd->erasesize);
7421 +               } else {
7422 +                       onenand_startaddr1 = DEVICE_FLASHCORE_0 |
7423 +                                       ((uint32_t)ofs / mtd->erasesize) ;
7424 +                       onenand_startaddr2 = DEVICE_BUFFERRAM_0;
7425 +                       onenand_startblock = ((uint32_t)ofs
7426 +                                               / mtd->erasesize);
7427 +               }
7428 +
7429 +               onenand_startaddr8 = 0x0000;
7430 +               dma_buffer->data.sfbcfg = SFLASH_BCFG |
7431 +                                       (nand_sfcmd_mode ? 0 : (1 << 24));
7432 +               dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
7433 +                                                       MSM_NAND_SFCMD_CMDXS,
7434 +                                                       nand_sfcmd_mode,
7435 +                                                       MSM_NAND_SFCMD_REGWR);
7436 +               dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
7437 +                                                       MSM_NAND_SFCMD_CMDXS,
7438 +                                                       nand_sfcmd_mode,
7439 +                                                       MSM_NAND_SFCMD_INTHI);
7440 +               dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
7441 +                                                       MSM_NAND_SFCMD_DATXS,
7442 +                                                       nand_sfcmd_mode,
7443 +                                                       MSM_NAND_SFCMD_REGRD);
7444 +               dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
7445 +                                                       MSM_NAND_SFCMD_CMDXS,
7446 +                                                       nand_sfcmd_mode,
7447 +                                                       MSM_NAND_SFCMD_REGWR);
7448 +               dma_buffer->data.sfexec = 1;
7449 +               dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
7450 +               dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
7451 +               dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
7452 +               dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
7453 +               dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
7454 +                                               (ONENAND_SYSTEM_CONFIG_1);
7455 +               dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
7456 +                                               (ONENAND_START_ADDRESS_1);
7457 +               dma_buffer->data.addr2 = (ONENAND_START_BLOCK_ADDRESS << 16) |
7458 +                                               (ONENAND_START_ADDRESS_2);
7459 +               dma_buffer->data.addr3 = (ONENAND_WRITE_PROT_STATUS << 16) |
7460 +                                               (ONENAND_COMMAND);
7461 +               dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
7462 +                                               (ONENAND_INTERRUPT_STATUS);
7463 +               dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
7464 +                                               (ONENAND_SYSTEM_CONFIG_1);
7465 +               dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
7466 +                                               (ONENAND_START_ADDRESS_1);
7467 +               dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
7468 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
7469 +               dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
7470 +                                               (onenand_startaddr1);
7471 +               dma_buffer->data.data2 = (onenand_startblock << 16) |
7472 +                                               (onenand_startaddr2);
7473 +               dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
7474 +                                               (ONENAND_CMD_UNLOCK);
7475 +               dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
7476 +                                               (CLEAN_DATA_16);
7477 +               dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
7478 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
7479 +               dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
7480 +                                               (ONENAND_STARTADDR1_RES);
7481 +
7482 +               /*************************************************************/
7483 +               /* Write the necessary address reg in the onenand device     */
7484 +               /*************************************************************/
7485 +
7486 +               /* Enable and configure the SFlash controller */
7487 +               cmd->cmd = 0;
7488 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
7489 +               cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
7490 +               cmd->len = 4;
7491 +               cmd++;
7492 +
7493 +               /* Block on cmd ready and write CMD register */
7494 +               cmd->cmd = DST_CRCI_NAND_CMD;
7495 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
7496 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7497 +               cmd->len = 4;
7498 +               cmd++;
7499 +
7500 +               /* Write the ADDR0 and ADDR1 registers */
7501 +               cmd->cmd = 0;
7502 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
7503 +               cmd->dst = MSM_NAND_ADDR0;
7504 +               cmd->len = 8;
7505 +               cmd++;
7506 +
7507 +               /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
7508 +               cmd->cmd = 0;
7509 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
7510 +               cmd->dst = MSM_NAND_ADDR2;
7511 +               cmd->len = 16;
7512 +               cmd++;
7513 +
7514 +               /* Write the ADDR6 registers */
7515 +               cmd->cmd = 0;
7516 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
7517 +               cmd->dst = MSM_NAND_ADDR6;
7518 +               cmd->len = 4;
7519 +               cmd++;
7520 +
7521 +               /* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
7522 +               cmd->cmd = 0;
7523 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
7524 +               cmd->dst = MSM_NAND_GENP_REG0;
7525 +               cmd->len = 16;
7526 +               cmd++;
7527 +
7528 +               /* Write the FLASH_DEV_CMD4,5,6 registers */
7529 +               cmd->cmd = 0;
7530 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
7531 +               cmd->dst = MSM_NAND_DEV_CMD4;
7532 +               cmd->len = 12;
7533 +               cmd++;
7534 +
7535 +               /* Kick the execute command */
7536 +               cmd->cmd = 0;
7537 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7538 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7539 +               cmd->len = 4;
7540 +               cmd++;
7541 +
7542 +               /* Block on data ready, and read the status register */
7543 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7544 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7545 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
7546 +               cmd->len = 4;
7547 +               cmd++;
7548 +
7549 +               /*************************************************************/
7550 +               /* Wait for the interrupt from the Onenand device controller */
7551 +               /*************************************************************/
7552 +
7553 +               /* Block on cmd ready and write CMD register */
7554 +               cmd->cmd = DST_CRCI_NAND_CMD;
7555 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
7556 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7557 +               cmd->len = 4;
7558 +               cmd++;
7559 +
7560 +               /* Kick the execute command */
7561 +               cmd->cmd = 0;
7562 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7563 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7564 +               cmd->len = 4;
7565 +               cmd++;
7566 +
7567 +               /* Block on data ready, and read the status register */
7568 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7569 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7570 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
7571 +               cmd->len = 4;
7572 +               cmd++;
7573 +
7574 +               /*********************************************************/
7575 +               /* Read the necessary status reg from the onenand device */
7576 +               /*********************************************************/
7577 +
7578 +               /* Block on cmd ready and write CMD register */
7579 +               cmd->cmd = DST_CRCI_NAND_CMD;
7580 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
7581 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7582 +               cmd->len = 4;
7583 +               cmd++;
7584 +
7585 +               /* Kick the execute command */
7586 +               cmd->cmd = 0;
7587 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7588 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7589 +               cmd->len = 4;
7590 +               cmd++;
7591 +
7592 +               /* Block on data ready, and read the status register */
7593 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7594 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7595 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
7596 +               cmd->len = 4;
7597 +               cmd++;
7598 +
7599 +               /* Read the GENP3 register */
7600 +               cmd->cmd = 0;
7601 +               cmd->src = MSM_NAND_GENP_REG3;
7602 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
7603 +               cmd->len = 4;
7604 +               cmd++;
7605 +
7606 +               /* Read the DEVCMD4 register */
7607 +               cmd->cmd = 0;
7608 +               cmd->src = MSM_NAND_DEV_CMD4;
7609 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
7610 +               cmd->len = 4;
7611 +               cmd++;
7612 +
7613 +               /************************************************************/
7614 +               /* Restore the necessary registers to proper values         */
7615 +               /************************************************************/
7616 +
7617 +               /* Block on cmd ready and write CMD register */
7618 +               cmd->cmd = DST_CRCI_NAND_CMD;
7619 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
7620 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7621 +               cmd->len = 4;
7622 +               cmd++;
7623 +
7624 +               /* Kick the execute command */
7625 +               cmd->cmd = 0;
7626 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7627 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7628 +               cmd->len = 4;
7629 +               cmd++;
7630 +
7631 +               /* Block on data ready, and read the status register */
7632 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7633 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7634 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
7635 +               cmd->len = 4;
7636 +               cmd++;
7637 +
7638 +
7639 +               BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
7640 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
7641 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
7642 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
7643 +
7644 +               dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
7645 +                               >> 3) | CMD_PTR_LP;
7646 +
7647 +               mb();
7648 +               msm_dmov_exec_cmd(chip->dma_channel,
7649 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
7650 +                               &dma_buffer->cmdptr)));
7651 +               mb();
7652 +
7653 +               write_prot_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
7654 +               interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
7655 +               controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
7656 +
7657 +#if VERBOSE
7658 +               pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
7659 +                                       dma_buffer->data.sfstat[0],
7660 +                                       dma_buffer->data.sfstat[1],
7661 +                                       dma_buffer->data.sfstat[2],
7662 +                                       dma_buffer->data.sfstat[3]);
7663 +
7664 +               pr_info("%s: controller_status = %x\n", __func__,
7665 +                                       controller_status);
7666 +               pr_info("%s: interrupt_status = %x\n", __func__,
7667 +                                       interrupt_status);
7668 +               pr_info("%s: write_prot_status = %x\n", __func__,
7669 +                                       write_prot_status);
7670 +#endif
7671 +               /* Check for errors, protection violations etc */
7672 +               if ((controller_status != 0)
7673 +                               || (dma_buffer->data.sfstat[0] & 0x110)
7674 +                               || (dma_buffer->data.sfstat[1] & 0x110)
7675 +                               || (dma_buffer->data.sfstat[2] & 0x110)
7676 +                               || (dma_buffer->data.sfstat[3] & 0x110)) {
7677 +                       pr_err("%s: ECC/MPU/OP error\n", __func__);
7678 +                       err = -EIO;
7679 +               }
7680 +
7681 +               if (!(write_prot_status & ONENAND_WP_US)) {
7682 +                       pr_err("%s: Unexpected status ofs = 0x%llx,"
7683 +                               "wp_status = %x\n",
7684 +                               __func__, ofs, write_prot_status);
7685 +                       err = -EIO;
7686 +               }
7687 +
7688 +               if (err)
7689 +                       break;
7690 +       }
7691 +
7692 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
7693 +
7694 +#if VERBOSE
7695 +       pr_info("\n%s: ret %d\n", __func__, err);
7696 +       pr_info("===================================================="
7697 +                       "=============\n");
7698 +#endif
7699 +       return err;
7700 +}
7701 +
7702 +static int msm_onenand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
7703 +{
7704 +       struct msm_nand_chip *chip = mtd->priv;
7705 +
7706 +       struct {
7707 +               dmov_s cmd[20];
7708 +               unsigned cmdptr;
7709 +               struct {
7710 +                       uint32_t sfbcfg;
7711 +                       uint32_t sfcmd[4];
7712 +                       uint32_t sfexec;
7713 +                       uint32_t sfstat[4];
7714 +                       uint32_t addr0;
7715 +                       uint32_t addr1;
7716 +                       uint32_t addr2;
7717 +                       uint32_t addr3;
7718 +                       uint32_t addr4;
7719 +                       uint32_t addr5;
7720 +                       uint32_t addr6;
7721 +                       uint32_t data0;
7722 +                       uint32_t data1;
7723 +                       uint32_t data2;
7724 +                       uint32_t data3;
7725 +                       uint32_t data4;
7726 +                       uint32_t data5;
7727 +                       uint32_t data6;
7728 +               } data;
7729 +       } *dma_buffer;
7730 +       dmov_s *cmd;
7731 +
7732 +       int err = 0;
7733 +
7734 +       uint16_t onenand_startaddr1;
7735 +       uint16_t onenand_startaddr8;
7736 +       uint16_t onenand_startaddr2;
7737 +       uint16_t onenand_startblock;
7738 +
7739 +       uint16_t controller_status;
7740 +       uint16_t interrupt_status;
7741 +       uint16_t write_prot_status;
7742 +
7743 +       uint64_t start_ofs;
7744 +
7745 +#if VERBOSE
7746 +       pr_info("===================================================="
7747 +                       "=============\n");
7748 +       pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
7749 +#endif
7750 +       /* 'ofs' & 'len' should align to block size */
7751 +       if (ofs&(mtd->erasesize - 1)) {
7752 +               pr_err("%s: Unsupported ofs address, 0x%llx\n",
7753 +                               __func__, ofs);
7754 +               return -EINVAL;
7755 +       }
7756 +
7757 +       if (len&(mtd->erasesize - 1)) {
7758 +               pr_err("%s: Unsupported len, %lld\n",
7759 +                               __func__, len);
7760 +               return -EINVAL;
7761 +       }
7762 +
7763 +       if (ofs+len > mtd->size) {
7764 +               pr_err("%s: Maximum chip size exceeded\n", __func__);
7765 +               return -EINVAL;
7766 +       }
7767 +
7768 +       wait_event(chip->wait_queue, (dma_buffer = msm_nand_get_dma_buffer
7769 +                               (chip, sizeof(*dma_buffer))));
7770 +
7771 +       for (start_ofs = ofs; ofs < start_ofs+len; ofs = ofs+mtd->erasesize) {
7772 +#if VERBOSE
7773 +               pr_info("%s: ofs 0x%llx len %lld\n", __func__, ofs, len);
7774 +#endif
7775 +
7776 +               cmd = dma_buffer->cmd;
7777 +               if ((onenand_info.device_id & ONENAND_DEVICE_IS_DDP)
7778 +                       && (ofs >= (mtd->size>>1))) { /* DDP Device */
7779 +                       onenand_startaddr1 = DEVICE_FLASHCORE_1 |
7780 +                               (((uint32_t)(ofs - (mtd->size>>1))
7781 +                                               / mtd->erasesize));
7782 +                       onenand_startaddr2 = DEVICE_BUFFERRAM_1;
7783 +                       onenand_startblock = ((uint32_t)(ofs - (mtd->size>>1))
7784 +                                               / mtd->erasesize);
7785 +               } else {
7786 +                       onenand_startaddr1 = DEVICE_FLASHCORE_0 |
7787 +                                       ((uint32_t)ofs / mtd->erasesize) ;
7788 +                       onenand_startaddr2 = DEVICE_BUFFERRAM_0;
7789 +                       onenand_startblock = ((uint32_t)ofs
7790 +                                               / mtd->erasesize);
7791 +               }
7792 +
7793 +               onenand_startaddr8 = 0x0000;
7794 +               dma_buffer->data.sfbcfg = SFLASH_BCFG |
7795 +                                       (nand_sfcmd_mode ? 0 : (1 << 24));
7796 +               dma_buffer->data.sfcmd[0] = SFLASH_PREPCMD(7, 0, 0,
7797 +                                                       MSM_NAND_SFCMD_CMDXS,
7798 +                                                       nand_sfcmd_mode,
7799 +                                                       MSM_NAND_SFCMD_REGWR);
7800 +               dma_buffer->data.sfcmd[1] = SFLASH_PREPCMD(0, 0, 32,
7801 +                                                       MSM_NAND_SFCMD_CMDXS,
7802 +                                                       nand_sfcmd_mode,
7803 +                                                       MSM_NAND_SFCMD_INTHI);
7804 +               dma_buffer->data.sfcmd[2] = SFLASH_PREPCMD(3, 7, 0,
7805 +                                                       MSM_NAND_SFCMD_DATXS,
7806 +                                                       nand_sfcmd_mode,
7807 +                                                       MSM_NAND_SFCMD_REGRD);
7808 +               dma_buffer->data.sfcmd[3] = SFLASH_PREPCMD(4, 10, 0,
7809 +                                                       MSM_NAND_SFCMD_CMDXS,
7810 +                                                       nand_sfcmd_mode,
7811 +                                                       MSM_NAND_SFCMD_REGWR);
7812 +               dma_buffer->data.sfexec = 1;
7813 +               dma_buffer->data.sfstat[0] = CLEAN_DATA_32;
7814 +               dma_buffer->data.sfstat[1] = CLEAN_DATA_32;
7815 +               dma_buffer->data.sfstat[2] = CLEAN_DATA_32;
7816 +               dma_buffer->data.sfstat[3] = CLEAN_DATA_32;
7817 +               dma_buffer->data.addr0 = (ONENAND_INTERRUPT_STATUS << 16) |
7818 +                                               (ONENAND_SYSTEM_CONFIG_1);
7819 +               dma_buffer->data.addr1 = (ONENAND_START_ADDRESS_8 << 16) |
7820 +                                               (ONENAND_START_ADDRESS_1);
7821 +               dma_buffer->data.addr2 = (ONENAND_START_BLOCK_ADDRESS << 16) |
7822 +                                               (ONENAND_START_ADDRESS_2);
7823 +               dma_buffer->data.addr3 = (ONENAND_WRITE_PROT_STATUS << 16) |
7824 +                                               (ONENAND_COMMAND);
7825 +               dma_buffer->data.addr4 = (ONENAND_CONTROLLER_STATUS << 16) |
7826 +                                               (ONENAND_INTERRUPT_STATUS);
7827 +               dma_buffer->data.addr5 = (ONENAND_INTERRUPT_STATUS << 16) |
7828 +                                               (ONENAND_SYSTEM_CONFIG_1);
7829 +               dma_buffer->data.addr6 = (ONENAND_START_ADDRESS_3 << 16) |
7830 +                                               (ONENAND_START_ADDRESS_1);
7831 +               dma_buffer->data.data0 = (ONENAND_CLRINTR << 16) |
7832 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
7833 +               dma_buffer->data.data1 = (onenand_startaddr8 << 16) |
7834 +                                               (onenand_startaddr1);
7835 +               dma_buffer->data.data2 = (onenand_startblock << 16) |
7836 +                                               (onenand_startaddr2);
7837 +               dma_buffer->data.data3 = (CLEAN_DATA_16 << 16) |
7838 +                                               (ONENAND_CMD_LOCK);
7839 +               dma_buffer->data.data4 = (CLEAN_DATA_16 << 16) |
7840 +                                               (CLEAN_DATA_16);
7841 +               dma_buffer->data.data5 = (ONENAND_CLRINTR << 16) |
7842 +                               (ONENAND_SYSCFG1_ECCENA(nand_sfcmd_mode));
7843 +               dma_buffer->data.data6 = (ONENAND_STARTADDR3_RES << 16) |
7844 +                                               (ONENAND_STARTADDR1_RES);
7845 +
7846 +               /*************************************************************/
7847 +               /* Write the necessary address reg in the onenand device     */
7848 +               /*************************************************************/
7849 +
7850 +               /* Enable and configure the SFlash controller */
7851 +               cmd->cmd = 0;
7852 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfbcfg);
7853 +               cmd->dst = MSM_NAND_SFLASHC_BURST_CFG;
7854 +               cmd->len = 4;
7855 +               cmd++;
7856 +
7857 +               /* Block on cmd ready and write CMD register */
7858 +               cmd->cmd = DST_CRCI_NAND_CMD;
7859 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[0]);
7860 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7861 +               cmd->len = 4;
7862 +               cmd++;
7863 +
7864 +               /* Write the ADDR0 and ADDR1 registers */
7865 +               cmd->cmd = 0;
7866 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr0);
7867 +               cmd->dst = MSM_NAND_ADDR0;
7868 +               cmd->len = 8;
7869 +               cmd++;
7870 +
7871 +               /* Write the ADDR2 ADDR3 ADDR4 ADDR5 registers */
7872 +               cmd->cmd = 0;
7873 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr2);
7874 +               cmd->dst = MSM_NAND_ADDR2;
7875 +               cmd->len = 16;
7876 +               cmd++;
7877 +
7878 +               /* Write the ADDR6 registers */
7879 +               cmd->cmd = 0;
7880 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.addr6);
7881 +               cmd->dst = MSM_NAND_ADDR6;
7882 +               cmd->len = 4;
7883 +               cmd++;
7884 +
7885 +               /* Write the GENP0, GENP1, GENP2, GENP3, GENP4 registers */
7886 +               cmd->cmd = 0;
7887 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data0);
7888 +               cmd->dst = MSM_NAND_GENP_REG0;
7889 +               cmd->len = 16;
7890 +               cmd++;
7891 +
7892 +               /* Write the FLASH_DEV_CMD4,5,6 registers */
7893 +               cmd->cmd = 0;
7894 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.data4);
7895 +               cmd->dst = MSM_NAND_DEV_CMD4;
7896 +               cmd->len = 12;
7897 +               cmd++;
7898 +
7899 +               /* Kick the execute command */
7900 +               cmd->cmd = 0;
7901 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7902 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7903 +               cmd->len = 4;
7904 +               cmd++;
7905 +
7906 +               /* Block on data ready, and read the status register */
7907 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7908 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7909 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[0]);
7910 +               cmd->len = 4;
7911 +               cmd++;
7912 +
7913 +               /*************************************************************/
7914 +               /* Wait for the interrupt from the Onenand device controller */
7915 +               /*************************************************************/
7916 +
7917 +               /* Block on cmd ready and write CMD register */
7918 +               cmd->cmd = DST_CRCI_NAND_CMD;
7919 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[1]);
7920 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7921 +               cmd->len = 4;
7922 +               cmd++;
7923 +
7924 +               /* Kick the execute command */
7925 +               cmd->cmd = 0;
7926 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7927 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7928 +               cmd->len = 4;
7929 +               cmd++;
7930 +
7931 +               /* Block on data ready, and read the status register */
7932 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7933 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7934 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[1]);
7935 +               cmd->len = 4;
7936 +               cmd++;
7937 +
7938 +               /*********************************************************/
7939 +               /* Read the necessary status reg from the onenand device */
7940 +               /*********************************************************/
7941 +
7942 +               /* Block on cmd ready and write CMD register */
7943 +               cmd->cmd = DST_CRCI_NAND_CMD;
7944 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[2]);
7945 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7946 +               cmd->len = 4;
7947 +               cmd++;
7948 +
7949 +               /* Kick the execute command */
7950 +               cmd->cmd = 0;
7951 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7952 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7953 +               cmd->len = 4;
7954 +               cmd++;
7955 +
7956 +               /* Block on data ready, and read the status register */
7957 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7958 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7959 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[2]);
7960 +               cmd->len = 4;
7961 +               cmd++;
7962 +
7963 +               /* Read the GENP3 register */
7964 +               cmd->cmd = 0;
7965 +               cmd->src = MSM_NAND_GENP_REG3;
7966 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data3);
7967 +               cmd->len = 4;
7968 +               cmd++;
7969 +
7970 +               /* Read the DEVCMD4 register */
7971 +               cmd->cmd = 0;
7972 +               cmd->src = MSM_NAND_DEV_CMD4;
7973 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.data4);
7974 +               cmd->len = 4;
7975 +               cmd++;
7976 +
7977 +               /************************************************************/
7978 +               /* Restore the necessary registers to proper values         */
7979 +               /************************************************************/
7980 +
7981 +               /* Block on cmd ready and write CMD register */
7982 +               cmd->cmd = DST_CRCI_NAND_CMD;
7983 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfcmd[3]);
7984 +               cmd->dst = MSM_NAND_SFLASHC_CMD;
7985 +               cmd->len = 4;
7986 +               cmd++;
7987 +
7988 +               /* Kick the execute command */
7989 +               cmd->cmd = 0;
7990 +               cmd->src = msm_virt_to_dma(chip, &dma_buffer->data.sfexec);
7991 +               cmd->dst = MSM_NAND_SFLASHC_EXEC_CMD;
7992 +               cmd->len = 4;
7993 +               cmd++;
7994 +
7995 +               /* Block on data ready, and read the status register */
7996 +               cmd->cmd = SRC_CRCI_NAND_DATA;
7997 +               cmd->src = MSM_NAND_SFLASHC_STATUS;
7998 +               cmd->dst = msm_virt_to_dma(chip, &dma_buffer->data.sfstat[3]);
7999 +               cmd->len = 4;
8000 +               cmd++;
8001 +
8002 +
8003 +               BUILD_BUG_ON(20 != ARRAY_SIZE(dma_buffer->cmd));
8004 +               BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
8005 +               dma_buffer->cmd[0].cmd |= CMD_OCB;
8006 +               cmd[-1].cmd |= CMD_OCU | CMD_LC;
8007 +
8008 +               dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd)
8009 +                               >> 3) | CMD_PTR_LP;
8010 +
8011 +               mb();
8012 +               msm_dmov_exec_cmd(chip->dma_channel,
8013 +                       DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
8014 +                               &dma_buffer->cmdptr)));
8015 +               mb();
8016 +
8017 +               write_prot_status = (dma_buffer->data.data3 >> 16) & 0x0000FFFF;
8018 +               interrupt_status = (dma_buffer->data.data4 >> 0) & 0x0000FFFF;
8019 +               controller_status = (dma_buffer->data.data4 >> 16) & 0x0000FFFF;
8020 +
8021 +#if VERBOSE
8022 +               pr_info("\n%s: sflash status %x %x %x %x\n", __func__,
8023 +                                       dma_buffer->data.sfstat[0],
8024 +                                       dma_buffer->data.sfstat[1],
8025 +                                       dma_buffer->data.sfstat[2],
8026 +                                       dma_buffer->data.sfstat[3]);
8027 +
8028 +               pr_info("%s: controller_status = %x\n", __func__,
8029 +                                       controller_status);
8030 +               pr_info("%s: interrupt_status = %x\n", __func__,
8031 +                                       interrupt_status);
8032 +               pr_info("%s: write_prot_status = %x\n", __func__,
8033 +                                       write_prot_status);
8034 +#endif
8035 +               /* Check for errors, protection violations etc */
8036 +               if ((controller_status != 0)
8037 +                               || (dma_buffer->data.sfstat[0] & 0x110)
8038 +                               || (dma_buffer->data.sfstat[1] & 0x110)
8039 +                               || (dma_buffer->data.sfstat[2] & 0x110)
8040 +                               || (dma_buffer->data.sfstat[3] & 0x110)) {
8041 +                       pr_err("%s: ECC/MPU/OP error\n", __func__);
8042 +                       err = -EIO;
8043 +               }
8044 +
8045 +               if (!(write_prot_status & ONENAND_WP_LS)) {
8046 +                       pr_err("%s: Unexpected status ofs = 0x%llx,"
8047 +                               "wp_status = %x\n",
8048 +                               __func__, ofs, write_prot_status);
8049 +                       err = -EIO;
8050 +               }
8051 +
8052 +               if (err)
8053 +                       break;
8054 +       }
8055 +
8056 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
8057 +
8058 +#if VERBOSE
8059 +       pr_info("\n%s: ret %d\n", __func__, err);
8060 +       pr_info("===================================================="
8061 +                       "=============\n");
8062 +#endif
8063 +       return err;
8064 +}
8065 +
8066 +static int msm_onenand_suspend(struct mtd_info *mtd)
8067 +{
8068 +       return 0;
8069 +}
8070 +
8071 +static void msm_onenand_resume(struct mtd_info *mtd)
8072 +{
8073 +}
8074 +
8075 +int msm_onenand_scan(struct mtd_info *mtd, int maxchips)
8076 +{
8077 +       struct msm_nand_chip *chip = mtd->priv;
8078 +
8079 +       /* Probe and check whether onenand device is present */
8080 +       if (flash_onenand_probe(chip))
8081 +               return -ENODEV;
8082 +
8083 +       mtd->size = 0x1000000 << ((onenand_info.device_id & 0xF0) >> 4);
8084 +       mtd->writesize = onenand_info.data_buf_size;
8085 +       mtd->oobsize = mtd->writesize >> 5;
8086 +       mtd->erasesize = mtd->writesize << 6;
8087 +       mtd->oobavail = msm_onenand_oob_64.oobavail;
8088 +       mtd->ecclayout = &msm_onenand_oob_64;
8089 +
8090 +       mtd->type = MTD_NANDFLASH;
8091 +       mtd->flags = MTD_CAP_NANDFLASH;
8092 +       mtd->_erase = msm_onenand_erase;
8093 +       mtd->_point = NULL;
8094 +       mtd->_unpoint = NULL;
8095 +       mtd->_read = msm_onenand_read;
8096 +       mtd->_write = msm_onenand_write;
8097 +       mtd->_read_oob = msm_onenand_read_oob;
8098 +       mtd->_write_oob = msm_onenand_write_oob;
8099 +       mtd->_lock = msm_onenand_lock;
8100 +       mtd->_unlock = msm_onenand_unlock;
8101 +       mtd->_suspend = msm_onenand_suspend;
8102 +       mtd->_resume = msm_onenand_resume;
8103 +       mtd->_block_isbad = msm_onenand_block_isbad;
8104 +       mtd->_block_markbad = msm_onenand_block_markbad;
8105 +       mtd->owner = THIS_MODULE;
8106 +
8107 +       pr_info("Found a supported onenand device\n");
8108 +
8109 +       return 0;
8110 +}
8111 +
8112 +static const unsigned int bch_sup_cntrl[] = {
8113 +       0x307, /* MSM7x2xA */
8114 +       0x4030, /* MDM 9x15 */
8115 +};
8116 +
8117 +static inline bool msm_nand_has_bch_ecc_engine(unsigned int hw_id)
8118 +{
8119 +       int i;
8120 +
8121 +       for (i = 0; i < ARRAY_SIZE(bch_sup_cntrl); i++) {
8122 +               if (hw_id == bch_sup_cntrl[i])
8123 +                       return true;
8124 +       }
8125 +
8126 +       return false;
8127 +}
8128 +
8129 +/**
8130 + * msm_nand_scan - [msm_nand Interface] Scan for the msm_nand device
8131 + * @param mtd          MTD device structure
8132 + * @param maxchips     Number of chips to scan for
8133 + *
8134 + * This fills out all the not initialized function pointers
8135 + * with the defaults.
8136 + * The flash ID is read and the mtd/chip structures are
8137 + * filled with the appropriate values.
8138 + */
8139 +int msm_nand_scan(struct mtd_info *mtd, int maxchips)
8140 +{
8141 +       struct msm_nand_chip *chip = mtd->priv;
8142 +       uint32_t flash_id = 0, i, mtd_writesize;
8143 +       uint8_t dev_found = 0;
8144 +       uint8_t wide_bus;
8145 +       uint32_t manid;
8146 +       uint32_t devid;
8147 +       uint32_t devcfg;
8148 +       struct nand_flash_dev *flashdev = NULL;
8149 +       struct nand_manufacturers  *flashman = NULL;
8150 +       unsigned int hw_id;
8151 +
8152 +       /*
8153 +        * Some Spansion parts, like the S34MS04G2, requires that the
8154 +        * NAND Flash be reset before issuing an ONFI probe.
8155 +        */
8156 +       flash_reset(chip);
8157 +
8158 +       /* Probe the Flash device for ONFI compliance */
8159 +       if (!flash_onfi_probe(chip)) {
8160 +               dev_found = 1;
8161 +       } else {
8162 +               /* Read the Flash ID from the Nand Flash Device */
8163 +               flash_id = flash_read_id(chip);
8164 +               manid = flash_id & 0xFF;
8165 +               devid = (flash_id >> 8) & 0xFF;
8166 +               devcfg = (flash_id >> 24) & 0xFF;
8167 +
8168 +               for (i = 0; !flashman && nand_manuf_ids[i].id; ++i)
8169 +                       if (nand_manuf_ids[i].id == manid)
8170 +                               flashman = &nand_manuf_ids[i];
8171 +               for (i = 0; !flashdev && nand_flash_ids[i].id; ++i)
8172 +                       if (nand_flash_ids[i].id == devid)
8173 +                               flashdev = &nand_flash_ids[i];
8174 +               if (!flashdev || !flashman) {
8175 +                       pr_err("ERROR: unknown nand device manuf=%x devid=%x\n",
8176 +                               manid, devid);
8177 +                       return -ENOENT;
8178 +               } else
8179 +                       dev_found = 1;
8180 +
8181 +               if (!flashdev->pagesize) {
8182 +                       supported_flash.flash_id = flash_id;
8183 +                       supported_flash.density = flashdev->chipsize << 20;
8184 +                       supported_flash.widebus = devcfg & (1 << 6) ? 1 : 0;
8185 +                       supported_flash.pagesize = 1024 << (devcfg & 0x3);
8186 +                       supported_flash.blksize = (64 * 1024) <<
8187 +                                                       ((devcfg >> 4) & 0x3);
8188 +                       supported_flash.oobsize = (8 << ((devcfg >> 2) & 0x3)) *
8189 +                               (supported_flash.pagesize >> 9);
8190 +
8191 +                       if ((supported_flash.oobsize > 64) &&
8192 +                               (supported_flash.pagesize == 2048)) {
8193 +                               pr_info("msm_nand: Found a 2K page device with"
8194 +                                       " %d oobsize - changing oobsize to 64 "
8195 +                                       "bytes.\n", supported_flash.oobsize);
8196 +                               supported_flash.oobsize = 64;
8197 +                       }
8198 +               } else {
8199 +                       supported_flash.flash_id = flash_id;
8200 +                       supported_flash.density = flashdev->chipsize << 20;
8201 +                       supported_flash.widebus = flashdev->options &
8202 +                                        NAND_BUSWIDTH_16 ? 1 : 0;
8203 +                       supported_flash.pagesize = flashdev->pagesize;
8204 +                       supported_flash.blksize = flashdev->erasesize;
8205 +                       supported_flash.oobsize = flashdev->pagesize >> 5;
8206 +               }
8207 +       }
8208 +
8209 +       if (dev_found) {
8210 +               (!interleave_enable) ? (i = 1) : (i = 2);
8211 +               wide_bus       = supported_flash.widebus;
8212 +               mtd->size      = supported_flash.density  * i;
8213 +               mtd->writesize = supported_flash.pagesize * i;
8214 +               mtd->oobsize   = supported_flash.oobsize  * i;
8215 +               mtd->erasesize = supported_flash.blksize  * i;
8216 +               mtd->writebufsize = mtd->writesize;
8217 +
8218 +               if (!interleave_enable)
8219 +                       mtd_writesize = mtd->writesize;
8220 +               else
8221 +                       mtd_writesize = mtd->writesize >> 1;
8222 +
8223 +               /* Check whether controller and NAND device support 8bit ECC*/
8224 +               hw_id = flash_rd_reg(chip, MSM_NAND_HW_INFO);
8225 +               if (msm_nand_has_bch_ecc_engine(hw_id)
8226 +                               && (supported_flash.ecc_correctability >= 8)) {
8227 +                       pr_info("Found supported NAND device for %dbit ECC\n",
8228 +                                       supported_flash.ecc_correctability);
8229 +                       enable_bch_ecc = 1;
8230 +               } else {
8231 +                       pr_info("Found a supported NAND device\n");
8232 +               }
8233 +               pr_info("NAND Controller ID : 0x%x\n", hw_id);
8234 +               pr_info("NAND Device ID  : 0x%x\n", supported_flash.flash_id);
8235 +               pr_info("Buswidth : %d Bits\n", (wide_bus) ? 16 : 8);
8236 +               pr_info("Density  : %lld MByte\n", (mtd->size>>20));
8237 +               pr_info("Pagesize : %d Bytes\n", mtd->writesize);
8238 +               pr_info("Erasesize: %d Bytes\n", mtd->erasesize);
8239 +               pr_info("Oobsize  : %d Bytes\n", mtd->oobsize);
8240 +       } else {
8241 +               pr_err("Unsupported Nand,Id: 0x%x \n", flash_id);
8242 +               return -ENODEV;
8243 +       }
8244 +
8245 +       /* Size of each codeword is 532Bytes incase of 8bit BCH ECC*/
8246 +       chip->cw_size = enable_bch_ecc ? 532 : 528;
8247 +       chip->CFG0 = (((mtd_writesize >> 9)-1) << 6) /* 4/8 cw/pg for 2/4k */
8248 +               |  (516 <<  9)  /* 516 user data bytes */
8249 +               |   (10 << 19)  /* 10 parity bytes */
8250 +               |    (5 << 27)  /* 5 address cycles */
8251 +               |    (0 << 30)  /* Do not read status before data */
8252 +               |    (1 << 31)  /* Send read cmd */
8253 +               /* 0 spare bytes for 16 bit nand or 1/2 spare bytes for 8 bit */
8254 +               | (wide_bus ? 0 << 23 : (enable_bch_ecc ? 2 << 23 : 1 << 23));
8255 +
8256 +       chip->CFG1 = (0 <<  0)  /* Enable ecc */
8257 +               |    (7 <<  2)  /* 8 recovery cycles */
8258 +               |    (0 <<  5)  /* Allow CS deassertion */
8259 +               /* Bad block marker location */
8260 +               |  ((mtd_writesize - (chip->cw_size * (
8261 +                                       (mtd_writesize >> 9) - 1)) + 1) <<  6)
8262 +               |    (0 << 16)  /* Bad block in user data area */
8263 +               |    (2 << 17)  /* 6 cycle tWB/tRB */
8264 +               | ((wide_bus) ? CFG1_WIDE_FLASH : 0); /* Wide flash bit */
8265 +
8266 +       chip->ecc_buf_cfg = 0x203;
8267 +       chip->CFG0_RAW = 0xA80420C0;
8268 +       chip->CFG1_RAW = 0x5045D;
8269 +
8270 +       if (enable_bch_ecc) {
8271 +               chip->CFG1 |= (1 << 27); /* Enable BCH engine */
8272 +               chip->ecc_bch_cfg = (0 << 0) /* Enable ECC*/
8273 +                       |   (0 << 1) /* Enable/Disable SW reset of ECC engine */
8274 +                       |   (1 << 4) /* 8bit ecc*/
8275 +                       |   ((wide_bus) ? (14 << 8) : (13 << 8))/*parity bytes*/
8276 +                       |   (516 << 16) /* 516 user data bytes */
8277 +                       |   (1 << 30); /* Turn on ECC engine clocks always */
8278 +               chip->CFG0_RAW = 0xA80428C0; /* CW size is increased to 532B */
8279 +       }
8280 +
8281 +       /*
8282 +        * For 4bit RS ECC (default ECC), parity bytes = 10 (for x8 and x16 I/O)
8283 +        * For 8bit BCH ECC, parity bytes = 13 (x8) or 14 (x16 I/O).
8284 +        */
8285 +       chip->ecc_parity_bytes = enable_bch_ecc ? (wide_bus ? 14 : 13) : 10;
8286 +
8287 +       pr_info("CFG0 Init  : 0x%08x\n", chip->CFG0);
8288 +       pr_info("CFG1 Init  : 0x%08x\n", chip->CFG1);
8289 +       pr_info("ECCBUFCFG  : 0x%08x\n", chip->ecc_buf_cfg);
8290 +
8291 +       if (mtd->oobsize == 64) {
8292 +               mtd->oobavail = msm_nand_oob_64.oobavail;
8293 +               mtd->ecclayout = &msm_nand_oob_64;
8294 +       } else if (mtd->oobsize == 128) {
8295 +               mtd->oobavail = msm_nand_oob_128.oobavail;
8296 +               mtd->ecclayout = &msm_nand_oob_128;
8297 +       } else if (mtd->oobsize == 224) {
8298 +               mtd->oobavail = wide_bus ? msm_nand_oob_224_x16.oobavail :
8299 +                       msm_nand_oob_224_x8.oobavail;
8300 +               mtd->ecclayout = wide_bus ? &msm_nand_oob_224_x16 :
8301 +                       &msm_nand_oob_224_x8;
8302 +       } else if (mtd->oobsize == 256) {
8303 +               mtd->oobavail = msm_nand_oob_256.oobavail;
8304 +               mtd->ecclayout = &msm_nand_oob_256;
8305 +       } else {
8306 +               pr_err("Unsupported Nand, oobsize: 0x%x \n",
8307 +                      mtd->oobsize);
8308 +               return -ENODEV;
8309 +       }
8310 +
8311 +       /* Fill in remaining MTD driver data */
8312 +       mtd->type = MTD_NANDFLASH;
8313 +       mtd->flags = MTD_CAP_NANDFLASH;
8314 +       /* mtd->ecctype = MTD_ECC_SW; */
8315 +       mtd->_erase = msm_nand_erase;
8316 +       mtd->_block_isbad = msm_nand_block_isbad;
8317 +       mtd->_block_markbad = msm_nand_block_markbad;
8318 +       mtd->_point = NULL;
8319 +       mtd->_unpoint = NULL;
8320 +       mtd->_read = msm_nand_read;
8321 +       mtd->_write = msm_nand_write;
8322 +       mtd->_read_oob  = msm_nand_read_oob;
8323 +       mtd->_write_oob = msm_nand_write_oob;
8324 +       if (dual_nand_ctlr_present) {
8325 +               mtd->_read_oob = msm_nand_read_oob_dualnandc;
8326 +               mtd->_write_oob = msm_nand_write_oob_dualnandc;
8327 +               if (interleave_enable) {
8328 +                       mtd->_erase = msm_nand_erase_dualnandc;
8329 +                       mtd->_block_isbad = msm_nand_block_isbad_dualnandc;
8330 +               }
8331 +       }
8332 +
8333 +       /* mtd->sync = msm_nand_sync; */
8334 +       mtd->_lock = NULL;
8335 +       /* mtd->_unlock = msm_nand_unlock; */
8336 +       mtd->_suspend = msm_nand_suspend;
8337 +       mtd->_resume = msm_nand_resume;
8338 +       mtd->owner = THIS_MODULE;
8339 +
8340 +       /* Unlock whole block */
8341 +       /* msm_nand_unlock_all(mtd); */
8342 +
8343 +       /* return this->scan_bbt(mtd); */
8344 +       return 0;
8345 +}
8346 +EXPORT_SYMBOL_GPL(msm_nand_scan);
8347 +
8348 +/**
8349 + * msm_nand_release - [msm_nand Interface] Free resources held by the msm_nand device
8350 + * @param mtd          MTD device structure
8351 + */
8352 +void msm_nand_release(struct mtd_info *mtd)
8353 +{
8354 +       /* struct msm_nand_chip *this = mtd->priv; */
8355 +
8356 +       /* Deregister the device */
8357 +       mtd_device_unregister(mtd);
8358 +}
8359 +EXPORT_SYMBOL_GPL(msm_nand_release);
8360 +
8361 +struct msm_nand_info {
8362 +       struct mtd_info         mtd;
8363 +       struct mtd_partition    *parts;
8364 +       struct msm_nand_chip    msm_nand;
8365 +};
8366 +
8367 +/* duplicating the NC01 XFR contents to NC10 */
8368 +static int msm_nand_nc10_xfr_settings(struct mtd_info *mtd)
8369 +{
8370 +       struct msm_nand_chip *chip = mtd->priv;
8371 +
8372 +       struct {
8373 +               dmov_s cmd[2];
8374 +               unsigned cmdptr;
8375 +       } *dma_buffer;
8376 +       dmov_s *cmd;
8377 +
8378 +       wait_event(chip->wait_queue,
8379 +               (dma_buffer = msm_nand_get_dma_buffer(
8380 +                               chip, sizeof(*dma_buffer))));
8381 +
8382 +       cmd = dma_buffer->cmd;
8383 +
8384 +       /* Copying XFR register contents from NC01 --> NC10 */
8385 +       cmd->cmd = 0;
8386 +       cmd->src = NC01(MSM_NAND_XFR_STEP1);
8387 +       cmd->dst = NC10(MSM_NAND_XFR_STEP1);
8388 +       cmd->len = 28;
8389 +       cmd++;
8390 +
8391 +       BUILD_BUG_ON(2 != ARRAY_SIZE(dma_buffer->cmd));
8392 +       BUG_ON(cmd - dma_buffer->cmd > ARRAY_SIZE(dma_buffer->cmd));
8393 +       dma_buffer->cmd[0].cmd |= CMD_OCB;
8394 +       cmd[-1].cmd |= CMD_OCU | CMD_LC;
8395 +       dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3)
8396 +                               | CMD_PTR_LP;
8397 +
8398 +       mb();
8399 +       msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST
8400 +                       | DMOV_CMD_ADDR(msm_virt_to_dma(chip,
8401 +                       &dma_buffer->cmdptr)));
8402 +       mb();
8403 +       msm_nand_release_dma_buffer(chip, dma_buffer, sizeof(*dma_buffer));
8404 +       return 0;
8405 +}
8406 +
8407 +static ssize_t boot_layout_show(struct device *dev,
8408 +                                  struct device_attribute *attr,
8409 +                                  char *buf)
8410 +{
8411 +       return sprintf(buf, "%d\n", boot_layout);
8412 +}
8413 +
8414 +static ssize_t boot_layout_store(struct device *dev,
8415 +                                   struct device_attribute *attr,
8416 +                                   const char *buf, size_t n)
8417 +{
8418 +       struct msm_nand_info *info = dev_get_drvdata(dev);
8419 +       struct msm_nand_chip *chip = info->mtd.priv;
8420 +       unsigned int ud_size;
8421 +       unsigned int spare_size;
8422 +       unsigned int ecc_num_data_bytes;
8423 +
8424 +       sscanf(buf, "%d", &boot_layout);
8425 +
8426 +       ud_size = boot_layout? 512: 516;
8427 +       spare_size = boot_layout? (chip->cw_size -
8428 +                                       (chip->ecc_parity_bytes+ 1+ ud_size)):
8429 +                                       (enable_bch_ecc ? 2 : 1);
8430 +       ecc_num_data_bytes = boot_layout? 512: 516;
8431 +
8432 +       chip->CFG0 = (chip->CFG0 & ~SPARE_SIZE_BYTES_MASK);
8433 +       chip->CFG0 |= (spare_size << 23);
8434 +
8435 +       chip->CFG0 = (chip->CFG0 & ~UD_SIZE_BYTES_MASK);
8436 +       chip->CFG0 |= (ud_size << 9);
8437 +
8438 +       chip->ecc_buf_cfg = (chip->ecc_buf_cfg & ~ECC_NUM_DATA_BYTES_MASK)
8439 +                               | (ecc_num_data_bytes << 16);
8440 +
8441 +       return n;
8442 +}
8443 +
8444 +static const DEVICE_ATTR(boot_layout, 0644, boot_layout_show, boot_layout_store);
8445 +
8446 +static int msm_nand_probe(struct platform_device *pdev)
8447 +
8448 +{
8449 +        struct msm_nand_info *info;
8450 +       struct resource *res;
8451 +       int err;
8452 +       struct mtd_part_parser_data ppdata = {};
8453 +
8454 +
8455 +       res = platform_get_resource(pdev,
8456 +                                       IORESOURCE_MEM, 0);
8457 +       if (!res || !res->start) {
8458 +               pr_err("%s: msm_nand_phys resource invalid/absent\n",
8459 +                               __func__);
8460 +               return -ENODEV;
8461 +       }
8462 +       msm_nand_phys = res->start;
8463 +
8464 +       info = devm_kzalloc(&pdev->dev, sizeof(struct msm_nand_info), GFP_KERNEL);
8465 +       if (!info) {
8466 +               pr_err("%s: No memory for msm_nand_info\n", __func__);
8467 +               return -ENOMEM;
8468 +       }
8469 +
8470 +       info->msm_nand.dev = &pdev->dev;
8471 +
8472 +       init_waitqueue_head(&info->msm_nand.wait_queue);
8473 +
8474 +       info->msm_nand.dma_channel = 3;
8475 +       pr_info("%s: dmac 0x%x\n", __func__, info->msm_nand.dma_channel);
8476 +
8477 +       /* this currently fails if dev is passed in */
8478 +       info->msm_nand.dma_buffer =
8479 +               dma_alloc_coherent(/*dev*/ NULL, MSM_NAND_DMA_BUFFER_SIZE,
8480 +                               &info->msm_nand.dma_addr, GFP_KERNEL);
8481 +       if (info->msm_nand.dma_buffer == NULL) {
8482 +               pr_err("%s: No memory for msm_nand.dma_buffer\n", __func__);
8483 +               err = -ENOMEM;
8484 +               goto out_free_info;
8485 +       }
8486 +
8487 +       pr_info("%s: allocated dma buffer at %p, dma_addr %x\n",
8488 +               __func__, info->msm_nand.dma_buffer, info->msm_nand.dma_addr);
8489 +
8490 +       /* Let default be VERSION_1 for backward compatibility */
8491 +       info->msm_nand.uncorrectable_bit_mask = BIT(8);
8492 +       info->msm_nand.num_err_mask = 0x1F;
8493 +
8494 +       info->mtd.name = dev_name(&pdev->dev);
8495 +       info->mtd.priv = &info->msm_nand;
8496 +       info->mtd.owner = THIS_MODULE;
8497 +
8498 +       /* config ebi2_cfg register only for ping pong mode!!! */
8499 +       if (!interleave_enable && dual_nand_ctlr_present)
8500 +               flash_wr_reg(&info->msm_nand, EBI2_CFG_REG, 0x4010080);
8501 +
8502 +       if (dual_nand_ctlr_present)
8503 +               msm_nand_nc10_xfr_settings(&info->mtd);
8504 +
8505 +       if (msm_nand_scan(&info->mtd, 1))
8506 +               if (msm_onenand_scan(&info->mtd, 1)) {
8507 +                       pr_err("%s: No nand device found\n", __func__);
8508 +                       err = -ENXIO;
8509 +                       goto out_free_dma_buffer;
8510 +               }
8511 +
8512 +       flash_wr_reg(&info->msm_nand, MSM_NAND_DEV_CMD_VLD,
8513 +                               DEV_CMD_VLD_SEQ_READ_START_VLD |
8514 +                               DEV_CMD_VLD_ERASE_START_VLD |
8515 +                               DEV_CMD_VLD_WRITE_START_VLD |
8516 +                               DEV_CMD_VLD_READ_START_VLD);
8517 +
8518 +       ppdata.of_node = pdev->dev.of_node;
8519 +       err = mtd_device_parse_register(&info->mtd, NULL, &ppdata, NULL, 0);
8520 +
8521 +       if (err < 0) {
8522 +               pr_err("%s: mtd_device_parse_register failed with err=%d\n",
8523 +                               __func__, err);
8524 +               goto out_free_dma_buffer;
8525 +       }
8526 +
8527 +       err = sysfs_create_file(&pdev->dev.kobj, &dev_attr_boot_layout.attr);
8528 +       if (err)
8529 +               goto out_free_dma_buffer;
8530 +
8531 +       dev_set_drvdata(&pdev->dev, info);
8532 +
8533 +       return 0;
8534 +
8535 +out_free_dma_buffer:
8536 +       dma_free_coherent(NULL, MSM_NAND_DMA_BUFFER_SIZE,
8537 +                       info->msm_nand.dma_buffer,
8538 +                       info->msm_nand.dma_addr);
8539 +out_free_info:
8540 +       return err;
8541 +}
8542 +
8543 +static int msm_nand_remove(struct platform_device *pdev)
8544 +{
8545 +       struct msm_nand_info *info = dev_get_drvdata(&pdev->dev);
8546 +
8547 +       dev_set_drvdata(&pdev->dev, NULL);
8548 +
8549 +       if (info) {
8550 +               msm_nand_release(&info->mtd);
8551 +               dma_free_coherent(NULL, MSM_NAND_DMA_BUFFER_SIZE,
8552 +                                 info->msm_nand.dma_buffer,
8553 +                                 info->msm_nand.dma_addr);
8554 +       }
8555 +
8556 +       sysfs_remove_file(&pdev->dev.kobj, &dev_attr_boot_layout.attr);
8557 +
8558 +       return 0;
8559 +}
8560 +
8561 +
8562 +#ifdef CONFIG_OF
8563 +static const struct of_device_id msm_nand_of_match[] = {
8564 +        { .compatible = "qcom,qcom_nand", },
8565 +        {},
8566 +};
8567 +MODULE_DEVICE_TABLE(of, msm_nand_of_match);
8568 +#endif
8569 +
8570 +
8571 +static struct platform_driver msm_nand_driver = {
8572 +       .probe          = msm_nand_probe,
8573 +       .remove         = msm_nand_remove,
8574 +       .driver = {
8575 +               .name           = "qcom_nand",
8576 +               .owner          = THIS_MODULE,
8577 +                .of_match_table = msm_nand_of_match,
8578 +       }
8579 +};
8580 +
8581 +
8582 +module_platform_driver(msm_nand_driver);
8583 +
8584 +MODULE_LICENSE("GPL");
8585 +MODULE_DESCRIPTION("msm_nand flash driver code");
8586 --- /dev/null
8587 +++ b/drivers/mtd/nand/qcom_nand.h
8588 @@ -0,0 +1,196 @@
8589 +/* drivers/mtd/devices/msm_nand.h
8590 + *
8591 + * Copyright (c) 2008-2011, The Linux Foundation. All rights reserved.
8592 + * Copyright (C) 2007 Google, Inc.
8593 + *
8594 + * This software is licensed under the terms of the GNU General Public
8595 + * License version 2, as published by the Free Software Foundation, and
8596 + * may be copied, distributed, and modified under those terms.
8597 + *
8598 + * This program is distributed in the hope that it will be useful,
8599 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
8600 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8601 + * GNU General Public License for more details.
8602 + *
8603 + */
8604 +
8605 +#ifndef __DRIVERS_MTD_DEVICES_MSM_NAND_H
8606 +#define __DRIVERS_MTD_DEVICES_MSM_NAND_H
8607 +
8608 +extern unsigned long msm_nand_phys;
8609 +extern unsigned long msm_nandc01_phys;
8610 +extern unsigned long msm_nandc10_phys;
8611 +extern unsigned long msm_nandc11_phys;
8612 +extern unsigned long ebi2_register_base;
8613 +
8614 +#define NC01(X) ((X) + msm_nandc01_phys - msm_nand_phys)
8615 +#define NC10(X) ((X) + msm_nandc10_phys - msm_nand_phys)
8616 +#define NC11(X) ((X) + msm_nandc11_phys - msm_nand_phys)
8617 +
8618 +#define MSM_NAND_REG(off) (msm_nand_phys + (off))
8619 +
8620 +#define MSM_NAND_FLASH_CMD            MSM_NAND_REG(0x0000)
8621 +#define MSM_NAND_ADDR0                MSM_NAND_REG(0x0004)
8622 +#define MSM_NAND_ADDR1                MSM_NAND_REG(0x0008)
8623 +#define MSM_NAND_FLASH_CHIP_SELECT    MSM_NAND_REG(0x000C)
8624 +#define MSM_NAND_EXEC_CMD             MSM_NAND_REG(0x0010)
8625 +#define MSM_NAND_FLASH_STATUS         MSM_NAND_REG(0x0014)
8626 +#define MSM_NAND_BUFFER_STATUS        MSM_NAND_REG(0x0018)
8627 +#define MSM_NAND_SFLASHC_STATUS       MSM_NAND_REG(0x001C)
8628 +#define MSM_NAND_DEV0_CFG0            MSM_NAND_REG(0x0020)
8629 +#define MSM_NAND_DEV0_CFG1            MSM_NAND_REG(0x0024)
8630 +#define MSM_NAND_DEV0_ECC_CFG        MSM_NAND_REG(0x0028)
8631 +#define MSM_NAND_DEV1_ECC_CFG        MSM_NAND_REG(0x002C)
8632 +#define MSM_NAND_DEV1_CFG0            MSM_NAND_REG(0x0030)
8633 +#define MSM_NAND_DEV1_CFG1            MSM_NAND_REG(0x0034)
8634 +#define MSM_NAND_SFLASHC_CMD          MSM_NAND_REG(0x0038)
8635 +#define MSM_NAND_SFLASHC_EXEC_CMD     MSM_NAND_REG(0x003C)
8636 +#define MSM_NAND_READ_ID              MSM_NAND_REG(0x0040)
8637 +#define MSM_NAND_READ_STATUS          MSM_NAND_REG(0x0044)
8638 +#define MSM_NAND_CONFIG_DATA          MSM_NAND_REG(0x0050)
8639 +#define MSM_NAND_CONFIG               MSM_NAND_REG(0x0054)
8640 +#define MSM_NAND_CONFIG_MODE          MSM_NAND_REG(0x0058)
8641 +#define MSM_NAND_CONFIG_STATUS        MSM_NAND_REG(0x0060)
8642 +#define MSM_NAND_MACRO1_REG           MSM_NAND_REG(0x0064)
8643 +#define MSM_NAND_XFR_STEP1            MSM_NAND_REG(0x0070)
8644 +#define MSM_NAND_XFR_STEP2            MSM_NAND_REG(0x0074)
8645 +#define MSM_NAND_XFR_STEP3            MSM_NAND_REG(0x0078)
8646 +#define MSM_NAND_XFR_STEP4            MSM_NAND_REG(0x007C)
8647 +#define MSM_NAND_XFR_STEP5            MSM_NAND_REG(0x0080)
8648 +#define MSM_NAND_XFR_STEP6            MSM_NAND_REG(0x0084)
8649 +#define MSM_NAND_XFR_STEP7            MSM_NAND_REG(0x0088)
8650 +#define MSM_NAND_GENP_REG0            MSM_NAND_REG(0x0090)
8651 +#define MSM_NAND_GENP_REG1            MSM_NAND_REG(0x0094)
8652 +#define MSM_NAND_GENP_REG2            MSM_NAND_REG(0x0098)
8653 +#define MSM_NAND_GENP_REG3            MSM_NAND_REG(0x009C)
8654 +#define MSM_NAND_DEV_CMD0             MSM_NAND_REG(0x00A0)
8655 +#define MSM_NAND_DEV_CMD1             MSM_NAND_REG(0x00A4)
8656 +#define MSM_NAND_DEV_CMD2             MSM_NAND_REG(0x00A8)
8657 +#define MSM_NAND_DEV_CMD_VLD          MSM_NAND_REG(0x00AC)
8658 +#define DEV_CMD_VLD_SEQ_READ_START_VLD         0x10
8659 +#define DEV_CMD_VLD_ERASE_START_VLD            0x8
8660 +#define DEV_CMD_VLD_WRITE_START_VLD            0x4
8661 +#define DEV_CMD_VLD_READ_STOP_VLD              0x2
8662 +#define DEV_CMD_VLD_READ_START_VLD             0x1
8663 +
8664 +#define MSM_NAND_EBI2_MISR_SIG_REG    MSM_NAND_REG(0x00B0)
8665 +#define MSM_NAND_ADDR2                MSM_NAND_REG(0x00C0)
8666 +#define MSM_NAND_ADDR3                MSM_NAND_REG(0x00C4)
8667 +#define MSM_NAND_ADDR4                MSM_NAND_REG(0x00C8)
8668 +#define MSM_NAND_ADDR5                MSM_NAND_REG(0x00CC)
8669 +#define MSM_NAND_DEV_CMD3             MSM_NAND_REG(0x00D0)
8670 +#define MSM_NAND_DEV_CMD4             MSM_NAND_REG(0x00D4)
8671 +#define MSM_NAND_DEV_CMD5             MSM_NAND_REG(0x00D8)
8672 +#define MSM_NAND_DEV_CMD6             MSM_NAND_REG(0x00DC)
8673 +#define MSM_NAND_SFLASHC_BURST_CFG    MSM_NAND_REG(0x00E0)
8674 +#define MSM_NAND_ADDR6                MSM_NAND_REG(0x00E4)
8675 +#define MSM_NAND_EBI2_ECC_BUF_CFG     MSM_NAND_REG(0x00F0)
8676 +#define MSM_NAND_HW_INFO             MSM_NAND_REG(0x00FC)
8677 +#define MSM_NAND_FLASH_BUFFER         MSM_NAND_REG(0x0100)
8678 +
8679 +/* device commands */
8680 +
8681 +#define MSM_NAND_CMD_SOFT_RESET         0x01
8682 +#define MSM_NAND_CMD_PAGE_READ          0x32
8683 +#define MSM_NAND_CMD_PAGE_READ_ECC      0x33
8684 +#define MSM_NAND_CMD_PAGE_READ_ALL      0x34
8685 +#define MSM_NAND_CMD_SEQ_PAGE_READ      0x15
8686 +#define MSM_NAND_CMD_PRG_PAGE           0x36
8687 +#define MSM_NAND_CMD_PRG_PAGE_ECC       0x37
8688 +#define MSM_NAND_CMD_PRG_PAGE_ALL       0x39
8689 +#define MSM_NAND_CMD_BLOCK_ERASE        0x3A
8690 +#define MSM_NAND_CMD_FETCH_ID           0x0B
8691 +#define MSM_NAND_CMD_STATUS             0x0C
8692 +#define MSM_NAND_CMD_RESET              0x0D
8693 +
8694 +/* Sflash Commands */
8695 +
8696 +#define MSM_NAND_SFCMD_DATXS            0x0
8697 +#define MSM_NAND_SFCMD_CMDXS            0x1
8698 +#define MSM_NAND_SFCMD_BURST            0x0
8699 +#define MSM_NAND_SFCMD_ASYNC            0x1
8700 +#define MSM_NAND_SFCMD_ABORT            0x1
8701 +#define MSM_NAND_SFCMD_REGRD            0x2
8702 +#define MSM_NAND_SFCMD_REGWR            0x3
8703 +#define MSM_NAND_SFCMD_INTLO            0x4
8704 +#define MSM_NAND_SFCMD_INTHI            0x5
8705 +#define MSM_NAND_SFCMD_DATRD            0x6
8706 +#define MSM_NAND_SFCMD_DATWR            0x7
8707 +
8708 +#define SFLASH_PREPCMD(numxfr, offval, delval, trnstp, mode, opcode) \
8709 +       ((numxfr<<20)|(offval<<12)|(delval<<6)|(trnstp<<5)|(mode<<4)|opcode)
8710 +
8711 +#define SFLASH_BCFG                    0x20100327
8712 +
8713 +/* Onenand addresses */
8714 +
8715 +#define ONENAND_MANUFACTURER_ID                0xF000
8716 +#define ONENAND_DEVICE_ID              0xF001
8717 +#define ONENAND_VERSION_ID             0xF002
8718 +#define ONENAND_DATA_BUFFER_SIZE       0xF003
8719 +#define ONENAND_BOOT_BUFFER_SIZE       0xF004
8720 +#define ONENAND_AMOUNT_OF_BUFFERS      0xF005
8721 +#define ONENAND_TECHNOLOGY             0xF006
8722 +#define ONENAND_START_ADDRESS_1                0xF100
8723 +#define ONENAND_START_ADDRESS_2                0xF101
8724 +#define ONENAND_START_ADDRESS_3                0xF102
8725 +#define ONENAND_START_ADDRESS_4                0xF103
8726 +#define ONENAND_START_ADDRESS_5                0xF104
8727 +#define ONENAND_START_ADDRESS_6                0xF105
8728 +#define ONENAND_START_ADDRESS_7                0xF106
8729 +#define ONENAND_START_ADDRESS_8                0xF107
8730 +#define ONENAND_START_BUFFER           0xF200
8731 +#define ONENAND_COMMAND                        0xF220
8732 +#define ONENAND_SYSTEM_CONFIG_1                0xF221
8733 +#define ONENAND_SYSTEM_CONFIG_2                0xF222
8734 +#define ONENAND_CONTROLLER_STATUS      0xF240
8735 +#define ONENAND_INTERRUPT_STATUS       0xF241
8736 +#define ONENAND_START_BLOCK_ADDRESS    0xF24C
8737 +#define ONENAND_WRITE_PROT_STATUS      0xF24E
8738 +#define ONENAND_ECC_STATUS             0xFF00
8739 +#define ONENAND_ECC_ERRPOS_MAIN0       0xFF01
8740 +#define ONENAND_ECC_ERRPOS_SPARE0      0xFF02
8741 +#define ONENAND_ECC_ERRPOS_MAIN1       0xFF03
8742 +#define ONENAND_ECC_ERRPOS_SPARE1      0xFF04
8743 +#define ONENAND_ECC_ERRPOS_MAIN2       0xFF05
8744 +#define ONENAND_ECC_ERRPOS_SPARE2      0xFF06
8745 +#define ONENAND_ECC_ERRPOS_MAIN3       0xFF07
8746 +#define ONENAND_ECC_ERRPOS_SPARE3      0xFF08
8747 +
8748 +/* Onenand commands */
8749 +#define ONENAND_WP_US                   (1 << 2)
8750 +#define ONENAND_WP_LS                   (1 << 1)
8751 +
8752 +#define ONENAND_CMDLOAD                        0x0000
8753 +#define ONENAND_CMDLOADSPARE           0x0013
8754 +#define ONENAND_CMDPROG                        0x0080
8755 +#define ONENAND_CMDPROGSPARE           0x001A
8756 +#define ONENAND_CMDERAS                        0x0094
8757 +#define ONENAND_CMD_UNLOCK              0x0023
8758 +#define ONENAND_CMD_LOCK                0x002A
8759 +
8760 +#define ONENAND_SYSCFG1_ECCENA(mode)   (0x40E0 | (mode ? 0 : 0x8002))
8761 +#define ONENAND_SYSCFG1_ECCDIS(mode)   (0x41E0 | (mode ? 0 : 0x8002))
8762 +
8763 +#define ONENAND_CLRINTR                        0x0000
8764 +#define ONENAND_STARTADDR1_RES         0x07FF
8765 +#define ONENAND_STARTADDR3_RES         0x07FF
8766 +
8767 +#define DATARAM0_0                     0x8
8768 +#define DEVICE_FLASHCORE_0              (0 << 15)
8769 +#define DEVICE_FLASHCORE_1              (1 << 15)
8770 +#define DEVICE_BUFFERRAM_0              (0 << 15)
8771 +#define DEVICE_BUFFERRAM_1              (1 << 15)
8772 +#define ONENAND_DEVICE_IS_DDP          (1 << 3)
8773 +
8774 +#define CLEAN_DATA_16                  0xFFFF
8775 +#define CLEAN_DATA_32                  0xFFFFFFFF
8776 +
8777 +#define EBI2_REG(off)                  (ebi2_register_base + (off))
8778 +#define EBI2_CHIP_SELECT_CFG0           EBI2_REG(0x0000)
8779 +#define EBI2_CFG_REG                   EBI2_REG(0x0004)
8780 +#define EBI2_NAND_ADM_MUX              EBI2_REG(0x005C)
8781 +
8782 +extern struct flash_platform_data msm_nand_data;
8783 +
8784 +#endif