diff options
author | Christophe Kerello <christophe.kerello@foss.st.com> | 2024-03-06 10:54:06 +0100 |
---|---|---|
committer | Patrice Chotard <patrice.chotard@foss.st.com> | 2024-04-19 10:29:10 +0200 |
commit | f5667d77403fc125bb87b8981de2f575ad2c06e5 (patch) | |
tree | 4637714d477ea8875d62037277de2142a02d2405 /drivers/mtd | |
parent | a10ee1322ae4aff1d9e1a283e89a90ce230e3aa8 (diff) | |
download | u-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.c | 47 |
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 */ } }; |