On 04/13/2018 04:41 AM, Daniel Gonzalez Cabanelas wrote:
> Hi, since the adoption of the Linux kernel 4.9 there are available drivers 
> for NAND flash in the brcm63xx target. However these drivers only support 
> brcm NAND versions 4.0 and  and up, giving support only for BCM6362 and 
> BCM63268 SoCs
> 
> I've made a patch for including the versions present in BCM6328 and BCM6368 
> (versions 2.1 and 2.2), basically I just added the required registers. The 
> NAND flash detection is ok, formating and mounting jffs2 filesystems also 
> seems to be OK. But when writting an remounting the partitions I get plenty 
> of jfss2 errors.

I would suggest running the mtd-tests modules and user-space test suite
to validate your changes are correct.

> 
> Probably the ECC in versions 2.1 and 2.2 need additional work, since some 
> bits are missing when comparing with version 4.0.

That is likely what is happening.

> 
> I was testing this stuff using the NAND chip as the secondary flash. Which is 
> de default configuration in the DGND3700 v1 (bcm6368), and hardware modded in 
> the AD1018 (bcm6328).
> 
> Is there any plan to include NAND support?. Not as the main flash chip  but 
> secondary for a first approach for further support in the future.
> 
> Regards.
> 
> diff --git a/target/linux/brcm63xx/config-4.9 
> b/target/linux/brcm63xx/config-4.9
> index f1c3471..7d48ba2 100644
> --- a/target/linux/brcm63xx/config-4.9
> +++ b/target/linux/brcm63xx/config-4.9
> @@ -168,6 +168,9 @@ CONFIG_MTD_CFI_STAA=y
>  # CONFIG_MTD_COMPLEX_MAPPINGS is not set
>  CONFIG_MTD_JEDECPROBE=y
>  CONFIG_MTD_M25P80=y
> +CONFIG_MTD_NAND=y
> +CONFIG_MTD_NAND_BRCMNAND=y
> +CONFIG_MTD_NAND_ECC=y
>  CONFIG_MTD_PARSER_IMAGETAG=y
>  CONFIG_MTD_PHYSMAP=y
>  CONFIG_MTD_REDBOOT_PARTS=y
> diff --git a/target/linux/brcm63xx/dts/ad1018-nor.dts 
> b/target/linux/brcm63xx/dts/ad1018-nor.dts
> index 93862c2..e7fcf7a 100644
> --- a/target/linux/brcm63xx/dts/ad1018-nor.dts
> +++ b/target/linux/brcm63xx/dts/ad1018-nor.dts
> @@ -140,6 +140,26 @@
>       };
>  };
>  
> +&nflash {
> +     status = "ok";
> +
> +     nandcs@0 {
> +             compatible = "brcm,nandcs";
> +             #size-cells = <1>;
> +             #address-cells = <1>;
> +             reg = <0>;
> +             nand-ecc-step-size = <512>;
> +             nand-ecc-strength = <15>;
> +             brcm,nand-oob-sector-size = <64>;
> +             //nand-on-flash-bbt;
> +
> +             nand_flash@0 {
> +                     label = "nand_flash";
> +                     reg = <0x0000000 0x8000000>;
> +             };
> +     };
> +};
> +
>  &uart0 {
>       status = "ok";
>  };
> diff --git a/target/linux/brcm63xx/dts/bcm63268.dtsi 
> b/target/linux/brcm63xx/dts/bcm63268.dtsi
> index 1b4b3e6..938c49f 100644
> --- a/target/linux/brcm63xx/dts/bcm63268.dtsi
> +++ b/target/linux/brcm63xx/dts/bcm63268.dtsi
> @@ -221,6 +221,19 @@
>                       status = "disabled";
>               };
>  
> +             nflash: nand@10000200 {
> +                     #address-cells = <1>;
> +                     #size-cells = <0>;
> +                     compatible = "brcm,nand-bcm6368", "brcm,brcmnand-v4.0", 
> "brcm,brcmnand";
> +                     reg = <0x10000200 0x180>, <0x10000600 0x200>, 
> <0x100000b0 0x10>;
> +                     reg-names = "nand", "nand-cache", "nand-int-base";
> +
> +                     interrupt-parent = <&periph_intc>;
> +                     interrupts = <50>;
> +
> +                     status = "disabled";
> +             };
> +
>               lsspi: spi@10000800 {
>                       #address-cells = <1>;
>                       #size-cells = <0>;
> diff --git a/target/linux/brcm63xx/dts/bcm6328.dtsi 
> b/target/linux/brcm63xx/dts/bcm6328.dtsi
> index d08b6ba..4155329 100644
> --- a/target/linux/brcm63xx/dts/bcm6328.dtsi
> +++ b/target/linux/brcm63xx/dts/bcm6328.dtsi
> @@ -4,6 +4,7 @@
>       compatible = "brcm,bcm6328";
>  
>       aliases {
> +             nflash = &nflash;
>               pinctrl = &pinctrl;
>               serial0 = &uart0;
>               serial1 = &uart1;
> @@ -179,6 +180,19 @@
>                       status = "disabled";
>               };
>  
> +             nflash: nand@10000200 {
> +                     #address-cells = <1>;
> +                     #size-cells = <0>;
> +                     compatible = "brcm,nand-bcm6368", "brcm,brcmnand-v2.1", 
> "brcm,brcmnand";
> +                     reg = <0x10000200 0x180>, <0x10000400 0x200>, 
> <0x10000070 0x10>;
> +                     reg-names = "nand", "nand-cache", "nand-int-base";
> +
> +                     interrupt-parent = <&periph_intc>;
> +                     interrupts = <0>;
> +
> +                     status = "disabled";
> +             };
> +
>               leds: led-controller@10000800 {
>                       #address-cells = <1>;
>                       #size-cells = <0>;
> diff --git a/target/linux/brcm63xx/dts/bcm6362.dtsi 
> b/target/linux/brcm63xx/dts/bcm6362.dtsi
> index 2ff5c52..9ead35b 100644
> --- a/target/linux/brcm63xx/dts/bcm6362.dtsi
> +++ b/target/linux/brcm63xx/dts/bcm6362.dtsi
> @@ -265,6 +265,19 @@
>                       status = "disabled";
>               };
>  
> +             nflash: nand@10000200 {
> +                     #address-cells = <1>;
> +                     #size-cells = <0>;
> +                     compatible = "brcm,nand-bcm6368", "brcm,brcmnand-v4.0", 
> "brcm,brcmnand";
> +                     reg = <0x10000200 0x180>, <0x10000600 0x200>, 
> <0x10000070 0x10>;
> +                     reg-names = "nand", "nand-cache", "nand-int-base";
> +
> +                     interrupt-parent = <&periph_intc>;
> +                     interrupts = <12>;
> +
> +                     status = "disabled";
> +             };
> +
>               lsspi: spi@10000800 {
>                       #address-cells = <1>;
>                       #size-cells = <0>;
> diff --git a/target/linux/brcm63xx/dts/bcm6368.dtsi 
> b/target/linux/brcm63xx/dts/bcm6368.dtsi
> index b834f9e..f00997b 100644
> --- a/target/linux/brcm63xx/dts/bcm6368.dtsi
> +++ b/target/linux/brcm63xx/dts/bcm6368.dtsi
> @@ -4,6 +4,7 @@
>       compatible = "brcm,bcm6368";
>  
>       aliases {
> +             nflash = &nflash;
>               pflash = &pflash;
>               pinctrl = &pinctrl;
>               serial0 = &uart0;
> @@ -298,6 +299,19 @@
>                       status = "disabled";
>               };
>  
> +             nflash: nand@10000200 {
> +                     #address-cells = <1>;
> +                     #size-cells = <0>;
> +                     compatible = "brcm,nand-bcm6368", "brcm,brcmnand-v2.1", 
> "brcm,brcmnand";
> +                     reg = <0x10000200 0x180>, <0x10000600 0x200>, 
> <0x10000070 0x10>;
> +                     reg-names = "nand", "nand-cache", "nand-int-base";
> +
> +                     interrupt-parent = <&periph_intc>;
> +                     interrupts = <10>;
> +
> +                     status = "disabled";
> +             };
> +
>               lsspi: spi@10000800 {
>                       #address-cells = <1>;
>                       #size-cells = <0>;
> diff --git a/target/linux/brcm63xx/dts/dgnd3700v1.dts 
> b/target/linux/brcm63xx/dts/dgnd3700v1.dts
> index cafa098..d331d98 100644
> --- a/target/linux/brcm63xx/dts/dgnd3700v1.dts
> +++ b/target/linux/brcm63xx/dts/dgnd3700v1.dts
> @@ -123,6 +123,26 @@
>       };
>  }; 
>  
> +&nflash {
> +     status = "ok";
> +
> +     nandcs@0 {
> +             compatible = "brcm,nandcs";
> +             #size-cells = <1>;
> +             #address-cells = <1>;
> +             reg = <0>;
> +             nand-ecc-step-size = <512>;
> +             nand-ecc-strength = <15>;
> +             brcm,nand-oob-sector-size = <64>;
> +             //nand-on-flash-bbt;
> +
> +             nand_flash@0 {
> +                     label = "nand_flash";
> +                     reg = <0x0000000 0x8000000>;
> +             };
> +     };
> +};
> +
>  &pinctrl {
>       pinctrl-names = "default";
>       pinctrl-0 = <&pinctrl_pci>;
> diff --git a/target/linux/brcm63xx/patches-4.9/810-nand.patch 
> b/target/linux/brcm63xx/patches-4.9/810-nand.patch
> new file mode 100644
> index 0000000..354407d
> --- /dev/null
> +++ b/target/linux/brcm63xx/patches-4.9/810-nand.patch
> @@ -0,0 +1,226 @@
> +--- a/drivers/mtd/nand/brcmnand/brcmnand.c
> ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c
> +@@ -222,8 +222,38 @@
> +     BRCMNAND_OOB_WRITE_10_BASE,     /* offset 0x10, if non-contiguous */
> +     BRCMNAND_FC_BASE,
> + };
> + 
> ++/* BRCMNAND v2.1 v2.2 */
> ++static const u16 brcmnand_regs_v21[] = {
> ++    [BRCMNAND_CMD_START]            =  0x04,
> ++    [BRCMNAND_CMD_EXT_ADDRESS]      =  0x08,
> ++    [BRCMNAND_CMD_ADDRESS]          =  0x0c,
> ++    [BRCMNAND_INTFC_STATUS]         =  0x5c,
> ++    [BRCMNAND_CS_SELECT]            =  0x14,
> ++    [BRCMNAND_CS_XOR]               =  0x18,
> ++    [BRCMNAND_LL_OP]                = 0,
> ++    [BRCMNAND_CS0_BASE]             =  0x40,
> ++    [BRCMNAND_CS1_BASE]             =  0,
> ++    [BRCMNAND_CORR_THRESHOLD]       =  0,
> ++    [BRCMNAND_CORR_THRESHOLD_EXT]   =     0,
> ++    [BRCMNAND_UNCORR_COUNT]         =     0,
> ++    [BRCMNAND_CORR_COUNT]           =     0,
> ++    [BRCMNAND_CORR_EXT_ADDR]        =  0x60,
> ++    [BRCMNAND_CORR_ADDR]            =  0x64,
> ++    [BRCMNAND_UNCORR_EXT_ADDR]      =  0x68,
> ++    [BRCMNAND_UNCORR_ADDR]          =  0x6c,
> ++    [BRCMNAND_SEMAPHORE]            =  0x50,
> ++    [BRCMNAND_ID]                   =  0x54,
> ++    [BRCMNAND_ID_EXT]               =  0x9c,
> ++    [BRCMNAND_LL_RDATA]             = 0,
> ++    [BRCMNAND_OOB_READ_BASE]        =  0x20,
> ++    [BRCMNAND_OOB_READ_10_BASE]     = 0,
> ++    [BRCMNAND_OOB_WRITE_BASE]       =  0x30,
> ++    [BRCMNAND_OOB_WRITE_10_BASE]    =     0,
> ++    [BRCMNAND_FC_BASE]              = 0x200,
> ++};
> ++
> + /* BRCMNAND v4.0 */
> + static const u16 brcmnand_regs_v40[] = {
> +     [BRCMNAND_CMD_START]            =  0x04,
> +     [BRCMNAND_CMD_EXT_ADDRESS]      =  0x08,
> +@@ -407,8 +437,17 @@
> +     [BRCMNAND_CS_TIMING1]           = 0x10,
> +     [BRCMNAND_CS_TIMING2]           = 0x14,
> + };
> + 
> ++/* Per chip-select offset for v2.1 v2.2 on CS0 only */
> ++static const u8 brcmnand_cs_offsets_cs0_v21[] = {
> ++    [BRCMNAND_CS_ACC_CONTROL]       = 0x00, //0x40
> ++    [BRCMNAND_CS_CFG_EXT]           = 0x04,
> ++    [BRCMNAND_CS_CFG]               = 0x04,
> ++    [BRCMNAND_CS_TIMING1]           = 0x08,
> ++    [BRCMNAND_CS_TIMING2]           = 0x0c,
> ++};
> ++
> + /*
> +  * Bitfields for the CFG and CFG_EXT registers. Pre-v7.1 controllers only 
> had
> +  * one config register, but once the bitfields overflowed, newer controllers
> +  * (v7.1 and newer) added a CFG_EXT register and shuffled a few fields 
> around.
> +@@ -421,8 +460,9 @@
> +     CFG_BUS_WIDTH                   = BIT(CFG_BUS_WIDTH_SHIFT),
> +     CFG_DEVICE_SIZE_SHIFT           = 24,
> + 
> +     /* Only for pre-v7.1 (with no CFG_EXT register) */
> ++    CFG_PAGE_SIZE_SHIFT_21          = 30, /* only v2.1 BCM6368 */
> +     CFG_PAGE_SIZE_SHIFT             = 20,
> +     CFG_BLK_SIZE_SHIFT              = 28,
> + 
> +     /* Only for v7.1+ (with CFG_EXT register) */
> +@@ -455,18 +495,20 @@
> + static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
> + {
> +     static const unsigned int block_sizes_v6[] = { 8, 16, 128, 256, 512, 
> 1024, 2048, 0 };
> +     static const unsigned int block_sizes_v4[] = { 16, 128, 8, 512, 256, 
> 1024, 2048, 0 };
> ++    static const unsigned int block_sizes_v2[] = { 16, 128, 8, 512, 0 };
> +     static const unsigned int page_sizes[] = { 512, 2048, 4096, 8192, 0 };
> + 
> +     ctrl->nand_version = nand_readreg(ctrl, 0) & 0xffff;
> + 
> +-    /* Only support v4.0+? */
> +-    if (ctrl->nand_version < 0x0400) {
> ++    /* Only support v2.1+? */
> ++    if (ctrl->nand_version < 0x0201) {
> +             dev_err(ctrl->dev, "version %#x not supported\n",
> +                     ctrl->nand_version);
> +             return -ENODEV;
> +     }
> ++    printk("NAND: Version %#x\n", ctrl->nand_version);
> + 
> +     /* Register offsets */
> +     if (ctrl->nand_version >= 0x0702)
> +             ctrl->reg_offsets = brcmnand_regs_v72;
> +@@ -477,8 +519,10 @@
> +     else if (ctrl->nand_version >= 0x0500)
> +             ctrl->reg_offsets = brcmnand_regs_v50;
> +     else if (ctrl->nand_version >= 0x0400)
> +             ctrl->reg_offsets = brcmnand_regs_v40;
> ++    else if (ctrl->nand_version >= 0x0201)
> ++            ctrl->reg_offsets = brcmnand_regs_v21;
> + 
> +     /* Chip-select stride */
> +     if (ctrl->nand_version >= 0x0701)
> +             ctrl->reg_spacing = 0x14;
> +@@ -491,10 +535,13 @@
> +     } else {
> +             ctrl->cs_offsets = brcmnand_cs_offsets;
> + 
> +             /* v5.0 and earlier has a different CS0 offset layout */
> +-            if (ctrl->nand_version <= 0x0500)
> ++            if (ctrl->nand_version >= 0x0300)
> +                     ctrl->cs0_offsets = brcmnand_cs_offsets_cs0;
> ++            else if (ctrl->nand_version >= 0x0201)
> ++              ctrl->cs0_offsets = brcmnand_cs_offsets_cs0_v21;
> ++            
> +     }
> + 
> +     /* Page / block sizes */
> +     if (ctrl->nand_version >= 0x0701) {
> +@@ -504,13 +551,19 @@
> +     } else {
> +             ctrl->page_sizes = page_sizes;
> +             if (ctrl->nand_version >= 0x0600)
> +                     ctrl->block_sizes = block_sizes_v6;
> +-            else
> ++            else if (ctrl->nand_version >= 0x0202)
> +                     ctrl->block_sizes = block_sizes_v4;
> ++            else
> ++                    ctrl->block_sizes = block_sizes_v2;
> ++              
> + 
> +             if (ctrl->nand_version < 0x0400) {
> +-                    ctrl->max_page_size = 4096;
> ++                    if (ctrl->nand_version <= 0x0202) 
> ++                            ctrl->max_page_size = 2048;
> ++                    else
> ++                            ctrl->max_page_size = 4096;
> +                     ctrl->max_block_size = 512 * 1024;
> +             }
> +     }
> + 
> +@@ -2023,10 +2076,15 @@
> +             (cfg->ful_adr_bytes << CFG_FUL_ADR_BYTES_SHIFT) |
> +             (!!(cfg->device_width == 16) << CFG_BUS_WIDTH_SHIFT) |
> +             (device_size << CFG_DEVICE_SIZE_SHIFT);
> +     if (cfg_offs == cfg_ext_offs) {
> +-            tmp |= (page_size << CFG_PAGE_SIZE_SHIFT) |
> +-                   (block_size << CFG_BLK_SIZE_SHIFT);
> ++            if (ctrl->nand_version = 0x0201){
> ++                    tmp |= (page_size << CFG_PAGE_SIZE_SHIFT_21) |
> ++                          (block_size << CFG_BLK_SIZE_SHIFT);
> ++            } else {
> ++                    tmp |= (page_size << CFG_PAGE_SIZE_SHIFT) |
> ++                          (block_size << CFG_BLK_SIZE_SHIFT);
> ++            }
> +             nand_writereg(ctrl, cfg_offs, tmp);
> +     } else {
> +             nand_writereg(ctrl, cfg_offs, tmp);
> +             tmp = (page_size << CFG_EXT_PAGE_SIZE_SHIFT) |
> +@@ -2377,8 +2435,9 @@
> + };
> + EXPORT_SYMBOL_GPL(brcmnand_pm_ops);
> + 
> + static const struct of_device_id brcmnand_of_match[] = {
> ++    { .compatible = "brcm,brcmnand-v2.1" },
> +     { .compatible = "brcm,brcmnand-v4.0" },
> +     { .compatible = "brcm,brcmnand-v5.0" },
> +     { .compatible = "brcm,brcmnand-v6.0" },
> +     { .compatible = "brcm,brcmnand-v6.1" },
> +--- a/arch/mips/bcm63xx/clk.c
> ++++ b/arch/mips/bcm63xx/clk.c
> +@@ -428,8 +428,25 @@
> +     .set    = pcie_set,
> + };
> + 
> + /*
> ++ * NAND clock
> ++ */
> ++static void nand_set(struct clk *clk, int enable)
> ++{
> ++    if (BCMCPU_IS_6362())
> ++            bcm_hwclock_set(CKCTL_6362_NAND_EN, enable);
> ++    else if (BCMCPU_IS_6368())
> ++            bcm_hwclock_set(CKCTL_6368_NAND_EN, enable);
> ++    else if (BCMCPU_IS_63268())
> ++            bcm_hwclock_set(CKCTL_63268_NAND_EN, enable);
> ++}
> ++
> ++static struct clk clk_nand = {
> ++    .set    = nand_set,
> ++};
> ++
> ++/*
> +  * Internal peripheral clock
> +  */
> + static struct clk clk_periph = {
> +     .rate   = (50 * 1000 * 1000),
> +@@ -610,8 +627,9 @@
> +     CLKDEV_INIT("10000120.serial", "refclk", &clk_periph),
> +     CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
> +     CLKDEV_INIT("10001000.spi", "pll", &clk_hsspi_pll),
> +     /* gated clocks */
> ++    CLKDEV_INIT(NULL, "nand", &clk_nand),
> +     CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
> +     CLKDEV_INIT(NULL, "usbh", &clk_usbh),
> +     CLKDEV_INIT(NULL, "usbd", &clk_usbd),
> +     CLKDEV_INIT(NULL, "spi", &clk_spi),
> +@@ -627,8 +645,9 @@
> +     CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
> +     CLKDEV_INIT("10000100.serial", "refclk", &clk_periph),
> +     CLKDEV_INIT("10000120.serial", "refclk", &clk_periph),
> +     /* gated clocks */
> ++    CLKDEV_INIT(NULL, "nand", &clk_nand),
> +     CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
> +     CLKDEV_INIT(NULL, "usbh", &clk_usbh),
> +     CLKDEV_INIT(NULL, "usbd", &clk_usbd),
> +     CLKDEV_INIT(NULL, "spi", &clk_spi),
> +@@ -645,8 +664,9 @@
> +     CLKDEV_INIT("100001a0.serial", "refclk", &clk_periph),
> +     CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
> +     CLKDEV_INIT("10001000.spi", "pll", &clk_hsspi_pll),
> +     /* gated clocks */
> ++    CLKDEV_INIT(NULL, "nand", &clk_nand),
> +     CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
> +     CLKDEV_INIT(NULL, "usbh", &clk_usbh),
> +     CLKDEV_INIT(NULL, "usbd", &clk_usbd),
> +     CLKDEV_INIT(NULL, "spi", &clk_spi),
> 
> 
> _______________________________________________
> Lede-dev mailing list
> Lede-dev@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/lede-dev
> 


-- 
Florian

_______________________________________________
Lede-dev mailing list
Lede-dev@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/lede-dev

Reply via email to