u32 ecc_ctl;
ecc_ctl = readl(nfc->regs + NFC_REG_ECC_CTL);
- ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE |
- NFC_ECC_BLOCK_SIZE_MSK);
+ ecc_ctl &= ~(NFC_ECC_MODE_MSK | NFC_ECC_PIPELINE);
+ if (nfc->caps->has_ecc_block_512)
+ ecc_ctl &= ~NFC_ECC_BLOCK_512;
ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION;
- if (nand->ecc.size == 512)
+ if (nand->ecc.size == 512 && nfc->caps->has_ecc_block_512)
ecc_ctl |= NFC_ECC_BLOCK_512;
writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL);
static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc)
{
struct nand_chip *nand = mtd_to_nand(mtd);
+ struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand);
+ struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller);
int ret;
if (!ecc->size) {
if (!ecc->size || !ecc->strength)
return -EINVAL;
+ /* If 512B ECC is not supported, switch to 1024 */
+ if (ecc->size == 512 && !nfc->caps->has_ecc_block_512)
+ ecc->size = 1024;
+
switch (ecc->mode) {
case NAND_ECC_SOFT_BCH:
break;
}
static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = {
+ .has_ecc_block_512 = true,
.nstrengths = 9,
.reg_ecc_err_cnt = NFC_REG_A10_ECC_ERR_CNT,
.reg_user_data = NFC_REG_A10_USER_DATA,
#define NFC_ECC_EN BIT(0)
#define NFC_ECC_PIPELINE BIT(3)
#define NFC_ECC_EXCEPTION BIT(4)
-#define NFC_ECC_BLOCK_SIZE_MSK BIT(5)
#define NFC_ECC_BLOCK_512 BIT(5)
#define NFC_RANDOM_EN BIT(9)
#define NFC_RANDOM_DIRECTION BIT(10)
* NAND Controller capabilities structure: stores NAND controller capabilities
* for distinction between compatible strings.
*
+ * @has_ecc_block_512: If the ECC can handle 512B or only 1024B chuncks
* @nstrengths: Number of element of ECC strengths array
* @reg_ecc_err_cnt: ECC error counter register
* @reg_user_data: User data register
* @pat_found_mask: ECC_PAT_FOUND mask in NFC_REG_PAT_FOUND register
*/
struct sunxi_nfc_caps {
+ bool has_ecc_block_512;
unsigned int nstrengths;
unsigned int reg_ecc_err_cnt;
unsigned int reg_user_data;