2019-06-24 09:38:56 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
2016-06-14 23:50:51 +08:00
|
|
|
/*
|
|
|
|
* MTK ECC controller driver.
|
|
|
|
* Copyright (C) 2016 MediaTek Inc.
|
|
|
|
* Authors: Xiaolei Li <xiaolei.li@mediatek.com>
|
|
|
|
* Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/dma-mapping.h>
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/clk.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/iopoll.h>
|
|
|
|
#include <linux/of.h>
|
|
|
|
#include <linux/of_platform.h>
|
|
|
|
#include <linux/mutex.h>
|
2022-04-24 11:25:23 +08:00
|
|
|
#include <linux/mtd/nand-ecc-mtk.h>
|
2016-06-14 23:50:51 +08:00
|
|
|
|
|
|
|
#define ECC_IDLE_MASK BIT(0)
|
|
|
|
#define ECC_IRQ_EN BIT(0)
|
2017-05-31 16:26:41 +08:00
|
|
|
#define ECC_PG_IRQ_SEL BIT(1)
|
2016-06-14 23:50:51 +08:00
|
|
|
#define ECC_OP_ENABLE (1)
|
|
|
|
#define ECC_OP_DISABLE (0)
|
|
|
|
|
|
|
|
#define ECC_ENCCON (0x00)
|
|
|
|
#define ECC_ENCCNFG (0x04)
|
|
|
|
#define ECC_MS_SHIFT (16)
|
|
|
|
#define ECC_ENCDIADDR (0x08)
|
|
|
|
#define ECC_ENCIDLE (0x0C)
|
|
|
|
#define ECC_DECCON (0x100)
|
|
|
|
#define ECC_DECCNFG (0x104)
|
|
|
|
#define DEC_EMPTY_EN BIT(31)
|
|
|
|
#define DEC_CNFG_CORRECT (0x3 << 12)
|
|
|
|
#define ECC_DECIDLE (0x10C)
|
|
|
|
#define ECC_DECENUM0 (0x114)
|
|
|
|
|
|
|
|
#define ECC_TIMEOUT (500000)
|
|
|
|
|
|
|
|
#define ECC_IDLE_REG(op) ((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE)
|
|
|
|
#define ECC_CTL_REG(op) ((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON)
|
|
|
|
|
2023-02-01 10:15:00 +08:00
|
|
|
#define ECC_ERRMASK_MT7622 GENMASK(4, 0)
|
|
|
|
#define ECC_ERRMASK_MT2701 GENMASK(5, 0)
|
|
|
|
#define ECC_ERRMASK_MT2712 GENMASK(6, 0)
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
struct mtk_ecc_caps {
|
|
|
|
u32 err_mask;
|
2022-04-03 00:03:13 +08:00
|
|
|
u32 err_shift;
|
2017-05-31 16:26:40 +08:00
|
|
|
const u8 *ecc_strength;
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
const u32 *ecc_regs;
|
2017-05-31 16:26:40 +08:00
|
|
|
u8 num_ecc_strength;
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
u8 ecc_mode_shift;
|
|
|
|
u32 parity_bits;
|
2017-05-31 16:26:41 +08:00
|
|
|
int pg_irq_sel;
|
2017-05-31 16:26:40 +08:00
|
|
|
};
|
|
|
|
|
2016-06-14 23:50:51 +08:00
|
|
|
struct mtk_ecc {
|
|
|
|
struct device *dev;
|
2017-05-31 16:26:40 +08:00
|
|
|
const struct mtk_ecc_caps *caps;
|
2016-06-14 23:50:51 +08:00
|
|
|
void __iomem *regs;
|
|
|
|
struct clk *clk;
|
|
|
|
|
|
|
|
struct completion done;
|
|
|
|
struct mutex lock;
|
|
|
|
u32 sectors;
|
2016-10-18 06:05:31 +08:00
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
u8 *eccdata;
|
|
|
|
};
|
|
|
|
|
2017-05-31 16:26:41 +08:00
|
|
|
/* ecc strength that each IP supports */
|
2017-05-31 16:26:40 +08:00
|
|
|
static const u8 ecc_strength_mt2701[] = {
|
|
|
|
4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
|
|
|
|
40, 44, 48, 52, 56, 60
|
2016-06-14 23:50:51 +08:00
|
|
|
};
|
|
|
|
|
2017-05-31 16:26:41 +08:00
|
|
|
static const u8 ecc_strength_mt2712[] = {
|
|
|
|
4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
|
|
|
|
40, 44, 48, 52, 56, 60, 68, 72, 80
|
|
|
|
};
|
|
|
|
|
2017-11-30 22:10:45 +08:00
|
|
|
static const u8 ecc_strength_mt7622[] = {
|
2022-04-03 00:03:13 +08:00
|
|
|
4, 6, 8, 10, 12
|
2017-11-30 22:10:45 +08:00
|
|
|
};
|
|
|
|
|
2023-02-01 10:15:00 +08:00
|
|
|
static const u8 ecc_strength_mt7986[] = {
|
|
|
|
4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24
|
|
|
|
};
|
|
|
|
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
enum mtk_ecc_regs {
|
|
|
|
ECC_ENCPAR00,
|
|
|
|
ECC_ENCIRQ_EN,
|
|
|
|
ECC_ENCIRQ_STA,
|
|
|
|
ECC_DECDONE,
|
|
|
|
ECC_DECIRQ_EN,
|
|
|
|
ECC_DECIRQ_STA,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int mt2701_ecc_regs[] = {
|
|
|
|
[ECC_ENCPAR00] = 0x10,
|
|
|
|
[ECC_ENCIRQ_EN] = 0x80,
|
|
|
|
[ECC_ENCIRQ_STA] = 0x84,
|
|
|
|
[ECC_DECDONE] = 0x124,
|
|
|
|
[ECC_DECIRQ_EN] = 0x200,
|
|
|
|
[ECC_DECIRQ_STA] = 0x204,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int mt2712_ecc_regs[] = {
|
|
|
|
[ECC_ENCPAR00] = 0x300,
|
|
|
|
[ECC_ENCIRQ_EN] = 0x80,
|
|
|
|
[ECC_ENCIRQ_STA] = 0x84,
|
|
|
|
[ECC_DECDONE] = 0x124,
|
|
|
|
[ECC_DECIRQ_EN] = 0x200,
|
|
|
|
[ECC_DECIRQ_STA] = 0x204,
|
|
|
|
};
|
|
|
|
|
2017-11-30 22:10:45 +08:00
|
|
|
static int mt7622_ecc_regs[] = {
|
|
|
|
[ECC_ENCPAR00] = 0x10,
|
|
|
|
[ECC_ENCIRQ_EN] = 0x30,
|
|
|
|
[ECC_ENCIRQ_STA] = 0x34,
|
|
|
|
[ECC_DECDONE] = 0x11c,
|
|
|
|
[ECC_DECIRQ_EN] = 0x140,
|
|
|
|
[ECC_DECIRQ_STA] = 0x144,
|
|
|
|
};
|
|
|
|
|
2016-06-14 23:50:51 +08:00
|
|
|
static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc,
|
|
|
|
enum mtk_ecc_operation op)
|
|
|
|
{
|
|
|
|
struct device *dev = ecc->dev;
|
|
|
|
u32 val;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = readl_poll_timeout_atomic(ecc->regs + ECC_IDLE_REG(op), val,
|
|
|
|
val & ECC_IDLE_MASK,
|
|
|
|
10, ECC_TIMEOUT);
|
|
|
|
if (ret)
|
|
|
|
dev_warn(dev, "%s NOT idle\n",
|
|
|
|
op == ECC_ENCODE ? "encoder" : "decoder");
|
|
|
|
}
|
|
|
|
|
|
|
|
static irqreturn_t mtk_ecc_irq(int irq, void *id)
|
|
|
|
{
|
|
|
|
struct mtk_ecc *ecc = id;
|
|
|
|
u32 dec, enc;
|
|
|
|
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA])
|
|
|
|
& ECC_IRQ_EN;
|
2016-06-14 23:50:51 +08:00
|
|
|
if (dec) {
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
dec = readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
|
2016-06-14 23:50:51 +08:00
|
|
|
if (dec & ecc->sectors) {
|
mtd: nand: mtk: fix infinite ECC decode IRQ issue
For MT2701 NAND Controller, there may generate infinite ECC decode IRQ
during long time burn test on some platforms. Once this issue occurred,
the ECC decode IRQ status cannot be cleared in the IRQ handler function,
and threads cannot be scheduled.
ECC HW generates decode IRQ each sector, so there will have more than one
decode IRQ if read one page of large page NAND.
Currently, ECC IRQ handle flow is that we will check whether it is decode
IRQ at first by reading the register ECC_DECIRQ_STA. This is a read-clear
type register. If this IRQ is decode IRQ, then the ECC IRQ signal will be
cleared at the same time.
Secondly, we will check whether all sectors are decoded by reading the
register ECC_DECDONE. This is because the current IRQ may be not dealed
in time, and the next sectors have been decoded before reading the
register ECC_DECIRQ_STA. Then, the next sectors's decode IRQs will not
be generated.
Thirdly, if all sectors are decoded by comparing with ecc->sectors, then we
will complete ecc->done, set ecc->sectors as 0, and disable ECC IRQ by
programming the register ECC_IRQ_REG(op) as 0. Otherwise, wait for the
next ECC IRQ.
But, there is a timing issue between step one and two. When we read the
reigster ECC_DECIRQ_STA, all sectors are decoded except the last sector,
and the ECC IRQ signal is cleared. But the last sector is decoded before
reading ECC_DECDONE, so the ECC IRQ signal is enabled again by ECC HW, and
it means we will receive one extra ECC IRQ later. In step three, we will
find that all sectors were decoded, then disable ECC IRQ and return.
When deal with the extra ECC IRQ, the ECC IRQ status cannot be cleared
anymore. That is because the register ECC_DECIRQ_STA can only be cleared
when the register ECC_IRQ_REG(op) is enabled. But actually we have
disabled ECC IRQ in the previous ECC IRQ handle. So, there will
keep receiving ECC decode IRQ.
Now, we read the register ECC_DECIRQ_STA once again before completing the
ecc done event. This ensures that there will be no extra ECC decode IRQ.
Also, remove writel(0, ecc->regs + ECC_IRQ_REG(op)) from irq handler,
because ECC IRQ is disabled in mtk_ecc_disable(). And clear ECC_DECIRQ_STA
in mtk_ecc_disable() in case there is a timeout to wait decode IRQ.
Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
Cc: <stable@vger.kernel.org>
Signed-off-by: Xiaolei Li <xiaolei.li@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-10-30 10:39:56 +08:00
|
|
|
/*
|
|
|
|
* Clear decode IRQ status once again to ensure that
|
|
|
|
* there will be no extra IRQ.
|
|
|
|
*/
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_STA]);
|
2016-06-14 23:50:51 +08:00
|
|
|
ecc->sectors = 0;
|
|
|
|
complete(&ecc->done);
|
|
|
|
} else {
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
} else {
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
enc = readl(ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_STA])
|
|
|
|
& ECC_IRQ_EN;
|
|
|
|
if (enc)
|
2016-06-14 23:50:51 +08:00
|
|
|
complete(&ecc->done);
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
else
|
2016-06-14 23:50:51 +08:00
|
|
|
return IRQ_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
static int mtk_ecc_config(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
|
2016-06-14 23:50:51 +08:00
|
|
|
{
|
2017-05-31 16:26:40 +08:00
|
|
|
u32 ecc_bit, dec_sz, enc_sz;
|
|
|
|
u32 reg, i;
|
|
|
|
|
|
|
|
for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
|
|
|
|
if (ecc->caps->ecc_strength[i] == config->strength)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == ecc->caps->num_ecc_strength) {
|
|
|
|
dev_err(ecc->dev, "invalid ecc strength %d\n",
|
2016-06-14 23:50:51 +08:00
|
|
|
config->strength);
|
2017-05-31 16:26:40 +08:00
|
|
|
return -EINVAL;
|
2016-06-14 23:50:51 +08:00
|
|
|
}
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
ecc_bit = i;
|
|
|
|
|
2016-06-14 23:50:51 +08:00
|
|
|
if (config->op == ECC_ENCODE) {
|
|
|
|
/* configure ECC encoder (in bits) */
|
|
|
|
enc_sz = config->len << 3;
|
|
|
|
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
|
2016-06-14 23:50:51 +08:00
|
|
|
reg |= (enc_sz << ECC_MS_SHIFT);
|
|
|
|
writel(reg, ecc->regs + ECC_ENCCNFG);
|
|
|
|
|
|
|
|
if (config->mode != ECC_NFI_MODE)
|
|
|
|
writel(lower_32_bits(config->addr),
|
|
|
|
ecc->regs + ECC_ENCDIADDR);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* configure ECC decoder (in bits) */
|
|
|
|
dec_sz = (config->len << 3) +
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
config->strength * ecc->caps->parity_bits;
|
2016-06-14 23:50:51 +08:00
|
|
|
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
reg = ecc_bit | (config->mode << ecc->caps->ecc_mode_shift);
|
2016-06-14 23:50:51 +08:00
|
|
|
reg |= (dec_sz << ECC_MS_SHIFT) | DEC_CNFG_CORRECT;
|
|
|
|
reg |= DEC_EMPTY_EN;
|
|
|
|
writel(reg, ecc->regs + ECC_DECCNFG);
|
|
|
|
|
|
|
|
if (config->sectors)
|
|
|
|
ecc->sectors = 1 << (config->sectors - 1);
|
|
|
|
}
|
2017-05-31 16:26:40 +08:00
|
|
|
|
|
|
|
return 0;
|
2016-06-14 23:50:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats,
|
|
|
|
int sectors)
|
|
|
|
{
|
|
|
|
u32 offset, i, err;
|
|
|
|
u32 bitflips = 0;
|
|
|
|
|
|
|
|
stats->corrected = 0;
|
|
|
|
stats->failed = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < sectors; i++) {
|
|
|
|
offset = (i >> 2) << 2;
|
|
|
|
err = readl(ecc->regs + ECC_DECENUM0 + offset);
|
2022-04-03 00:03:13 +08:00
|
|
|
err = err >> ((i % 4) * ecc->caps->err_shift);
|
2017-05-31 16:26:40 +08:00
|
|
|
err &= ecc->caps->err_mask;
|
|
|
|
if (err == ecc->caps->err_mask) {
|
2016-06-14 23:50:51 +08:00
|
|
|
/* uncorrectable errors */
|
|
|
|
stats->failed++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
stats->corrected += err;
|
|
|
|
bitflips = max_t(u32, bitflips, err);
|
|
|
|
}
|
|
|
|
|
|
|
|
stats->bitflips = bitflips;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_get_stats);
|
|
|
|
|
|
|
|
void mtk_ecc_release(struct mtk_ecc *ecc)
|
|
|
|
{
|
|
|
|
clk_disable_unprepare(ecc->clk);
|
|
|
|
put_device(ecc->dev);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_release);
|
|
|
|
|
|
|
|
static void mtk_ecc_hw_init(struct mtk_ecc *ecc)
|
|
|
|
{
|
|
|
|
mtk_ecc_wait_idle(ecc, ECC_ENCODE);
|
|
|
|
writew(ECC_OP_DISABLE, ecc->regs + ECC_ENCCON);
|
|
|
|
|
|
|
|
mtk_ecc_wait_idle(ecc, ECC_DECODE);
|
|
|
|
writel(ECC_OP_DISABLE, ecc->regs + ECC_DECCON);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct mtk_ecc *mtk_ecc_get(struct device_node *np)
|
|
|
|
{
|
|
|
|
struct platform_device *pdev;
|
|
|
|
struct mtk_ecc *ecc;
|
|
|
|
|
|
|
|
pdev = of_find_device_by_node(np);
|
2019-02-07 22:01:32 +08:00
|
|
|
if (!pdev)
|
2016-06-14 23:50:51 +08:00
|
|
|
return ERR_PTR(-EPROBE_DEFER);
|
|
|
|
|
|
|
|
ecc = platform_get_drvdata(pdev);
|
2019-02-07 22:01:32 +08:00
|
|
|
if (!ecc) {
|
|
|
|
put_device(&pdev->dev);
|
|
|
|
return ERR_PTR(-EPROBE_DEFER);
|
|
|
|
}
|
|
|
|
|
2016-06-14 23:50:51 +08:00
|
|
|
clk_prepare_enable(ecc->clk);
|
|
|
|
mtk_ecc_hw_init(ecc);
|
|
|
|
|
|
|
|
return ecc;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct mtk_ecc *of_mtk_ecc_get(struct device_node *of_node)
|
|
|
|
{
|
|
|
|
struct mtk_ecc *ecc = NULL;
|
|
|
|
struct device_node *np;
|
|
|
|
|
2022-04-24 11:25:25 +08:00
|
|
|
np = of_parse_phandle(of_node, "nand-ecc-engine", 0);
|
|
|
|
/* for backward compatibility */
|
|
|
|
if (!np)
|
|
|
|
np = of_parse_phandle(of_node, "ecc-engine", 0);
|
2016-06-14 23:50:51 +08:00
|
|
|
if (np) {
|
|
|
|
ecc = mtk_ecc_get(np);
|
|
|
|
of_node_put(np);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ecc;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(of_mtk_ecc_get);
|
|
|
|
|
|
|
|
int mtk_ecc_enable(struct mtk_ecc *ecc, struct mtk_ecc_config *config)
|
|
|
|
{
|
|
|
|
enum mtk_ecc_operation op = config->op;
|
2017-05-31 16:26:41 +08:00
|
|
|
u16 reg_val;
|
2016-06-14 23:50:51 +08:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = mutex_lock_interruptible(&ecc->lock);
|
|
|
|
if (ret) {
|
|
|
|
dev_err(ecc->dev, "interrupted when attempting to lock\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
mtk_ecc_wait_idle(ecc, op);
|
2017-05-31 16:26:40 +08:00
|
|
|
|
|
|
|
ret = mtk_ecc_config(ecc, config);
|
2017-07-03 18:54:28 +08:00
|
|
|
if (ret) {
|
|
|
|
mutex_unlock(&ecc->lock);
|
2017-05-31 16:26:40 +08:00
|
|
|
return ret;
|
2017-07-03 18:54:28 +08:00
|
|
|
}
|
2017-05-31 16:26:40 +08:00
|
|
|
|
2017-06-23 15:12:25 +08:00
|
|
|
if (config->mode != ECC_NFI_MODE || op != ECC_ENCODE) {
|
|
|
|
init_completion(&ecc->done);
|
|
|
|
reg_val = ECC_IRQ_EN;
|
|
|
|
/*
|
|
|
|
* For ECC_NFI_MODE, if ecc->caps->pg_irq_sel is 1, then it
|
|
|
|
* means this chip can only generate one ecc irq during page
|
|
|
|
* read / write. If is 0, generate one ecc irq each ecc step.
|
|
|
|
*/
|
|
|
|
if (ecc->caps->pg_irq_sel && config->mode == ECC_NFI_MODE)
|
|
|
|
reg_val |= ECC_PG_IRQ_SEL;
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
if (op == ECC_ENCODE)
|
|
|
|
writew(reg_val, ecc->regs +
|
|
|
|
ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
|
|
|
|
else
|
|
|
|
writew(reg_val, ecc->regs +
|
|
|
|
ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
|
2017-06-23 15:12:25 +08:00
|
|
|
}
|
2016-06-14 23:50:51 +08:00
|
|
|
|
2017-06-23 15:12:24 +08:00
|
|
|
writew(ECC_OP_ENABLE, ecc->regs + ECC_CTL_REG(op));
|
|
|
|
|
2016-06-14 23:50:51 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_enable);
|
|
|
|
|
|
|
|
void mtk_ecc_disable(struct mtk_ecc *ecc)
|
|
|
|
{
|
|
|
|
enum mtk_ecc_operation op = ECC_ENCODE;
|
|
|
|
|
|
|
|
/* find out the running operation */
|
|
|
|
if (readw(ecc->regs + ECC_CTL_REG(op)) != ECC_OP_ENABLE)
|
|
|
|
op = ECC_DECODE;
|
|
|
|
|
|
|
|
/* disable it */
|
|
|
|
mtk_ecc_wait_idle(ecc, op);
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
if (op == ECC_DECODE) {
|
mtd: nand: mtk: fix infinite ECC decode IRQ issue
For MT2701 NAND Controller, there may generate infinite ECC decode IRQ
during long time burn test on some platforms. Once this issue occurred,
the ECC decode IRQ status cannot be cleared in the IRQ handler function,
and threads cannot be scheduled.
ECC HW generates decode IRQ each sector, so there will have more than one
decode IRQ if read one page of large page NAND.
Currently, ECC IRQ handle flow is that we will check whether it is decode
IRQ at first by reading the register ECC_DECIRQ_STA. This is a read-clear
type register. If this IRQ is decode IRQ, then the ECC IRQ signal will be
cleared at the same time.
Secondly, we will check whether all sectors are decoded by reading the
register ECC_DECDONE. This is because the current IRQ may be not dealed
in time, and the next sectors have been decoded before reading the
register ECC_DECIRQ_STA. Then, the next sectors's decode IRQs will not
be generated.
Thirdly, if all sectors are decoded by comparing with ecc->sectors, then we
will complete ecc->done, set ecc->sectors as 0, and disable ECC IRQ by
programming the register ECC_IRQ_REG(op) as 0. Otherwise, wait for the
next ECC IRQ.
But, there is a timing issue between step one and two. When we read the
reigster ECC_DECIRQ_STA, all sectors are decoded except the last sector,
and the ECC IRQ signal is cleared. But the last sector is decoded before
reading ECC_DECDONE, so the ECC IRQ signal is enabled again by ECC HW, and
it means we will receive one extra ECC IRQ later. In step three, we will
find that all sectors were decoded, then disable ECC IRQ and return.
When deal with the extra ECC IRQ, the ECC IRQ status cannot be cleared
anymore. That is because the register ECC_DECIRQ_STA can only be cleared
when the register ECC_IRQ_REG(op) is enabled. But actually we have
disabled ECC IRQ in the previous ECC IRQ handle. So, there will
keep receiving ECC decode IRQ.
Now, we read the register ECC_DECIRQ_STA once again before completing the
ecc done event. This ensures that there will be no extra ECC decode IRQ.
Also, remove writel(0, ecc->regs + ECC_IRQ_REG(op)) from irq handler,
because ECC IRQ is disabled in mtk_ecc_disable(). And clear ECC_DECIRQ_STA
in mtk_ecc_disable() in case there is a timeout to wait decode IRQ.
Fixes: 1d6b1e464950 ("mtd: mediatek: driver for MTK Smart Device")
Cc: <stable@vger.kernel.org>
Signed-off-by: Xiaolei Li <xiaolei.li@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-10-30 10:39:56 +08:00
|
|
|
/*
|
|
|
|
* Clear decode IRQ status in case there is a timeout to wait
|
|
|
|
* decode IRQ.
|
|
|
|
*/
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
readw(ecc->regs + ecc->caps->ecc_regs[ECC_DECDONE]);
|
|
|
|
writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_DECIRQ_EN]);
|
|
|
|
} else {
|
|
|
|
writew(0, ecc->regs + ecc->caps->ecc_regs[ECC_ENCIRQ_EN]);
|
|
|
|
}
|
|
|
|
|
2016-06-14 23:50:51 +08:00
|
|
|
writew(ECC_OP_DISABLE, ecc->regs + ECC_CTL_REG(op));
|
|
|
|
|
|
|
|
mutex_unlock(&ecc->lock);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_disable);
|
|
|
|
|
|
|
|
int mtk_ecc_wait_done(struct mtk_ecc *ecc, enum mtk_ecc_operation op)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = wait_for_completion_timeout(&ecc->done, msecs_to_jiffies(500));
|
|
|
|
if (!ret) {
|
|
|
|
dev_err(ecc->dev, "%s timeout - interrupt did not arrive)\n",
|
|
|
|
(op == ECC_ENCODE) ? "encoder" : "decoder");
|
|
|
|
return -ETIMEDOUT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_wait_done);
|
|
|
|
|
|
|
|
int mtk_ecc_encode(struct mtk_ecc *ecc, struct mtk_ecc_config *config,
|
|
|
|
u8 *data, u32 bytes)
|
|
|
|
{
|
|
|
|
dma_addr_t addr;
|
2016-10-18 06:05:31 +08:00
|
|
|
u32 len;
|
|
|
|
int ret;
|
2016-06-14 23:50:51 +08:00
|
|
|
|
|
|
|
addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE);
|
|
|
|
ret = dma_mapping_error(ecc->dev, addr);
|
|
|
|
if (ret) {
|
|
|
|
dev_err(ecc->dev, "dma mapping error\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
config->op = ECC_ENCODE;
|
|
|
|
config->addr = addr;
|
|
|
|
ret = mtk_ecc_enable(ecc, config);
|
|
|
|
if (ret) {
|
|
|
|
dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = mtk_ecc_wait_done(ecc, ECC_ENCODE);
|
|
|
|
if (ret)
|
|
|
|
goto timeout;
|
|
|
|
|
|
|
|
mtk_ecc_wait_idle(ecc, ECC_ENCODE);
|
|
|
|
|
|
|
|
/* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
len = (config->strength * ecc->caps->parity_bits + 7) >> 3;
|
2016-06-14 23:50:51 +08:00
|
|
|
|
2016-10-18 06:05:31 +08:00
|
|
|
/* write the parity bytes generated by the ECC back to temp buffer */
|
2017-05-31 16:26:41 +08:00
|
|
|
__ioread32_copy(ecc->eccdata,
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
ecc->regs + ecc->caps->ecc_regs[ECC_ENCPAR00],
|
2017-05-31 16:26:41 +08:00
|
|
|
round_up(len, 4));
|
2016-10-18 06:05:31 +08:00
|
|
|
|
|
|
|
/* copy into possibly unaligned OOB region with actual length */
|
|
|
|
memcpy(data + bytes, ecc->eccdata, len);
|
2016-06-14 23:50:51 +08:00
|
|
|
timeout:
|
|
|
|
|
|
|
|
dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);
|
|
|
|
mtk_ecc_disable(ecc);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_encode);
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
void mtk_ecc_adjust_strength(struct mtk_ecc *ecc, u32 *p)
|
2016-06-14 23:50:51 +08:00
|
|
|
{
|
2017-05-31 16:26:40 +08:00
|
|
|
const u8 *ecc_strength = ecc->caps->ecc_strength;
|
2016-06-14 23:50:51 +08:00
|
|
|
int i;
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
for (i = 0; i < ecc->caps->num_ecc_strength; i++) {
|
|
|
|
if (*p <= ecc_strength[i]) {
|
2016-06-14 23:50:51 +08:00
|
|
|
if (!i)
|
2017-05-31 16:26:40 +08:00
|
|
|
*p = ecc_strength[i];
|
|
|
|
else if (*p != ecc_strength[i])
|
|
|
|
*p = ecc_strength[i - 1];
|
2016-06-14 23:50:51 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
*p = ecc_strength[ecc->caps->num_ecc_strength - 1];
|
2016-06-14 23:50:51 +08:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_adjust_strength);
|
|
|
|
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
|
|
|
|
{
|
|
|
|
return ecc->caps->parity_bits;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
|
2023-02-01 10:15:00 +08:00
|
|
|
.err_mask = ECC_ERRMASK_MT2701,
|
2022-04-03 00:03:13 +08:00
|
|
|
.err_shift = 8,
|
2017-05-31 16:26:40 +08:00
|
|
|
.ecc_strength = ecc_strength_mt2701,
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
.ecc_regs = mt2701_ecc_regs,
|
2017-05-31 16:26:40 +08:00
|
|
|
.num_ecc_strength = 20,
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
.ecc_mode_shift = 5,
|
|
|
|
.parity_bits = 14,
|
2017-05-31 16:26:41 +08:00
|
|
|
.pg_irq_sel = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = {
|
2023-02-01 10:15:00 +08:00
|
|
|
.err_mask = ECC_ERRMASK_MT2712,
|
2022-04-03 00:03:13 +08:00
|
|
|
.err_shift = 8,
|
2017-05-31 16:26:41 +08:00
|
|
|
.ecc_strength = ecc_strength_mt2712,
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
.ecc_regs = mt2712_ecc_regs,
|
2017-05-31 16:26:41 +08:00
|
|
|
.num_ecc_strength = 23,
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
.ecc_mode_shift = 5,
|
|
|
|
.parity_bits = 14,
|
2017-05-31 16:26:41 +08:00
|
|
|
.pg_irq_sel = 1,
|
2017-05-31 16:26:40 +08:00
|
|
|
};
|
|
|
|
|
2017-11-30 22:10:45 +08:00
|
|
|
static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
|
2023-02-01 10:15:00 +08:00
|
|
|
.err_mask = ECC_ERRMASK_MT7622,
|
2022-04-03 00:03:13 +08:00
|
|
|
.err_shift = 5,
|
2017-11-30 22:10:45 +08:00
|
|
|
.ecc_strength = ecc_strength_mt7622,
|
|
|
|
.ecc_regs = mt7622_ecc_regs,
|
2022-04-03 00:03:13 +08:00
|
|
|
.num_ecc_strength = 5,
|
2017-11-30 22:10:45 +08:00
|
|
|
.ecc_mode_shift = 4,
|
|
|
|
.parity_bits = 13,
|
|
|
|
.pg_irq_sel = 0,
|
|
|
|
};
|
|
|
|
|
2023-02-01 10:15:00 +08:00
|
|
|
static const struct mtk_ecc_caps mtk_ecc_caps_mt7986 = {
|
|
|
|
.err_mask = ECC_ERRMASK_MT7622,
|
|
|
|
.err_shift = 8,
|
|
|
|
.ecc_strength = ecc_strength_mt7986,
|
|
|
|
.ecc_regs = mt2712_ecc_regs,
|
|
|
|
.num_ecc_strength = 11,
|
|
|
|
.ecc_mode_shift = 5,
|
|
|
|
.parity_bits = 14,
|
|
|
|
.pg_irq_sel = 1,
|
|
|
|
};
|
|
|
|
|
2017-05-31 16:26:40 +08:00
|
|
|
static const struct of_device_id mtk_ecc_dt_match[] = {
|
|
|
|
{
|
|
|
|
.compatible = "mediatek,mt2701-ecc",
|
|
|
|
.data = &mtk_ecc_caps_mt2701,
|
2017-05-31 16:26:41 +08:00
|
|
|
}, {
|
|
|
|
.compatible = "mediatek,mt2712-ecc",
|
|
|
|
.data = &mtk_ecc_caps_mt2712,
|
2017-11-30 22:10:45 +08:00
|
|
|
}, {
|
|
|
|
.compatible = "mediatek,mt7622-ecc",
|
|
|
|
.data = &mtk_ecc_caps_mt7622,
|
2023-02-01 10:15:00 +08:00
|
|
|
}, {
|
|
|
|
.compatible = "mediatek,mt7986-ecc",
|
|
|
|
.data = &mtk_ecc_caps_mt7986,
|
2017-05-31 16:26:40 +08:00
|
|
|
},
|
|
|
|
{},
|
|
|
|
};
|
|
|
|
|
2016-06-14 23:50:51 +08:00
|
|
|
static int mtk_ecc_probe(struct platform_device *pdev)
|
|
|
|
{
|
|
|
|
struct device *dev = &pdev->dev;
|
|
|
|
struct mtk_ecc *ecc;
|
2017-05-31 16:26:40 +08:00
|
|
|
u32 max_eccdata_size;
|
2016-06-14 23:50:51 +08:00
|
|
|
int irq, ret;
|
|
|
|
|
|
|
|
ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL);
|
|
|
|
if (!ecc)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2018-04-16 10:33:54 +08:00
|
|
|
ecc->caps = of_device_get_match_data(dev);
|
2017-05-31 16:26:40 +08:00
|
|
|
|
|
|
|
max_eccdata_size = ecc->caps->num_ecc_strength - 1;
|
|
|
|
max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size];
|
mtd: nand: mtk: Support different MTK NAND flash controller IP
MT7622 uses an MTK's earlier NAND flash controller IP which support
different sector size, max spare size per sector and paraity bits...,
some register's offset and definition also been changed in the NAND
flash controller, this patch is the preparation to support MT7622
NAND flash controller.
MT7622 NFC and ECC engine are similar to MT2701's, except below
differences:
(1)MT7622 NFC's max sector size(ECC data size) is 512 bytes, and
MT2701's is 1024, and MT7622's max sector number is 8.
(2)The parity bit of MT7622 is 13, MT2701 is 14.
(3)MT7622 ECC supports less ECC strength, max to 16 bit ecc strength.
(4)MT7622 supports less spare size per sector, max spare size per
sector is 28 bytes.
(5)Some register's offset are different, include ECC_ENCIRQ_EN,
ECC_ENCIRQ_STA, ECC_DECDONE, ECC_DECIRQ_EN and ECC_DECIRQ_STA.
(6)ENC_MODE of ECC_ENCCNFG register is moved from bit 5-6 to bit 4-5.
Signed-off-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
2017-11-30 22:10:44 +08:00
|
|
|
max_eccdata_size = (max_eccdata_size * ecc->caps->parity_bits + 7) >> 3;
|
2017-05-31 16:26:40 +08:00
|
|
|
max_eccdata_size = round_up(max_eccdata_size, 4);
|
|
|
|
ecc->eccdata = devm_kzalloc(dev, max_eccdata_size, GFP_KERNEL);
|
|
|
|
if (!ecc->eccdata)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2021-09-01 15:41:52 +08:00
|
|
|
ecc->regs = devm_platform_ioremap_resource(pdev, 0);
|
2021-04-08 19:15:12 +08:00
|
|
|
if (IS_ERR(ecc->regs))
|
2016-06-14 23:50:51 +08:00
|
|
|
return PTR_ERR(ecc->regs);
|
|
|
|
|
|
|
|
ecc->clk = devm_clk_get(dev, NULL);
|
|
|
|
if (IS_ERR(ecc->clk)) {
|
|
|
|
dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk));
|
|
|
|
return PTR_ERR(ecc->clk);
|
|
|
|
}
|
|
|
|
|
|
|
|
irq = platform_get_irq(pdev, 0);
|
2019-07-31 02:15:30 +08:00
|
|
|
if (irq < 0)
|
2017-08-10 00:35:21 +08:00
|
|
|
return irq;
|
2016-06-14 23:50:51 +08:00
|
|
|
|
|
|
|
ret = dma_set_mask(dev, DMA_BIT_MASK(32));
|
|
|
|
if (ret) {
|
|
|
|
dev_err(dev, "failed to set DMA mask\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = devm_request_irq(dev, irq, mtk_ecc_irq, 0x0, "mtk-ecc", ecc);
|
|
|
|
if (ret) {
|
|
|
|
dev_err(dev, "failed to request irq\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ecc->dev = dev;
|
|
|
|
mutex_init(&ecc->lock);
|
|
|
|
platform_set_drvdata(pdev, ecc);
|
|
|
|
dev_info(dev, "probed\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
static int mtk_ecc_suspend(struct device *dev)
|
|
|
|
{
|
|
|
|
struct mtk_ecc *ecc = dev_get_drvdata(dev);
|
|
|
|
|
|
|
|
clk_disable_unprepare(ecc->clk);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int mtk_ecc_resume(struct device *dev)
|
|
|
|
{
|
|
|
|
struct mtk_ecc *ecc = dev_get_drvdata(dev);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = clk_prepare_enable(ecc->clk);
|
|
|
|
if (ret) {
|
|
|
|
dev_err(dev, "failed to enable clk\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static SIMPLE_DEV_PM_OPS(mtk_ecc_pm_ops, mtk_ecc_suspend, mtk_ecc_resume);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
MODULE_DEVICE_TABLE(of, mtk_ecc_dt_match);
|
|
|
|
|
|
|
|
static struct platform_driver mtk_ecc_driver = {
|
|
|
|
.probe = mtk_ecc_probe,
|
|
|
|
.driver = {
|
|
|
|
.name = "mtk-ecc",
|
mtd: Fix misuses of of_match_ptr()
of_match_ptr() either expands to NULL if !CONFIG_OF, or is transparent
otherwise. There are several drivers using this macro which keep their
of_device_id array enclosed within an #ifdef CONFIG_OF check, these are
considered fine. However, When misused, the of_device_id array pointed
by this macro will produce a warning because it is finally unused when
compiled without OF support.
A number of fixes are possible:
- Always depend on CONFIG_OF, but this will not always work and may
break boards.
- Enclose the compatible array by #ifdef's, this may save a bit of
memory but will reduce build coverage.
- Tell the compiler the array may be unused, if this can be avoided,
let's not do this.
- Just drop the macro, setting the of_device_id array for a non OF
enabled platform is not an issue, it will just be unused.
The latter solution seems the more appropriate, so let's use it.
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Acked-by: Paul Cercueil <paul@crapouillou.net>
Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Acked-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/linux-mtd/20220127110631.1064705-1-miquel.raynal@bootlin.com
2022-01-27 19:06:31 +08:00
|
|
|
.of_match_table = mtk_ecc_dt_match,
|
2016-06-14 23:50:51 +08:00
|
|
|
#ifdef CONFIG_PM_SLEEP
|
|
|
|
.pm = &mtk_ecc_pm_ops,
|
|
|
|
#endif
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
module_platform_driver(mtk_ecc_driver);
|
|
|
|
|
|
|
|
MODULE_AUTHOR("Xiaolei Li <xiaolei.li@mediatek.com>");
|
|
|
|
MODULE_DESCRIPTION("MTK Nand ECC Driver");
|
2019-06-24 09:38:56 +08:00
|
|
|
MODULE_LICENSE("Dual MIT/GPL");
|