aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd
diff options
context:
space:
mode:
authorChristophe Kerello <christophe.kerello@foss.st.com>2024-03-06 10:54:06 +0100
committerPatrice Chotard <patrice.chotard@foss.st.com>2024-04-19 10:29:10 +0200
commitf5667d77403fc125bb87b8981de2f575ad2c06e5 (patch)
tree4637714d477ea8875d62037277de2142a02d2405 /drivers/mtd
parenta10ee1322ae4aff1d9e1a283e89a90ce230e3aa8 (diff)
downloadu-boot-f5667d77403fc125bb87b8981de2f575ad2c06e5.zip
u-boot-f5667d77403fc125bb87b8981de2f575ad2c06e5.tar.gz
u-boot-f5667d77403fc125bb87b8981de2f575ad2c06e5.tar.bz2
mtd: rawnand: stm32_fmc2: add MP25 support
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> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/raw/stm32_fmc2_nand.c47
1 files 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 3528824..d284b8c 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 */ }
};