mtd: nand_mrvl_nfc: Add support for HW BCH ECC
Add support for HW BCH ECC for those HW versions that support it. Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Tested-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
f7d39e122e
commit
87bddaf82e
1 changed files with 25 additions and 1 deletions
|
@ -92,6 +92,8 @@
|
||||||
#define NDSR_RDDREQ (0x1 << 1)
|
#define NDSR_RDDREQ (0x1 << 1)
|
||||||
#define NDSR_WRCMDREQ (0x1)
|
#define NDSR_WRCMDREQ (0x1)
|
||||||
|
|
||||||
|
#define NDECCCTRL_BCH_EN BIT(0)
|
||||||
|
|
||||||
#define NDCB0_LEN_OVRD (0x1 << 28)
|
#define NDCB0_LEN_OVRD (0x1 << 28)
|
||||||
#define NDCB0_ST_ROW_EN (0x1 << 26)
|
#define NDCB0_ST_ROW_EN (0x1 << 26)
|
||||||
#define NDCB0_AUTO_RS (0x1 << 25)
|
#define NDCB0_AUTO_RS (0x1 << 25)
|
||||||
|
@ -426,6 +428,17 @@ static void mrvl_nand_start(struct mrvl_nand_host *host)
|
||||||
{
|
{
|
||||||
uint32_t ndcr;
|
uint32_t ndcr;
|
||||||
|
|
||||||
|
if (host->hwflags & HWFLAGS_ECC_BCH) {
|
||||||
|
uint32_t reg = nand_readl(host, NDECCCTRL);
|
||||||
|
|
||||||
|
if (host->use_ecc && host->ecc_bch)
|
||||||
|
reg |= NDECCCTRL_BCH_EN;
|
||||||
|
else
|
||||||
|
reg &= ~NDECCCTRL_BCH_EN;
|
||||||
|
|
||||||
|
nand_writel(host, NDECCCTRL, reg);
|
||||||
|
}
|
||||||
|
|
||||||
ndcr = host->reg_ndcr;
|
ndcr = host->reg_ndcr;
|
||||||
if (host->use_ecc)
|
if (host->use_ecc)
|
||||||
ndcr |= NDCR_ECC_EN;
|
ndcr |= NDCR_ECC_EN;
|
||||||
|
@ -794,8 +807,14 @@ static int mrvl_nand_read_page_hwecc(struct mtd_info *mtd,
|
||||||
else
|
else
|
||||||
ret = -EBADMSG;
|
ret = -EBADMSG;
|
||||||
}
|
}
|
||||||
if (ndsr & NDSR_CORERR)
|
if (ndsr & NDSR_CORERR) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
if ((host->hwflags & HWFLAGS_ECC_BCH) && host->ecc_bch) {
|
||||||
|
ret = NDSR_ERR_CNT(ndsr);
|
||||||
|
ndsr &= ~(NDSR_ERR_CNT_MASK << NDSR_ERR_CNT_OFF);
|
||||||
|
nand_writel(host, NDSR, ndsr);
|
||||||
|
}
|
||||||
|
}
|
||||||
dev_dbg(host->dev, "%s(buf=%p, page=%d, oob_required=%d) => %d\n",
|
dev_dbg(host->dev, "%s(buf=%p, page=%d, oob_required=%d) => %d\n",
|
||||||
__func__, buf, page, oob_required, ret);
|
__func__, buf, page, oob_required, ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1011,6 +1030,11 @@ static int mrvl_nand_scan(struct mtd_info *mtd)
|
||||||
ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes);
|
ndcr |= NDCR_RD_ID_CNT(host->read_id_bytes);
|
||||||
host->reg_ndcr = ndcr;
|
host->reg_ndcr = ndcr;
|
||||||
|
|
||||||
|
/* Device detection must be done with BCH ECC disabled */
|
||||||
|
if (host->hwflags & HWFLAGS_ECC_BCH)
|
||||||
|
nand_writel(host, NDECCCTRL,
|
||||||
|
nand_readl(host, NDECCCTRL) & ~NDECCCTRL_BCH_EN);
|
||||||
|
|
||||||
mrvl_nand_set_timing(host, true);
|
mrvl_nand_set_timing(host, true);
|
||||||
if (nand_scan_ident(mtd, 1, NULL)) {
|
if (nand_scan_ident(mtd, 1, NULL)) {
|
||||||
host->reg_ndcr |= NDCR_DWIDTH_M | NDCR_DWIDTH_C;
|
host->reg_ndcr |= NDCR_DWIDTH_M | NDCR_DWIDTH_C;
|
||||||
|
|
Loading…
Reference in a new issue