1 From ebb9653d4a87c64fb679e4c339e867556dada719 Mon Sep 17 00:00:00 2001
2 From: Chuanhong Guo <gch981213@gmail.com>
3 Date: Tue, 22 Mar 2022 18:44:21 +0800
4 Subject: [PATCH 11/15] mtd: nand: make mtk_ecc.c a separated module
6 this code will be used in mediatek snfi spi-mem controller with
9 Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
10 (cherry picked from commit 316f47cec4ce5b81aa8006de202d8769c117a52d)
12 drivers/mtd/nand/Kconfig | 7 +++++++
13 drivers/mtd/nand/Makefile | 1 +
14 drivers/mtd/nand/{raw/mtk_ecc.c => ecc-mtk.c} | 3 +--
15 drivers/mtd/nand/raw/Kconfig | 1 +
16 drivers/mtd/nand/raw/Makefile | 2 +-
17 drivers/mtd/nand/raw/mtk_nand.c | 2 +-
18 .../nand/raw/mtk_ecc.h => include/linux/mtd/nand-ecc-mtk.h | 0
19 7 files changed, 12 insertions(+), 4 deletions(-)
20 rename drivers/mtd/nand/{raw/mtk_ecc.c => ecc-mtk.c} (99%)
21 rename drivers/mtd/nand/raw/mtk_ecc.h => include/linux/mtd/nand-ecc-mtk.h (100%)
23 --- a/drivers/mtd/nand/Kconfig
24 +++ b/drivers/mtd/nand/Kconfig
25 @@ -50,6 +50,13 @@ config MTD_NAND_MTK_BMT
26 bool "Support MediaTek NAND Bad-block Management Table"
29 +config MTD_NAND_ECC_MEDIATEK
30 + tristate "Mediatek hardware ECC engine"
31 + depends on HAS_IOMEM
34 + This enables support for the hardware ECC engine from Mediatek.
39 --- a/drivers/mtd/nand/Makefile
40 +++ b/drivers/mtd/nand/Makefile
42 nandcore-objs := core.o bbt.o
43 obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
44 obj-$(CONFIG_MTD_NAND_MTK_BMT) += mtk_bmt.o mtk_bmt_v2.o mtk_bmt_bbt.o mtk_bmt_nmbm.o
45 +obj-$(CONFIG_MTD_NAND_ECC_MEDIATEK) += ecc-mtk.o
49 --- a/drivers/mtd/nand/raw/mtk_ecc.c
52 -// SPDX-License-Identifier: GPL-2.0 OR MIT
54 - * MTK ECC controller driver.
55 - * Copyright (C) 2016 MediaTek Inc.
56 - * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
57 - * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
60 -#include <linux/platform_device.h>
61 -#include <linux/dma-mapping.h>
62 -#include <linux/interrupt.h>
63 -#include <linux/clk.h>
64 -#include <linux/module.h>
65 -#include <linux/iopoll.h>
66 -#include <linux/of.h>
67 -#include <linux/of_platform.h>
68 -#include <linux/mutex.h>
72 -#define ECC_IDLE_MASK BIT(0)
73 -#define ECC_IRQ_EN BIT(0)
74 -#define ECC_PG_IRQ_SEL BIT(1)
75 -#define ECC_OP_ENABLE (1)
76 -#define ECC_OP_DISABLE (0)
78 -#define ECC_ENCCON (0x00)
79 -#define ECC_ENCCNFG (0x04)
80 -#define ECC_MS_SHIFT (16)
81 -#define ECC_ENCDIADDR (0x08)
82 -#define ECC_ENCIDLE (0x0C)
83 -#define ECC_DECCON (0x100)
84 -#define ECC_DECCNFG (0x104)
85 -#define DEC_EMPTY_EN BIT(31)
86 -#define DEC_CNFG_CORRECT (0x3 << 12)
87 -#define ECC_DECIDLE (0x10C)
88 -#define ECC_DECENUM0 (0x114)
90 -#define ECC_TIMEOUT (500000)
92 -#define ECC_IDLE_REG(op) ((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE)
93 -#define ECC_CTL_REG(op) ((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON)
95 -struct mtk_ecc_caps {
98 - const u8 *ecc_strength;
99 - const u32 *ecc_regs;
100 - u8 num_ecc_strength;
107 - struct device *dev;
108 - const struct mtk_ecc_caps *caps;
109 - void __iomem *regs;
112 - struct completion done;
119 -/* ecc strength that each IP supports */
120 -static const u8 ecc_strength_mt2701[] = {
121 - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
122 - 40, 44, 48, 52, 56, 60
125 -static const u8 ecc_strength_mt2712[] = {
126 - 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
127 - 40, 44, 48, 52, 56, 60, 68, 72, 80
130 -static const u8 ecc_strength_mt7622[] = {
143 -static int mt2701_ecc_regs[] = {
144 - [ECC_ENCPAR00] = 0x10,
145 - [ECC_ENCIRQ_EN] = 0x80,
146 - [ECC_ENCIRQ_STA] = 0x84,
147 - [ECC_DECDONE] = 0x124,
148 - [ECC_DECIRQ_EN] = 0x200,
149 - [ECC_DECIRQ_STA] = 0x204,
152 -static int mt2712_ecc_regs[] = {
153 - [ECC_ENCPAR00] = 0x300,
154 - [ECC_ENCIRQ_EN] = 0x80,
155 - [ECC_ENCIRQ_STA] = 0x84,
156 - [ECC_DECDONE] = 0x124,
157 - [ECC_DECIRQ_EN] = 0x200,
158 - [ECC_DECIRQ_STA] = 0x204,
161 -static int mt7622_ecc_regs[] = {
162 - [ECC_ENCPAR00] = 0x10,
163 - [ECC_ENCIRQ_EN] = 0x30,
164 - [ECC_ENCIRQ_STA] = 0x34,
165 - [ECC_DECDONE] = 0x11c,
166 - [ECC_DECIRQ_EN] = 0x140,
167 - [ECC_DECIRQ_STA] = 0x144,
170 -static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
171 - enum mtk_ecc_operation op)
173 - struct device *dev = ecc->dev;
177 - ret = readl_poll_timeout_atomic(ecc->regs + ECC_IDLE_REG(op), val,
178 - val & ECC_IDLE_MASK,
181 - dev_warn(dev, "%s NOT idle\n",
182 - op == ECC_ENCODE ? "encoder" : "decoder");
185 -static irqreturn_t mtk_ecc_irq(int irq, void *id)
187 - struct mtk_ecc *ecc = id;
190 - dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA])
193 - dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
194 - if (dec & ecc->sectors) {
196 - * Clear decode IRQ status once again to ensure that
197 - * there will be no extra IRQ.
199 - readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA]);
201 - complete(&ecc->done);
203 - return IRQ_HANDLED;
206 - enc = readl(ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_STA])
209 - complete(&ecc->done);
214 - return IRQ_HANDLED;
217 -static int mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
219 - u32 ecc_bit, dec_sz, enc_sz;
222 - for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
223 - if (ecc->caps->ecc_strength[i] == config->strength)
227 - if (i == ecc->caps->num_ecc_strength) {
228 - dev_err(ecc->dev, "invalid ecc strength %d\n",
235 - if (config->op == ECC_ENCODE) {
236 - /* configure ECC encoder (in bits) */
237 - enc_sz = config->len << 3;
239 - reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
240 - reg |= (enc_sz << ECC_MS_SHIFT);
241 - writel(reg, ecc->regs + ECC_ENCCNFG);
243 - if (config->mode != ECC_NFI_MODE)
244 - writel(lower_32_bits(config->addr),
245 - ecc->regs + ECC_ENCDIADDR);
248 - /* configure ECC decoder (in bits) */
249 - dec_sz = (config->len << 3) +
250 - config->strength * ecc->caps->parity_bits;
252 - reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
253 - reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT;
254 - reg |= DEC_EMPTY_EN;
255 - writel(reg, ecc->regs + ECC_DECCNFG);
257 - if (config->sectors)
258 - ecc->sectors = 1 << (config->sectors - 1);
264 -void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
267 - u32 offset, i, err;
270 - stats->corrected = 0;
273 - for (i = 0; i < sectors; i++) {
274 - offset = (i >> 2) << 2;
275 - err = readl(ecc->regs + ECC_DECENUM0 + offset);
276 - err = err >> ((i % 4) * ecc->caps->err_shift);
277 - err &= ecc->caps->err_mask;
278 - if (err == ecc->caps->err_mask) {
279 - /* uncorrectable errors */
284 - stats->corrected += err;
285 - bitflips = max_t(u32, bitflips, err);
288 - stats->bitflips = bitflips;
290 -EXPORT_SYMBOL(mtk_ecc_get_stats);
292 -void mtk_ecc_release(struct mtk_ecc *ecc)
294 - clk_disable_unprepare(ecc->clk);
295 - put_device(ecc->dev);
297 -EXPORT_SYMBOL(mtk_ecc_release);
299 -static void mtk_ecc_hw_init(struct mtk_ecc *ecc)
301 - mtk_ecc_wait_idle(ecc, ECC_ENCODE);
302 - writew(ECC_OP_DISABLE, ecc->regs + ECC_ENCCON);
304 - mtk_ecc_wait_idle(ecc, ECC_DECODE);
305 - writel(ECC_OP_DISABLE, ecc->regs + ECC_DECCON);
308 -static struct mtk_ecc *mtk_ecc_get(struct device_node *np)
310 - struct platform_device *pdev;
311 - struct mtk_ecc *ecc;
313 - pdev = of_find_device_by_node(np);
315 - return ERR_PTR(-EPROBE_DEFER);
317 - ecc = platform_get_drvdata(pdev);
319 - put_device(&pdev->dev);
320 - return ERR_PTR(-EPROBE_DEFER);
323 - clk_prepare_enable(ecc->clk);
324 - mtk_ecc_hw_init(ecc);
329 -struct mtk_ecc *of_mtk_ecc_get(struct device_node *of_node)
331 - struct mtk_ecc *ecc = NULL;
332 - struct device_node *np;
334 - np = of_parse_phandle(of_node, "ecc-engine", 0);
336 - ecc = mtk_ecc_get(np);
342 -EXPORT_SYMBOL(of_mtk_ecc_get);
344 -int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
346 - enum mtk_ecc_operation op = config->op;
350 - ret = mutex_lock_interruptible(&ecc->lock);
352 - dev_err(ecc->dev, "interrupted when attempting to lock\n");
356 - mtk_ecc_wait_idle(ecc, op);
358 - ret = mtk_ecc_config(ecc, config);
360 - mutex_unlock(&ecc->lock);
364 - if (config->mode != ECC_NFI_MODE || op != ECC_ENCODE) {
365 - init_completion(&ecc->done);
366 - reg_val = ECC_IRQ_EN;
368 - * For ECC_NFI_MODE, if ecc->caps->pg_irq_sel is 1, then it
369 - * means this chip can only generate one ecc irq during page
370 - * read / write. If is 0, generate one ecc irq each ecc step.
372 - if (ecc->caps->pg_irq_sel && config->mode == ECC_NFI_MODE)
373 - reg_val |= ECC_PG_IRQ_SEL;
374 - if (op == ECC_ENCODE)
375 - writew(reg_val, ecc->regs +
376 - ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
378 - writew(reg_val, ecc->regs +
379 - ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
382 - writew(ECC_OP_ENABLE, ecc->regs + ECC_CTL_REG(op));
386 -EXPORT_SYMBOL(mtk_ecc_enable);
388 -void mtk_ecc_disable(struct mtk_ecc *ecc)
390 - enum mtk_ecc_operation op = ECC_ENCODE;
392 - /* find out the running operation */
393 - if (readw(ecc->regs + ECC_CTL_REG(op)) != ECC_OP_ENABLE)
397 - mtk_ecc_wait_idle(ecc, op);
398 - if (op == ECC_DECODE) {
400 - * Clear decode IRQ status in case there is a timeout to wait
403 - readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
404 - writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
406 - writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
409 - writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op));
411 - mutex_unlock(&ecc->lock);
413 -EXPORT_SYMBOL(mtk_ecc_disable);
415 -int mtk_ecc_wait_done(struct mtk_ecc *ecc, enum mtk_ecc_operation op)
419 - ret = wait_for_completion_timeout(&ecc->done, msecs_to_jiffies(500));
421 - dev_err(ecc->dev, "%s timeout - interrupt did not arrive)\n",
422 - (op == ECC_ENCODE) ? "encoder" : "decoder");
428 -EXPORT_SYMBOL(mtk_ecc_wait_done);
430 -int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
431 - u8 *data, u32 bytes)
437 - addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
438 - ret = dma_mapping_error(ecc->dev, addr);
440 - dev_err(ecc->dev, "dma mapping error\n");
444 - config->op = ECC_ENCODE;
445 - config->addr = addr;
446 - ret = mtk_ecc_enable(ecc, config);
448 - dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
452 - ret = mtk_ecc_wait_done(ecc, ECC_ENCODE);
456 - mtk_ecc_wait_idle(ecc, ECC_ENCODE);
458 - /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
459 - len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
461 - /* write the parity bytes generated by the ECC back to temp buffer */
462 - __ioread32_copy(ecc->eccdata,
463 - ecc->regs + ecc->caps->ecc_regs[ECC_ENCPAR00],
466 - /* copy into possibly unaligned OOB region with actual length */
467 - memcpy(data + bytes, ecc->eccdata, len);
470 - dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
471 - mtk_ecc_disable(ecc);
475 -EXPORT_SYMBOL(mtk_ecc_encode);
477 -void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p)
479 - const u8 *ecc_strength = ecc->caps->ecc_strength;
482 - for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
483 - if (*p <= ecc_strength[i]) {
485 - *p = ecc_strength[i];
486 - else if (*p != ecc_strength[i])
487 - *p = ecc_strength[i - 1];
492 - *p = ecc_strength[ecc->caps->num_ecc_strength - 1];
494 -EXPORT_SYMBOL(mtk_ecc_adjust_strength);
496 -unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
498 - return ecc->caps->parity_bits;
500 -EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
502 -static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
505 - .ecc_strength = ecc_strength_mt2701,
506 - .ecc_regs = mt2701_ecc_regs,
507 - .num_ecc_strength = 20,
508 - .ecc_mode_shift = 5,
513 -static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
516 - .ecc_strength = ecc_strength_mt2712,
517 - .ecc_regs = mt2712_ecc_regs,
518 - .num_ecc_strength = 23,
519 - .ecc_mode_shift = 5,
524 -static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
527 - .ecc_strength = ecc_strength_mt7622,
528 - .ecc_regs = mt7622_ecc_regs,
529 - .num_ecc_strength = 5,
530 - .ecc_mode_shift = 4,
535 -static const struct of_device_id mtk_ecc_dt_match[] = {
537 - .compatible = "mediatek,mt2701-ecc",
538 - .data = &mtk_ecc_caps_mt2701,
540 - .compatible = "mediatek,mt2712-ecc",
541 - .data = &mtk_ecc_caps_mt2712,
543 - .compatible = "mediatek,mt7622-ecc",
544 - .data = &mtk_ecc_caps_mt7622,
549 -static int mtk_ecc_probe(struct platform_device *pdev)
551 - struct device *dev = &pdev->dev;
552 - struct mtk_ecc *ecc;
553 - struct resource *res;
554 - u32 max_eccdata_size;
557 - ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL);
561 - ecc->caps = of_device_get_match_data(dev);
563 - max_eccdata_size = ecc->caps->num_ecc_strength - 1;
564 - max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size];
565 - max_eccdata_size = (max_eccdata_size * ecc->caps->parity_bits + 7) >> 3;
566 - max_eccdata_size = round_up(max_eccdata_size, 4);
567 - ecc->eccdata = devm_kzalloc(dev, max_eccdata_size, GFP_KERNEL);
571 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
572 - ecc->regs = devm_ioremap_resource(dev, res);
573 - if (IS_ERR(ecc->regs))
574 - return PTR_ERR(ecc->regs);
576 - ecc->clk = devm_clk_get(dev, NULL);
577 - if (IS_ERR(ecc->clk)) {
578 - dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk));
579 - return PTR_ERR(ecc->clk);
582 - irq = platform_get_irq(pdev, 0);
586 - ret = dma_set_mask(dev, DMA_BIT_MASK(32));
588 - dev_err(dev, "failed to set DMA mask\n");
592 - ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, "mtk-ecc", ecc);
594 - dev_err(dev, "failed to request irq\n");
599 - mutex_init(&ecc->lock);
600 - platform_set_drvdata(pdev, ecc);
601 - dev_info(dev, "probed\n");
606 -#ifdef CONFIG_PM_SLEEP
607 -static int mtk_ecc_suspend(struct device *dev)
609 - struct mtk_ecc *ecc = dev_get_drvdata(dev);
611 - clk_disable_unprepare(ecc->clk);
616 -static int mtk_ecc_resume(struct device *dev)
618 - struct mtk_ecc *ecc = dev_get_drvdata(dev);
621 - ret = clk_prepare_enable(ecc->clk);
623 - dev_err(dev, "failed to enable clk\n");
630 -static SIMPLE_DEV_PM_OPS(mtk_ecc_pm_ops, mtk_ecc_suspend, mtk_ecc_resume);
633 -MODULE_DEVICE_TABLE(of, mtk_ecc_dt_match);
635 -static struct platform_driver mtk_ecc_driver = {
636 - .probe = mtk_ecc_probe,
639 - .of_match_table = of_match_ptr(mtk_ecc_dt_match),
640 -#ifdef CONFIG_PM_SLEEP
641 - .pm = &mtk_ecc_pm_ops,
646 -module_platform_driver(mtk_ecc_driver);
648 -MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>");
649 -MODULE_DESCRIPTION("MTK Nand ECC Driver");
650 -MODULE_LICENSE("Dual MIT/GPL");
652 +++ b/drivers/mtd/nand/ecc-mtk.c
654 +// SPDX-License-Identifier: GPL-2.0 OR MIT
656 + * MTK ECC controller driver.
657 + * Copyright (C) 2016 MediaTek Inc.
658 + * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
659 + * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
662 +#include <linux/platform_device.h>
663 +#include <linux/dma-mapping.h>
664 +#include <linux/interrupt.h>
665 +#include <linux/clk.h>
666 +#include <linux/module.h>
667 +#include <linux/iopoll.h>
668 +#include <linux/of.h>
669 +#include <linux/of_platform.h>
670 +#include <linux/mutex.h>
671 +#include <linux/mtd/nand-ecc-mtk.h>
673 +#define ECC_IDLE_MASK BIT(0)
674 +#define ECC_IRQ_EN BIT(0)
675 +#define ECC_PG_IRQ_SEL BIT(1)
676 +#define ECC_OP_ENABLE (1)
677 +#define ECC_OP_DISABLE (0)
679 +#define ECC_ENCCON (0x00)
680 +#define ECC_ENCCNFG (0x04)
681 +#define ECC_MS_SHIFT (16)
682 +#define ECC_ENCDIADDR (0x08)
683 +#define ECC_ENCIDLE (0x0C)
684 +#define ECC_DECCON (0x100)
685 +#define ECC_DECCNFG (0x104)
686 +#define DEC_EMPTY_EN BIT(31)
687 +#define DEC_CNFG_CORRECT (0x3 << 12)
688 +#define ECC_DECIDLE (0x10C)
689 +#define ECC_DECENUM0 (0x114)
691 +#define ECC_TIMEOUT (500000)
693 +#define ECC_IDLE_REG(op) ((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE)
694 +#define ECC_CTL_REG(op) ((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON)
696 +struct mtk_ecc_caps {
699 + const u8 *ecc_strength;
700 + const u32 *ecc_regs;
701 + u8 num_ecc_strength;
708 + struct device *dev;
709 + const struct mtk_ecc_caps *caps;
710 + void __iomem *regs;
713 + struct completion done;
720 +/* ecc strength that each IP supports */
721 +static const u8 ecc_strength_mt2701[] = {
722 + 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
723 + 40, 44, 48, 52, 56, 60
726 +static const u8 ecc_strength_mt2712[] = {
727 + 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
728 + 40, 44, 48, 52, 56, 60, 68, 72, 80
731 +static const u8 ecc_strength_mt7622[] = {
744 +static int mt2701_ecc_regs[] = {
745 + [ECC_ENCPAR00] = 0x10,
746 + [ECC_ENCIRQ_EN] = 0x80,
747 + [ECC_ENCIRQ_STA] = 0x84,
748 + [ECC_DECDONE] = 0x124,
749 + [ECC_DECIRQ_EN] = 0x200,
750 + [ECC_DECIRQ_STA] = 0x204,
753 +static int mt2712_ecc_regs[] = {
754 + [ECC_ENCPAR00] = 0x300,
755 + [ECC_ENCIRQ_EN] = 0x80,
756 + [ECC_ENCIRQ_STA] = 0x84,
757 + [ECC_DECDONE] = 0x124,
758 + [ECC_DECIRQ_EN] = 0x200,
759 + [ECC_DECIRQ_STA] = 0x204,
762 +static int mt7622_ecc_regs[] = {
763 + [ECC_ENCPAR00] = 0x10,
764 + [ECC_ENCIRQ_EN] = 0x30,
765 + [ECC_ENCIRQ_STA] = 0x34,
766 + [ECC_DECDONE] = 0x11c,
767 + [ECC_DECIRQ_EN] = 0x140,
768 + [ECC_DECIRQ_STA] = 0x144,
771 +static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
772 + enum mtk_ecc_operation op)
774 + struct device *dev = ecc->dev;
778 + ret = readl_poll_timeout_atomic(ecc->regs + ECC_IDLE_REG(op), val,
779 + val & ECC_IDLE_MASK,
782 + dev_warn(dev, "%s NOT idle\n",
783 + op == ECC_ENCODE ? "encoder" : "decoder");
786 +static irqreturn_t mtk_ecc_irq(int irq, void *id)
788 + struct mtk_ecc *ecc = id;
791 + dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA])
794 + dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
795 + if (dec & ecc->sectors) {
797 + * Clear decode IRQ status once again to ensure that
798 + * there will be no extra IRQ.
800 + readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA]);
802 + complete(&ecc->done);
804 + return IRQ_HANDLED;
807 + enc = readl(ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_STA])
810 + complete(&ecc->done);
815 + return IRQ_HANDLED;
818 +static int mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
820 + u32 ecc_bit, dec_sz, enc_sz;
823 + for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
824 + if (ecc->caps->ecc_strength[i] == config->strength)
828 + if (i == ecc->caps->num_ecc_strength) {
829 + dev_err(ecc->dev, "invalid ecc strength %d\n",
836 + if (config->op == ECC_ENCODE) {
837 + /* configure ECC encoder (in bits) */
838 + enc_sz = config->len << 3;
840 + reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
841 + reg |= (enc_sz << ECC_MS_SHIFT);
842 + writel(reg, ecc->regs + ECC_ENCCNFG);
844 + if (config->mode != ECC_NFI_MODE)
845 + writel(lower_32_bits(config->addr),
846 + ecc->regs + ECC_ENCDIADDR);
849 + /* configure ECC decoder (in bits) */
850 + dec_sz = (config->len << 3) +
851 + config->strength * ecc->caps->parity_bits;
853 + reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
854 + reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT;
855 + reg |= DEC_EMPTY_EN;
856 + writel(reg, ecc->regs + ECC_DECCNFG);
858 + if (config->sectors)
859 + ecc->sectors = 1 << (config->sectors - 1);
865 +void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
868 + u32 offset, i, err;
871 + stats->corrected = 0;
874 + for (i = 0; i < sectors; i++) {
875 + offset = (i >> 2) << 2;
876 + err = readl(ecc->regs + ECC_DECENUM0 + offset);
877 + err = err >> ((i % 4) * ecc->caps->err_shift);
878 + err &= ecc->caps->err_mask;
879 + if (err == ecc->caps->err_mask) {
880 + /* uncorrectable errors */
885 + stats->corrected += err;
886 + bitflips = max_t(u32, bitflips, err);
889 + stats->bitflips = bitflips;
891 +EXPORT_SYMBOL(mtk_ecc_get_stats);
893 +void mtk_ecc_release(struct mtk_ecc *ecc)
895 + clk_disable_unprepare(ecc->clk);
896 + put_device(ecc->dev);
898 +EXPORT_SYMBOL(mtk_ecc_release);
900 +static void mtk_ecc_hw_init(struct mtk_ecc *ecc)
902 + mtk_ecc_wait_idle(ecc, ECC_ENCODE);
903 + writew(ECC_OP_DISABLE, ecc->regs + ECC_ENCCON);
905 + mtk_ecc_wait_idle(ecc, ECC_DECODE);
906 + writel(ECC_OP_DISABLE, ecc->regs + ECC_DECCON);
909 +static struct mtk_ecc *mtk_ecc_get(struct device_node *np)
911 + struct platform_device *pdev;
912 + struct mtk_ecc *ecc;
914 + pdev = of_find_device_by_node(np);
916 + return ERR_PTR(-EPROBE_DEFER);
918 + ecc = platform_get_drvdata(pdev);
920 + put_device(&pdev->dev);
921 + return ERR_PTR(-EPROBE_DEFER);
924 + clk_prepare_enable(ecc->clk);
925 + mtk_ecc_hw_init(ecc);
930 +struct mtk_ecc *of_mtk_ecc_get(struct device_node *of_node)
932 + struct mtk_ecc *ecc = NULL;
933 + struct device_node *np;
935 + np = of_parse_phandle(of_node, "ecc-engine", 0);
937 + ecc = mtk_ecc_get(np);
943 +EXPORT_SYMBOL(of_mtk_ecc_get);
945 +int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
947 + enum mtk_ecc_operation op = config->op;
951 + ret = mutex_lock_interruptible(&ecc->lock);
953 + dev_err(ecc->dev, "interrupted when attempting to lock\n");
957 + mtk_ecc_wait_idle(ecc, op);
959 + ret = mtk_ecc_config(ecc, config);
961 + mutex_unlock(&ecc->lock);
965 + if (config->mode != ECC_NFI_MODE || op != ECC_ENCODE) {
966 + init_completion(&ecc->done);
967 + reg_val = ECC_IRQ_EN;
969 + * For ECC_NFI_MODE, if ecc->caps->pg_irq_sel is 1, then it
970 + * means this chip can only generate one ecc irq during page
971 + * read / write. If is 0, generate one ecc irq each ecc step.
973 + if (ecc->caps->pg_irq_sel && config->mode == ECC_NFI_MODE)
974 + reg_val |= ECC_PG_IRQ_SEL;
975 + if (op == ECC_ENCODE)
976 + writew(reg_val, ecc->regs +
977 + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
979 + writew(reg_val, ecc->regs +
980 + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
983 + writew(ECC_OP_ENABLE, ecc->regs + ECC_CTL_REG(op));
987 +EXPORT_SYMBOL(mtk_ecc_enable);
989 +void mtk_ecc_disable(struct mtk_ecc *ecc)
991 + enum mtk_ecc_operation op = ECC_ENCODE;
993 + /* find out the running operation */
994 + if (readw(ecc->regs + ECC_CTL_REG(op)) != ECC_OP_ENABLE)
998 + mtk_ecc_wait_idle(ecc, op);
999 + if (op == ECC_DECODE) {
1001 + * Clear decode IRQ status in case there is a timeout to wait
1004 + readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
1005 + writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
1007 + writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
1010 + writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op));
1012 + mutex_unlock(&ecc->lock);
1014 +EXPORT_SYMBOL(mtk_ecc_disable);
1016 +int mtk_ecc_wait_done(struct mtk_ecc *ecc, enum mtk_ecc_operation op)
1020 + ret = wait_for_completion_timeout(&ecc->done, msecs_to_jiffies(500));
1022 + dev_err(ecc->dev, "%s timeout - interrupt did not arrive)\n",
1023 + (op == ECC_ENCODE) ? "encoder" : "decoder");
1024 + return -ETIMEDOUT;
1029 +EXPORT_SYMBOL(mtk_ecc_wait_done);
1031 +int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
1032 + u8 *data, u32 bytes)
1038 + addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
1039 + ret = dma_mapping_error(ecc->dev, addr);
1041 + dev_err(ecc->dev, "dma mapping error\n");
1045 + config->op = ECC_ENCODE;
1046 + config->addr = addr;
1047 + ret = mtk_ecc_enable(ecc, config);
1049 + dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
1053 + ret = mtk_ecc_wait_done(ecc, ECC_ENCODE);
1057 + mtk_ecc_wait_idle(ecc, ECC_ENCODE);
1059 + /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
1060 + len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
1062 + /* write the parity bytes generated by the ECC back to temp buffer */
1063 + __ioread32_copy(ecc->eccdata,
1064 + ecc->regs + ecc->caps->ecc_regs[ECC_ENCPAR00],
1065 + round_up(len, 4));
1067 + /* copy into possibly unaligned OOB region with actual length */
1068 + memcpy(data + bytes, ecc->eccdata, len);
1071 + dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
1072 + mtk_ecc_disable(ecc);
1076 +EXPORT_SYMBOL(mtk_ecc_encode);
1078 +void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p)
1080 + const u8 *ecc_strength = ecc->caps->ecc_strength;
1083 + for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
1084 + if (*p <= ecc_strength[i]) {
1086 + *p = ecc_strength[i];
1087 + else if (*p != ecc_strength[i])
1088 + *p = ecc_strength[i - 1];
1093 + *p = ecc_strength[ecc->caps->num_ecc_strength - 1];
1095 +EXPORT_SYMBOL(mtk_ecc_adjust_strength);
1097 +unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
1099 + return ecc->caps->parity_bits;
1101 +EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
1103 +static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
1106 + .ecc_strength = ecc_strength_mt2701,
1107 + .ecc_regs = mt2701_ecc_regs,
1108 + .num_ecc_strength = 20,
1109 + .ecc_mode_shift = 5,
1110 + .parity_bits = 14,
1114 +static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
1117 + .ecc_strength = ecc_strength_mt2712,
1118 + .ecc_regs = mt2712_ecc_regs,
1119 + .num_ecc_strength = 23,
1120 + .ecc_mode_shift = 5,
1121 + .parity_bits = 14,
1125 +static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
1128 + .ecc_strength = ecc_strength_mt7622,
1129 + .ecc_regs = mt7622_ecc_regs,
1130 + .num_ecc_strength = 5,
1131 + .ecc_mode_shift = 4,
1132 + .parity_bits = 13,
1136 +static const struct of_device_id mtk_ecc_dt_match[] = {
1138 + .compatible = "mediatek,mt2701-ecc",
1139 + .data = &mtk_ecc_caps_mt2701,
1141 + .compatible = "mediatek,mt2712-ecc",
1142 + .data = &mtk_ecc_caps_mt2712,
1144 + .compatible = "mediatek,mt7622-ecc",
1145 + .data = &mtk_ecc_caps_mt7622,
1150 +static int mtk_ecc_probe(struct platform_device *pdev)
1152 + struct device *dev = &pdev->dev;
1153 + struct mtk_ecc *ecc;
1154 + struct resource *res;
1155 + u32 max_eccdata_size;
1158 + ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL);
1162 + ecc->caps = of_device_get_match_data(dev);
1164 + max_eccdata_size = ecc->caps->num_ecc_strength - 1;
1165 + max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size];
1166 + max_eccdata_size = (max_eccdata_size * ecc->caps->parity_bits + 7) >> 3;
1167 + max_eccdata_size = round_up(max_eccdata_size, 4);
1168 + ecc->eccdata = devm_kzalloc(dev, max_eccdata_size, GFP_KERNEL);
1169 + if (!ecc->eccdata)
1172 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1173 + ecc->regs = devm_ioremap_resource(dev, res);
1174 + if (IS_ERR(ecc->regs))
1175 + return PTR_ERR(ecc->regs);
1177 + ecc->clk = devm_clk_get(dev, NULL);
1178 + if (IS_ERR(ecc->clk)) {
1179 + dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk));
1180 + return PTR_ERR(ecc->clk);
1183 + irq = platform_get_irq(pdev, 0);
1187 + ret = dma_set_mask(dev, DMA_BIT_MASK(32));
1189 + dev_err(dev, "failed to set DMA mask\n");
1193 + ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, "mtk-ecc", ecc);
1195 + dev_err(dev, "failed to request irq\n");
1200 + mutex_init(&ecc->lock);
1201 + platform_set_drvdata(pdev, ecc);
1202 + dev_info(dev, "probed\n");
1207 +#ifdef CONFIG_PM_SLEEP
1208 +static int mtk_ecc_suspend(struct device *dev)
1210 + struct mtk_ecc *ecc = dev_get_drvdata(dev);
1212 + clk_disable_unprepare(ecc->clk);
1217 +static int mtk_ecc_resume(struct device *dev)
1219 + struct mtk_ecc *ecc = dev_get_drvdata(dev);
1222 + ret = clk_prepare_enable(ecc->clk);
1224 + dev_err(dev, "failed to enable clk\n");
1231 +static SIMPLE_DEV_PM_OPS(mtk_ecc_pm_ops, mtk_ecc_suspend, mtk_ecc_resume);
1234 +MODULE_DEVICE_TABLE(of, mtk_ecc_dt_match);
1236 +static struct platform_driver mtk_ecc_driver = {
1237 + .probe = mtk_ecc_probe,
1239 + .name = "mtk-ecc",
1240 + .of_match_table = of_match_ptr(mtk_ecc_dt_match),
1241 +#ifdef CONFIG_PM_SLEEP
1242 + .pm = &mtk_ecc_pm_ops,
1247 +module_platform_driver(mtk_ecc_driver);
1249 +MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>");
1250 +MODULE_DESCRIPTION("MTK Nand ECC Driver");
1251 +MODULE_LICENSE("Dual MIT/GPL");
1252 --- a/drivers/mtd/nand/raw/Kconfig
1253 +++ b/drivers/mtd/nand/raw/Kconfig
1254 @@ -360,6 +360,7 @@ config MTD_NAND_QCOM
1257 tristate "MTK NAND controller"
1258 + depends on MTD_NAND_ECC_MEDIATEK
1259 depends on ARCH_MEDIATEK || COMPILE_TEST
1260 depends on HAS_IOMEM
1262 --- a/drivers/mtd/nand/raw/Makefile
1263 +++ b/drivers/mtd/nand/raw/Makefile
1264 @@ -48,7 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_n
1265 obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o
1266 obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/
1267 obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o
1268 -obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
1269 +obj-$(CONFIG_MTD_NAND_MTK) += mtk_nand.o
1270 obj-$(CONFIG_MTD_NAND_MXIC) += mxic_nand.o
1271 obj-$(CONFIG_MTD_NAND_TEGRA) += tegra_nand.o
1272 obj-$(CONFIG_MTD_NAND_STM32_FMC2) += stm32_fmc2_nand.o
1273 --- a/drivers/mtd/nand/raw/mtk_nand.c
1274 +++ b/drivers/mtd/nand/raw/mtk_nand.c
1276 #include <linux/iopoll.h>
1277 #include <linux/of.h>
1278 #include <linux/of_device.h>
1279 -#include "mtk_ecc.h"
1280 +#include <linux/mtd/nand-ecc-mtk.h>
1282 /* NAND controller register definition */
1283 #define NFI_CNFG (0x00)
1284 --- a/drivers/mtd/nand/raw/mtk_ecc.h
1287 -/* SPDX-License-Identifier: GPL-2.0 OR MIT */
1289 - * MTK SDG1 ECC controller
1291 - * Copyright (c) 2016 Mediatek
1292 - * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
1293 - * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
1296 -#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__
1297 -#define __DRIVERS_MTD_NAND_MTK_ECC_H__
1299 -#include <linux/types.h>
1301 -enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
1302 -enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE};
1304 -struct device_node;
1307 -struct mtk_ecc_stats {
1313 -struct mtk_ecc_config {
1314 - enum mtk_ecc_operation op;
1315 - enum mtk_ecc_mode mode;
1322 -int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32);
1323 -void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int);
1324 -int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation);
1325 -int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *);
1326 -void mtk_ecc_disable(struct mtk_ecc *);
1327 -void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p);
1328 -unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc);
1330 -struct mtk_ecc *of_mtk_ecc_get(struct device_node *);
1331 -void mtk_ecc_release(struct mtk_ecc *);
1335 +++ b/include/linux/mtd/nand-ecc-mtk.h
1337 +/* SPDX-License-Identifier: GPL-2.0 OR MIT */
1339 + * MTK SDG1 ECC controller
1341 + * Copyright (c) 2016 Mediatek
1342 + * Authors: Xiaolei Li <xiaolei.li@mediatek.com>
1343 + * Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
1346 +#ifndef __DRIVERS_MTD_NAND_MTK_ECC_H__
1347 +#define __DRIVERS_MTD_NAND_MTK_ECC_H__
1349 +#include <linux/types.h>
1351 +enum mtk_ecc_mode {ECC_DMA_MODE = 0, ECC_NFI_MODE = 1};
1352 +enum mtk_ecc_operation {ECC_ENCODE, ECC_DECODE};
1354 +struct device_node;
1357 +struct mtk_ecc_stats {
1363 +struct mtk_ecc_config {
1364 + enum mtk_ecc_operation op;
1365 + enum mtk_ecc_mode mode;
1372 +int mtk_ecc_encode(struct mtk_ecc *, struct mtk_ecc_config *, u8 *, u32);
1373 +void mtk_ecc_get_stats(struct mtk_ecc *, struct mtk_ecc_stats *, int);
1374 +int mtk_ecc_wait_done(struct mtk_ecc *, enum mtk_ecc_operation);
1375 +int mtk_ecc_enable(struct mtk_ecc *, struct mtk_ecc_config *);
1376 +void mtk_ecc_disable(struct mtk_ecc *);
1377 +void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p);
1378 +unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc);
1380 +struct mtk_ecc *of_mtk_ecc_get(struct device_node *);
1381 +void mtk_ecc_release(struct mtk_ecc *);