kernel: update 3.14 to 3.14.18
[openwrt/svn-archive/archive.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