2024-02-19 14:06:41

by Christophe Kerello

[permalink] [raw]
Subject: [PATCH v2 0/3] 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.

For MP1 SoCs, MDMA is used and the max burst size is 128.
For MP25 SoC, DMA3 is used and the max burst size is 64.

Changes in v2:
- dt-bindings commit message has been updated.
- V1 patch 10, 11 and 12 have been squashed and reworked.

Christophe Kerello (3):
dt-bindings: mtd: st,stm32: add MP25 support
mtd: rawnand: stm32_fmc2: use dma_get_slave_caps to get DMA max burst
mtd: rawnand: stm32_fmc2: add MP25 support

.../bindings/mtd/st,stm32-fmc2-nand.yaml | 25 +++++-
drivers/mtd/nand/raw/stm32_fmc2_nand.c | 83 +++++++++++++++----
2 files changed, 93 insertions(+), 15 deletions(-)

--
2.25.1



2024-02-19 14:07:17

by Christophe Kerello

[permalink] [raw]
Subject: [PATCH v2 2/3] mtd: rawnand: stm32_fmc2: use dma_get_slave_caps to get DMA max burst

Use dma_get_slave_caps API to get the max burst size of a DMA channel.

For MP1 SoCs, MDMA is used and the max burst size is 128.
For MP25 SoC, DMA3 is used and the max burst size is 64.

Signed-off-by: Christophe Kerello <[email protected]>
---
drivers/mtd/nand/raw/stm32_fmc2_nand.c | 29 +++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 88811139aaf5..a7db7b675514 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -264,6 +264,8 @@ struct stm32_fmc2_nfc {
struct sg_table dma_ecc_sg;
u8 *ecc_buf;
int dma_ecc_len;
+ u32 tx_dma_max_burst;
+ u32 rx_dma_max_burst;

struct completion complete;
struct completion dma_data_complete;
@@ -347,20 +349,26 @@ static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr)
stm32_fmc2_nfc_setup(chip);
stm32_fmc2_nfc_timings_init(chip);

