diff options
author | Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> | 2016-06-14 11:50:51 -0400 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@free-electrons.com> | 2016-07-11 02:39:54 -0400 |
commit | 1d6b1e4649500c170fb6e243c0b92f40bb8a0185 (patch) | |
tree | 755446f8040858dab7c2e19ff4705376f2f48fc1 | |
parent | cac4fcc0d3d8b666e8c7cc738bfdceb814e6e523 (diff) |
mtd: mediatek: driver for MTK Smart Device
Add support for mediatek's SDG1 NFC nand controller embedded in SoC
2701
Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Tested-by: Xiaolei Li <xiaolei.li@mediatek.com>
-rw-r--r-- | drivers/mtd/nand/Kconfig | 7 | ||||
-rw-r--r-- | drivers/mtd/nand/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/mtk_ecc.c | 530 | ||||
-rw-r--r-- | drivers/mtd/nand/mtk_ecc.h | 50 | ||||
-rw-r--r-- | drivers/mtd/nand/mtk_nand.c | 1526 |
5 files changed, 2114 insertions, 0 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index f05e0e9eb2f7..3c26e899789e 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -563,4 +563,11 @@ config MTD_NAND_QCOM | |||
563 | Enables support for NAND flash chips on SoCs containing the EBI2 NAND | 563 | Enables support for NAND flash chips on SoCs containing the EBI2 NAND |
564 | controller. This controller is found on IPQ806x SoC. | 564 | controller. This controller is found on IPQ806x SoC. |
565 | 565 | ||
566 | config MTD_NAND_MTK | ||
567 | tristate "Support for NAND controller on MTK SoCs" | ||
568 | depends on HAS_DMA | ||
569 | help | ||
570 | Enables support for NAND controller on MTK SoCs. | ||
571 | This controller is found on mt27xx, mt81xx, mt65xx SoCs. | ||
572 | |||
566 | endif # MTD_NAND | 573 | endif # MTD_NAND |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index f55335373f7c..cafde6f3d957 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -57,5 +57,6 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o | |||
57 | obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o | 57 | obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o |
58 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ | 58 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ |
59 | obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o | 59 | obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o |
60 | obj-$(CONFIG_MTD_NAND_MTK) += mtk_nand.o mtk_ecc.o | ||
60 | 61 | ||
61 | nand-objs := nand_base.o nand_bbt.o nand_timings.o | 62 | nand-objs := nand_base.o nand_bbt.o nand_timings.o |
diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c new file mode 100644 index 000000000000..25a4fbd4d24a --- /dev/null +++ b/drivers/mtd/nand/mtk_ecc.c | |||
@@ -0,0 +1,530 @@ | |||
1 | /* | ||
2 | * MTK ECC controller driver. | ||
3 | * Copyright (C) 2016 MediaTek Inc. | ||
4 | * Authors: Xiaolei Li <xiaolei.li@mediatek.com> | ||
5 | * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/dma-mapping.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/iopoll.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/of_platform.h> | ||
25 | #include <linux/mutex.h> | ||
26 | |||
27 | #include "mtk_ecc.h" | ||
28 | |||
29 | #define ECC_IDLE_MASK BIT(0) | ||
30 | #define ECC_IRQ_EN BIT(0) | ||
31 | #define ECC_OP_ENABLE (1) | ||
32 | #define ECC_OP_DISABLE (0) | ||
33 | |||
34 | #define ECC_ENCCON (0x00) | ||
35 | #define ECC_ENCCNFG (0x04) | ||
36 | #define ECC_CNFG_4BIT (0) | ||
37 | #define ECC_CNFG_6BIT (1) | ||
38 | #define ECC_CNFG_8BIT (2) | ||
39 | #define ECC_CNFG_10BIT (3) | ||
40 | #define ECC_CNFG_12BIT (4) | ||
41 | #define ECC_CNFG_14BIT (5) | ||
42 | #define ECC_CNFG_16BIT (6) | ||
43 | #define ECC_CNFG_18BIT (7) | ||
44 | #define ECC_CNFG_20BIT (8) | ||
45 | #define ECC_CNFG_22BIT (9) | ||
46 | #define ECC_CNFG_24BIT (0xa) | ||
47 | #define ECC_CNFG_28BIT (0xb) | ||
48 | #define ECC_CNFG_32BIT (0xc) | ||
49 | #define ECC_CNFG_36BIT (0xd) | ||
50 | #define ECC_CNFG_40BIT (0xe) | ||
51 | #define ECC_CNFG_44BIT (0xf) | ||
52 | #define ECC_CNFG_48BIT (0x10) | ||
53 | #define ECC_CNFG_52BIT (0x11) | ||
54 | #define ECC_CNFG_56BIT (0x12) | ||
55 | #define ECC_CNFG_60BIT (0x13) | ||
56 | #define ECC_MODE_SHIFT (5) | ||
57 | #define ECC_MS_SHIFT (16) | ||
58 | #define ECC_ENCDIADDR (0x08) | ||
59 | #define ECC_ENCIDLE (0x0C) | ||
60 | #define ECC_ENCPAR(x) (0x10 + (x) * sizeof(u32)) | ||
61 | #define ECC_ENCIRQ_EN (0x80) | ||
62 | #define ECC_ENCIRQ_STA (0x84) | ||
63 | #define ECC_DECCON (0x100) | ||
64 | #define ECC_DECCNFG (0x104) | ||
65 | #define DEC_EMPTY_EN BIT(31) | ||
66 | #define DEC_CNFG_CORRECT (0x3 << 12) | ||
67 | #define ECC_DECIDLE (0x10C) | ||
68 | #define ECC_DECENUM0 (0x114) | ||
69 | #define ERR_MASK (0x3f) | ||
70 | #define ECC_DECDONE (0x124) | ||
71 | #define ECC_DECIRQ_EN (0x200) | ||
72 | #define ECC_DECIRQ_STA (0x204) | ||
73 | |||
74 | #define ECC_TIMEOUT (500000) | ||
75 | |||
76 | #define ECC_IDLE_REG(op) ((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE) | ||
77 | #define ECC_CTL_REG(op) ((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON) | ||
78 | #define ECC_IRQ_REG(op) ((op) == ECC_ENCODE ? \ | ||
79 | ECC_ENCIRQ_EN : ECC_DECIRQ_EN) | ||
80 | |||
81 | struct mtk_ecc { | ||
82 | struct device *dev; | ||
83 | void __iomem *regs; | ||
84 | struct clk *clk; | ||
85 | |||
86 | struct completion done; | ||
87 | struct mutex lock; | ||
88 | u32 sectors; | ||
89 | }; | ||
90 | |||
91 | static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc, | ||
92 | enum mtk_ecc_operation op) | ||
93 | { | ||
94 | struct device *dev = ecc->dev; | ||
95 | u32 val; | ||
96 | int ret; | ||
97 | |||
98 | ret = readl_poll_timeout_atomic(ecc->regs + ECC_IDLE_REG(op), val, | ||
99 | val & ECC_IDLE_MASK, | ||
100 | 10, ECC_TIMEOUT); | ||
101 | if (ret) | ||
102 | dev_warn(dev, "%s NOT idle\n", | ||
103 | op == ECC_ENCODE ? "encoder" : "decoder"); | ||
104 | } | ||
105 | |||
106 | static irqreturn_t mtk_ecc_irq(int irq, void *id) | ||
107 | { | ||
108 | struct mtk_ecc *ecc = id; | ||
109 | enum mtk_ecc_operation op; | ||
110 | u32 dec, enc; | ||
111 | |||
112 | dec = readw(ecc->regs + ECC_DECIRQ_STA) & ECC_IRQ_EN; | ||
113 | if (dec) { | ||
114 | op = ECC_DECODE; | ||
115 | dec = readw(ecc->regs + ECC_DECDONE); | ||
116 | if (dec & ecc->sectors) { | ||
117 | ecc->sectors = 0; | ||
118 | complete(&ecc->done); | ||
119 | } else { | ||
120 | return IRQ_HANDLED; | ||
121 | } | ||
122 | } else { | ||
123 | enc = readl(ecc->regs + ECC_ENCIRQ_STA) & ECC_IRQ_EN; | ||
124 | if (enc) { | ||
125 | op = ECC_ENCODE; | ||
126 | complete(&ecc->done); | ||
127 | } else { | ||
128 | return IRQ_NONE; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | writel(0, ecc->regs + ECC_IRQ_REG(op)); | ||
133 | |||
134 | return IRQ_HANDLED; | ||
135 | } | ||
136 | |||
137 | static void mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config) | ||
138 | { | ||
139 | u32 ecc_bit = ECC_CNFG_4BIT, dec_sz, enc_sz; | ||
140 | u32 reg; | ||
141 | |||
142 | switch (config->strength) { | ||
143 | case 4: | ||
144 | ecc_bit = ECC_CNFG_4BIT; | ||
145 | break; | ||
146 | case 6: | ||
147 | ecc_bit = ECC_CNFG_6BIT; | ||
148 | break; | ||
149 | case 8: | ||
150 | ecc_bit = ECC_CNFG_8BIT; | ||
151 | break; | ||
152 | case 10: | ||
153 | ecc_bit = ECC_CNFG_10BIT; | ||
154 | break; | ||
155 | case 12: | ||
156 | ecc_bit = ECC_CNFG_12BIT; | ||
157 | break; | ||
158 | case 14: | ||
159 | ecc_bit = ECC_CNFG_14BIT; | ||
160 | break; | ||
161 | case 16: | ||
162 | ecc_bit = ECC_CNFG_16BIT; | ||
163 | break; | ||
164 | case 18: | ||
165 | ecc_bit = ECC_CNFG_18BIT; | ||
166 | break; | ||
167 | case 20: | ||
168 | ecc_bit = ECC_CNFG_20BIT; | ||
169 | break; | ||
170 | case 22: | ||
171 | ecc_bit = ECC_CNFG_22BIT; | ||
172 | break; | ||
173 | case 24: | ||
174 | ecc_bit = ECC_CNFG_24BIT; | ||
175 | break; | ||
176 | case 28: | ||
177 | ecc_bit = ECC_CNFG_28BIT; | ||
178 | break; | ||
179 | case 32: | ||
180 | ecc_bit = ECC_CNFG_32BIT; | ||
181 | break; | ||
182 | case 36: | ||
183 | ecc_bit = ECC_CNFG_36BIT; | ||
184 | break; | ||
185 | case 40: | ||
186 | ecc_bit = ECC_CNFG_40BIT; | ||
187 | break; | ||
188 | case 44: | ||
189 | ecc_bit = ECC_CNFG_44BIT; | ||
190 | break; | ||
191 | case 48: | ||
192 | ecc_bit = ECC_CNFG_48BIT; | ||
193 | break; | ||
194 | case 52: | ||
195 | ecc_bit = ECC_CNFG_52BIT; | ||
196 | break; | ||
197 | case 56: | ||
198 | ecc_bit = ECC_CNFG_56BIT; | ||
199 | break; | ||
200 | case 60: | ||
201 | ecc_bit = ECC_CNFG_60BIT; | ||
202 | break; | ||
203 | default: | ||
204 | dev_err(ecc->dev, "invalid strength %d, default to 4 bits\n", | ||
205 | config->strength); | ||
206 | } | ||
207 | |||
208 | if (config->op == ECC_ENCODE) { | ||
209 | /* configure ECC encoder (in bits) */ | ||
210 | enc_sz = config->len << 3; | ||
211 | |||
212 | reg = ecc_bit | (config->mode << ECC_MODE_SHIFT); | ||
213 | reg |= (enc_sz << ECC_MS_SHIFT); | ||
214 | writel(reg, ecc->regs + ECC_ENCCNFG); | ||
215 | |||
216 | if (config->mode != ECC_NFI_MODE) | ||
217 | writel(lower_32_bits(config->addr), | ||
218 | ecc->regs + ECC_ENCDIADDR); | ||
219 | |||
220 | } else { | ||
221 | /* configure ECC decoder (in bits) */ | ||
222 | dec_sz = (config->len << 3) + | ||
223 | config->strength * ECC_PARITY_BITS; | ||
224 | |||
225 | reg = ecc_bit | (config->mode << ECC_MODE_SHIFT); | ||
226 | reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT; | ||
227 | reg |= DEC_EMPTY_EN; | ||
228 | writel(reg, ecc->regs + ECC_DECCNFG); | ||
229 | |||
230 | if (config->sectors) | ||
231 | ecc->sectors = 1 << (config->sectors - 1); | ||
232 | } | ||
233 | } | ||
234 | |||
235 | void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats, | ||
236 | int sectors) | ||
237 | { | ||
238 | u32 offset, i, err; | ||
239 | u32 bitflips = 0; | ||
240 | |||
241 | stats->corrected = 0; | ||
242 | stats->failed = 0; | ||
243 | |||
244 | for (i = 0; i < sectors; i++) { | ||
245 | offset = (i >> 2) << 2; | ||
246 | err = readl(ecc->regs + ECC_DECENUM0 + offset); | ||
247 | err = err >> ((i % 4) * 8); | ||
248 | err &= ERR_MASK; | ||
249 | if (err == ERR_MASK) { | ||
250 | /* uncorrectable errors */ | ||
251 | stats->failed++; | ||
252 | continue; | ||
253 | } | ||
254 | |||
255 | stats->corrected += err; | ||
256 | bitflips = max_t(u32, bitflips, err); | ||
257 | } | ||
258 | |||
259 | stats->bitflips = bitflips; | ||
260 | } | ||
261 | EXPORT_SYMBOL(mtk_ecc_get_stats); | ||
262 | |||
263 | void mtk_ecc_release(struct mtk_ecc *ecc) | ||
264 | { | ||
265 | clk_disable_unprepare(ecc->clk); | ||
266 | put_device(ecc->dev); | ||
267 | } | ||
268 | EXPORT_SYMBOL(mtk_ecc_release); | ||
269 | |||
270 | static void mtk_ecc_hw_init(struct mtk_ecc *ecc) | ||
271 | { | ||
272 | mtk_ecc_wait_idle(ecc, ECC_ENCODE); | ||
273 | writew(ECC_OP_DISABLE, ecc->regs + ECC_ENCCON); | ||
274 | |||
275 | mtk_ecc_wait_idle(ecc, ECC_DECODE); | ||
276 | writel(ECC_OP_DISABLE, ecc->regs + ECC_DECCON); | ||
277 | } | ||
278 | |||
279 | static struct mtk_ecc *mtk_ecc_get(struct device_node *np) | ||
280 | { | ||
281 | struct platform_device *pdev; | ||
282 | struct mtk_ecc *ecc; | ||
283 | |||
284 | pdev = of_find_device_by_node(np); | ||
285 | if (!pdev || !platform_get_drvdata(pdev)) | ||
286 | return ERR_PTR(-EPROBE_DEFER); | ||
287 | |||
288 | get_device(&pdev->dev); | ||
289 | ecc = platform_get_drvdata(pdev); | ||
290 | clk_prepare_enable(ecc->clk); | ||
291 | mtk_ecc_hw_init(ecc); | ||
292 | |||
293 | return ecc; | ||
294 | } | ||
295 | |||
296 | struct mtk_ecc *of_mtk_ecc_get(struct device_node *of_node) | ||
297 | { | ||
298 | struct mtk_ecc *ecc = NULL; | ||
299 | struct device_node *np; | ||
300 | |||
301 | np = of_parse_phandle(of_node, "ecc-engine", 0); | ||
302 | if (np) { | ||
303 | ecc = mtk_ecc_get(np); | ||
304 | of_node_put(np); | ||
305 | } | ||
306 | |||
307 | return ecc; | ||
308 | } | ||
309 | EXPORT_SYMBOL(of_mtk_ecc_get); | ||
310 | |||
311 | int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config) | ||
312 | { | ||
313 | enum mtk_ecc_operation op = config->op; | ||
314 | int ret; | ||
315 | |||
316 | ret = mutex_lock_interruptible(&ecc->lock); | ||
317 | if (ret) { | ||
318 | dev_err(ecc->dev, "interrupted when attempting to lock\n"); | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | mtk_ecc_wait_idle(ecc, op); | ||
323 | mtk_ecc_config(ecc, config); | ||
324 | writew(ECC_OP_ENABLE, ecc->regs + ECC_CTL_REG(op)); | ||
325 | |||
326 | init_completion(&ecc->done); | ||
327 | writew(ECC_IRQ_EN, ecc->regs + ECC_IRQ_REG(op)); | ||
328 | |||
329 | return 0; | ||
330 | } | ||
331 | EXPORT_SYMBOL(mtk_ecc_enable); | ||
332 | |||
333 | void mtk_ecc_disable(struct mtk_ecc *ecc) | ||
334 | { | ||
335 | enum mtk_ecc_operation op = ECC_ENCODE; | ||
336 | |||
337 | /* find out the running operation */ | ||
338 | if (readw(ecc->regs + ECC_CTL_REG(op)) != ECC_OP_ENABLE) | ||
339 | op = ECC_DECODE; | ||
340 | |||
341 | /* disable it */ | ||
342 | mtk_ecc_wait_idle(ecc, op); | ||
343 | writew(0, ecc->regs + ECC_IRQ_REG(op)); | ||
344 | writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op)); | ||
345 | |||
346 | mutex_unlock(&ecc->lock); | ||
347 | } | ||
348 | EXPORT_SYMBOL(mtk_ecc_disable); | ||
349 | |||
350 | int mtk_ecc_wait_done(struct mtk_ecc *ecc, enum mtk_ecc_operation op) | ||
351 | { | ||
352 | int ret; | ||
353 | |||
354 | ret = wait_for_completion_timeout(&ecc->done, msecs_to_jiffies(500)); | ||
355 | if (!ret) { | ||
356 | dev_err(ecc->dev, "%s timeout - interrupt did not arrive)\n", | ||
357 | (op == ECC_ENCODE) ? "encoder" : "decoder"); | ||
358 | return -ETIMEDOUT; | ||
359 | } | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | EXPORT_SYMBOL(mtk_ecc_wait_done); | ||
364 | |||
365 | int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config, | ||
366 | u8 *data, u32 bytes) | ||
367 | { | ||
368 | dma_addr_t addr; | ||
369 | u32 *p, len, i; | ||
370 | int ret = 0; | ||
371 | |||
372 | addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE); | ||
373 | ret = dma_mapping_error(ecc->dev, addr); | ||
374 | if (ret) { | ||
375 | dev_err(ecc->dev, "dma mapping error\n"); | ||
376 | return -EINVAL; | ||
377 | } | ||
378 | |||
379 | config->op = ECC_ENCODE; | ||
380 | config->addr = addr; | ||
381 | ret = mtk_ecc_enable(ecc, config); | ||
382 | if (ret) { | ||
383 | dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | ret = mtk_ecc_wait_done(ecc, ECC_ENCODE); | ||
388 | if (ret) | ||
389 | goto timeout; | ||
390 | |||
391 | mtk_ecc_wait_idle(ecc, ECC_ENCODE); | ||
392 | |||
393 | /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */ | ||
394 | len = (config->strength * ECC_PARITY_BITS + 7) >> 3; | ||
395 | p = (u32 *)(data + bytes); | ||
396 | |||
397 | /* write the parity bytes generated by the ECC back to the OOB region */ | ||
398 | for (i = 0; i < len; i++) | ||
399 | p[i] = readl(ecc->regs + ECC_ENCPAR(i)); | ||
400 | timeout: | ||
401 | |||
402 | dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE); | ||
403 | mtk_ecc_disable(ecc); | ||
404 | |||
405 | return ret; | ||
406 | } | ||
407 | EXPORT_SYMBOL(mtk_ecc_encode); | ||
408 | |||
409 | void mtk_ecc_adjust_strength(u32 *p) | ||
410 | { | ||
411 | u32 ecc[] = {4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, | ||
412 | 40, 44, 48, 52, 56, 60}; | ||
413 | int i; | ||
414 | |||
415 | for (i = 0; i < ARRAY_SIZE(ecc); i++) { | ||
416 | if (*p <= ecc[i]) { | ||
417 | if (!i) | ||
418 | *p = ecc[i]; | ||
419 | else if (*p != ecc[i]) | ||
420 | *p = ecc[i - 1]; | ||
421 | return; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | *p = ecc[ARRAY_SIZE(ecc) - 1]; | ||
426 | } | ||
427 | EXPORT_SYMBOL(mtk_ecc_adjust_strength); | ||
428 | |||
429 | static int mtk_ecc_probe(struct platform_device *pdev) | ||
430 | { | ||
431 | struct device *dev = &pdev->dev; | ||
432 | struct mtk_ecc *ecc; | ||
433 | struct resource *res; | ||
434 | int irq, ret; | ||
435 | |||
436 | ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); | ||
437 | if (!ecc) | ||
438 | return -ENOMEM; | ||
439 | |||
440 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
441 | ecc->regs = devm_ioremap_resource(dev, res); | ||
442 | if (IS_ERR(ecc->regs)) { | ||
443 | dev_err(dev, "failed to map regs: %ld\n", PTR_ERR(ecc->regs)); | ||
444 | return PTR_ERR(ecc->regs); | ||
445 | } | ||
446 | |||
447 | ecc->clk = devm_clk_get(dev, NULL); | ||
448 | if (IS_ERR(ecc->clk)) { | ||
449 | dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk)); | ||
450 | return PTR_ERR(ecc->clk); | ||
451 | } | ||
452 | |||
453 | irq = platform_get_irq(pdev, 0); | ||
454 | if (irq < 0) { | ||
455 | dev_err(dev, "failed to get irq\n"); | ||
456 | return -EINVAL; | ||
457 | } | ||
458 | |||
459 | ret = dma_set_mask(dev, DMA_BIT_MASK(32)); | ||
460 | if (ret) { | ||
461 | dev_err(dev, "failed to set DMA mask\n"); | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, "mtk-ecc", ecc); | ||
466 | if (ret) { | ||
467 | dev_err(dev, "failed to request irq\n"); | ||
468 | return -EINVAL; | ||
469 | } | ||
470 | |||
471 | ecc->dev = dev; | ||
472 | mutex_init(&ecc->lock); | ||
473 | platform_set_drvdata(pdev, ecc); | ||
474 | dev_info(dev, "probed\n"); | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | #ifdef CONFIG_PM_SLEEP | ||
480 | static int mtk_ecc_suspend(struct device *dev) | ||
481 | { | ||
482 | struct mtk_ecc *ecc = dev_get_drvdata(dev); | ||
483 | |||
484 | clk_disable_unprepare(ecc->clk); | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | static int mtk_ecc_resume(struct device *dev) | ||
490 | { | ||
491 | struct mtk_ecc *ecc = dev_get_drvdata(dev); | ||
492 | int ret; | ||
493 | |||
494 | ret = clk_prepare_enable(ecc->clk); | ||
495 | if (ret) { | ||
496 | dev_err(dev, "failed to enable clk\n"); | ||
497 | return ret; | ||
498 | } | ||
499 | |||
500 | mtk_ecc_hw_init(ecc); | ||
501 | |||
502 | return 0; | ||
503 | } | ||
504 | |||
505 | static SIMPLE_DEV_PM_OPS(mtk_ecc_pm_ops, mtk_ecc_suspend, mtk_ecc_resume); | ||
506 | #endif | ||
507 | |||
508 | static const struct of_device_id mtk_ecc_dt_match[] = { | ||
509 | { .compatible = "mediatek,mt2701-ecc" }, | ||
510 | {}, | ||
511 | }; | ||
512 | |||
513 | MODULE_DEVICE_TABLE(of, mtk_ecc_dt_match); | ||
514 | |||
515 | static struct platform_driver mtk_ecc_driver = { | ||
516 | .probe = mtk_ecc_probe, | ||
517 | .driver = { | ||
518 | .name = "mtk-ecc", | ||
519 | .of_match_table = of_match_ptr(mtk_ecc_dt_match), | ||
520 | #ifdef CONFIG_PM_SLEEP | ||
521 | .pm = &mtk_ecc_pm_ops, | ||
522 | #endif | ||
523 | }, | ||
524 | }; | ||
525 | |||
526 | module_platform_driver(mtk_ecc_driver); | ||
527 | |||
528 | MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>"); | ||
529 | MODULE_DESCRIPTION("MTK Nand ECC Driver"); | ||
530 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mtd/nand/mtk_ecc.h b/drivers/mtd/nand/mtk_ecc.h new file mode 100644 index 000000000000..cbeba5cd1c13 --- /dev/null +++ b/drivers/mtd/nand/mtk_ecc.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* | ||
2 | * MTK SDG1 ECC controller | ||
3 | * | ||
4 | * Copyright (c) 2016 Mediatek | ||
5 | * Authors: Xiaolei Li <xiaolei.li@mediatek.com> | ||
6 | * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published | ||
9 | * by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__ | ||
13 | #define __DRIVERS_MTD_NAND_MTK_ECC_H__ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | #define ECC_PARITY_BITS (14) | ||
18 | |||
19 | enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1}; | ||
20 | enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE}; | ||
21 | |||
22 | struct device_node; | ||
23 | struct mtk_ecc; | ||
24 | |||
25 | struct mtk_ecc_stats { | ||
26 | u32 corrected; | ||
27 | u32 bitflips; | ||
28 | u32 failed; | ||
29 | }; | ||
30 | |||
31 | struct mtk_ecc_config { | ||
32 | enum mtk_ecc_operation op; | ||
33 | enum mtk_ecc_mode mode; | ||
34 | dma_addr_t addr; | ||
35 | u32 strength; | ||
36 | u32 sectors; | ||
37 | u32 len; | ||
38 | }; | ||
39 | |||
40 | int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32); | ||
41 | void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int); | ||
42 | int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation); | ||
43 | int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *); | ||
44 | void mtk_ecc_disable(struct mtk_ecc *); | ||
45 | void mtk_ecc_adjust_strength(u32 *); | ||
46 | |||
47 | struct mtk_ecc *of_mtk_ecc_get(struct device_node *); | ||
48 | void mtk_ecc_release(struct mtk_ecc *); | ||
49 | |||
50 | #endif | ||
diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c new file mode 100644 index 000000000000..ddaa2acb9dd7 --- /dev/null +++ b/drivers/mtd/nand/mtk_nand.c | |||
@@ -0,0 +1,1526 @@ | |||
1 | /* | ||
2 | * MTK NAND Flash controller driver. | ||
3 | * Copyright (C) 2016 MediaTek Inc. | ||
4 | * Authors: Xiaolei Li <xiaolei.li@mediatek.com> | ||
5 | * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/dma-mapping.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/mtd/nand.h> | ||
23 | #include <linux/mtd/mtd.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/iopoll.h> | ||
26 | #include <linux/of.h> | ||
27 | #include "mtk_ecc.h" | ||
28 | |||
29 | /* NAND controller register definition */ | ||
30 | #define NFI_CNFG (0x00) | ||
31 | #define CNFG_AHB BIT(0) | ||
32 | #define CNFG_READ_EN BIT(1) | ||
33 | #define CNFG_DMA_BURST_EN BIT(2) | ||
34 | #define CNFG_BYTE_RW BIT(6) | ||
35 | #define CNFG_HW_ECC_EN BIT(8) | ||
36 | #define CNFG_AUTO_FMT_EN BIT(9) | ||
37 | #define CNFG_OP_CUST (6 << 12) | ||
38 | #define NFI_PAGEFMT (0x04) | ||
39 | #define PAGEFMT_FDM_ECC_SHIFT (12) | ||
40 | #define PAGEFMT_FDM_SHIFT (8) | ||
41 | #define PAGEFMT_SPARE_16 (0) | ||
42 | #define PAGEFMT_SPARE_26 (1) | ||
43 | #define PAGEFMT_SPARE_27 (2) | ||
44 | #define PAGEFMT_SPARE_28 (3) | ||
45 | #define PAGEFMT_SPARE_32 (4) | ||
46 | #define PAGEFMT_SPARE_36 (5) | ||
47 | #define PAGEFMT_SPARE_40 (6) | ||
48 | #define PAGEFMT_SPARE_44 (7) | ||
49 | #define PAGEFMT_SPARE_48 (8) | ||
50 | #define PAGEFMT_SPARE_49 (9) | ||
51 | #define PAGEFMT_SPARE_50 (0xa) | ||
52 | #define PAGEFMT_SPARE_51 (0xb) | ||
53 | #define PAGEFMT_SPARE_52 (0xc) | ||
54 | #define PAGEFMT_SPARE_62 (0xd) | ||
55 | #define PAGEFMT_SPARE_63 (0xe) | ||
56 | #define PAGEFMT_SPARE_64 (0xf) | ||
57 | #define PAGEFMT_SPARE_SHIFT (4) | ||
58 | #define PAGEFMT_SEC_SEL_512 BIT(2) | ||
59 | #define PAGEFMT_512_2K (0) | ||
60 | #define PAGEFMT_2K_4K (1) | ||
61 | #define PAGEFMT_4K_8K (2) | ||
62 | #define PAGEFMT_8K_16K (3) | ||
63 | /* NFI control */ | ||
64 | #define NFI_CON (0x08) | ||
65 | #define CON_FIFO_FLUSH BIT(0) | ||
66 | #define CON_NFI_RST BIT(1) | ||
67 | #define CON_BRD BIT(8) /* burst read */ | ||
68 | #define CON_BWR BIT(9) /* burst write */ | ||
69 | #define CON_SEC_SHIFT (12) | ||
70 | /* Timming control register */ | ||
71 | #define NFI_ACCCON (0x0C) | ||
72 | #define NFI_INTR_EN (0x10) | ||
73 | #define INTR_AHB_DONE_EN BIT(6) | ||
74 | #define NFI_INTR_STA (0x14) | ||
75 | #define NFI_CMD (0x20) | ||
76 | #define NFI_ADDRNOB (0x30) | ||
77 | #define NFI_COLADDR (0x34) | ||
78 | #define NFI_ROWADDR (0x38) | ||
79 | #define NFI_STRDATA (0x40) | ||
80 | #define STAR_EN (1) | ||
81 | #define STAR_DE (0) | ||
82 | #define NFI_CNRNB (0x44) | ||
83 | #define NFI_DATAW (0x50) | ||
84 | #define NFI_DATAR (0x54) | ||
85 | #define NFI_PIO_DIRDY (0x58) | ||
86 | #define PIO_DI_RDY (0x01) | ||
87 | #define NFI_STA (0x60) | ||
88 | #define STA_CMD BIT(0) | ||
89 | #define STA_ADDR BIT(1) | ||
90 | #define STA_BUSY BIT(8) | ||
91 | #define STA_EMP_PAGE BIT(12) | ||
92 | #define NFI_FSM_CUSTDATA (0xe << 16) | ||
93 | #define NFI_FSM_MASK (0xf << 16) | ||
94 | #define NFI_ADDRCNTR (0x70) | ||
95 | #define CNTR_MASK GENMASK(16, 12) | ||
96 | #define NFI_STRADDR (0x80) | ||
97 | #define NFI_BYTELEN (0x84) | ||
98 | #define NFI_CSEL (0x90) | ||
99 | #define NFI_FDML(x) (0xA0 + (x) * sizeof(u32) * 2) | ||
100 | #define NFI_FDMM(x) (0xA4 + (x) * sizeof(u32) * 2) | ||
101 | #define NFI_FDM_MAX_SIZE (8) | ||
102 | #define NFI_FDM_MIN_SIZE (1) | ||
103 | #define NFI_MASTER_STA (0x224) | ||
104 | #define MASTER_STA_MASK (0x0FFF) | ||
105 | #define NFI_EMPTY_THRESH (0x23C) | ||
106 | |||
107 | #define MTK_NAME "mtk-nand" | ||
108 | #define KB(x) ((x) * 1024UL) | ||
109 | #define MB(x) (KB(x) * 1024UL) | ||
110 | |||
111 | #define MTK_TIMEOUT (500000) | ||
112 | #define MTK_RESET_TIMEOUT (1000000) | ||
113 | #define MTK_MAX_SECTOR (16) | ||
114 | #define MTK_NAND_MAX_NSELS (2) | ||
115 | |||
116 | struct mtk_nfc_bad_mark_ctl { | ||
117 | void (*bm_swap)(struct mtd_info *, u8 *buf, int raw); | ||
118 | u32 sec; | ||
119 | u32 pos; | ||
120 | }; | ||
121 | |||
122 | /* | ||
123 | * FDM: region used to store free OOB data | ||
124 | */ | ||
125 | struct mtk_nfc_fdm { | ||
126 | u32 reg_size; | ||
127 | u32 ecc_size; | ||
128 | }; | ||
129 | |||
130 | struct mtk_nfc_nand_chip { | ||
131 | struct list_head node; | ||
132 | struct nand_chip nand; | ||
133 | |||
134 | struct mtk_nfc_bad_mark_ctl bad_mark; | ||
135 | struct mtk_nfc_fdm fdm; | ||
136 | u32 spare_per_sector; | ||
137 | |||
138 | int nsels; | ||
139 | u8 sels[0]; | ||
140 | /* nothing after this field */ | ||
141 | }; | ||
142 | |||
143 | struct mtk_nfc_clk { | ||
144 | struct clk *nfi_clk; | ||
145 | struct clk *pad_clk; | ||
146 | }; | ||
147 | |||
148 | struct mtk_nfc { | ||
149 | struct nand_hw_control controller; | ||
150 | struct mtk_ecc_config ecc_cfg; | ||
151 | struct mtk_nfc_clk clk; | ||
152 | struct mtk_ecc *ecc; | ||
153 | |||
154 | struct device *dev; | ||
155 | void __iomem *regs; | ||
156 | |||
157 | struct completion done; | ||
158 | struct list_head chips; | ||
159 | |||
160 | u8 *buffer; | ||
161 | }; | ||
162 | |||
163 | static inline struct mtk_nfc_nand_chip *to_mtk_nand(struct nand_chip *nand) | ||
164 | { | ||
165 | return container_of(nand, struct mtk_nfc_nand_chip, nand); | ||
166 | } | ||
167 | |||
168 | static inline u8 *data_ptr(struct nand_chip *chip, const u8 *p, int i) | ||
169 | { | ||
170 | return (u8 *)p + i * chip->ecc.size; | ||
171 | } | ||
172 | |||
173 | static inline u8 *oob_ptr(struct nand_chip *chip, int i) | ||
174 | { | ||
175 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
176 | u8 *poi; | ||
177 | |||
178 | /* map the sector's FDM data to free oob: | ||
179 | * the beginning of the oob area stores the FDM data of bad mark sectors | ||
180 | */ | ||
181 | |||
182 | if (i < mtk_nand->bad_mark.sec) | ||
183 | poi = chip->oob_poi + (i + 1) * mtk_nand->fdm.reg_size; | ||
184 | else if (i == mtk_nand->bad_mark.sec) | ||
185 | poi = chip->oob_poi; | ||
186 | else | ||
187 | poi = chip->oob_poi + i * mtk_nand->fdm.reg_size; | ||
188 | |||
189 | return poi; | ||
190 | } | ||
191 | |||
192 | static inline int mtk_data_len(struct nand_chip *chip) | ||
193 | { | ||
194 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
195 | |||
196 | return chip->ecc.size + mtk_nand->spare_per_sector; | ||
197 | } | ||
198 | |||
199 | static inline u8 *mtk_data_ptr(struct nand_chip *chip, int i) | ||
200 | { | ||
201 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
202 | |||
203 | return nfc->buffer + i * mtk_data_len(chip); | ||
204 | } | ||
205 | |||
206 | static inline u8 *mtk_oob_ptr(struct nand_chip *chip, int i) | ||
207 | { | ||
208 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
209 | |||
210 | return nfc->buffer + i * mtk_data_len(chip) + chip->ecc.size; | ||
211 | } | ||
212 | |||
213 | static inline void nfi_writel(struct mtk_nfc *nfc, u32 val, u32 reg) | ||
214 | { | ||
215 | writel(val, nfc->regs + reg); | ||
216 | } | ||
217 | |||
218 | static inline void nfi_writew(struct mtk_nfc *nfc, u16 val, u32 reg) | ||
219 | { | ||
220 | writew(val, nfc->regs + reg); | ||
221 | } | ||
222 | |||
223 | static inline void nfi_writeb(struct mtk_nfc *nfc, u8 val, u32 reg) | ||
224 | { | ||
225 | writeb(val, nfc->regs + reg); | ||
226 | } | ||
227 | |||
228 | static inline u32 nfi_readl(struct mtk_nfc *nfc, u32 reg) | ||
229 | { | ||
230 | return readl_relaxed(nfc->regs + reg); | ||
231 | } | ||
232 | |||
233 | static inline u16 nfi_readw(struct mtk_nfc *nfc, u32 reg) | ||
234 | { | ||
235 | return readw_relaxed(nfc->regs + reg); | ||
236 | } | ||
237 | |||
238 | static inline u8 nfi_readb(struct mtk_nfc *nfc, u32 reg) | ||
239 | { | ||
240 | return readb_relaxed(nfc->regs + reg); | ||
241 | } | ||
242 | |||
243 | static void mtk_nfc_hw_reset(struct mtk_nfc *nfc) | ||
244 | { | ||
245 | struct device *dev = nfc->dev; | ||
246 | u32 val; | ||
247 | int ret; | ||
248 | |||
249 | /* reset all registers and force the NFI master to terminate */ | ||
250 | nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON); | ||
251 | |||
252 | /* wait for the master to finish the last transaction */ | ||
253 | ret = readl_poll_timeout(nfc->regs + NFI_MASTER_STA, val, | ||
254 | !(val & MASTER_STA_MASK), 50, | ||
255 | MTK_RESET_TIMEOUT); | ||
256 | if (ret) | ||
257 | dev_warn(dev, "master active in reset [0x%x] = 0x%x\n", | ||
258 | NFI_MASTER_STA, val); | ||
259 | |||
260 | /* ensure any status register affected by the NFI master is reset */ | ||
261 | nfi_writel(nfc, CON_FIFO_FLUSH | CON_NFI_RST, NFI_CON); | ||
262 | nfi_writew(nfc, STAR_DE, NFI_STRDATA); | ||
263 | } | ||
264 | |||
265 | static int mtk_nfc_send_command(struct mtk_nfc *nfc, u8 command) | ||
266 | { | ||
267 | struct device *dev = nfc->dev; | ||
268 | u32 val; | ||
269 | int ret; | ||
270 | |||
271 | nfi_writel(nfc, command, NFI_CMD); | ||
272 | |||
273 | ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val, | ||
274 | !(val & STA_CMD), 10, MTK_TIMEOUT); | ||
275 | if (ret) { | ||
276 | dev_warn(dev, "nfi core timed out entering command mode\n"); | ||
277 | return -EIO; | ||
278 | } | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int mtk_nfc_send_address(struct mtk_nfc *nfc, int addr) | ||
284 | { | ||
285 | struct device *dev = nfc->dev; | ||
286 | u32 val; | ||
287 | int ret; | ||
288 | |||
289 | nfi_writel(nfc, addr, NFI_COLADDR); | ||
290 | nfi_writel(nfc, 0, NFI_ROWADDR); | ||
291 | nfi_writew(nfc, 1, NFI_ADDRNOB); | ||
292 | |||
293 | ret = readl_poll_timeout_atomic(nfc->regs + NFI_STA, val, | ||
294 | !(val & STA_ADDR), 10, MTK_TIMEOUT); | ||
295 | if (ret) { | ||
296 | dev_warn(dev, "nfi core timed out entering address mode\n"); | ||
297 | return -EIO; | ||
298 | } | ||
299 | |||
300 | return 0; | ||
301 | } | ||
302 | |||
303 | static int mtk_nfc_hw_runtime_config(struct mtd_info *mtd) | ||
304 | { | ||
305 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
306 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
307 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
308 | u32 fmt, spare; | ||
309 | |||
310 | if (!mtd->writesize) | ||
311 | return 0; | ||
312 | |||
313 | spare = mtk_nand->spare_per_sector; | ||
314 | |||
315 | switch (mtd->writesize) { | ||
316 | case 512: | ||
317 | fmt = PAGEFMT_512_2K | PAGEFMT_SEC_SEL_512; | ||
318 | break; | ||
319 | case KB(2): | ||
320 | if (chip->ecc.size == 512) | ||
321 | fmt = PAGEFMT_2K_4K | PAGEFMT_SEC_SEL_512; | ||
322 | else | ||
323 | fmt = PAGEFMT_512_2K; | ||
324 | break; | ||
325 | case KB(4): | ||
326 | if (chip->ecc.size == 512) | ||
327 | fmt = PAGEFMT_4K_8K | PAGEFMT_SEC_SEL_512; | ||
328 | else | ||
329 | fmt = PAGEFMT_2K_4K; | ||
330 | break; | ||
331 | case KB(8): | ||
332 | if (chip->ecc.size == 512) | ||
333 | fmt = PAGEFMT_8K_16K | PAGEFMT_SEC_SEL_512; | ||
334 | else | ||
335 | fmt = PAGEFMT_4K_8K; | ||
336 | break; | ||
337 | case KB(16): | ||
338 | fmt = PAGEFMT_8K_16K; | ||
339 | break; | ||
340 | default: | ||
341 | dev_err(nfc->dev, "invalid page len: %d\n", mtd->writesize); | ||
342 | return -EINVAL; | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * the hardware will double the value for this eccsize, so we need to | ||
347 | * halve it | ||
348 | */ | ||
349 | if (chip->ecc.size == 1024) | ||
350 | spare >>= 1; | ||
351 | |||
352 | switch (spare) { | ||
353 | case 16: | ||
354 | fmt |= (PAGEFMT_SPARE_16 << PAGEFMT_SPARE_SHIFT); | ||
355 | break; | ||
356 | case 26: | ||
357 | fmt |= (PAGEFMT_SPARE_26 << PAGEFMT_SPARE_SHIFT); | ||
358 | break; | ||
359 | case 27: | ||
360 | fmt |= (PAGEFMT_SPARE_27 << PAGEFMT_SPARE_SHIFT); | ||
361 | break; | ||
362 | case 28: | ||
363 | fmt |= (PAGEFMT_SPARE_28 << PAGEFMT_SPARE_SHIFT); | ||
364 | break; | ||
365 | case 32: | ||
366 | fmt |= (PAGEFMT_SPARE_32 << PAGEFMT_SPARE_SHIFT); | ||
367 | break; | ||
368 | case 36: | ||
369 | fmt |= (PAGEFMT_SPARE_36 << PAGEFMT_SPARE_SHIFT); | ||
370 | break; | ||
371 | case 40: | ||
372 | fmt |= (PAGEFMT_SPARE_40 << PAGEFMT_SPARE_SHIFT); | ||
373 | break; | ||
374 | case 44: | ||
375 | fmt |= (PAGEFMT_SPARE_44 << PAGEFMT_SPARE_SHIFT); | ||
376 | break; | ||
377 | case 48: | ||
378 | fmt |= (PAGEFMT_SPARE_48 << PAGEFMT_SPARE_SHIFT); | ||
379 | break; | ||
380 | case 49: | ||
381 | fmt |= (PAGEFMT_SPARE_49 << PAGEFMT_SPARE_SHIFT); | ||
382 | break; | ||
383 | case 50: | ||
384 | fmt |= (PAGEFMT_SPARE_50 << PAGEFMT_SPARE_SHIFT); | ||
385 | break; | ||
386 | case 51: | ||
387 | fmt |= (PAGEFMT_SPARE_51 << PAGEFMT_SPARE_SHIFT); | ||
388 | break; | ||
389 | case 52: | ||
390 | fmt |= (PAGEFMT_SPARE_52 << PAGEFMT_SPARE_SHIFT); | ||
391 | break; | ||
392 | case 62: | ||
393 | fmt |= (PAGEFMT_SPARE_62 << PAGEFMT_SPARE_SHIFT); | ||
394 | break; | ||
395 | case 63: | ||
396 | fmt |= (PAGEFMT_SPARE_63 << PAGEFMT_SPARE_SHIFT); | ||
397 | break; | ||
398 | case 64: | ||
399 | fmt |= (PAGEFMT_SPARE_64 << PAGEFMT_SPARE_SHIFT); | ||
400 | break; | ||
401 | default: | ||
402 | dev_err(nfc->dev, "invalid spare per sector %d\n", spare); | ||
403 | return -EINVAL; | ||
404 | } | ||
405 | |||
406 | fmt |= mtk_nand->fdm.reg_size << PAGEFMT_FDM_SHIFT; | ||
407 | fmt |= mtk_nand->fdm.ecc_size << PAGEFMT_FDM_ECC_SHIFT; | ||
408 | nfi_writew(nfc, fmt, NFI_PAGEFMT); | ||
409 | |||
410 | nfc->ecc_cfg.strength = chip->ecc.strength; | ||
411 | nfc->ecc_cfg.len = chip->ecc.size + mtk_nand->fdm.ecc_size; | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static void mtk_nfc_select_chip(struct mtd_info *mtd, int chip) | ||
417 | { | ||
418 | struct nand_chip *nand = mtd_to_nand(mtd); | ||
419 | struct mtk_nfc *nfc = nand_get_controller_data(nand); | ||
420 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(nand); | ||
421 | |||
422 | if (chip < 0) | ||
423 | return; | ||
424 | |||
425 | mtk_nfc_hw_runtime_config(mtd); | ||
426 | |||
427 | nfi_writel(nfc, mtk_nand->sels[chip], NFI_CSEL); | ||
428 | } | ||
429 | |||
430 | static int mtk_nfc_dev_ready(struct mtd_info *mtd) | ||
431 | { | ||
432 | struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); | ||
433 | |||
434 | if (nfi_readl(nfc, NFI_STA) & STA_BUSY) | ||
435 | return 0; | ||
436 | |||
437 | return 1; | ||
438 | } | ||
439 | |||
440 | static void mtk_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) | ||
441 | { | ||
442 | struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); | ||
443 | |||
444 | if (ctrl & NAND_ALE) { | ||
445 | mtk_nfc_send_address(nfc, dat); | ||
446 | } else if (ctrl & NAND_CLE) { | ||
447 | mtk_nfc_hw_reset(nfc); | ||
448 | |||
449 | nfi_writew(nfc, CNFG_OP_CUST, NFI_CNFG); | ||
450 | mtk_nfc_send_command(nfc, dat); | ||
451 | } | ||
452 | } | ||
453 | |||
454 | static inline void mtk_nfc_wait_ioready(struct mtk_nfc *nfc) | ||
455 | { | ||
456 | int rc; | ||
457 | u8 val; | ||
458 | |||
459 | rc = readb_poll_timeout_atomic(nfc->regs + NFI_PIO_DIRDY, val, | ||
460 | val & PIO_DI_RDY, 10, MTK_TIMEOUT); | ||
461 | if (rc < 0) | ||
462 | dev_err(nfc->dev, "data not ready\n"); | ||
463 | } | ||
464 | |||
465 | static inline u8 mtk_nfc_read_byte(struct mtd_info *mtd) | ||
466 | { | ||
467 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
468 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
469 | u32 reg; | ||
470 | |||
471 | /* after each byte read, the NFI_STA reg is reset by the hardware */ | ||
472 | reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK; | ||
473 | if (reg != NFI_FSM_CUSTDATA) { | ||
474 | reg = nfi_readw(nfc, NFI_CNFG); | ||
475 | reg |= CNFG_BYTE_RW | CNFG_READ_EN; | ||
476 | nfi_writew(nfc, reg, NFI_CNFG); | ||
477 | |||
478 | /* | ||
479 | * set to max sector to allow the HW to continue reading over | ||
480 | * unaligned accesses | ||
481 | */ | ||
482 | reg = (MTK_MAX_SECTOR << CON_SEC_SHIFT) | CON_BRD; | ||
483 | nfi_writel(nfc, reg, NFI_CON); | ||
484 | |||
485 | /* trigger to fetch data */ | ||
486 | nfi_writew(nfc, STAR_EN, NFI_STRDATA); | ||
487 | } | ||
488 | |||
489 | mtk_nfc_wait_ioready(nfc); | ||
490 | |||
491 | return nfi_readb(nfc, NFI_DATAR); | ||
492 | } | ||
493 | |||
494 | static void mtk_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len) | ||
495 | { | ||
496 | int i; | ||
497 | |||
498 | for (i = 0; i < len; i++) | ||
499 | buf[i] = mtk_nfc_read_byte(mtd); | ||
500 | } | ||
501 | |||
502 | static void mtk_nfc_write_byte(struct mtd_info *mtd, u8 byte) | ||
503 | { | ||
504 | struct mtk_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); | ||
505 | u32 reg; | ||
506 | |||
507 | reg = nfi_readl(nfc, NFI_STA) & NFI_FSM_MASK; | ||
508 | |||
509 | if (reg != NFI_FSM_CUSTDATA) { | ||
510 | reg = nfi_readw(nfc, NFI_CNFG) | CNFG_BYTE_RW; | ||
511 | nfi_writew(nfc, reg, NFI_CNFG); | ||
512 | |||
513 | reg = MTK_MAX_SECTOR << CON_SEC_SHIFT | CON_BWR; | ||
514 | nfi_writel(nfc, reg, NFI_CON); | ||
515 | |||
516 | nfi_writew(nfc, STAR_EN, NFI_STRDATA); | ||
517 | } | ||
518 | |||
519 | mtk_nfc_wait_ioready(nfc); | ||
520 | nfi_writeb(nfc, byte, NFI_DATAW); | ||
521 | } | ||
522 | |||
523 | static void mtk_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | ||
524 | { | ||
525 | int i; | ||
526 | |||
527 | for (i = 0; i < len; i++) | ||
528 | mtk_nfc_write_byte(mtd, buf[i]); | ||
529 | } | ||
530 | |||
531 | static int mtk_nfc_sector_encode(struct nand_chip *chip, u8 *data) | ||
532 | { | ||
533 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
534 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
535 | int size = chip->ecc.size + mtk_nand->fdm.reg_size; | ||
536 | |||
537 | nfc->ecc_cfg.mode = ECC_DMA_MODE; | ||
538 | nfc->ecc_cfg.op = ECC_ENCODE; | ||
539 | |||
540 | return mtk_ecc_encode(nfc->ecc, &nfc->ecc_cfg, data, size); | ||
541 | } | ||
542 | |||
543 | static void mtk_nfc_no_bad_mark_swap(struct mtd_info *a, u8 *b, int c) | ||
544 | { | ||
545 | /* nop */ | ||
546 | } | ||
547 | |||
548 | static void mtk_nfc_bad_mark_swap(struct mtd_info *mtd, u8 *buf, int raw) | ||
549 | { | ||
550 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
551 | struct mtk_nfc_nand_chip *nand = to_mtk_nand(chip); | ||
552 | u32 bad_pos = nand->bad_mark.pos; | ||
553 | |||
554 | if (raw) | ||
555 | bad_pos += nand->bad_mark.sec * mtk_data_len(chip); | ||
556 | else | ||
557 | bad_pos += nand->bad_mark.sec * chip->ecc.size; | ||
558 | |||
559 | swap(chip->oob_poi[0], buf[bad_pos]); | ||
560 | } | ||
561 | |||
562 | static int mtk_nfc_format_subpage(struct mtd_info *mtd, u32 offset, | ||
563 | u32 len, const u8 *buf) | ||
564 | { | ||
565 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
566 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
567 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
568 | struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; | ||
569 | u32 start, end; | ||
570 | int i, ret; | ||
571 | |||
572 | start = offset / chip->ecc.size; | ||
573 | end = DIV_ROUND_UP(offset + len, chip->ecc.size); | ||
574 | |||
575 | memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); | ||
576 | for (i = 0; i < chip->ecc.steps; i++) { | ||
577 | memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i), | ||
578 | chip->ecc.size); | ||
579 | |||
580 | if (start > i || i >= end) | ||
581 | continue; | ||
582 | |||
583 | if (i == mtk_nand->bad_mark.sec) | ||
584 | mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1); | ||
585 | |||
586 | memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size); | ||
587 | |||
588 | /* program the CRC back to the OOB */ | ||
589 | ret = mtk_nfc_sector_encode(chip, mtk_data_ptr(chip, i)); | ||
590 | if (ret < 0) | ||
591 | return ret; | ||
592 | } | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static void mtk_nfc_format_page(struct mtd_info *mtd, const u8 *buf) | ||
598 | { | ||
599 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
600 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
601 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
602 | struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; | ||
603 | u32 i; | ||
604 | |||
605 | memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); | ||
606 | for (i = 0; i < chip->ecc.steps; i++) { | ||
607 | if (buf) | ||
608 | memcpy(mtk_data_ptr(chip, i), data_ptr(chip, buf, i), | ||
609 | chip->ecc.size); | ||
610 | |||
611 | if (i == mtk_nand->bad_mark.sec) | ||
612 | mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1); | ||
613 | |||
614 | memcpy(mtk_oob_ptr(chip, i), oob_ptr(chip, i), fdm->reg_size); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | static inline void mtk_nfc_read_fdm(struct nand_chip *chip, u32 start, | ||
619 | u32 sectors) | ||
620 | { | ||
621 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
622 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
623 | struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; | ||
624 | u32 vall, valm; | ||
625 | u8 *oobptr; | ||
626 | int i, j; | ||
627 | |||
628 | for (i = 0; i < sectors; i++) { | ||
629 | oobptr = oob_ptr(chip, start + i); | ||
630 | vall = nfi_readl(nfc, NFI_FDML(i)); | ||
631 | valm = nfi_readl(nfc, NFI_FDMM(i)); | ||
632 | |||
633 | for (j = 0; j < fdm->reg_size; j++) | ||
634 | oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8); | ||
635 | } | ||
636 | } | ||
637 | |||
638 | static inline void mtk_nfc_write_fdm(struct nand_chip *chip) | ||
639 | { | ||
640 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
641 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
642 | struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; | ||
643 | u32 vall, valm; | ||
644 | u8 *oobptr; | ||
645 | int i, j; | ||
646 | |||
647 | for (i = 0; i < chip->ecc.steps; i++) { | ||
648 | oobptr = oob_ptr(chip, i); | ||
649 | vall = 0; | ||
650 | valm = 0; | ||
651 | for (j = 0; j < 8; j++) { | ||
652 | if (j < 4) | ||
653 | vall |= (j < fdm->reg_size ? oobptr[j] : 0xff) | ||
654 | << (j * 8); | ||
655 | else | ||
656 | valm |= (j < fdm->reg_size ? oobptr[j] : 0xff) | ||
657 | << ((j - 4) * 8); | ||
658 | } | ||
659 | nfi_writel(nfc, vall, NFI_FDML(i)); | ||
660 | nfi_writel(nfc, valm, NFI_FDMM(i)); | ||
661 | } | ||
662 | } | ||
663 | |||
664 | static int mtk_nfc_do_write_page(struct mtd_info *mtd, struct nand_chip *chip, | ||
665 | const u8 *buf, int page, int len) | ||
666 | { | ||
667 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
668 | struct device *dev = nfc->dev; | ||
669 | dma_addr_t addr; | ||
670 | u32 reg; | ||
671 | int ret; | ||
672 | |||
673 | addr = dma_map_single(dev, (void *)buf, len, DMA_TO_DEVICE); | ||
674 | ret = dma_mapping_error(nfc->dev, addr); | ||
675 | if (ret) { | ||
676 | dev_err(nfc->dev, "dma mapping error\n"); | ||
677 | return -EINVAL; | ||
678 | } | ||
679 | |||
680 | reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AHB | CNFG_DMA_BURST_EN; | ||
681 | nfi_writew(nfc, reg, NFI_CNFG); | ||
682 | |||
683 | nfi_writel(nfc, chip->ecc.steps << CON_SEC_SHIFT, NFI_CON); | ||
684 | nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR); | ||
685 | nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN); | ||
686 | |||
687 | init_completion(&nfc->done); | ||
688 | |||
689 | reg = nfi_readl(nfc, NFI_CON) | CON_BWR; | ||
690 | nfi_writel(nfc, reg, NFI_CON); | ||
691 | nfi_writew(nfc, STAR_EN, NFI_STRDATA); | ||
692 | |||
693 | ret = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500)); | ||
694 | if (!ret) { | ||
695 | dev_err(dev, "program ahb done timeout\n"); | ||
696 | nfi_writew(nfc, 0, NFI_INTR_EN); | ||
697 | ret = -ETIMEDOUT; | ||
698 | goto timeout; | ||
699 | } | ||
700 | |||
701 | ret = readl_poll_timeout_atomic(nfc->regs + NFI_ADDRCNTR, reg, | ||
702 | (reg & CNTR_MASK) >= chip->ecc.steps, | ||
703 | 10, MTK_TIMEOUT); | ||
704 | if (ret) | ||
705 | dev_err(dev, "hwecc write timeout\n"); | ||
706 | |||
707 | timeout: | ||
708 | |||
709 | dma_unmap_single(nfc->dev, addr, len, DMA_TO_DEVICE); | ||
710 | nfi_writel(nfc, 0, NFI_CON); | ||
711 | |||
712 | return ret; | ||
713 | } | ||
714 | |||
715 | static int mtk_nfc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | ||
716 | const u8 *buf, int page, int raw) | ||
717 | { | ||
718 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
719 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
720 | size_t len; | ||
721 | const u8 *bufpoi; | ||
722 | u32 reg; | ||
723 | int ret; | ||
724 | |||
725 | if (!raw) { | ||
726 | /* OOB => FDM: from register, ECC: from HW */ | ||
727 | reg = nfi_readw(nfc, NFI_CNFG) | CNFG_AUTO_FMT_EN; | ||
728 | nfi_writew(nfc, reg | CNFG_HW_ECC_EN, NFI_CNFG); | ||
729 | |||
730 | nfc->ecc_cfg.op = ECC_ENCODE; | ||
731 | nfc->ecc_cfg.mode = ECC_NFI_MODE; | ||
732 | ret = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg); | ||
733 | if (ret) { | ||
734 | /* clear NFI config */ | ||
735 | reg = nfi_readw(nfc, NFI_CNFG); | ||
736 | reg &= ~(CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); | ||
737 | nfi_writew(nfc, reg, NFI_CNFG); | ||
738 | |||
739 | return ret; | ||
740 | } | ||
741 | |||
742 | memcpy(nfc->buffer, buf, mtd->writesize); | ||
743 | mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, raw); | ||
744 | bufpoi = nfc->buffer; | ||
745 | |||
746 | /* write OOB into the FDM registers (OOB area in MTK NAND) */ | ||
747 | mtk_nfc_write_fdm(chip); | ||
748 | } else { | ||
749 | bufpoi = buf; | ||
750 | } | ||
751 | |||
752 | len = mtd->writesize + (raw ? mtd->oobsize : 0); | ||
753 | ret = mtk_nfc_do_write_page(mtd, chip, bufpoi, page, len); | ||
754 | |||
755 | if (!raw) | ||
756 | mtk_ecc_disable(nfc->ecc); | ||
757 | |||
758 | return ret; | ||
759 | } | ||
760 | |||
761 | static int mtk_nfc_write_page_hwecc(struct mtd_info *mtd, | ||
762 | struct nand_chip *chip, const u8 *buf, | ||
763 | int oob_on, int page) | ||
764 | { | ||
765 | return mtk_nfc_write_page(mtd, chip, buf, page, 0); | ||
766 | } | ||
767 | |||
768 | static int mtk_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | ||
769 | const u8 *buf, int oob_on, int pg) | ||
770 | { | ||
771 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
772 | |||
773 | mtk_nfc_format_page(mtd, buf); | ||
774 | return mtk_nfc_write_page(mtd, chip, nfc->buffer, pg, 1); | ||
775 | } | ||
776 | |||
777 | static int mtk_nfc_write_subpage_hwecc(struct mtd_info *mtd, | ||
778 | struct nand_chip *chip, u32 offset, | ||
779 | u32 data_len, const u8 *buf, | ||
780 | int oob_on, int page) | ||
781 | { | ||
782 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
783 | int ret; | ||
784 | |||
785 | ret = mtk_nfc_format_subpage(mtd, offset, data_len, buf); | ||
786 | if (ret < 0) | ||
787 | return ret; | ||
788 | |||
789 | /* use the data in the private buffer (now with FDM and CRC) */ | ||
790 | return mtk_nfc_write_page(mtd, chip, nfc->buffer, page, 1); | ||
791 | } | ||
792 | |||
793 | static int mtk_nfc_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, | ||
794 | int page) | ||
795 | { | ||
796 | int ret; | ||
797 | |||
798 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | ||
799 | |||
800 | ret = mtk_nfc_write_page_raw(mtd, chip, NULL, 1, page); | ||
801 | if (ret < 0) | ||
802 | return -EIO; | ||
803 | |||
804 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
805 | ret = chip->waitfunc(mtd, chip); | ||
806 | |||
807 | return ret & NAND_STATUS_FAIL ? -EIO : 0; | ||
808 | } | ||
809 | |||
810 | static int mtk_nfc_update_ecc_stats(struct mtd_info *mtd, u8 *buf, u32 sectors) | ||
811 | { | ||
812 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
813 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
814 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
815 | struct mtk_ecc_stats stats; | ||
816 | int rc, i; | ||
817 | |||
818 | rc = nfi_readl(nfc, NFI_STA) & STA_EMP_PAGE; | ||
819 | if (rc) { | ||
820 | memset(buf, 0xff, sectors * chip->ecc.size); | ||
821 | for (i = 0; i < sectors; i++) | ||
822 | memset(oob_ptr(chip, i), 0xff, mtk_nand->fdm.reg_size); | ||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | mtk_ecc_get_stats(nfc->ecc, &stats, sectors); | ||
827 | mtd->ecc_stats.corrected += stats.corrected; | ||
828 | mtd->ecc_stats.failed += stats.failed; | ||
829 | |||
830 | return stats.bitflips; | ||
831 | } | ||
832 | |||
833 | static int mtk_nfc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | ||
834 | u32 data_offs, u32 readlen, | ||
835 | u8 *bufpoi, int page, int raw) | ||
836 | { | ||
837 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
838 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
839 | u32 spare = mtk_nand->spare_per_sector; | ||
840 | u32 column, sectors, start, end, reg; | ||
841 | dma_addr_t addr; | ||
842 | int bitflips; | ||
843 | size_t len; | ||
844 | u8 *buf; | ||
845 | int rc; | ||
846 | |||
847 | start = data_offs / chip->ecc.size; | ||
848 | end = DIV_ROUND_UP(data_offs + readlen, chip->ecc.size); | ||
849 | |||
850 | sectors = end - start; | ||
851 | column = start * (chip->ecc.size + spare); | ||
852 | |||
853 | len = sectors * chip->ecc.size + (raw ? sectors * spare : 0); | ||
854 | buf = bufpoi + start * chip->ecc.size; | ||
855 | |||
856 | if (column != 0) | ||
857 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, column, -1); | ||
858 | |||
859 | addr = dma_map_single(nfc->dev, buf, len, DMA_FROM_DEVICE); | ||
860 | rc = dma_mapping_error(nfc->dev, addr); | ||
861 | if (rc) { | ||
862 | dev_err(nfc->dev, "dma mapping error\n"); | ||
863 | |||
864 | return -EINVAL; | ||
865 | } | ||
866 | |||
867 | reg = nfi_readw(nfc, NFI_CNFG); | ||
868 | reg |= CNFG_READ_EN | CNFG_DMA_BURST_EN | CNFG_AHB; | ||
869 | if (!raw) { | ||
870 | reg |= CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN; | ||
871 | nfi_writew(nfc, reg, NFI_CNFG); | ||
872 | |||
873 | nfc->ecc_cfg.mode = ECC_NFI_MODE; | ||
874 | nfc->ecc_cfg.sectors = sectors; | ||
875 | nfc->ecc_cfg.op = ECC_DECODE; | ||
876 | rc = mtk_ecc_enable(nfc->ecc, &nfc->ecc_cfg); | ||
877 | if (rc) { | ||
878 | dev_err(nfc->dev, "ecc enable\n"); | ||
879 | /* clear NFI_CNFG */ | ||
880 | reg &= ~(CNFG_DMA_BURST_EN | CNFG_AHB | CNFG_READ_EN | | ||
881 | CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); | ||
882 | nfi_writew(nfc, reg, NFI_CNFG); | ||
883 | dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE); | ||
884 | |||
885 | return rc; | ||
886 | } | ||
887 | } else { | ||
888 | nfi_writew(nfc, reg, NFI_CNFG); | ||
889 | } | ||
890 | |||
891 | nfi_writel(nfc, sectors << CON_SEC_SHIFT, NFI_CON); | ||
892 | nfi_writew(nfc, INTR_AHB_DONE_EN, NFI_INTR_EN); | ||
893 | nfi_writel(nfc, lower_32_bits(addr), NFI_STRADDR); | ||
894 | |||
895 | init_completion(&nfc->done); | ||
896 | reg = nfi_readl(nfc, NFI_CON) | CON_BRD; | ||
897 | nfi_writel(nfc, reg, NFI_CON); | ||
898 | nfi_writew(nfc, STAR_EN, NFI_STRDATA); | ||
899 | |||
900 | rc = wait_for_completion_timeout(&nfc->done, msecs_to_jiffies(500)); | ||
901 | if (!rc) | ||
902 | dev_warn(nfc->dev, "read ahb/dma done timeout\n"); | ||
903 | |||
904 | rc = readl_poll_timeout_atomic(nfc->regs + NFI_BYTELEN, reg, | ||
905 | (reg & CNTR_MASK) >= sectors, 10, | ||
906 | MTK_TIMEOUT); | ||
907 | if (rc < 0) { | ||
908 | dev_err(nfc->dev, "subpage done timeout\n"); | ||
909 | bitflips = -EIO; | ||
910 | } else { | ||
911 | bitflips = 0; | ||
912 | if (!raw) { | ||
913 | rc = mtk_ecc_wait_done(nfc->ecc, ECC_DECODE); | ||
914 | bitflips = rc < 0 ? -ETIMEDOUT : | ||
915 | mtk_nfc_update_ecc_stats(mtd, buf, sectors); | ||
916 | mtk_nfc_read_fdm(chip, start, sectors); | ||
917 | } | ||
918 | } | ||
919 | |||
920 | dma_unmap_single(nfc->dev, addr, len, DMA_FROM_DEVICE); | ||
921 | |||
922 | if (raw) | ||
923 | goto done; | ||
924 | |||
925 | mtk_ecc_disable(nfc->ecc); | ||
926 | |||
927 | if (clamp(mtk_nand->bad_mark.sec, start, end) == mtk_nand->bad_mark.sec) | ||
928 | mtk_nand->bad_mark.bm_swap(mtd, bufpoi, raw); | ||
929 | done: | ||
930 | nfi_writel(nfc, 0, NFI_CON); | ||
931 | |||
932 | return bitflips; | ||
933 | } | ||
934 | |||
935 | static int mtk_nfc_read_subpage_hwecc(struct mtd_info *mtd, | ||
936 | struct nand_chip *chip, u32 off, | ||
937 | u32 len, u8 *p, int pg) | ||
938 | { | ||
939 | return mtk_nfc_read_subpage(mtd, chip, off, len, p, pg, 0); | ||
940 | } | ||
941 | |||
942 | static int mtk_nfc_read_page_hwecc(struct mtd_info *mtd, | ||
943 | struct nand_chip *chip, u8 *p, | ||
944 | int oob_on, int pg) | ||
945 | { | ||
946 | return mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, p, pg, 0); | ||
947 | } | ||
948 | |||
949 | static int mtk_nfc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | ||
950 | u8 *buf, int oob_on, int page) | ||
951 | { | ||
952 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
953 | struct mtk_nfc *nfc = nand_get_controller_data(chip); | ||
954 | struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; | ||
955 | int i, ret; | ||
956 | |||
957 | memset(nfc->buffer, 0xff, mtd->writesize + mtd->oobsize); | ||
958 | ret = mtk_nfc_read_subpage(mtd, chip, 0, mtd->writesize, nfc->buffer, | ||
959 | page, 1); | ||
960 | if (ret < 0) | ||
961 | return ret; | ||
962 | |||
963 | for (i = 0; i < chip->ecc.steps; i++) { | ||
964 | memcpy(oob_ptr(chip, i), mtk_oob_ptr(chip, i), fdm->reg_size); | ||
965 | |||
966 | if (i == mtk_nand->bad_mark.sec) | ||
967 | mtk_nand->bad_mark.bm_swap(mtd, nfc->buffer, 1); | ||
968 | |||
969 | if (buf) | ||
970 | memcpy(data_ptr(chip, buf, i), mtk_data_ptr(chip, i), | ||
971 | chip->ecc.size); | ||
972 | } | ||
973 | |||
974 | return ret; | ||
975 | } | ||
976 | |||
977 | static int mtk_nfc_read_oob_std(struct mtd_info *mtd, struct nand_chip *chip, | ||
978 | int page) | ||
979 | { | ||
980 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); | ||
981 | |||
982 | return mtk_nfc_read_page_raw(mtd, chip, NULL, 1, page); | ||
983 | } | ||
984 | |||
985 | static inline void mtk_nfc_hw_init(struct mtk_nfc *nfc) | ||
986 | { | ||
987 | /* | ||
988 | * ACCON: access timing control register | ||
989 | * ------------------------------------- | ||
990 | * 31:28: minimum required time for CS post pulling down after accessing | ||
991 | * the device | ||
992 | * 27:22: minimum required time for CS pre pulling down before accessing | ||
993 | * the device | ||
994 | * 21:16: minimum required time from NCEB low to NREB low | ||
995 | * 15:12: minimum required time from NWEB high to NREB low. | ||
996 | * 11:08: write enable hold time | ||
997 | * 07:04: write wait states | ||
998 | * 03:00: read wait states | ||
999 | */ | ||
1000 | nfi_writel(nfc, 0x10804211, NFI_ACCCON); | ||
1001 | |||
1002 | /* | ||
1003 | * CNRNB: nand ready/busy register | ||
1004 | * ------------------------------- | ||
1005 | * 7:4: timeout register for polling the NAND busy/ready signal | ||
1006 | * 0 : poll the status of the busy/ready signal after [7:4]*16 cycles. | ||
1007 | */ | ||
1008 | nfi_writew(nfc, 0xf1, NFI_CNRNB); | ||
1009 | nfi_writew(nfc, PAGEFMT_8K_16K, NFI_PAGEFMT); | ||
1010 | |||
1011 | mtk_nfc_hw_reset(nfc); | ||
1012 | |||
1013 | nfi_readl(nfc, NFI_INTR_STA); | ||
1014 | nfi_writel(nfc, 0, NFI_INTR_EN); | ||
1015 | } | ||
1016 | |||
1017 | static irqreturn_t mtk_nfc_irq(int irq, void *id) | ||
1018 | { | ||
1019 | struct mtk_nfc *nfc = id; | ||
1020 | u16 sta, ien; | ||
1021 | |||
1022 | sta = nfi_readw(nfc, NFI_INTR_STA); | ||
1023 | ien = nfi_readw(nfc, NFI_INTR_EN); | ||
1024 | |||
1025 | if (!(sta & ien)) | ||
1026 | return IRQ_NONE; | ||
1027 | |||
1028 | nfi_writew(nfc, ~sta & ien, NFI_INTR_EN); | ||
1029 | complete(&nfc->done); | ||
1030 | |||
1031 | return IRQ_HANDLED; | ||
1032 | } | ||
1033 | |||
1034 | static int mtk_nfc_enable_clk(struct device *dev, struct mtk_nfc_clk *clk) | ||
1035 | { | ||
1036 | int ret; | ||
1037 | |||
1038 | ret = clk_prepare_enable(clk->nfi_clk); | ||
1039 | if (ret) { | ||
1040 | dev_err(dev, "failed to enable nfi clk\n"); | ||
1041 | return ret; | ||
1042 | } | ||
1043 | |||
1044 | ret = clk_prepare_enable(clk->pad_clk); | ||
1045 | if (ret) { | ||
1046 | dev_err(dev, "failed to enable pad clk\n"); | ||
1047 | clk_disable_unprepare(clk->nfi_clk); | ||
1048 | return ret; | ||
1049 | } | ||
1050 | |||
1051 | return 0; | ||
1052 | } | ||
1053 | |||
1054 | static void mtk_nfc_disable_clk(struct mtk_nfc_clk *clk) | ||
1055 | { | ||
1056 | clk_disable_unprepare(clk->nfi_clk); | ||
1057 | clk_disable_unprepare(clk->pad_clk); | ||
1058 | } | ||
1059 | |||
1060 | static int mtk_nfc_ooblayout_free(struct mtd_info *mtd, int section, | ||
1061 | struct mtd_oob_region *oob_region) | ||
1062 | { | ||
1063 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
1064 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
1065 | struct mtk_nfc_fdm *fdm = &mtk_nand->fdm; | ||
1066 | u32 eccsteps; | ||
1067 | |||
1068 | eccsteps = mtd->writesize / chip->ecc.size; | ||
1069 | |||
1070 | if (section >= eccsteps) | ||
1071 | return -ERANGE; | ||
1072 | |||
1073 | oob_region->length = fdm->reg_size - fdm->ecc_size; | ||
1074 | oob_region->offset = section * fdm->reg_size + fdm->ecc_size; | ||
1075 | |||
1076 | return 0; | ||
1077 | } | ||
1078 | |||
1079 | static int mtk_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, | ||
1080 | struct mtd_oob_region *oob_region) | ||
1081 | { | ||
1082 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
1083 | struct mtk_nfc_nand_chip *mtk_nand = to_mtk_nand(chip); | ||
1084 | u32 eccsteps; | ||
1085 | |||
1086 | if (section) | ||
1087 | return -ERANGE; | ||
1088 | |||
1089 | eccsteps = mtd->writesize / chip->ecc.size; | ||
1090 | oob_region->offset = mtk_nand->fdm.reg_size * eccsteps; | ||
1091 | oob_region->length = mtd->oobsize - oob_region->offset; | ||
1092 | |||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | static const struct mtd_ooblayout_ops mtk_nfc_ooblayout_ops = { | ||
1097 | .free = mtk_nfc_ooblayout_free, | ||
1098 | .ecc = mtk_nfc_ooblayout_ecc, | ||
1099 | }; | ||
1100 | |||
1101 | static void mtk_nfc_set_fdm(struct mtk_nfc_fdm *fdm, struct mtd_info *mtd) | ||
1102 | { | ||
1103 | struct nand_chip *nand = mtd_to_nand(mtd); | ||
1104 | struct mtk_nfc_nand_chip *chip = to_mtk_nand(nand); | ||
1105 | u32 ecc_bytes; | ||
1106 | |||
1107 | ecc_bytes = DIV_ROUND_UP(nand->ecc.strength * ECC_PARITY_BITS, 8); | ||
1108 | |||
1109 | fdm->reg_size = chip->spare_per_sector - ecc_bytes; | ||
1110 | if (fdm->reg_size > NFI_FDM_MAX_SIZE) | ||
1111 | fdm->reg_size = NFI_FDM_MAX_SIZE; | ||
1112 | |||
1113 | /* bad block mark storage */ | ||
1114 | fdm->ecc_size = 1; | ||
1115 | } | ||
1116 | |||
1117 | static void mtk_nfc_set_bad_mark_ctl(struct mtk_nfc_bad_mark_ctl *bm_ctl, | ||
1118 | struct mtd_info *mtd) | ||
1119 | { | ||
1120 | struct nand_chip *nand = mtd_to_nand(mtd); | ||
1121 | |||
1122 | if (mtd->writesize == 512) { | ||
1123 | bm_ctl->bm_swap = mtk_nfc_no_bad_mark_swap; | ||
1124 | } else { | ||
1125 | bm_ctl->bm_swap = mtk_nfc_bad_mark_swap; | ||
1126 | bm_ctl->sec = mtd->writesize / mtk_data_len(nand); | ||
1127 | bm_ctl->pos = mtd->writesize % mtk_data_len(nand); | ||
1128 | } | ||
1129 | } | ||
1130 | |||
1131 | static void mtk_nfc_set_spare_per_sector(u32 *sps, struct mtd_info *mtd) | ||
1132 | { | ||
1133 | struct nand_chip *nand = mtd_to_nand(mtd); | ||
1134 | u32 spare[] = {16, 26, 27, 28, 32, 36, 40, 44, | ||
1135 | 48, 49, 50, 51, 52, 62, 63, 64}; | ||
1136 | u32 eccsteps, i; | ||
1137 | |||
1138 | eccsteps = mtd->writesize / nand->ecc.size; | ||
1139 | *sps = mtd->oobsize / eccsteps; | ||
1140 | |||
1141 | if (nand->ecc.size == 1024) | ||
1142 | *sps >>= 1; | ||
1143 | |||
1144 | for (i = 0; i < ARRAY_SIZE(spare); i++) { | ||
1145 | if (*sps <= spare[i]) { | ||
1146 | if (!i) | ||
1147 | *sps = spare[i]; | ||
1148 | else if (*sps != spare[i]) | ||
1149 | *sps = spare[i - 1]; | ||
1150 | break; | ||
1151 | } | ||
1152 | } | ||
1153 | |||
1154 | if (i >= ARRAY_SIZE(spare)) | ||
1155 | *sps = spare[ARRAY_SIZE(spare) - 1]; | ||
1156 | |||
1157 | if (nand->ecc.size == 1024) | ||
1158 | *sps <<= 1; | ||
1159 | } | ||
1160 | |||
1161 | static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd) | ||
1162 | { | ||
1163 | struct nand_chip *nand = mtd_to_nand(mtd); | ||
1164 | u32 spare; | ||
1165 | int free; | ||
1166 | |||
1167 | /* support only ecc hw mode */ | ||
1168 | if (nand->ecc.mode != NAND_ECC_HW) { | ||
1169 | dev_err(dev, "ecc.mode not supported\n"); | ||
1170 | return -EINVAL; | ||
1171 | } | ||
1172 | |||
1173 | /* if optional dt settings not present */ | ||
1174 | if (!nand->ecc.size || !nand->ecc.strength) { | ||
1175 | /* use datasheet requirements */ | ||
1176 | nand->ecc.strength = nand->ecc_strength_ds; | ||
1177 | nand->ecc.size = nand->ecc_step_ds; | ||
1178 | |||
1179 | /* | ||
1180 | * align eccstrength and eccsize | ||
1181 | * this controller only supports 512 and 1024 sizes | ||
1182 | */ | ||
1183 | if (nand->ecc.size < 1024) { | ||
1184 | if (mtd->writesize > 512) { | ||
1185 | nand->ecc.size = 1024; | ||
1186 | nand->ecc.strength <<= 1; | ||
1187 | } else { | ||
1188 | nand->ecc.size = 512; | ||
1189 | } | ||
1190 | } else { | ||
1191 | nand->ecc.size = 1024; | ||
1192 | } | ||
1193 | |||
1194 | mtk_nfc_set_spare_per_sector(&spare, mtd); | ||
1195 | |||
1196 | /* calculate oob bytes except ecc parity data */ | ||
1197 | free = ((nand->ecc.strength * ECC_PARITY_BITS) + 7) >> 3; | ||
1198 | free = spare - free; | ||
1199 | |||
1200 | /* | ||
1201 | * enhance ecc strength if oob left is bigger than max FDM size | ||
1202 | * or reduce ecc strength if oob size is not enough for ecc | ||
1203 | * parity data. | ||
1204 | */ | ||
1205 | if (free > NFI_FDM_MAX_SIZE) { | ||
1206 | spare -= NFI_FDM_MAX_SIZE; | ||
1207 | nand->ecc.strength = (spare << 3) / ECC_PARITY_BITS; | ||
1208 | } else if (free < 0) { | ||
1209 | spare -= NFI_FDM_MIN_SIZE; | ||
1210 | nand->ecc.strength = (spare << 3) / ECC_PARITY_BITS; | ||
1211 | } | ||
1212 | } | ||
1213 | |||
1214 | mtk_ecc_adjust_strength(&nand->ecc.strength); | ||
1215 | |||
1216 | dev_info(dev, "eccsize %d eccstrength %d\n", | ||
1217 | nand->ecc.size, nand->ecc.strength); | ||
1218 | |||
1219 | return 0; | ||
1220 | } | ||
1221 | |||
1222 | static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc, | ||
1223 | struct device_node *np) | ||
1224 | { | ||
1225 | struct mtk_nfc_nand_chip *chip; | ||
1226 | struct nand_chip *nand; | ||
1227 | struct mtd_info *mtd; | ||
1228 | int nsels, len; | ||
1229 | u32 tmp; | ||
1230 | int ret; | ||
1231 | int i; | ||
1232 | |||
1233 | if (!of_get_property(np, "reg", &nsels)) | ||
1234 | return -ENODEV; | ||
1235 | |||
1236 | nsels /= sizeof(u32); | ||
1237 | if (!nsels || nsels > MTK_NAND_MAX_NSELS) { | ||
1238 | dev_err(dev, "invalid reg property size %d\n", nsels); | ||
1239 | return -EINVAL; | ||
1240 | } | ||
1241 | |||
1242 | chip = devm_kzalloc(dev, sizeof(*chip) + nsels * sizeof(u8), | ||
1243 | GFP_KERNEL); | ||
1244 | if (!chip) | ||
1245 | return -ENOMEM; | ||
1246 | |||
1247 | chip->nsels = nsels; | ||
1248 | for (i = 0; i < nsels; i++) { | ||
1249 | ret = of_property_read_u32_index(np, "reg", i, &tmp); | ||
1250 | if (ret) { | ||
1251 | dev_err(dev, "reg property failure : %d\n", ret); | ||
1252 | return ret; | ||
1253 | } | ||
1254 | chip->sels[i] = tmp; | ||
1255 | } | ||
1256 | |||
1257 | nand = &chip->nand; | ||
1258 | nand->controller = &nfc->controller; | ||
1259 | |||
1260 | nand_set_flash_node(nand, np); | ||
1261 | nand_set_controller_data(nand, nfc); | ||
1262 | |||
1263 | nand->options |= NAND_USE_BOUNCE_BUFFER | NAND_SUBPAGE_READ; | ||
1264 | nand->dev_ready = mtk_nfc_dev_ready; | ||
1265 | nand->select_chip = mtk_nfc_select_chip; | ||
1266 | nand->write_byte = mtk_nfc_write_byte; | ||
1267 | nand->write_buf = mtk_nfc_write_buf; | ||
1268 | nand->read_byte = mtk_nfc_read_byte; | ||
1269 | nand->read_buf = mtk_nfc_read_buf; | ||
1270 | nand->cmd_ctrl = mtk_nfc_cmd_ctrl; | ||
1271 | |||
1272 | /* set default mode in case dt entry is missing */ | ||
1273 | nand->ecc.mode = NAND_ECC_HW; | ||
1274 | |||
1275 | nand->ecc.write_subpage = mtk_nfc_write_subpage_hwecc; | ||
1276 | nand->ecc.write_page_raw = mtk_nfc_write_page_raw; | ||
1277 | nand->ecc.write_page = mtk_nfc_write_page_hwecc; | ||
1278 | nand->ecc.write_oob_raw = mtk_nfc_write_oob_std; | ||
1279 | nand->ecc.write_oob = mtk_nfc_write_oob_std; | ||
1280 | |||
1281 | nand->ecc.read_subpage = mtk_nfc_read_subpage_hwecc; | ||
1282 | nand->ecc.read_page_raw = mtk_nfc_read_page_raw; | ||
1283 | nand->ecc.read_page = mtk_nfc_read_page_hwecc; | ||
1284 | nand->ecc.read_oob_raw = mtk_nfc_read_oob_std; | ||
1285 | nand->ecc.read_oob = mtk_nfc_read_oob_std; | ||
1286 | |||
1287 | mtd = nand_to_mtd(nand); | ||
1288 | mtd->owner = THIS_MODULE; | ||
1289 | mtd->dev.parent = dev; | ||
1290 | mtd->name = MTK_NAME; | ||
1291 | mtd_set_ooblayout(mtd, &mtk_nfc_ooblayout_ops); | ||
1292 | |||
1293 | mtk_nfc_hw_init(nfc); | ||
1294 | |||
1295 | ret = nand_scan_ident(mtd, nsels, NULL); | ||
1296 | if (ret) | ||
1297 | return -ENODEV; | ||
1298 | |||
1299 | /* store bbt magic in page, cause OOB is not protected */ | ||
1300 | if (nand->bbt_options & NAND_BBT_USE_FLASH) | ||
1301 | nand->bbt_options |= NAND_BBT_NO_OOB; | ||
1302 | |||
1303 | ret = mtk_nfc_ecc_init(dev, mtd); | ||
1304 | if (ret) | ||
1305 | return -EINVAL; | ||
1306 | |||
1307 | if (nand->options & NAND_BUSWIDTH_16) { | ||
1308 | dev_err(dev, "16bits buswidth not supported"); | ||
1309 | return -EINVAL; | ||
1310 | } | ||
1311 | |||
1312 | mtk_nfc_set_spare_per_sector(&chip->spare_per_sector, mtd); | ||
1313 | mtk_nfc_set_fdm(&chip->fdm, mtd); | ||
1314 | mtk_nfc_set_bad_mark_ctl(&chip->bad_mark, mtd); | ||
1315 | |||
1316 | len = mtd->writesize + mtd->oobsize; | ||
1317 | nfc->buffer = devm_kzalloc(dev, len, GFP_KERNEL); | ||
1318 | if (!nfc->buffer) | ||
1319 | return -ENOMEM; | ||
1320 | |||
1321 | ret = nand_scan_tail(mtd); | ||
1322 | if (ret) | ||
1323 | return -ENODEV; | ||
1324 | |||
1325 | ret = mtd_device_parse_register(mtd, NULL, NULL, NULL, 0); | ||
1326 | if (ret) { | ||
1327 | dev_err(dev, "mtd parse partition error\n"); | ||
1328 | nand_release(mtd); | ||
1329 | return ret; | ||
1330 | } | ||
1331 | |||
1332 | list_add_tail(&chip->node, &nfc->chips); | ||
1333 | |||
1334 | return 0; | ||
1335 | } | ||
1336 | |||
1337 | static int mtk_nfc_nand_chips_init(struct device *dev, struct mtk_nfc *nfc) | ||
1338 | { | ||
1339 | struct device_node *np = dev->of_node; | ||
1340 | struct device_node *nand_np; | ||
1341 | int ret; | ||
1342 | |||
1343 | for_each_child_of_node(np, nand_np) { | ||
1344 | ret = mtk_nfc_nand_chip_init(dev, nfc, nand_np); | ||
1345 | if (ret) { | ||
1346 | of_node_put(nand_np); | ||
1347 | return ret; | ||
1348 | } | ||
1349 | } | ||
1350 | |||
1351 | return 0; | ||
1352 | } | ||
1353 | |||
1354 | static int mtk_nfc_probe(struct platform_device *pdev) | ||
1355 | { | ||
1356 | struct device *dev = &pdev->dev; | ||
1357 | struct device_node *np = dev->of_node; | ||
1358 | struct mtk_nfc *nfc; | ||
1359 | struct resource *res; | ||
1360 | int ret, irq; | ||
1361 | |||
1362 | nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); | ||
1363 | if (!nfc) | ||
1364 | return -ENOMEM; | ||
1365 | |||
1366 | spin_lock_init(&nfc->controller.lock); | ||
1367 | init_waitqueue_head(&nfc->controller.wq); | ||
1368 | INIT_LIST_HEAD(&nfc->chips); | ||
1369 | |||
1370 | /* probe defer if not ready */ | ||
1371 | nfc->ecc = of_mtk_ecc_get(np); | ||
1372 | if (IS_ERR(nfc->ecc)) | ||
1373 | return PTR_ERR(nfc->ecc); | ||
1374 | else if (!nfc->ecc) | ||
1375 | return -ENODEV; | ||
1376 | |||
1377 | nfc->dev = dev; | ||
1378 | |||
1379 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1380 | nfc->regs = devm_ioremap_resource(dev, res); | ||
1381 | if (IS_ERR(nfc->regs)) { | ||
1382 | ret = PTR_ERR(nfc->regs); | ||
1383 | dev_err(dev, "no nfi base\n"); | ||
1384 | goto release_ecc; | ||
1385 | } | ||
1386 | |||
1387 | nfc->clk.nfi_clk = devm_clk_get(dev, "nfi_clk"); | ||
1388 | if (IS_ERR(nfc->clk.nfi_clk)) { | ||
1389 | dev_err(dev, "no clk\n"); | ||
1390 | ret = PTR_ERR(nfc->clk.nfi_clk); | ||
1391 | goto release_ecc; | ||
1392 | } | ||
1393 | |||
1394 | nfc->clk.pad_clk = devm_clk_get(dev, "pad_clk"); | ||
1395 | if (IS_ERR(nfc->clk.pad_clk)) { | ||
1396 | dev_err(dev, "no pad clk\n"); | ||
1397 | ret = PTR_ERR(nfc->clk.pad_clk); | ||
1398 | goto release_ecc; | ||
1399 | } | ||
1400 | |||
1401 | ret = mtk_nfc_enable_clk(dev, &nfc->clk); | ||
1402 | if (ret) | ||
1403 | goto release_ecc; | ||
1404 | |||
1405 | irq = platform_get_irq(pdev, 0); | ||
1406 | if (irq < 0) { | ||
1407 | dev_err(dev, "no nfi irq resource\n"); | ||
1408 | ret = -EINVAL; | ||
1409 | goto clk_disable; | ||
1410 | } | ||
1411 | |||
1412 | ret = devm_request_irq(dev, irq, mtk_nfc_irq, 0x0, "mtk-nand", nfc); | ||
1413 | if (ret) { | ||
1414 | dev_err(dev, "failed to request nfi irq\n"); | ||
1415 | goto clk_disable; | ||
1416 | } | ||
1417 | |||
1418 | ret = dma_set_mask(dev, DMA_BIT_MASK(32)); | ||
1419 | if (ret) { | ||
1420 | dev_err(dev, "failed to set dma mask\n"); | ||
1421 | goto clk_disable; | ||
1422 | } | ||
1423 | |||
1424 | platform_set_drvdata(pdev, nfc); | ||
1425 | |||
1426 | ret = mtk_nfc_nand_chips_init(dev, nfc); | ||
1427 | if (ret) { | ||
1428 | dev_err(dev, "failed to init nand chips\n"); | ||
1429 | goto clk_disable; | ||
1430 | } | ||
1431 | |||
1432 | return 0; | ||
1433 | |||
1434 | clk_disable: | ||
1435 | mtk_nfc_disable_clk(&nfc->clk); | ||
1436 | |||
1437 | release_ecc: | ||
1438 | mtk_ecc_release(nfc->ecc); | ||
1439 | |||
1440 | return ret; | ||
1441 | } | ||
1442 | |||
1443 | static int mtk_nfc_remove(struct platform_device *pdev) | ||
1444 | { | ||
1445 | struct mtk_nfc *nfc = platform_get_drvdata(pdev); | ||
1446 | struct mtk_nfc_nand_chip *chip; | ||
1447 | |||
1448 | while (!list_empty(&nfc->chips)) { | ||
1449 | chip = list_first_entry(&nfc->chips, struct mtk_nfc_nand_chip, | ||
1450 | node); | ||
1451 | nand_release(nand_to_mtd(&chip->nand)); | ||
1452 | list_del(&chip->node); | ||
1453 | } | ||
1454 | |||
1455 | mtk_ecc_release(nfc->ecc); | ||
1456 | mtk_nfc_disable_clk(&nfc->clk); | ||
1457 | |||
1458 | return 0; | ||
1459 | } | ||
1460 | |||
1461 | #ifdef CONFIG_PM_SLEEP | ||
1462 | static int mtk_nfc_suspend(struct device *dev) | ||
1463 | { | ||
1464 | struct mtk_nfc *nfc = dev_get_drvdata(dev); | ||
1465 | |||
1466 | mtk_nfc_disable_clk(&nfc->clk); | ||
1467 | |||
1468 | return 0; | ||
1469 | } | ||
1470 | |||
1471 | static int mtk_nfc_resume(struct device *dev) | ||
1472 | { | ||
1473 | struct mtk_nfc *nfc = dev_get_drvdata(dev); | ||
1474 | struct mtk_nfc_nand_chip *chip; | ||
1475 | struct nand_chip *nand; | ||
1476 | struct mtd_info *mtd; | ||
1477 | int ret; | ||
1478 | u32 i; | ||
1479 | |||
1480 | udelay(200); | ||
1481 | |||
1482 | ret = mtk_nfc_enable_clk(dev, &nfc->clk); | ||
1483 | if (ret) | ||
1484 | return ret; | ||
1485 | |||
1486 | mtk_nfc_hw_init(nfc); | ||
1487 | |||
1488 | /* reset NAND chip if VCC was powered off */ | ||
1489 | list_for_each_entry(chip, &nfc->chips, node) { | ||
1490 | nand = &chip->nand; | ||
1491 | mtd = nand_to_mtd(nand); | ||
1492 | for (i = 0; i < chip->nsels; i++) { | ||
1493 | nand->select_chip(mtd, i); | ||
1494 | nand->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | ||
1495 | } | ||
1496 | } | ||
1497 | |||
1498 | return 0; | ||
1499 | } | ||
1500 | |||
1501 | static SIMPLE_DEV_PM_OPS(mtk_nfc_pm_ops, mtk_nfc_suspend, mtk_nfc_resume); | ||
1502 | #endif | ||
1503 | |||
1504 | static const struct of_device_id mtk_nfc_id_table[] = { | ||
1505 | { .compatible = "mediatek,mt2701-nfc" }, | ||
1506 | {} | ||
1507 | }; | ||
1508 | MODULE_DEVICE_TABLE(of, mtk_nfc_id_table); | ||
1509 | |||
1510 | static struct platform_driver mtk_nfc_driver = { | ||
1511 | .probe = mtk_nfc_probe, | ||
1512 | .remove = mtk_nfc_remove, | ||
1513 | .driver = { | ||
1514 | .name = MTK_NAME, | ||
1515 | .of_match_table = mtk_nfc_id_table, | ||
1516 | #ifdef CONFIG_PM_SLEEP | ||
1517 | .pm = &mtk_nfc_pm_ops, | ||
1518 | #endif | ||
1519 | }, | ||
1520 | }; | ||
1521 | |||
1522 | module_platform_driver(mtk_nfc_driver); | ||
1523 | |||
1524 | MODULE_LICENSE("GPL"); | ||
1525 | MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>"); | ||
1526 | MODULE_DESCRIPTION("MTK Nand Flash Controller Driver"); | ||