]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
mtd: rawnand: brcmnand: Add support for v7.3 controller
authorKamal Dasu <kdasu.kdev@gmail.com>
Sat, 11 Feb 2023 15:29:01 +0000 (16:29 +0100)
committerDario Binacchi <dario.binacchi@amarulasolutions.com>
Mon, 27 Feb 2023 15:29:30 +0000 (16:29 +0100)
This change adds support for brcm NAND v7.3 controller. This controller
uses a newer version of flash_dma engine and change mostly implements
these differences.

Signed-off-by: Kamal Dasu <kdasu.kdev@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
[Ported to U-Boot from the Linux kernel]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: William Zhang <william.zhang@broadcom.com>
Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
drivers/mtd/nand/raw/brcmnand/brcmnand.c

index 571f1c795da064aeb26e4a33b9c4d3e416a05798..170aece0aa797ececf5628e2f6071b8f36af7e22 100644 (file)
@@ -86,6 +86,12 @@ struct brcm_nand_dma_desc {
 #define FLASH_DMA_ECC_ERROR    (1 << 8)
 #define FLASH_DMA_CORR_ERROR   (1 << 9)
 
+/* Bitfields for DMA_MODE */
+#define FLASH_DMA_MODE_STOP_ON_ERROR   BIT(1) /* stop in Uncorr ECC error */
+#define FLASH_DMA_MODE_MODE            BIT(0) /* link list */
+#define FLASH_DMA_MODE_MASK            (FLASH_DMA_MODE_STOP_ON_ERROR | \
+                                               FLASH_DMA_MODE_MODE)
+
 /* 512B flash cache in the NAND controller HW */
 #define FC_SHIFT               9U
 #define FC_BYTES               512U