- if (nfc->dma_tx_ch && nfc->dma_rx_ch) {
+ if (nfc->dma_tx_ch) {
memset(&dma_cfg, 0, sizeof(dma_cfg));
- dma_cfg.src_addr = nfc->data_phys_addr[nfc->cs_sel];
dma_cfg.dst_addr = nfc->data_phys_addr[nfc->cs_sel];
- dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- dma_cfg.src_maxburst = 32;
- dma_cfg.dst_maxburst = 32;
+ dma_cfg.dst_maxburst = nfc->tx_dma_max_burst /
+ dma_cfg.dst_addr_width;

ret = dmaengine_slave_config(nfc->dma_tx_ch, &dma_cfg);
if (ret) {
dev_err(nfc->dev, "tx DMA engine slave config failed\n");
return ret;
}
+ }
+
+ if (nfc->dma_rx_ch) {
+ memset(&dma_cfg, 0, sizeof(dma_cfg));
+ dma_cfg.src_addr = nfc->data_phys_addr[nfc->cs_sel];
+ dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ dma_cfg.src_maxburst = nfc->rx_dma_max_burst /
+ dma_cfg.src_addr_width;

ret = dmaengine_slave_config(nfc->dma_rx_ch, &dma_cfg);
if (ret) {
@@ -1545,6 +1553,7 @@ static int stm32_fmc2_nfc_setup_interface(struct nand_chip *chip, int chipnr,

static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc)
{
+ struct dma_slave_caps caps;
int ret = 0;

nfc->dma_tx_ch = dma_request_chan(nfc->dev, "tx");
@@ -1557,6 +1566,11 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc)
goto err_dma;
}

+ ret = dma_get_slave_caps(nfc->dma_tx_ch, &caps);
+ if (ret)
+ return ret;
+ nfc->tx_dma_max_burst = caps.max_burst;
+
nfc->dma_rx_ch = dma_request_chan(nfc->dev, "rx");
if (IS_ERR(nfc->dma_rx_ch)) {
ret = PTR_ERR(nfc->dma_rx_ch);
@@ -1567,6 +1581,11 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc)
goto err_dma;
}

+ ret = dma_get_slave_caps(nfc->dma_rx_ch, &caps);
+ if (ret)
+ return ret;
+ nfc->rx_dma_max_burst = caps.max_burst;
+
nfc->dma_ecc_ch = dma_request_chan(nfc->dev, "ecc");
if (IS_ERR(nfc->dma_ecc_ch)) {
ret = PTR_ERR(nfc->dma_ecc_ch);
--
2.25.1


2024-02-19 14:07:38

by Christophe Kerello

[permalink] [raw]
Subject: [PATCH v2 3/3] 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 <[email protected]>
---
Changes in v2:
- V1 patch 10, 11 and 12 have been squashed and reworked.
- a platform data structure is handling the difference between MP1 and MP25.

drivers/mtd/nand/raw/stm32_fmc2_nand.c | 54 +++++++++++++++++++++-----
1 file changed, 45 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index a7db7b675514..264556939a00 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/mtd/rawnand.h>
#include <linux/of_address.h>
+#include <linux/of_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
@@ -37,7 +38,7 @@
#define FMC2_MAX_SG 16

/* Max chip enable */
-#define FMC2_MAX_CE 2
+#define FMC2_MAX_CE 4

/* Max ECC buffer length */
#define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
@@ -243,6 +244,13 @@ 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;
+
+struct stm32_fmc2_nfc_data {
+ int max_ncs;
+ int (*set_cdev)(struct stm32_fmc2_nfc *nfc);
+};
+
struct stm32_fmc2_nfc {
struct nand_controller base;
struct stm32_fmc2_nand nand;
@@ -256,6 +264,7 @@ struct stm32_fmc2_nfc {
phys_addr_t data_phys_addr[FMC2_MAX_CE];
struct clk *clk;
u8 irq_state;
+ const struct stm32_fmc2_nfc_data *data;

struct dma_chan *dma_tx_ch;
struct dma_chan *dma_rx_ch;
@@ -1809,7 +1818,7 @@ static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc,
return ret;
}

- if (cs >= FMC2_MAX_CE) {
+ if (cs >= nfc->data->max_ncs) {
dev_err(nfc->dev, "invalid reg value: %d\n", cs);
return -EINVAL;
}
@@ -1915,9 +1924,17 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
nand_controller_init(&nfc->base);
nfc->base.ops = &stm32_fmc2_nfc_controller_ops;

- ret = stm32_fmc2_nfc_set_cdev(nfc);
- if (ret)
- return ret;
+ nfc->data = of_device_get_match_data(dev);
+ if (!nfc->data)
+ return -EINVAL;
+
+ if (nfc->data->set_cdev) {
+ ret = nfc->data->set_cdev(nfc);
+ if (ret)
+ return ret;
+ } else {
+ nfc->cdev = dev->parent;
+ }

ret = stm32_fmc2_nfc_parse_dt(nfc);
if (ret)
@@ -1936,7 +1953,7 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
if (nfc->dev == nfc->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;
@@ -2092,7 +2109,7 @@ static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev)

stm32_fmc2_nfc_wp_disable(nand);

- for (chip_cs = 0; chip_cs < FMC2_MAX_CE; chip_cs++) {
+ for (chip_cs = 0; chip_cs < nfc->data->max_ncs; chip_cs++) {
if (!(nfc->cs_assigned & BIT(chip_cs)))
continue;

@@ -2105,9 +2122,28 @@ static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(stm32_fmc2_nfc_pm_ops, stm32_fmc2_nfc_suspend,
stm32_fmc2_nfc_resume);

+static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp1_data = {
+ .max_ncs = 2,
+ .set_cdev = stm32_fmc2_nfc_set_cdev,
+};
+
+static const struct stm32_fmc2_nfc_data stm32_fmc2_nfc_mp25_data = {
+ .max_ncs = 4,
+};
+
static const struct of_device_id stm32_fmc2_nfc_match[] = {
- {.compatible = "st,stm32mp15-fmc2"},
- {.compatible = "st,stm32mp1-fmc2-nfc"},
+ {
+ .compatible = "st,stm32mp15-fmc2",
+ .data = &stm32_fmc2_nfc_mp1_data,
+ },
+ {
+ .compatible = "st,stm32mp1-fmc2-nfc",
+ .data = &stm32_fmc2_nfc_mp1_data,
+ },
+ {
+ .compatible = "st,stm32mp25-fmc2-nfc",
+ .data = &stm32_fmc2_nfc_mp25_data,
+ },
{}
};
MODULE_DEVICE_TABLE(of, stm32_fmc2_nfc_match);
--
2.25.1


2024-02-19 14:07:45

by Christophe Kerello

[permalink] [raw]
Subject: [PATCH v2 1/3] dt-bindings: mtd: st,stm32: add MP25 support

Add a compatible string to support MP25 SoC.

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.

Signed-off-by: Christophe Kerello <[email protected]>
---
Changes in v2:
- commit message has been updated.

.../bindings/mtd/st,stm32-fmc2-nand.yaml | 25 ++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
index e72cb5bacaf0..b8ef9ba88e92 100644
--- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
@@ -14,10 +14,11 @@ properties:
enum:
- st,stm32mp15-fmc2
- st,stm32mp1-fmc2-nfc
+ - st,stm32mp25-fmc2-nfc

reg:
minItems: 6
- maxItems: 7
+ maxItems: 12

interrupts:
maxItems: 1
@@ -92,6 +93,28 @@ allOf:
- description: Chip select 1 command
- description: Chip select 1 address space

+ - if:
+ properties:
+ compatible:
+ contains:
+ const: st,stm32mp25-fmc2-nfc
+ then:
+ properties:
+ reg:
+ items:
+ - description: Chip select 0 data
+ - description: Chip select 0 command
+ - description: Chip select 0 address space
+ - description: Chip select 1 data
+ - description: Chip select 1 command
+ - description: Chip select 1 address space
+ - description: Chip select 2 data
+ - description: Chip select 2 command
+ - description: Chip select 2 address space
+ - description: Chip select 3 data
+ - description: Chip select 3 command
+ - description: Chip select 3 address space
+
required:
- compatible
- reg
--
2.25.1


2024-02-20 10:21:15

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] dt-bindings: mtd: st,stm32: add MP25 support

On 19/02/2024 15:05, Christophe Kerello wrote:
> Add a compatible string to support MP25 SoC.
>
> 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.
>
> Signed-off-by: Christophe Kerello <[email protected]>
> ---
> Changes in v2:
> - commit message has been updated.
>

Reviewed-by: Krzysztof Kozlowski <[email protected]>

Best regards,
Krzysztof


2024-02-26 10:50:27

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] dt-bindings: mtd: st,stm32: add MP25 support

On Mon, 2024-02-19 at 14:05:03 UTC, Christophe Kerello wrote:
> Add a compatible string to support MP25 SoC.
>
> 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.
>
> Signed-off-by: Christophe Kerello <[email protected]>
> Reviewed-by: Krzysztof Kozlowski <[email protected]>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel

2024-02-26 10:50:40

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH v2 2/3] mtd: rawnand: stm32_fmc2: use dma_get_slave_caps to get DMA max burst

On Mon, 2024-02-19 at 14:05:04 UTC, Christophe Kerello wrote:
> Use dma_get_slave_caps API to get the max burst size of a DMA channel.
>
> For MP1 SoCs, MDMA is used and the max burst size is 128.
> For MP25 SoC, DMA3 is used and the max burst size is 64.
>
> Signed-off-by: Christophe Kerello <[email protected]>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel

2024-02-26 11:57:10

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH v2 3/3] mtd: rawnand: stm32_fmc2: add MP25 support

On Mon, 2024-02-19 at 14:05:05 UTC, 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 <[email protected]>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.

Miquel