diff mbox series

[v2,02/10] mtd: rawnand: brcmnand: Add support for v7.3 controller

Message ID 20230211152909.1436133-3-linus.walleij@linaro.org
State New
Headers show
Series Backport BRCMNAND changes from Linux | expand

Commit Message

Linus Walleij Feb. 11, 2023, 3:29 p.m. UTC
From: Kamal Dasu <kdasu.kdev@gmail.com>

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>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 106 ++++++++++++++++++-----
 1 file changed, 84 insertions(+), 22 deletions(-)

Comments

William Zhang Feb. 22, 2023, 1:11 a.m. UTC | #1
On 02/11/2023 07:29 AM, Linus Walleij wrote:
> From: Kamal Dasu <kdasu.kdev@gmail.com>
> 
> 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>
> ---
>   drivers/mtd/nand/raw/brcmnand/brcmnand.c | 106 ++++++++++++++++++-----
>   1 file changed, 84 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> index 571f1c795da0..170aece0aa79 100644
> --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
> @@ -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) */
> 

Acked-by: William Zhang <william.zhang@broadcom.com>
diff mbox series

Patch

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 571f1c795da0..170aece0aa79 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -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) */