[PATCH 11/24] mtd: rawnand: sunxi: cosmetic: add has_ecc_block_512 capability
    Richard GENOUD 
    richard.genoud at bootlin.com
       
    Mon Oct 20 09:02:58 CEST 2025
    
    
  
Hi,
Le 18/10/2025 à 01:11, Andre Przywara a écrit :
> Hi,
> 
> On 16/10/2025 15:27, Richard Genoud wrote:
>> Introduce has_ecc_block_512 capability
>>
>> The H616 controller can't handle 512 bytes ECC block size.
>> Let it be a capability.
>>
>> No functional change.
>>
>> Signed-off-by: Richard Genoud <richard.genoud at bootlin.com>
>> ---
>>   drivers/mtd/nand/raw/sunxi_nand.c | 14 +++++++++++---
>>   drivers/mtd/nand/raw/sunxi_nand.h |  2 ++
>>   2 files changed, 13 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/ 
>> sunxi_nand.c
>> index 869b3ddd971c..fddb1cada023 100644
>> --- a/drivers/mtd/nand/raw/sunxi_nand.c
>> +++ b/drivers/mtd/nand/raw/sunxi_nand.c
>> @@ -660,11 +660,12 @@ static void sunxi_nfc_hw_ecc_enable(struct 
>> mtd_info *mtd)
>>       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_SIZE_MSK;
> 
> So if I get this correctly, then NFC_ECC_BLOCK_SIZE_MSK and 
> NFC_ECC_BLOCK_512 are referring to the same single bit register field, 
> in bit 5? Can we lose the MSK definition then, and clear the field 
> unconditionally? Or is it that on the H6/H616 we must never touch bit 5, 
> because it refers to something else (NDFC_RANDOM_EN?)?
> In any case I think we don't need identical MSK and BLOCK_512 
> definitions, do we?
Yes, 2nd case:
On A23/A10, the bit 5 (NFC_ECC_BLOCK_512) in NDFC_ECC_CTL register 
(0x34) is controlling the size of one ECC data block (0: 1024bytes 1:512 
bytes).
On H6, this bit NFC_ECC_BLOCK_512 doesn't exists anymore, but instead, 
bit 5 of NDFC_ECC_CTL register (0x34) is NDFC_RANDOM_EN (which was 
itself on bit 9 for A10/A23)
So yes, we can definitely loose NFC_ECC_BLOCK_SIZE_MSK, and keep 
has_ecc_block_512 to differentiate A10 from H6.
> 
> By the way: Do you have any MMIO frame register description for the old 
> NAND device? I checked some of the older manuals, but the ones I looked 
> at were only showing timing diagrams, but no register map.
Yes, the NAND controller in A33 is the same (AFAIK) than on A23:
https://linux-sunxi.org/images/4/49/A33_Nand_Flash_Controller_Specification.pdf
Thanks!
> 
> Cheers,
> Andre
> 
>>       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);
>> @@ -1454,6 +1455,8 @@ static void sunxi_nand_ecc_cleanup(struct 
>> nand_ecc_ctrl *ecc)
>>   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) {
>> @@ -1464,6 +1467,10 @@ static int sunxi_nand_ecc_init(struct mtd_info 
>> *mtd, struct nand_ecc_ctrl *ecc)
>>       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;
>> @@ -1715,6 +1722,7 @@ static int sunxi_nand_probe(struct udevice *dev)
>>   }
>>   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,
>> diff --git a/drivers/mtd/nand/raw/sunxi_nand.h b/drivers/mtd/nand/raw/ 
>> sunxi_nand.h
>> index 35079d37bb1f..be294d7cea0a 100644
>> --- a/drivers/mtd/nand/raw/sunxi_nand.h
>> +++ b/drivers/mtd/nand/raw/sunxi_nand.h
>> @@ -169,6 +169,7 @@
>>    * 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
>> @@ -176,6 +177,7 @@
>>    * @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;
> 
-- 
Richard Genoud, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
    
    
More information about the U-Boot
mailing list