diff mbox series

mtd: rawnand: stm32_fmc2: add MP25 support

Message ID 20240306095406.314825-1-christophe.kerello@foss.st.com
State Accepted
Commit f5667d77403fc125bb87b8981de2f575ad2c06e5
Delegated to: Patrice Chotard
Headers show
Series mtd: rawnand: stm32_fmc2: add MP25 support | expand

Commit Message

Christophe Kerello March 6, 2024, 9:54 a.m. UTC
FMC2 IP supports up to 4 chip select. On MP1 SoC, only 2 of them are
available when on MP25 SoC, the 4 chip select are available.

Let's use a platform data structure for parameters that will differ.

Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
---

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 47 ++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 7 deletions(-)

Comments

Patrice CHOTARD March 8, 2024, 11:26 a.m. UTC | #1
On 3/6/24 10:54, Christophe Kerello wrote:
> FMC2 IP supports up to 4 chip select. On MP1 SoC, only 2 of them are
> available when on MP25 SoC, the 4 chip select are available.
> 
> Let's use a platform data structure for parameters that will differ.
> 
> Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
> ---
> 
>  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 47 ++++++++++++++++++++++----
>  1 file changed, 40 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> index 3528824575b..d284b8cbb12 100644
> --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> @@ -34,7 +34,7 @@
>  #define FMC2_RB_DELAY_US		30
>  
>  /* Max chip enable */
> -#define FMC2_MAX_CE			2
> +#define FMC2_MAX_CE			4
>  
>  /* Timings */
>  #define FMC2_THIZ			1
> @@ -160,6 +160,11 @@ static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
>  	return container_of(chip, struct stm32_fmc2_nand, chip);
>  }
>  
> +struct stm32_fmc2_nfc_data {
> +	int max_ncs;
> +	struct udevice *(*get_cdev)(struct udevice *dev);
> +};
> +
>  struct stm32_fmc2_nfc {
>  	struct nand_hw_control base;
>  	struct stm32_fmc2_nand nand;
> @@ -169,6 +174,7 @@ struct stm32_fmc2_nfc {
>  	fdt_addr_t cmd_base[FMC2_MAX_CE];
>  	fdt_addr_t addr_base[FMC2_MAX_CE];
>  	struct clk clk;
> +	const struct stm32_fmc2_nfc_data *data;
>  
>  	u8 cs_assigned;
>  	int cs_sel;
> @@ -815,7 +821,7 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, ofnode node)
>  	}
>  
>  	for (i = 0; i < nand->ncs; i++) {
> -		if (cs[i] >= FMC2_MAX_CE) {
> +		if (cs[i] >= nfc->data->max_ncs) {
>  			log_err("Invalid reg value: %d\n", nand->cs_used[i]);
>  			return -EINVAL;
>  		}
> @@ -906,10 +912,18 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  	spin_lock_init(&nfc->controller.lock);
>  	init_waitqueue_head(&nfc->controller.wq);
>  
> -	cdev = stm32_fmc2_nfc_get_cdev(dev);
> -	if (!cdev)
> +	nfc->data = (void *)dev_get_driver_data(dev);
> +	if (!nfc->data)
>  		return -EINVAL;
>  
> +	if (nfc->data->get_cdev) {
> +		cdev = nfc->data->get_cdev(dev);
> +		if (!cdev)
> +			return -EINVAL;
> +	} else {
> +		cdev = dev->parent;
> +	}
> +
>  	ret = stm32_fmc2_nfc_parse_dt(dev, nfc);
>  	if (ret)
>  		return ret;
> @@ -921,7 +935,7 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  	if (dev == cdev)
>  		start_region = 1;
>  
> -	for (chip_cs = 0, mem_region = start_region; chip_cs < FMC2_MAX_CE;
> +	for (chip_cs = 0, mem_region = start_region; chip_cs < nfc->data->max_ncs;
>  	     chip_cs++, mem_region += 3) {
>  		if (!(nfc->cs_assigned & BIT(chip_cs)))
>  			continue;
> @@ -1033,9 +1047,28 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  	return nand_register(0, mtd);
>  }
>  
> +static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp1_data = {
> +	.max_ncs = 2,
> +	.get_cdev = stm32_fmc2_nfc_get_cdev,
> +};
> +
> +static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp25_data = {
> +	.max_ncs = 4,
> +};
> +
>  static const struct udevice_id stm32_fmc2_nfc_match[] = {
> -	{ .compatible = "st,stm32mp15-fmc2" },
> -	{ .compatible = "st,stm32mp1-fmc2-nfc" },
> +	{
> +		.compatible = "st,stm32mp15-fmc2",
> +		.data = (ulong)&stm32_fmc2_nfc_mp1_data,
> +	},
> +	{
> +		.compatible = "st,stm32mp1-fmc2-nfc",
> +		.data = (ulong)&stm32_fmc2_nfc_mp1_data,
> +	},
> +	{
> +		.compatible = "st,stm32mp25-fmc2-nfc",
> +		.data = (ulong)&stm32_fmc2_nfc_mp25_data,
> +	},
>  	{ /* Sentinel */ }
>  };
>  
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice
Patrice CHOTARD April 19, 2024, 12:13 p.m. UTC | #2
On 3/6/24 10:54, Christophe Kerello wrote:
> FMC2 IP supports up to 4 chip select. On MP1 SoC, only 2 of them are
> available when on MP25 SoC, the 4 chip select are available.
> 
> Let's use a platform data structure for parameters that will differ.
> 
> Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
> ---
> 
>  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 47 ++++++++++++++++++++++----
>  1 file changed, 40 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> index 3528824575b..d284b8cbb12 100644
> --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> @@ -34,7 +34,7 @@
>  #define FMC2_RB_DELAY_US		30
>  
>  /* Max chip enable */
> -#define FMC2_MAX_CE			2
> +#define FMC2_MAX_CE			4
>  
>  /* Timings */
>  #define FMC2_THIZ			1
> @@ -160,6 +160,11 @@ static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
>  	return container_of(chip, struct stm32_fmc2_nand, chip);
>  }
>  
> +struct stm32_fmc2_nfc_data {
> +	int max_ncs;
> +	struct udevice *(*get_cdev)(struct udevice *dev);
> +};
> +
>  struct stm32_fmc2_nfc {
>  	struct nand_hw_control base;
>  	struct stm32_fmc2_nand nand;
> @@ -169,6 +174,7 @@ struct stm32_fmc2_nfc {
>  	fdt_addr_t cmd_base[FMC2_MAX_CE];
>  	fdt_addr_t addr_base[FMC2_MAX_CE];
>  	struct clk clk;
> +	const struct stm32_fmc2_nfc_data *data;
>  
>  	u8 cs_assigned;
>  	int cs_sel;
> @@ -815,7 +821,7 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, ofnode node)
>  	}
>  
>  	for (i = 0; i < nand->ncs; i++) {
> -		if (cs[i] >= FMC2_MAX_CE) {
> +		if (cs[i] >= nfc->data->max_ncs) {
>  			log_err("Invalid reg value: %d\n", nand->cs_used[i]);
>  			return -EINVAL;
>  		}
> @@ -906,10 +912,18 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  	spin_lock_init(&nfc->controller.lock);
>  	init_waitqueue_head(&nfc->controller.wq);
>  
> -	cdev = stm32_fmc2_nfc_get_cdev(dev);
> -	if (!cdev)
> +	nfc->data = (void *)dev_get_driver_data(dev);
> +	if (!nfc->data)
>  		return -EINVAL;
>  
> +	if (nfc->data->get_cdev) {
> +		cdev = nfc->data->get_cdev(dev);
> +		if (!cdev)
> +			return -EINVAL;
> +	} else {
> +		cdev = dev->parent;
> +	}
> +
>  	ret = stm32_fmc2_nfc_parse_dt(dev, nfc);
>  	if (ret)
>  		return ret;
> @@ -921,7 +935,7 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  	if (dev == cdev)
>  		start_region = 1;
>  
> -	for (chip_cs = 0, mem_region = start_region; chip_cs < FMC2_MAX_CE;
> +	for (chip_cs = 0, mem_region = start_region; chip_cs < nfc->data->max_ncs;
>  	     chip_cs++, mem_region += 3) {
>  		if (!(nfc->cs_assigned & BIT(chip_cs)))
>  			continue;
> @@ -1033,9 +1047,28 @@ static int stm32_fmc2_nfc_probe(struct udevice *dev)
>  	return nand_register(0, mtd);
>  }
>  
> +static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp1_data = {
> +	.max_ncs = 2,
> +	.get_cdev = stm32_fmc2_nfc_get_cdev,
> +};
> +
> +static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp25_data = {
> +	.max_ncs = 4,
> +};
> +
>  static const struct udevice_id stm32_fmc2_nfc_match[] = {
> -	{ .compatible = "st,stm32mp15-fmc2" },
> -	{ .compatible = "st,stm32mp1-fmc2-nfc" },
> +	{
> +		.compatible = "st,stm32mp15-fmc2",
> +		.data = (ulong)&stm32_fmc2_nfc_mp1_data,
> +	},
> +	{
> +		.compatible = "st,stm32mp1-fmc2-nfc",
> +		.data = (ulong)&stm32_fmc2_nfc_mp1_data,
> +	},
> +	{
> +		.compatible = "st,stm32mp25-fmc2-nfc",
> +		.data = (ulong)&stm32_fmc2_nfc_mp25_data,
> +	},
>  	{ /* Sentinel */ }
>  };
>  

Applied on u-boot-stm32/master
diff mbox series

Patch

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 3528824575b..d284b8cbb12 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -34,7 +34,7 @@ 
 #define FMC2_RB_DELAY_US		30
 
 /* Max chip enable */
-#define FMC2_MAX_CE			2
+#define FMC2_MAX_CE			4
 
 /* Timings */
 #define FMC2_THIZ			1
@@ -160,6 +160,11 @@  static inline struct stm32_fmc2_nand *to_fmc2_nand(struct nand_chip *chip)
 	return container_of(chip, struct stm32_fmc2_nand, chip);
 }
 
+struct stm32_fmc2_nfc_data {
+	int max_ncs;
+	struct udevice *(*get_cdev)(struct udevice *dev);
+};
+
 struct stm32_fmc2_nfc {
 	struct nand_hw_control base;
 	struct stm32_fmc2_nand nand;
@@ -169,6 +174,7 @@  struct stm32_fmc2_nfc {
 	fdt_addr_t cmd_base[FMC2_MAX_CE];
 	fdt_addr_t addr_base[FMC2_MAX_CE];
 	struct clk clk;
+	const struct stm32_fmc2_nfc_data *data;
 
 	u8 cs_assigned;
 	int cs_sel;
@@ -815,7 +821,7 @@  static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, ofnode node)
 	}
 
 	for (i = 0; i < nand->ncs; i++) {
-		if (cs[i] >= FMC2_MAX_CE) {
+		if (cs[i] >= nfc->data->max_ncs) {
 			log_err("Invalid reg value: %d\n", nand->cs_used[i]);
 			return -EINVAL;
 		}
@@ -906,10 +912,18 @@  static int stm32_fmc2_nfc_probe(struct udevice *dev)
 	spin_lock_init(&nfc->controller.lock);
 	init_waitqueue_head(&nfc->controller.wq);
 
-	cdev = stm32_fmc2_nfc_get_cdev(dev);
-	if (!cdev)
+	nfc->data = (void *)dev_get_driver_data(dev);
+	if (!nfc->data)
 		return -EINVAL;
 
+	if (nfc->data->get_cdev) {
+		cdev = nfc->data->get_cdev(dev);
+		if (!cdev)
+			return -EINVAL;
+	} else {
+		cdev = dev->parent;
+	}
+
 	ret = stm32_fmc2_nfc_parse_dt(dev, nfc);
 	if (ret)
 		return ret;
@@ -921,7 +935,7 @@  static int stm32_fmc2_nfc_probe(struct udevice *dev)
 	if (dev == cdev)
 		start_region = 1;
 
-	for (chip_cs = 0, mem_region = start_region; chip_cs < FMC2_MAX_CE;
+	for (chip_cs = 0, mem_region = start_region; chip_cs < nfc->data->max_ncs;
 	     chip_cs++, mem_region += 3) {
 		if (!(nfc->cs_assigned & BIT(chip_cs)))
 			continue;
@@ -1033,9 +1047,28 @@  static int stm32_fmc2_nfc_probe(struct udevice *dev)
 	return nand_register(0, mtd);
 }
 
+static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp1_data = {
+	.max_ncs = 2,
+	.get_cdev = stm32_fmc2_nfc_get_cdev,
+};
+
+static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp25_data = {
+	.max_ncs = 4,
+};
+
 static const struct udevice_id stm32_fmc2_nfc_match[] = {
-	{ .compatible = "st,stm32mp15-fmc2" },
-	{ .compatible = "st,stm32mp1-fmc2-nfc" },
+	{
+		.compatible = "st,stm32mp15-fmc2",
+		.data = (ulong)&stm32_fmc2_nfc_mp1_data,
+	},
+	{
+		.compatible = "st,stm32mp1-fmc2-nfc",
+		.data = (ulong)&stm32_fmc2_nfc_mp1_data,
+	},
+	{
+		.compatible = "st,stm32mp25-fmc2-nfc",
+		.data = (ulong)&stm32_fmc2_nfc_mp25_data,
+	},
 	{ /* Sentinel */ }
 };