@@ -98,6 +104,53 @@ struct brcm_nand_dma_desc {
 #define NAND_CTRL_RDY                  (INTFC_CTLR_READY | INTFC_FLASH_READY)
 #define NAND_POLL_STATUS_TIMEOUT_MS    100
 
+/* flash_dma registers */
+enum flash_dma_reg {
+       FLASH_DMA_REVISION = 0,
+       FLASH_DMA_FIRST_DESC,
+       FLASH_DMA_FIRST_DESC_EXT,
+       FLASH_DMA_CTRL,
+       FLASH_DMA_MODE,
+       FLASH_DMA_STATUS,
+       FLASH_DMA_INTERRUPT_DESC,
+       FLASH_DMA_INTERRUPT_DESC_EXT,
+       FLASH_DMA_ERROR_STATUS,
+       FLASH_DMA_CURRENT_DESC,
+       FLASH_DMA_CURRENT_DESC_EXT,
+};
+
+#ifndef __UBOOT__
+/* flash_dma registers v1*/
+static const u16 flash_dma_regs_v1[] = {
+       [FLASH_DMA_REVISION]            = 0x00,
+       [FLASH_DMA_FIRST_DESC]          = 0x04,
+       [FLASH_DMA_FIRST_DESC_EXT]      = 0x08,
+       [FLASH_DMA_CTRL]                = 0x0c,
+       [FLASH_DMA_MODE]                = 0x10,
+       [FLASH_DMA_STATUS]              = 0x14,
+       [FLASH_DMA_INTERRUPT_DESC]      = 0x18,
+       [FLASH_DMA_INTERRUPT_DESC_EXT]  = 0x1c,
+       [FLASH_DMA_ERROR_STATUS]        = 0x20,
+       [FLASH_DMA_CURRENT_DESC]        = 0x24,
+       [FLASH_DMA_CURRENT_DESC_EXT]    = 0x28,
+};
+
+/* flash_dma registers v4 */
+static const u16 flash_dma_regs_v4[] = {
+       [FLASH_DMA_REVISION]            = 0x00,
+       [FLASH_DMA_FIRST_DESC]          = 0x08,
+       [FLASH_DMA_FIRST_DESC_EXT]      = 0x0c,
+       [FLASH_DMA_CTRL]                = 0x10,
+       [FLASH_DMA_MODE]                = 0x14,
+       [FLASH_DMA_STATUS]              = 0x18,
+       [FLASH_DMA_INTERRUPT_DESC]      = 0x20,
+       [FLASH_DMA_INTERRUPT_DESC_EXT]  = 0x24,
+       [FLASH_DMA_ERROR_STATUS]        = 0x28,
+       [FLASH_DMA_CURRENT_DESC]        = 0x30,
+       [FLASH_DMA_CURRENT_DESC_EXT]    = 0x34,
+};
+#endif /* __UBOOT__ */
+
 /* Controller feature flags */
 enum {
        BRCMNAND_HAS_1K_SECTORS                 = BIT(0),
@@ -135,6 +188,8 @@ struct brcmnand_controller {
        /* List of NAND hosts (one for each chip-select) */
        struct list_head host_list;
 
+       /* flash_dma reg */
+       const u16               *flash_dma_offsets;
        struct brcm_nand_dma_desc *dma_desc;
        dma_addr_t              dma_pa;
 
@@ -473,7 +528,7 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
        /* Register offsets */
        if (ctrl->nand_version >= 0x0702)
                ctrl->reg_offsets = brcmnand_regs_v72;
-       else if (ctrl->nand_version >= 0x0701)
+       else if (ctrl->nand_version == 0x0701)
                ctrl->reg_offsets = brcmnand_regs_v71;
        else if (ctrl->nand_version >= 0x0600)
                ctrl->reg_offsets = brcmnand_regs_v60;
@@ -518,7 +573,7 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
        }
 
        /* Maximum spare area sector size (per 512B) */
-       if (ctrl->nand_version >= 0x0702)
+       if (ctrl->nand_version == 0x0702)
                ctrl->max_oob = 128;
        else if (ctrl->nand_version >= 0x0600)
                ctrl->max_oob = 64;
@@ -553,6 +608,17 @@ static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
        return 0;
 }
 
+#ifndef __UBOOT__
+static void brcmnand_flash_dma_revision_init(struct brcmnand_controller *ctrl)
+{
+       /* flash_dma register offsets */
+       if (ctrl->nand_version >= 0x0703)
+               ctrl->flash_dma_offsets = flash_dma_regs_v4;
+       else
+               ctrl->flash_dma_offsets = flash_dma_regs_v1;
+}
+#endif /* __UBOOT__ */
+
 static inline u32 brcmnand_read_reg(struct brcmnand_controller *ctrl,
                enum brcmnand_reg reg)
 {
@@ -675,7 +741,7 @@ static void brcmnand_wr_corr_thresh(struct brcmnand_host *host, u8 val)
        enum brcmnand_reg reg = BRCMNAND_CORR_THRESHOLD;
        int cs = host->cs;
 
-       if (ctrl->nand_version >= 0x0702)
+       if (ctrl->nand_version == 0x0702)
                bits = 7;
        else if (ctrl->nand_version >= 0x0600)
                bits = 6;
@@ -729,7 +795,7 @@ enum {
 
 static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl)
 {
-       if (ctrl->nand_version >= 0x0702)
+       if (ctrl->nand_version == 0x0702)
                return GENMASK(7, 0);
        else if (ctrl->nand_version >= 0x0600)
                return GENMASK(6, 0);
@@ -877,20 +943,6 @@ static inline void brcmnand_set_wp(struct brcmnand_controller *ctrl, bool en)
  * Flash DMA
  ***********************************************************************/
 
-enum flash_dma_reg {
-       FLASH_DMA_REVISION              = 0x00,
-       FLASH_DMA_FIRST_DESC            = 0x04,
-       FLASH_DMA_FIRST_DESC_EXT        = 0x08,
-       FLASH_DMA_CTRL                  = 0x0c,
-       FLASH_DMA_MODE                  = 0x10,
-       FLASH_DMA_STATUS                = 0x14,
-       FLASH_DMA_INTERRUPT_DESC        = 0x18,
-       FLASH_DMA_INTERRUPT_DESC_EXT    = 0x1c,
-       FLASH_DMA_ERROR_STATUS          = 0x20,
-       FLASH_DMA_CURRENT_DESC          = 0x24,
-       FLASH_DMA_CURRENT_DESC_EXT      = 0x28,
-};
-
 static inline bool has_flash_dma(struct brcmnand_controller *ctrl)
 {
        return ctrl->flash_dma_base;
@@ -906,14 +958,19 @@ static inline bool flash_dma_buf_ok(const void *buf)
 #endif /* __UBOOT__ */
 }
 
-static inline void flash_dma_writel(struct brcmnand_controller *ctrl, u8 offs,
-                                   u32 val)
+static inline void flash_dma_writel(struct brcmnand_controller *ctrl,
+                                   enum flash_dma_reg dma_reg, u32 val)
 {
+       u16 offs = ctrl->flash_dma_offsets[dma_reg];
+
        brcmnand_writel(val, ctrl->flash_dma_base + offs);
 }
 
-static inline u32 flash_dma_readl(struct brcmnand_controller *ctrl, u8 offs)
+static inline u32 flash_dma_readl(struct brcmnand_controller *ctrl,
+                                 enum flash_dma_reg dma_reg)
 {
+       u16 offs = ctrl->flash_dma_offsets[dma_reg];
+
        return brcmnand_readl(ctrl->flash_dma_base + offs);
 }
 
@@ -2470,6 +2527,7 @@ static const struct of_device_id brcmnand_of_match[] = {
        { .compatible = "brcm,brcmnand-v7.0" },
        { .compatible = "brcm,brcmnand-v7.1" },
        { .compatible = "brcm,brcmnand-v7.2" },
+       { .compatible = "brcm,brcmnand-v7.3" },
        {},
 };
 MODULE_DEVICE_TABLE(of, brcmnand_of_match);
@@ -2600,7 +2658,11 @@ int brcmnand_probe(struct udevice *dev, struct brcmnand_soc *soc)
                        goto err;
                }
 
-               flash_dma_writel(ctrl, FLASH_DMA_MODE, 1); /* linked-list */
+               /* initialize the dma version */
+               brcmnand_flash_dma_revision_init(ctrl);
+
+               /* linked-list and stop on error */
+               flash_dma_writel(ctrl, FLASH_DMA_MODE, FLASH_DMA_MODE_MASK);
                flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0);
 
                /* Allocate descriptor(s) */