Re: [Linux-stm32] [PATCH v2][next] mtd: rawnand: stm32_fmc2: Fix fall-through warnings for Clang

2021-03-05 Thread Christophe Kerello

Hi Gustavo,

On 3/5/21 9:09 AM, Gustavo A. R. Silva wrote:

In preparation to enable -Wimplicit-fallthrough for Clang, fix a couple
of warnings by explicitly adding a couple of fallthrough pseudo-keywords
instead of letting the code fall through to the next case.

Link: https://github.com/KSPP/linux/issues/115
Signed-off-by: Gustavo A. R. Silva 
---
Changes in v2:
  Make use of a break statement instead of fallthrough for consistency.
  Link: https://lore.kernel.org/lkml/20201123093347.719a77cf@xps13/

  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 550bda4d1415..1c277fbb91f2 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -531,6 +531,7 @@ static int stm32_fmc2_nfc_ham_correct(struct nand_chip 
*chip, u8 *dat,
switch (b % 4) {
case 2:
bit_position += shifting;
+   break;
case 1:
break;
default:
@@ -546,6 +547,7 @@ static int stm32_fmc2_nfc_ham_correct(struct nand_chip 
*chip, u8 *dat,
switch (b % 4) {
case 2:
byte_addr += shifting;
+   break;
case 1:
break;
default:



Reviewed-by: Christophe Kerello 

Regards,
Christophe Kerello.


[PATCH v2] mtd: rawnand: stm32_fmc2: fix broken ECC

2020-10-30 Thread Christophe Kerello
Since commit d7157ff49a5b ("mtd: rawnand: Use the ECC framework user
input parsing bits"), ECC are broken in FMC2 driver in case of
nand-ecc-step-size and nand-ecc-strength are not set in the device tree.
To avoid this issue, the default settings are now set in
stm32_fmc2_nfc_attach_chip function.

Signed-off-by: Christophe Kerello 
Fixes: d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input parsing 
bits")
---
Changes in v2:
 - move default ECC settings in stm32_fmc2_nfc_attach_chip function.

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

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b31a581..550bda4 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1708,6 +1708,13 @@ static int stm32_fmc2_nfc_attach_chip(struct nand_chip 
*chip)
return -EINVAL;
}
 
+   /* Default ECC settings in case they are not set in the device tree */
+   if (!chip->ecc.size)
+   chip->ecc.size = FMC2_ECC_STEP_SIZE;
+
+   if (!chip->ecc.strength)
+   chip->ecc.strength = FMC2_ECC_BCH8;
+
ret = nand_ecc_choose_conf(chip, _fmc2_nfc_ecc_caps,
   mtd->oobsize - FMC2_BBM_LEN);
if (ret) {
@@ -1727,8 +1734,7 @@ static int stm32_fmc2_nfc_attach_chip(struct nand_chip 
*chip)
 
mtd_set_ooblayout(mtd, _fmc2_nfc_ooblayout_ops);
 
-   if (chip->options & NAND_BUSWIDTH_16)
-   stm32_fmc2_nfc_set_buswidth_16(nfc, true);
+   stm32_fmc2_nfc_setup(chip);
 
return 0;
 }
@@ -1952,11 +1958,6 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
 NAND_USES_DMA;
 
-   /* Default ECC settings */
-   chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
-   chip->ecc.size = FMC2_ECC_STEP_SIZE;
-   chip->ecc.strength = FMC2_ECC_BCH8;
-
/* Scan to find existence of the device */
ret = nand_scan(chip, nand->ncs);
if (ret)
-- 
1.9.1



Re: [PATCH] mtd: rawnand: stm32_fmc2: fix broken ECC

2020-10-30 Thread Christophe Kerello

Hi Miquel,

On 10/30/20 9:19 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Thu, 29 Oct
2020 17:38:12 +0100:


Since commit d7157ff49a5b ("mtd: rawnand: Use the ECC framework user
input parsing bits"), ECC are broken in FMC2 driver in case of
nand-ecc-step-size and nand-ecc-strength are not set in the device tree.
The default user configuration set in FMC2 driver is lost when
rawnand_dt_init function is called. To avoid to lose the default user
configuration, it is needed to move it in the new user_conf structure.

Signed-off-by: Christophe Kerello 
Fixes: d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input parsing 
bits")
---
  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 8 +---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b31a581..dc86ac9 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1846,6 +1846,7 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
struct resource *res;
struct mtd_info *mtd;
struct nand_chip *chip;
+   struct nand_device *nanddev;
struct resource cres;
int chip_cs, mem_region, ret, irq;
int start_region = 0;
@@ -1952,10 +1953,11 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
 NAND_USES_DMA;
  
-	/* Default ECC settings */

+   /* Default ECC user settings */
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
-   chip->ecc.size = FMC2_ECC_STEP_SIZE;
-   chip->ecc.strength = FMC2_ECC_BCH8;
+   nanddev = mtd_to_nanddev(mtd);
+   nanddev->ecc.user_conf.step_size = FMC2_ECC_STEP_SIZE;
+   nanddev->ecc.user_conf.strength = FMC2_ECC_BCH8;
  
  	/* Scan to find existence of the device */

ret = nand_scan(chip, nand->ncs);


Sorry for breaking the driver with this change, but now I think we
should have all ECC related bits in ->attach() instead of ->probe().
The ->attach() hook is called during the nand_scan() operation and at
this point the chip's requirements/layout are known (not before). I
know that certain controllers don't really care about that, here your
simply hardcode these two fields and you don't need to know anything
about the chip's properties. But as a bid to harmonize all drivers with
the target of a generic ECC engine in mind, I think it's now time to
move these three lines (chip->ecc.* = ...) at the top of ->attach().
Also, these fields should have been populated by the core so perhaps
the best approach is to check if the user requirements are synced with
the controller's capabilities and error out otherwise?

We plan to send a fixes PR for -rc2, if the v2 arrives today I'll
integrate it.


Ok. Issue is that the controller is initialized when 
stm32_fmc2_nfc_select_chip is called. This function will be called 
before the ->attach() hook, when the first command will be sent to the 
NAND device (reset command). So, moving the default ECC initialization

needs probably more modifications in the driver.
I will try to send a v2 today.

Regards,
Christophe Kerello.



Thanks,
Miquèl



[PATCH] mtd: rawnand: stm32_fmc2: fix broken ECC

2020-10-29 Thread Christophe Kerello
Since commit d7157ff49a5b ("mtd: rawnand: Use the ECC framework user
input parsing bits"), ECC are broken in FMC2 driver in case of
nand-ecc-step-size and nand-ecc-strength are not set in the device tree.
The default user configuration set in FMC2 driver is lost when
rawnand_dt_init function is called. To avoid to lose the default user
configuration, it is needed to move it in the new user_conf structure.

Signed-off-by: Christophe Kerello 
Fixes: d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input parsing 
bits")
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b31a581..dc86ac9 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1846,6 +1846,7 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
struct resource *res;
struct mtd_info *mtd;
struct nand_chip *chip;
+   struct nand_device *nanddev;
struct resource cres;
int chip_cs, mem_region, ret, irq;
int start_region = 0;
@@ -1952,10 +1953,11 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE |
 NAND_USES_DMA;
 
-   /* Default ECC settings */
+   /* Default ECC user settings */
chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
-   chip->ecc.size = FMC2_ECC_STEP_SIZE;
-   chip->ecc.strength = FMC2_ECC_BCH8;
+   nanddev = mtd_to_nanddev(mtd);
+   nanddev->ecc.user_conf.step_size = FMC2_ECC_STEP_SIZE;
+   nanddev->ecc.user_conf.strength = FMC2_ECC_BCH8;
 
/* Scan to find existence of the device */
ret = nand_scan(chip, nand->ncs);
-- 
1.9.1



[PATCH 1/2] ARM: multi_v7_defconfig: add FMC2 EBI controller support

2020-09-04 Thread Christophe Kerello
This patch adds FMC2 EBI controller support used by STM32MP SOCs.

Signed-off-by: Christophe Kerello 
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index e9e76e3..4929cc8 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -1011,6 +1011,7 @@ CONFIG_EXTCON_MAX14577=m
 CONFIG_EXTCON_MAX77693=m
 CONFIG_EXTCON_MAX8997=m
 CONFIG_TI_AEMIF=y
+CONFIG_STM32_FMC2_EBI=y
 CONFIG_EXYNOS5422_DMC=m
 CONFIG_IIO=y
 CONFIG_IIO_SW_TRIGGER=y
-- 
1.9.1



[PATCH 2/2] ARM: dts: stm32: add FMC2 EBI support for stm32mp157c

2020-09-04 Thread Christophe Kerello
This patch adds FMC2 External Bus Interface support on stm32mp157c.

Signed-off-by: Christophe Kerello 
---
 arch/arm/boot/dts/stm32mp151.dtsi | 43 +++
 arch/arm/boot/dts/stm32mp157c-ev1.dts | 16 +++--
 2 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/arch/arm/boot/dts/stm32mp151.dtsi 
b/arch/arm/boot/dts/stm32mp151.dtsi
index bfe2902..4fd7572 100644
--- a/arch/arm/boot/dts/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/stm32mp151.dtsi
@@ -1302,23 +1302,38 @@
dma-requests = <48>;
};
 
-   fmc: nand-controller@58002000 {
-   compatible = "st,stm32mp15-fmc2";
-   reg = <0x58002000 0x1000>,
- <0x8000 0x1000>,
- <0x8801 0x1000>,
- <0x8802 0x1000>,
- <0x8100 0x1000>,
- <0x8901 0x1000>,
- <0x8902 0x1000>;
-   interrupts = ;
-   dmas = < 20 0x10 0x12000a02 0x0 0x0>,
-  < 20 0x10 0x12000a08 0x0 0x0>,
-  < 21 0x10 0x12000a0a 0x0 0x0>;
-   dma-names = "tx", "rx", "ecc";
+   fmc: memory-controller@58002000 {
+   #address-cells = <2>;
+   #size-cells = <1>;
+   compatible = "st,stm32mp1-fmc2-ebi";
+   reg = <0x58002000 0x1000>;
clocks = < FMC_K>;
resets = < FMC_R>;
status = "disabled";
+
+   ranges = <0 0 0x6000 0x0400>, /* EBI CS 1 */
+<1 0 0x6400 0x0400>, /* EBI CS 2 */
+<2 0 0x6800 0x0400>, /* EBI CS 3 */
+<3 0 0x6c00 0x0400>, /* EBI CS 4 */
+<4 0 0x8000 0x1000>; /* NAND */
+
+   nand-controller@4,0 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   compatible = "st,stm32mp1-fmc2-nfc";
+   reg = <4 0x 0x1000>,
+ <4 0x0801 0x1000>,
+ <4 0x0802 0x1000>,
+ <4 0x0100 0x1000>,
+ <4 0x0901 0x1000>,
+ <4 0x0902 0x1000>;
+   interrupts = ;
+   dmas = < 20 0x2 0x12000a02 0x0 0x0>,
+  < 20 0x2 0x12000a08 0x0 0x0>,
+  < 21 0x2 0x12000a0a 0x0 0x0>;
+   dma-names = "tx", "rx", "ecc";
+   status = "disabled";
+   };
};
 
qspi: spi@58003000 {
diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts 
b/arch/arm/boot/dts/stm32mp157c-ev1.dts
index 85628e1..a55e80c 100644
--- a/arch/arm/boot/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts
@@ -158,14 +158,16 @@
pinctrl-0 = <_pins_a>;
pinctrl-1 = <_sleep_pins_a>;
status = "okay";
-   #address-cells = <1>;
-   #size-cells = <0>;
 
-   nand@0 {
-   reg = <0>;
-   nand-on-flash-bbt;
-   #address-cells = <1>;
-   #size-cells = <1>;
+   nand-controller@4,0 {
+   status = "okay";
+
+   nand@0 {
+   reg = <0>;
+   nand-on-flash-bbt;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
};
 };
 
-- 
1.9.1



[PATCH 0/2] add FMC2 EBI controller support

2020-09-04 Thread Christophe Kerello
This patchset enables FMC2 EBI support on STM32MP1 SOCs.

Christophe Kerello (2):
  ARM: multi_v7_defconfig: add FMC2 EBI controller support
  ARM: dts: stm32: add FMC2 EBI support for stm32mp157c

 arch/arm/boot/dts/stm32mp151.dtsi | 43 +++
 arch/arm/boot/dts/stm32mp157c-ev1.dts | 16 +++--
 arch/arm/configs/multi_v7_defconfig   |  1 +
 3 files changed, 39 insertions(+), 21 deletions(-)

-- 
1.9.1



Re: [Linux-stm32] [PATCH v3 3/3] ARM: dts: stm32: add initial support for stm32mp157-odyssey board

2020-07-22 Thread Christophe Kerello

Hello Marcin,

On 7/21/20 8:53 PM, Marcin Sloniewski wrote:

+ {
+   pinctrl-names = "default", "opendrain", "sleep";
+   pinctrl-0 = <_b4_pins_a _d47_pins_a>;
+   pinctrl-1 = <_b4_od_pins_a _d47_pins_a>;
+   pinctrl-2 = <_b4_sleep_pins_a _d47_sleep_pins_a>;
+   non-removable;
+   no-sd;
+   no-sdio;
+   st,neg-edge;
+   bus-width = <4>;
+   vmmc-supply = <>;
+   vqmmc-supply = <>;
+   mmc-ddr-3_3v;
+   status = "okay";
+};


Based on the pins muxed, 8 data lines are configured, but the bus width 
is set to 4. What is the reason of not setting this property to 8?


Regards,
Christophe Kerello.


[PATCH] mtd: rawnand: stm32_fmc2: fix a buffer overflow

2020-07-21 Thread Christophe Kerello
This patch solves following static checker warning:
drivers/mtd/nand/raw/stm32_fmc2_nand.c:350 stm32_fmc2_nfc_select_chip()
error: buffer overflow 'nfc->data_phys_addr' 2 <= 2

The CS value can only be 0 or 1.

Signed-off-by: Christophe Kerello 
Fixes: 2cd457f328c1 ("mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash 
controller driver")
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index a4140af..74fecde 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1791,7 +1791,7 @@ static int stm32_fmc2_nfc_parse_child(struct 
stm32_fmc2_nfc *nfc,
return ret;
}
 
-   if (cs > FMC2_MAX_CE) {
+   if (cs >= FMC2_MAX_CE) {
dev_err(nfc->dev, "invalid reg value: %d\n", cs);
return -EINVAL;
}
-- 
1.9.1



Re: [PATCH v5 4/6] memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver

2020-06-30 Thread Christophe Kerello

Hi Richard,

On 6/30/20 11:13 AM, Richard Weinberger wrote:

On Fri, Jun 12, 2020 at 5:24 PM Christophe Kerello
 wrote:


The driver adds the support for the STMicroelectronics FMC2 EBI controller
found on STM32MP SOCs.

Signed-off-by: Christophe Kerello 
---
+   if (!IS_ERR(rstc)) {
+   reset_control_assert(rstc);
+   reset_control_deassert(rstc);


Shouldn't there be a small delay between assert and deassert?
Other than that the code looks good to me.



Even if I have currently not met any issue, I will add a udelay(2) to be 
safe. It will be part of v6.


Thanks,
Christophe Kerello.


[PATCH v5 5/6] mtd: rawnand: stm32_fmc2: use regmap APIs

2020-06-12 Thread Christophe Kerello
This patch uses regmap APIs to access all FMC2 registers.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/Kconfig   |   2 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 268 +++--
 2 files changed, 127 insertions(+), 143 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 113f610..0a03ebf 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -415,6 +415,8 @@ config MTD_NAND_TEGRA
 config MTD_NAND_STM32_FMC2
tristate "Support for NAND controller on STM32MP SoCs"
depends on MACH_STM32MP157 || COMPILE_TEST
+   select REGMAP
+   select REGMAP_MMIO
help
  Enables support for NAND Flash chips on SoCs containing the FMC2
  NAND controller. This controller is found on STM32MP SoCs.
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index e7b706b..6aa3695 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* Bad block marker length */
@@ -203,6 +204,16 @@
 #define FMC2_BCHDSR4_EBP7  GENMASK(12, 0)
 #define FMC2_BCHDSR4_EBP8  GENMASK(28, 16)
 
+/* Regmap registers configuration */
+#define FMC2_MAX_REGISTER  0x3fc
+
+static const struct regmap_config stm32_fmc2_regmap_cfg = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = sizeof(u32),
+   .max_register = FMC2_MAX_REGISTER,
+};
+
 enum stm32_fmc2_ecc {
FMC2_ECC_HAM = 1,
FMC2_ECC_BCH4 = 4,
@@ -242,7 +253,7 @@ struct stm32_fmc2_nfc {
struct nand_controller base;
struct stm32_fmc2_nand nand;
struct device *dev;
-   void __iomem *io_base;
+   struct regmap *regmap;
void __iomem *data_base[FMC2_MAX_CE];
void __iomem *cmd_base[FMC2_MAX_CE];
void __iomem *addr_base[FMC2_MAX_CE];
@@ -277,40 +288,37 @@ static void stm32_fmc2_nfc_timings_init(struct nand_chip 
*chip)
struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *timings = >timings;
-   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
u32 pmem, patt;
 
/* Set tclr/tar timings */
-   pcr &= ~FMC2_PCR_TCLR;
-   pcr |= FIELD_PREP(FMC2_PCR_TCLR, timings->tclr);
-   pcr &= ~FMC2_PCR_TAR;
-   pcr |= FIELD_PREP(FMC2_PCR_TAR, timings->tar);
+   regmap_update_bits(nfc->regmap, FMC2_PCR,
+  FMC2_PCR_TCLR | FMC2_PCR_TAR,
+  FIELD_PREP(FMC2_PCR_TCLR, timings->tclr) |
+  FIELD_PREP(FMC2_PCR_TAR, timings->tar));
 
/* Set tset/twait/thold/thiz timings in common bank */
pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem);
pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait);
pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem);
pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz);
+   regmap_write(nfc->regmap, FMC2_PMEM, pmem);
 
/* Set tset/twait/thold/thiz timings in attribut bank */
patt = FIELD_PREP(FMC2_PATT_ATTSET, timings->tset_att);
patt |= FIELD_PREP(FMC2_PATT_ATTWAIT, timings->twait);
patt |= FIELD_PREP(FMC2_PATT_ATTHOLD, timings->thold_att);
patt |= FIELD_PREP(FMC2_PATT_ATTHIZ, timings->thiz);
-
-   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
-   writel_relaxed(pmem, nfc->io_base + FMC2_PMEM);
-   writel_relaxed(patt, nfc->io_base + FMC2_PATT);
+   regmap_write(nfc->regmap, FMC2_PATT, patt);
 }
 
 static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
 {
struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
-   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
+   u32 pcr = 0, pcr_mask;
 
/* Configure ECC algorithm (default configuration is Hamming) */
-   pcr &= ~FMC2_PCR_ECCALG;
-   pcr &= ~FMC2_PCR_BCHECC;
+   pcr_mask = FMC2_PCR_ECCALG;
+   pcr_mask |= FMC2_PCR_BCHECC;
if (chip->ecc.strength == FMC2_ECC_BCH8) {
pcr |= FMC2_PCR_ECCALG;
pcr |= FMC2_PCR_BCHECC;
@@ -319,15 +327,15 @@ static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
}
 
/* Set buswidth */
-   pcr &= ~FMC2_PCR_PWID;
+   pcr_mask |= FMC2_PCR_PWID;
if (chip->options & NAND_BUSWIDTH_16)
pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16);
 
/* Set ECC sector size */
-   pcr &= ~FMC2_PCR_ECCSS;
+   pcr_mask |= FMC2_PCR_ECCSS;
pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_512);
 
-   writel_relaxed(

[PATCH v5 0/6] add STM32 FMC2 EBI controller driver

2020-06-12 Thread Christophe Kerello
The FMC2 functional block makes the interface with: synchronous and
asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
peripherals) and NAND flash memories.
Its main purposes are:
  - to translate AXI transactions into the appropriate external device
protocol
  - to meet the access time requirements of the external devices
All external devices share the addresses, data and control signals with the
controller. Each external device is accessed by means of a unique Chip
Select. The FMC2 performs only one access at a time to an external device.

Changes in v5:
 - NAND:
   - do not display errors if the driver is deferred.
   - look at the parent compatible string to match what we expect.
 - bindings:
   - add Rob reviewed-by tag on patch 3.
   - fix indent descriptions.
   - add new NFC compatible string to handle reg number of entries. 

Changes in v4:
 - bindings:
   - fix filename: st,stm32-fmc2-ebi.yaml

Changes in v3:
 - NAND:
   - rename labels used on errors
   - add in the commit log the reason to increase FMC2_TIMEOUT_MS (patch 3)
   - add Miquel reviewed-by tag (patches 2/4/5/9)
 - EBI:
   - move in memory folder
   - merge MFD and BUS drivers to avoid a MFD driver
 - bindings:
   - pattern name has been modified
   - vendor properties have been modified
 - s/_/-/
 - add unit suffix (-ns) on timing properties

Christophe Kerello (6):
  mtd: rawnand: stm32_fmc2: do not display errors if the driver is
deferred
  dt-bindings: mtd: update STM32 FMC2 NAND controller documentation
  dt-bindings: memory-controller: add STM32 FMC2 EBI controller
documentation
  memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver
  mtd: rawnand: stm32_fmc2: use regmap APIs
  mtd: rawnand: stm32_fmc2: get resources from parent node

 .../memory-controllers/st,stm32-fmc2-ebi.yaml  |  252 
 .../bindings/mtd/st,stm32-fmc2-nand.yaml   |   83 +-
 drivers/memory/Kconfig |   10 +
 drivers/memory/Makefile|1 +
 drivers/memory/stm32-fmc2-ebi.c| 1206 
 drivers/mtd/nand/raw/Kconfig   |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c |  311 ++---
 7 files changed, 1688 insertions(+), 176 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
 create mode 100644 drivers/memory/stm32-fmc2-ebi.c

-- 
1.9.1



[PATCH v5 6/6] mtd: rawnand: stm32_fmc2: get resources from parent node

2020-06-12 Thread Christophe Kerello
FMC2 EBI support has been added. Common resources (registers base
address and clock) can now be shared between the 2 drivers using
"st,stm32mp1-fmc2-nfc" compatible string. It means that the
common resources should now be found in the parent device when EBI
node is available.

Signed-off-by: Christophe Kerello 
---
Changes in v5:
 - look at the parent compatible string to match what we expect.

 drivers/mtd/nand/raw/Kconfig   |  3 +-
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 71 --
 2 files changed, 51 insertions(+), 23 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 0a03ebf..8dd0d7c 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -415,8 +415,7 @@ config MTD_NAND_TEGRA
 config MTD_NAND_STM32_FMC2
tristate "Support for NAND controller on STM32MP SoCs"
depends on MACH_STM32MP157 || COMPILE_TEST
-   select REGMAP
-   select REGMAP_MMIO
+   select MFD_SYSCON
help
  Enables support for NAND Flash chips on SoCs containing the FMC2
  NAND controller. This controller is found on STM32MP SoCs.
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 6aa3695..396b325 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -11,8 +11,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -204,16 +206,6 @@
 #define FMC2_BCHDSR4_EBP7  GENMASK(12, 0)
 #define FMC2_BCHDSR4_EBP8  GENMASK(28, 16)
 
-/* Regmap registers configuration */
-#define FMC2_MAX_REGISTER  0x3fc
-
-static const struct regmap_config stm32_fmc2_regmap_cfg = {
-   .reg_bits = 32,
-   .val_bits = 32,
-   .reg_stride = sizeof(u32),
-   .max_register = FMC2_MAX_REGISTER,
-};
-
 enum stm32_fmc2_ecc {
FMC2_ECC_HAM = 1,
FMC2_ECC_BCH4 = 4,
@@ -253,6 +245,7 @@ struct stm32_fmc2_nfc {
struct nand_controller base;
struct stm32_fmc2_nand nand;
struct device *dev;
+   struct device *cdev;
struct regmap *regmap;
void __iomem *data_base[FMC2_MAX_CE];
void __iomem *cmd_base[FMC2_MAX_CE];
@@ -1384,8 +1377,9 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc 
*nfc)
pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT);
 
/* Enable FMC2 controller */
-   regmap_update_bits(nfc->regmap, FMC2_BCR1,
-  FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN);
+   if (nfc->dev == nfc->cdev)
+   regmap_update_bits(nfc->regmap, FMC2_BCR1,
+  FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN);
 
regmap_write(nfc->regmap, FMC2_PCR, pcr);
regmap_write(nfc->regmap, FMC2_PMEM, FMC2_PMEM_DEFAULT);
@@ -1815,6 +1809,33 @@ static int stm32_fmc2_nfc_parse_dt(struct stm32_fmc2_nfc 
*nfc)
return ret;
 }
 
+static int stm32_fmc2_nfc_set_cdev(struct stm32_fmc2_nfc *nfc)
+{
+   struct device *dev = nfc->dev;
+   bool ebi_found = false;
+
+   if (dev->parent && of_device_is_compatible(dev->parent->of_node,
+  "st,stm32mp1-fmc2-ebi"))
+   ebi_found = true;
+
+   if (of_device_is_compatible(dev->of_node, "st,stm32mp1-fmc2-nfc")) {
+   if (ebi_found) {
+   nfc->cdev = dev->parent;
+
+   return 0;
+   }
+
+   return -EINVAL;
+   }
+
+   if (ebi_found)
+   return -EINVAL;
+
+   nfc->cdev = dev;
+
+   return 0;
+}
+
 static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -1824,8 +1845,9 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
struct resource *res;
struct mtd_info *mtd;
struct nand_chip *chip;
-   void __iomem *mmio;
+   struct resource cres;
int chip_cs, mem_region, ret, irq;
+   int start_region = 0;
 
nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
if (!nfc)
@@ -1835,22 +1857,28 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
nand_controller_init(>base);
nfc->base.ops = _fmc2_nfc_controller_ops;
 
+   ret = stm32_fmc2_nfc_set_cdev(nfc);
+   if (ret)
+   return ret;
+
ret = stm32_fmc2_nfc_parse_dt(nfc);
if (ret)
return ret;
 
-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   mmio = devm_ioremap_resource(dev, res);
-   if (IS_ERR(mmio))
-   return PTR_ERR(mmio);
+   ret = of_address_to_resource(nfc->cdev->of_node, 0, );
+   if (ret)
+   return ret;
+
+   nfc->io_phys_addr = cres.start;
 
-   nfc->regmap = dev

[PATCH v5 2/6] dt-bindings: mtd: update STM32 FMC2 NAND controller documentation

2020-06-12 Thread Christophe Kerello
These bindings can be used on SOCs where the FMC2 NAND controller is
in standalone. In case that the FMC2 embeds 2 controllers (an external
bus controller and a raw NAND controller), the register base address,
the clock and the reset will be defined in the parent node.

Signed-off-by: Christophe Kerello 
---
Changes in v4:
 - add new NFC compatible string to handle reg number of entries.

 .../bindings/mtd/st,stm32-fmc2-nand.yaml   | 83 +++---
 1 file changed, 57 insertions(+), 26 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml 
b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
index b059267..6ae7de1 100644
--- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
@@ -9,32 +9,19 @@ title: STMicroelectronics Flexible Memory Controller 2 (FMC2) 
Bindings
 maintainers:
   - Christophe Kerello 
 
-allOf:
-  - $ref: "nand-controller.yaml#"
-
 properties:
   compatible:
-const: st,stm32mp15-fmc2
+enum:
+  - st,stm32mp15-fmc2
+  - st,stm32mp1-fmc2-nfc
 
   reg:
-items:
-  - description: Registers
-  - 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
+minItems: 6
+maxItems: 7
 
   interrupts:
 maxItems: 1
 
-  clocks:
-maxItems: 1
-
-  resets:
-maxItems: 1
-
   dmas:
 items:
   - description: tx DMA channel
@@ -57,11 +44,55 @@ patternProperties:
   nand-ecc-strength:
 enum: [1, 4 ,8 ]
 
+allOf:
+  - $ref: "nand-controller.yaml#"
+
+  - if:
+  properties:
+compatible:
+  contains:
+const: st,stm32mp15-fmc2
+then:
+  properties:
+reg:
+  items:
+- description: Registers
+- 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
+
+clocks:
+  maxItems: 1
+
+resets:
+  maxItems: 1
+
+  required:
+- clocks
+
+  - if:
+  properties:
+compatible:
+  contains:
+const: st,stm32mp1-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
+
 required:
   - compatible
   - reg
   - interrupts
-  - clocks
 
 examples:
   - |
@@ -77,13 +108,13 @@ examples:
 <0x8100 0x1000>,
 <0x8901 0x1000>,
 <0x8902 0x1000>;
-interrupts = ;
-dmas = < 20 0x10 0x12000a02 0x0 0x0>,
-   < 20 0x10 0x12000a08 0x0 0x0>,
-   < 21 0x10 0x12000a0a 0x0 0x0>;
-dma-names = "tx", "rx", "ecc";
-clocks = < FMC_K>;
-resets = < FMC_R>;
+  interrupts = ;
+  dmas = < 20 0x2 0x12000a02 0x0 0x0>,
+ < 20 0x2 0x12000a08 0x0 0x0>,
+ < 21 0x2 0x12000a0a 0x0 0x0>;
+  dma-names = "tx", "rx", "ecc";
+  clocks = < FMC_K>;
+  resets = < FMC_R>;
   #address-cells = <1>;
   #size-cells = <0>;
 
-- 
1.9.1



[PATCH v5 1/6] mtd: rawnand: stm32_fmc2: do not display errors if the driver is deferred

2020-06-12 Thread Christophe Kerello
A MDMA issue has been solved on Kernel 5.7. The effect of this fix is
that the MDMA driver is now deferred and the FMC2 NFC driver is also
deferred. All is working fine but there is a FMC2 log in the console:
stm32_fmc2_nfc 58002000.nand-controller: failed to request tx DMA
channel: -517

This patch removes the display of this log in the console in case of
this error is -EPROBE_DEFER.

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 65c9d17..e7b706b 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1570,7 +1570,7 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc 
*nfc)
nfc->dma_tx_ch = dma_request_chan(nfc->dev, "tx");
if (IS_ERR(nfc->dma_tx_ch)) {
ret = PTR_ERR(nfc->dma_tx_ch);
-   if (ret != -ENODEV)
+   if (ret != -ENODEV && ret != -EPROBE_DEFER)
dev_err(nfc->dev,
"failed to request tx DMA channel: %d\n", ret);
nfc->dma_tx_ch = NULL;
@@ -1580,7 +1580,7 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc 
*nfc)
nfc->dma_rx_ch = dma_request_chan(nfc->dev, "rx");
if (IS_ERR(nfc->dma_rx_ch)) {
ret = PTR_ERR(nfc->dma_rx_ch);
-   if (ret != -ENODEV)
+   if (ret != -ENODEV && ret != -EPROBE_DEFER)
dev_err(nfc->dev,
"failed to request rx DMA channel: %d\n", ret);
nfc->dma_rx_ch = NULL;
@@ -1590,7 +1590,7 @@ static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc 
*nfc)
nfc->dma_ecc_ch = dma_request_chan(nfc->dev, "ecc");
if (IS_ERR(nfc->dma_ecc_ch)) {
ret = PTR_ERR(nfc->dma_ecc_ch);
-   if (ret != -ENODEV)
+   if (ret != -ENODEV && ret != -EPROBE_DEFER)
dev_err(nfc->dev,
"failed to request ecc DMA channel: %d\n", ret);
nfc->dma_ecc_ch = NULL;
-- 
1.9.1



[PATCH v5 3/6] dt-bindings: memory-controller: add STM32 FMC2 EBI controller documentation

2020-06-12 Thread Christophe Kerello
This patch adds the documentation of the device tree bindings for the STM32
FMC2 EBI controller.

Signed-off-by: Christophe Kerello 
Reviewed-by: Rob Herring 
---
Changes in v5:
 - fix indent descriptions
 - add Rob reviewed-by tag

Changes in v4:
 - fix filename: st,stm32-fmc2-ebi.yaml

Changes in v3:
 - pattern name has been modified
 - vendor properties have been modified
   - s/_/-/
   - add unit suffix (-ns) on timing properties

 .../memory-controllers/st,stm32-fmc2-ebi.yaml  | 252 +
 1 file changed, 252 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
new file mode 100644
index 000..70eaf73
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
@@ -0,0 +1,252 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2-ebi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings
+
+description: |
+  The FMC2 functional block makes the interface with: synchronous and
+  asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
+  peripherals) and NAND flash memories.
+  Its main purposes are:
+- to translate AXI transactions into the appropriate external device
+  protocol
+- to meet the access time requirements of the external devices
+  All external devices share the addresses, data and control signals with the
+  controller. Each external device is accessed by means of a unique Chip
+  Select. The FMC2 performs only one access at a time to an external device.
+
+maintainers:
+  - Christophe Kerello 
+
+properties:
+  compatible:
+const: st,stm32mp1-fmc2-ebi
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  resets:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 1
+
+  ranges:
+description: |
+  Reflects the memory layout with four integer values per bank. Format:
+   0  
+
+patternProperties:
+  "^.*@[0-4],[a-f0-9]+$":
+type: object
+
+properties:
+  reg:
+description: Bank number, base address and size of the device.
+
+  st,fmc2-ebi-cs-transaction-type:
+description: |
+  Select one of the transactions type supported
+  0: Asynchronous mode 1 SRAM/FRAM.
+  1: Asynchronous mode 1 PSRAM.
+  2: Asynchronous mode A SRAM/FRAM.
+  3: Asynchronous mode A PSRAM.
+  4: Asynchronous mode 2 NOR.
+  5: Asynchronous mode B NOR.
+  6: Asynchronous mode C NOR.
+  7: Asynchronous mode D NOR.
+  8: Synchronous read synchronous write PSRAM.
+  9: Synchronous read asynchronous write PSRAM.
+  10: Synchronous read synchronous write NOR.
+  11: Synchronous read asynchronous write NOR.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 11
+
+  st,fmc2-ebi-cs-cclk-enable:
+description: Continuous clock enable (first bank must be configured
+  in synchronous mode). The FMC_CLK is generated continuously
+  during asynchronous and synchronous access. By default, the
+  FMC_CLK is only generated during synchronous access.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-mux-enable:
+description: Address/Data multiplexed on databus (valid only with
+  NOR and PSRAM transactions type). By default, Address/Data
+  are not multiplexed.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-buswidth:
+description: Data bus width
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [ 8, 16 ]
+default: 16
+
+  st,fmc2-ebi-cs-waitpol-high:
+description: Wait signal polarity (NWAIT signal active high).
+  By default, NWAIT is active low.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-waitcfg-enable:
+description: The NWAIT signal indicates wheither the data from the
+  device are valid or if a wait state must be inserted when accessing
+  the device in synchronous mode. By default, the NWAIT signal is
+  active one data cycle before wait state.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-wait-enable:
+description: The NWAIT signal is enabled (its level is taken into
+  account after the programmed latency period to insert wait states
+  if asserted). By default, the NWAIT signal is disabled.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-asyncwait-enable:
+   

[PATCH v5 4/6] memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver

2020-06-12 Thread Christophe Kerello
The driver adds the support for the STMicroelectronics FMC2 EBI controller
found on STM32MP SOCs.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - Move in memory folder
 - Merge MFD and BUS drivers to avoid a MFD driver

 drivers/memory/Kconfig  |   10 +
 drivers/memory/Makefile |1 +
 drivers/memory/stm32-fmc2-ebi.c | 1206 +++
 3 files changed, 1217 insertions(+)
 create mode 100644 drivers/memory/stm32-fmc2-ebi.c

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 9bddca2..c651aaf 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -163,6 +163,16 @@ config PL353_SMC
  This driver is for the ARM PL351/PL353 Static Memory
  Controller(SMC) module.
 
+config STM32_FMC2_EBI
+   tristate "Support for FMC2 External Bus Interface on STM32MP SoCs"
+   depends on MACH_STM32MP157 || COMPILE_TEST
+   select MFD_SYSCON
+   help
+ Select this option to enable the STM32 FMC2 External Bus Interface
+ controller. This driver configures the transactions with external
+ devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on
+ SOCs containing the FMC2 External Bus Interface.
+
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
 
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 27b4934..c7d36db 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
 obj-$(CONFIG_MTK_SMI)  += mtk-smi.o
 obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
 obj-$(CONFIG_PL353_SMC)+= pl353-smc.o
+obj-$(CONFIG_STM32_FMC2_EBI)   += stm32-fmc2-ebi.o
 
 obj-$(CONFIG_SAMSUNG_MC)   += samsung/
 obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c
new file mode 100644
index 000..4d5758c4
--- /dev/null
+++ b/drivers/memory/stm32-fmc2-ebi.c
@@ -0,0 +1,1206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2020
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_BTR1  0x4
+#define FMC2_BCR(x)((x) * 0x8 + FMC2_BCR1)
+#define FMC2_BTR(x)((x) * 0x8 + FMC2_BTR1)
+#define FMC2_PCSCNTR   0x20
+#define FMC2_BWTR1 0x104
+#define FMC2_BWTR(x)   ((x) * 0x8 + FMC2_BWTR1)
+
+/* Register: FMC2_BCR1 */
+#define FMC2_BCR1_CCLKEN   BIT(20)
+#define FMC2_BCR1_FMC2EN   BIT(31)
+
+/* Register: FMC2_BCRx */
+#define FMC2_BCR_MBKEN BIT(0)
+#define FMC2_BCR_MUXEN BIT(1)
+#define FMC2_BCR_MTYP  GENMASK(3, 2)
+#define FMC2_BCR_MWID  GENMASK(5, 4)
+#define FMC2_BCR_FACCENBIT(6)
+#define FMC2_BCR_BURSTEN   BIT(8)
+#define FMC2_BCR_WAITPOL   BIT(9)
+#define FMC2_BCR_WAITCFG   BIT(11)
+#define FMC2_BCR_WREN  BIT(12)
+#define FMC2_BCR_WAITENBIT(13)
+#define FMC2_BCR_EXTMODBIT(14)
+#define FMC2_BCR_ASYNCWAIT BIT(15)
+#define FMC2_BCR_CPSIZEGENMASK(18, 16)
+#define FMC2_BCR_CBURSTRW  BIT(19)
+#define FMC2_BCR_NBLSETGENMASK(23, 22)
+
+/* Register: FMC2_BTRx/FMC2_BWTRx */
+#define FMC2_BXTR_ADDSET   GENMASK(3, 0)
+#define FMC2_BXTR_ADDHLD   GENMASK(7, 4)
+#define FMC2_BXTR_DATAST   GENMASK(15, 8)
+#define FMC2_BXTR_BUSTURN  GENMASK(19, 16)
+#define FMC2_BTR_CLKDIVGENMASK(23, 20)
+#define FMC2_BTR_DATLATGENMASK(27, 24)
+#define FMC2_BXTR_ACCMOD   GENMASK(29, 28)
+#define FMC2_BXTR_DATAHLD  GENMASK(31, 30)
+
+/* Register: FMC2_PCSCNTR */
+#define FMC2_PCSCNTR_CSCOUNT   GENMASK(15, 0)
+#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
+
+#define FMC2_MAX_EBI_CE4
+#define FMC2_MAX_BANKS 5
+
+#define FMC2_BCR_CPSIZE_0  0x0
+#define FMC2_BCR_CPSIZE_1280x1
+#define FMC2_BCR_CPSIZE_2560x2
+#define FMC2_BCR_CPSIZE_5120x3
+#define FMC2_BCR_CPSIZE_1024   0x4
+
+#define FMC2_BCR_MWID_80x0
+#define FMC2_BCR_MWID_16   0x1
+
+#define FMC2_BCR_MTYP_SRAM 0x0
+#define FMC2_BCR_MTYP_PSRAM0x1
+#define FMC2_BCR_MTYP_NOR  0x2
+
+#define FMC2_BXTR_EXTMOD_A 0x0
+#define FMC2_BXTR_EXTMOD_B 0x1
+#define FMC2_BXTR_EXTMOD_C 0x2
+#define FMC2_BXTR_EXTMOD_D 0x3
+
+#define FMC2_BCR_NBLSET_MAX0x3

Re: [PATCH v4 06/10] dt-bindings: mtd: update STM32 FMC2 NAND controller documentation

2020-05-15 Thread Christophe Kerello

Hi Rob,

On 5/14/20 7:55 PM, Rob Herring wrote:

On Thu, May 14, 2020 at 11:35 AM Christophe Kerello
 wrote:


Hi Rob,

On 5/14/20 5:00 PM, Rob Herring wrote:

On Wed, May 06, 2020 at 11:11:15AM +0200, Christophe Kerello wrote:

These bindings can be used on SOCs where the FMC2 NAND controller is
in standalone. In case that the FMC2 embeds 2 controllers (an external
bus controller and a raw NAND controller), the register base and the
clock will be defined in the parent node. It is the reason why the
register base address and the clock are now optional.

Signed-off-by: Christophe Kerello 
---
   .../devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml   | 19 
++-
   1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml 
b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
index b059267..68fac1a 100644
--- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
@@ -18,13 +18,15 @@ properties:

 reg:
   items:
-  - description: Registers
+  - description: Registers (optional)


The only thing that can be optional are the last entries. You have to do
a 'oneOf' with 6 entries and 7 entries.


Ok, so the way to describe the reg property in my case should be:
 reg:
   oneOf:
 - description: FMC2 embeds the NFC controller in standalone.
   items:
 - description: Registers
 - 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: FMC2 embeds the NFC controller and the EBI
 controller.
   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



And where's your new compatible string for this different h/w?


  From NFC controller point of view, it is the same HW.


That's what everyone says until they have some quirk or integration
difference to handle.


In the case that we have 2 controllers embedded, the register base is
shared.
The NFC driver will check at probe time the compatible string of its
parent node.
In case that it is "st,stm32mp1-fmc2-ebi", then the driver will find the
register base in the parent node (EBI node), otherwise it will find it
in the NFC node.
Is it better to have 2 compatible strings (one for each reg description)
than checking the parent's compatible string and have only one
compatible string?


Why not just put the register base into the child node too? While
overlapping 'reg' regions for siblings is bad, it's fine for child
nodes. I guess since there are chip selects for the child nodes that
may not work here.

It doesn't hurt to have another compatible. You can always make the
old one a fallback. With different compatibles you can make sure reg
has the right number of entries.

Rob



I will add a new compatible string to handle the reg property.
It will be part of v5.

Regards,
Christophe Kerello.


Re: [PATCH v4 07/10] dt-bindings: memory-controller: add STM32 FMC2 EBI controller documentation

2020-05-14 Thread Christophe Kerello

Hi Rob,

On 5/14/20 5:07 PM, Rob Herring wrote:

On Wed, May 06, 2020 at 11:11:16AM +0200, Christophe Kerello wrote:

This patch adds the documentation of the device tree bindings for the STM32
FMC2 EBI controller.

Signed-off-by: Christophe Kerello 
---
Changes in v4:
  - fix filename: st,stm32-fmc2-ebi.yaml

Changes in v3:
  - pattern name has been modified
  - vendor properties have been modified
- s/_/-/
- add unit suffix (-ns) on timing properties

  .../memory-controllers/st,stm32-fmc2-ebi.yaml  | 261 +
  1 file changed, 261 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
new file mode 100644
index 000..bf130c3
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
@@ -0,0 +1,261 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2-ebi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings
+
+description: |
+  The FMC2 functional block makes the interface with: synchronous and
+  asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
+  peripherals) and NAND flash memories.
+  Its main purposes are:
+- to translate AXI transactions into the appropriate external device
+  protocol
+- to meet the access time requirements of the external devices
+  All external devices share the addresses, data and control signals with the
+  controller. Each external device is accessed by means of a unique Chip
+  Select. The FMC2 performs only one access at a time to an external device.
+
+maintainers:
+  - Christophe Kerello 
+
+properties:
+  compatible:
+const: st,stm32mp1-fmc2-ebi
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  resets:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 1
+
+  ranges:
+description: |
+  Reflects the memory layout with four integer values per bank. Format:
+   0  
+
+patternProperties:
+  "^.*@[0-4],[a-f0-9]+$":
+type: object
+
+properties:
+  reg:
+description: Bank number, base address and size of the device.
+
+  st,fmc2-ebi-cs-transaction-type:
+description: |
+ Select one of the transactions type supported


Indent should be 2 more than 'description'.


Ok, it will be part of v5.




+   0: Asynchronous mode 1 SRAM/FRAM.
+   1: Asynchronous mode 1 PSRAM.
+   2: Asynchronous mode A SRAM/FRAM.
+   3: Asynchronous mode A PSRAM.
+   4: Asynchronous mode 2 NOR.
+   5: Asynchronous mode B NOR.
+   6: Asynchronous mode C NOR.
+   7: Asynchronous mode D NOR.
+   8: Synchronous read synchronous write PSRAM.
+   9: Synchronous read asynchronous write PSRAM.
+   10: Synchronous read synchronous write NOR.
+   11: Synchronous read asynchronous write NOR.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 11
+
+  st,fmc2-ebi-cs-cclk-enable:
+description: Continuous clock enable (first bank must be configured
+ in synchronous mode). The FMC_CLK is generated 
continuously
+ during asynchronous and synchronous access. By default, 
the
+ FMC_CLK is only generated during synchronous access.


Indent 2 more than 'description'. You can run this through yaml-format
in dtschema repo and it will re-flow everything for you.


Ok, it will be part of v5.

Regards,
Christophe Kerello.



With these fixed,

Reviewed-by: Rob Herring 



+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-mux-enable:
+description: Address/Data multiplexed on databus (valid only with
+ NOR and PSRAM transactions type). By default, Address/Data
+ are not multiplexed.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-buswidth:
+description: Data bus width
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [ 8, 16 ]
+default: 16
+
+  st,fmc2-ebi-cs-waitpol-high:
+description: Wait signal polarity (NWAIT signal active high).
+ By default, NWAIT is active low.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-waitcfg-enable:
+description: The NWAIT signal indicates wheither the data from the
+ device are

Re: [PATCH v4 06/10] dt-bindings: mtd: update STM32 FMC2 NAND controller documentation

2020-05-14 Thread Christophe Kerello

Hi Rob,

On 5/14/20 5:00 PM, Rob Herring wrote:

On Wed, May 06, 2020 at 11:11:15AM +0200, Christophe Kerello wrote:

These bindings can be used on SOCs where the FMC2 NAND controller is
in standalone. In case that the FMC2 embeds 2 controllers (an external
bus controller and a raw NAND controller), the register base and the
clock will be defined in the parent node. It is the reason why the
register base address and the clock are now optional.

Signed-off-by: Christophe Kerello 
---
  .../devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml   | 19 ++-
  1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml 
b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
index b059267..68fac1a 100644
--- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
@@ -18,13 +18,15 @@ properties:
  
reg:

  items:
-  - description: Registers
+  - description: Registers (optional)


The only thing that can be optional are the last entries. You have to do
a 'oneOf' with 6 entries and 7 entries.


Ok, so the way to describe the reg property in my case should be:
   reg:
 oneOf:
   - description: FMC2 embeds the NFC controller in standalone.
 items:
   - description: Registers
   - 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: FMC2 embeds the NFC controller and the EBI
   controller.
 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



And where's your new compatible string for this different h/w?


From NFC controller point of view, it is the same HW.
In the case that we have 2 controllers embedded, the register base is 
shared.
The NFC driver will check at probe time the compatible string of its 
parent node.
In case that it is "st,stm32mp1-fmc2-ebi", then the driver will find the 
register base in the parent node (EBI node), otherwise it will find it 
in the NFC node.
Is it better to have 2 compatible strings (one for each reg description) 
than checking the parent's compatible string and have only one 
compatible string?


Regards,
Christophe Kerello.




- 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
+minItems: 6
+maxItems: 7
  
interrupts:

  maxItems: 1
@@ -61,7 +63,6 @@ required:
- compatible
- reg
- interrupts
-  - clocks
  
  examples:

- |
@@ -77,13 +78,13 @@ examples:
  <0x8100 0x1000>,
  <0x8901 0x1000>,
  <0x8902 0x1000>;
-interrupts = ;
-dmas = < 20 0x10 0x12000a02 0x0 0x0>,
-   < 20 0x10 0x12000a08 0x0 0x0>,
-   < 21 0x10 0x12000a0a 0x0 0x0>;
-dma-names = "tx", "rx", "ecc";
-clocks = < FMC_K>;
-resets = < FMC_R>;
+  interrupts = ;
+  dmas = < 20 0x2 0x12000a02 0x0 0x0>,
+ < 20 0x2 0x12000a08 0x0 0x0>,
+ < 21 0x2 0x12000a0a 0x0 0x0>;
+  dma-names = "tx", "rx", "ecc";
+  clocks = < FMC_K>;
+  resets = < FMC_R>;
#address-cells = <1>;
#size-cells = <0>;
  
--

1.9.1



[PATCH v5 2/2] mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros

2020-05-12 Thread Christophe Kerello
This patch removes custom macros and uses FIELD_PREP and FIELD_GET macros.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v5:
 - rebase on top of nand/next
Changes in v3:
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 177 -
 1 file changed, 85 insertions(+), 92 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 901ebd8..8f02d5e 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -4,6 +4,7 @@
  * Author: Christophe Kerello 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -84,20 +85,16 @@
 /* Register: FMC2_PCR */
 #define FMC2_PCR_PWAITEN   BIT(1)
 #define FMC2_PCR_PBKEN BIT(2)
-#define FMC2_PCR_PWID_MASK GENMASK(5, 4)
-#define FMC2_PCR_PWID(x)   (((x) & 0x3) << 4)
+#define FMC2_PCR_PWID  GENMASK(5, 4)
 #define FMC2_PCR_PWID_BUSWIDTH_8   0
 #define FMC2_PCR_PWID_BUSWIDTH_16  1
 #define FMC2_PCR_ECCEN BIT(6)
 #define FMC2_PCR_ECCALGBIT(8)
-#define FMC2_PCR_TCLR_MASK GENMASK(12, 9)
-#define FMC2_PCR_TCLR(x)   (((x) & 0xf) << 9)
+#define FMC2_PCR_TCLR  GENMASK(12, 9)
 #define FMC2_PCR_TCLR_DEFAULT  0xf
-#define FMC2_PCR_TAR_MASK  GENMASK(16, 13)
-#define FMC2_PCR_TAR(x)(((x) & 0xf) << 13)
+#define FMC2_PCR_TAR   GENMASK(16, 13)
 #define FMC2_PCR_TAR_DEFAULT   0xf
-#define FMC2_PCR_ECCSS_MASKGENMASK(19, 17)
-#define FMC2_PCR_ECCSS(x)  (((x) & 0x7) << 17)
+#define FMC2_PCR_ECCSS GENMASK(19, 17)
 #define FMC2_PCR_ECCSS_512 1
 #define FMC2_PCR_ECCSS_20483
 #define FMC2_PCR_BCHECCBIT(24)
@@ -107,17 +104,17 @@
 #define FMC2_SR_NWRF   BIT(6)
 
 /* Register: FMC2_PMEM */
-#define FMC2_PMEM_MEMSET(x)(((x) & 0xff) << 0)
-#define FMC2_PMEM_MEMWAIT(x)   (((x) & 0xff) << 8)
-#define FMC2_PMEM_MEMHOLD(x)   (((x) & 0xff) << 16)
-#define FMC2_PMEM_MEMHIZ(x)(((x) & 0xff) << 24)
+#define FMC2_PMEM_MEMSET   GENMASK(7, 0)
+#define FMC2_PMEM_MEMWAIT  GENMASK(15, 8)
+#define FMC2_PMEM_MEMHOLD  GENMASK(23, 16)
+#define FMC2_PMEM_MEMHIZ   GENMASK(31, 24)
 #define FMC2_PMEM_DEFAULT  0x0a0a0a0a
 
 /* Register: FMC2_PATT */
-#define FMC2_PATT_ATTSET(x)(((x) & 0xff) << 0)
-#define FMC2_PATT_ATTWAIT(x)   (((x) & 0xff) << 8)
-#define FMC2_PATT_ATTHOLD(x)   (((x) & 0xff) << 16)
-#define FMC2_PATT_ATTHIZ(x)(((x) & 0xff) << 24)
+#define FMC2_PATT_ATTSET   GENMASK(7, 0)
+#define FMC2_PATT_ATTWAIT  GENMASK(15, 8)
+#define FMC2_PATT_ATTHOLD  GENMASK(23, 16)
+#define FMC2_PATT_ATTHIZ   GENMASK(31, 24)
 #define FMC2_PATT_DEFAULT  0x0a0a0a0a
 
 /* Register: FMC2_ISR */
@@ -132,9 +129,9 @@
 /* Register: FMC2_CSQCFGR1 */
 #define FMC2_CSQCFGR1_CMD2EN   BIT(1)
 #define FMC2_CSQCFGR1_DMADEN   BIT(2)
-#define FMC2_CSQCFGR1_ACYNBR(x)(((x) & 0x7) << 4)
-#define FMC2_CSQCFGR1_CMD1(x)  (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR1_CMD2(x)  (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR1_ACYNBR   GENMASK(6, 4)
+#define FMC2_CSQCFGR1_CMD1 GENMASK(15, 8)
+#define FMC2_CSQCFGR1_CMD2 GENMASK(23, 16)
 #define FMC2_CSQCFGR1_CMD1TBIT(24)
 #define FMC2_CSQCFGR1_CMD2TBIT(25)
 
@@ -142,13 +139,13 @@
 #define FMC2_CSQCFGR2_SQSDTEN  BIT(0)
 #define FMC2_CSQCFGR2_RCMD2EN  BIT(1)
 #define FMC2_CSQCFGR2_DMASEN   BIT(2)
-#define FMC2_CSQCFGR2_RCMD1(x) (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR2_RCMD2(x) (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR2_RCMD1GENMASK(15, 8)
+#define FMC2_CSQCFGR2_RCMD2GENMASK(23, 16)
 #define FMC2_CSQCFGR2_RCMD1T   BIT(24)
 #define FMC2_CSQCFGR2_RCMD2T   BIT(25)
 
 /* Register: FMC2_CSQCFGR3 */
-#define FMC2_CSQCFGR3_SNBR(x)  (((x) & 0x1f) << 8)
+#define FMC2_CSQCFGR3_SNBR GENMASK(13, 8)
 #define FMC2_CSQCFGR3_AC1T BIT(16)
 #define FMC2_CSQCFGR3_AC2T BIT(17)
 #define FMC2_CSQCFGR3_AC3T BIT(18)
@@ -159,15 +156,15 @@
 #define FMC2_CSQCFGR3_RAC2TBIT(23)
 
 /* Register: FMC2_CSQCAR1 */
-#define FMC2_CSQCAR1_ADDC1(x)  (((x) & 0xff) << 0)
-#define FMC2_CSQCAR1_ADDC2(x)  (((x) & 0xff) << 8)
-#define FMC2_CSQCAR1_ADDC3(x)  (((x) & 0xff) << 16)
-#define FMC2_

[PATCH v5 1/2] mtd: rawnand: stm32_fmc2: cosmetic change to use nfc instead of fmc2 where relevant

2020-05-12 Thread Christophe Kerello
This patch renames functions and local variables.
This cleanup is done to get all functions starting by stm32_fmc2_nfc
in the FMC2 raw NAND driver when all functions will start by
stm32_fmc2_ebi in the FMC2 EBI driver.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v5:
 - rebase on top of nand/next
Changes in v3:
 - fix s/conf/cf/, s/nfc/NFC/
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 810 -
 1 file changed, 403 insertions(+), 407 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 30083e5..901ebd8 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -280,12 +280,12 @@ static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct 
nand_controller *base)
return container_of(base, struct stm32_fmc2_nfc, base);
 }
 
-static void stm32_fmc2_timings_init(struct nand_chip *chip)
+static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *timings = >timings;
-   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
u32 pmem, patt;
 
/* Set tclr/tar timings */
@@ -306,15 +306,15 @@ static void stm32_fmc2_timings_init(struct nand_chip 
*chip)
patt |= FMC2_PATT_ATTHOLD(timings->thold_att);
patt |= FMC2_PATT_ATTHIZ(timings->thiz);
 
-   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
-   writel_relaxed(pmem, fmc2->io_base + FMC2_PMEM);
-   writel_relaxed(patt, fmc2->io_base + FMC2_PATT);
+   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
+   writel_relaxed(pmem, nfc->io_base + FMC2_PMEM);
+   writel_relaxed(patt, nfc->io_base + FMC2_PATT);
 }
 
-static void stm32_fmc2_setup(struct nand_chip *chip)
+static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
-   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
+   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
 
/* Configure ECC algorithm (default configuration is Hamming) */
pcr &= ~FMC2_PCR_ECCALG;
@@ -335,174 +335,174 @@ static void stm32_fmc2_setup(struct nand_chip *chip)
pcr &= ~FMC2_PCR_ECCSS_MASK;
pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
 
-   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
 }
 
-static int stm32_fmc2_select_chip(struct nand_chip *chip, int chipnr)
+static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct dma_slave_config dma_cfg;
int ret;
 
-   if (nand->cs_used[chipnr] == fmc2->cs_sel)
+   if (nand->cs_used[chipnr] == nfc->cs_sel)
return 0;
 
-   fmc2->cs_sel = nand->cs_used[chipnr];
-   stm32_fmc2_setup(chip);
-   stm32_fmc2_timings_init(chip);
+   nfc->cs_sel = nand->cs_used[chipnr];
+   stm32_fmc2_nfc_setup(chip);
+   stm32_fmc2_nfc_timings_init(chip);
 
-   if (fmc2->dma_tx_ch && fmc2->dma_rx_ch) {
+   if (nfc->dma_tx_ch && nfc->dma_rx_ch) {
memset(_cfg, 0, sizeof(dma_cfg));
-   dma_cfg.src_addr = fmc2->data_phys_addr[fmc2->cs_sel];
-   dma_cfg.dst_addr = fmc2->data_phys_addr[fmc2->cs_sel];
+   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;
 
-   ret = dmaengine_slave_config(fmc2->dma_tx_ch, _cfg);
+   ret = dmaengine_slave_config(nfc->dma_tx_ch, _cfg);
if (ret) {
-   dev_err(fmc2->dev, "tx DMA engine slave config 
failed\n");
+   dev_err(nfc->dev, "tx DMA engine slave config 
failed\n");
return ret;
}
 
-   ret = dmaengine_slave_config(fmc2->dma_rx_ch, _cfg);
+   ret = dmaengine_slave_config(nfc->dma_rx_ch, _cfg);
if (ret) {
-   

[PATCH v5 0/2] mtd: rawnand: stm32_fmc2: rebase cosmetic change on top of nand/next

2020-05-12 Thread Christophe Kerello
This set of patches is a rebase of the patches that were not applied
on nand/next.

Changes in v5:
 - rebase on top of nand/next

Changes in v3:
 - add Miquel reviewed-by tag

Christophe Kerello (2):
  mtd: rawnand: stm32_fmc2: cosmetic change to use nfc instead of
fmc2 where relevant
  mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 987 -
 1 file changed, 488 insertions(+), 499 deletions(-)

-- 
1.9.1



Re: [PATCH v4 04/10] mtd: rawnand: stm32_fmc2: cleanup

2020-05-12 Thread Christophe Kerello

Hi Miquel,

On 5/11/20 10:39 PM, Miquel Raynal wrote:


Christophe Kerello  wrote on Wed, 6 May 2020
11:11:13 +0200:


This patch renames functions and local variables.
This cleanup is done to get all functions starting by stm32_fmc2_nfc
in the FMC2 raw NAND driver when all functions will start by
stm32_fmc2_ebi in the FMC2 EBI driver.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 


Applied to nand/next as well but for an unknown reason I had to do it
by hand because the patch would not apply.

Thanks,
Miquèl


This is strange, I can apply this patch on my tree without any conflicts.
There is a compilation issue line 1301.

@@ -1302,44 +1298,45 @@ static void stm32_fmc2_write_data(struct 
nand_chip *chip, const void *buf,


if (force_8bit && chip->options & NAND_BUSWIDTH_16)
/* Reconfigure bus width to 16-bit */
-   stm32_fmc2_set_buswidth_16(fmc2, true);
+   stm32_fmc2_nfc_set_buswidth_16(nfc, true);
 }

I will rebase on top of nand/next today to check that there is no issues 
with the driver.


Regards,
Christophe Kerello.


Re: [PATCH v4 10/10] mtd: rawnand: stm32_fmc2: get resources from parent node

2020-05-11 Thread Christophe Kerello

Hi Miquel,

On 5/11/20 4:45 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Mon, 11 May
2020 16:19:47 +0200:


Hi Miquel,

On 5/11/20 2:58 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Mon, 11 May
2020 14:47:09 +0200:
   

Hi Miquel,

On 5/11/20 1:59 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Mon, 11 May
2020 12:21:03 +0200:
>>>> Hi Miquel,


On 5/11/20 11:18 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 6 May 2020
11:11:19 +0200:
 >>>> FMC2 EBI support has been added. Common resources (registers base

and clock) are now shared between the 2 drivers. It means that the
common resources should now be found in the parent device when EBI
node is available.

Signed-off-by: Christophe Kerello 
---


[...]
 >>>> +

+static bool stm32_fmc2_nfc_check_for_parent(struct platform_device *pdev)
+{
+   u32 i;
+   int nb_resources = 0;
+
+   /* Count the number of resources in reg property */
+   for (i = 0; i < pdev->num_resources; i++) {
+   struct resource *res = >resource[i];
+
+   if (resource_type(res) == IORESOURCE_MEM)
+   nb_resources++;
+   }
+
+   /* Each CS needs 3 resources defined (data, cmd and addr) */
+   if (nb_resources % 3)
+   return false;
+
+   return true;
+}


This function looks fragile. Why not just checking the compatible
string of the parent node?
 >>

Yes, it is another way to check that we have an EBI parent node.

In this implementation, I was checking the number of reg tuples.
In case we have 6, it means that the register base address is defined in the 
parent node (EBI node).
In case we have 7, it means that the register base address is defined in the 
current node (NFC node).


Yes, I understand what you are doing, but I kind of dislike the logic.
Relying on the number of reg tuples is something that can be done (I
used it myself one time), but I think this is more a hack that you do
when you have no other way to differentiate. I guess the proper way
would be to look at the parent's compatible. If it matches what you
expect, then you can store the dev->of_node->parent->dev somewhere in
your controller's structure and then use it to initialize the clock and
regmap. This way you don't have to move anything else in the probe path.
>>

OK, I will check the compatible string of the parent device using 
of_device_is_compatible API in v5.
In case of the parent is found, I will add it in the structure of the 
controller (dev_parent).
I will rely on this field only to get the common resources (the register base 
address and the clock) in the NFC node or in the EBI node.


I had something slightly different in mind: what about setting a
default value to this field as being the controller's device itself.
This way, once it is set to either the parent device or the device
itself, you can use it "blindly" in your devm_clk_get/regmap_init calls?
   


I will try to explain what I have in mind.

I will add a new field in the structure of the controller (not called 
dev_parent but cdev)
struct device *cdev;

Then, at probe time, this field will be assigned:
nfc->cdev = of_device_is_compatible(dev->parent->of_node, "bla bla") : 
dev->parent ? dev;


That's what I had in mind. Maybe you'll have to use
dev->of_node->parent though, I think they are not equivalent.



For the clock, it will be
nfc->clk = devm_clk_get(nfc->cdev, NULL);

For the register base, I need to replace:
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mmio = devm_ioremap_resource(dev, res);
if (IS_ERR(mmio))
return PTR_ERR(mmio);

nfc->regmap = devm_regmap_init_mmio(dev, mmio, _fmc2_regmap_cfg);
if (IS_ERR(nfc->regmap))
return PTR_ERR(nfc->regmap);

nfc->io_phys_addr = res->start;

With:

ret = of_address_to_resource(nfc->cdev->of_node, 0, );
if (ret)
return ret;

nfc->io_phys_addr = res.start;

nfc->regmap = device_node_to_regmap(nfc->cdev->of_node);
if (IS_ERR(nfc->regmap))
return PTR_ERR(nfc->regmap);

I expect that you were thinking about something like this proposal.


This means the regmap has already been initialized, can you make sure
it is actually the case? What if the probe of the EBI block happens
next, or is deferred? (maybe you'll get a -EPROBE_DEFER, which is fine
then). Please try booting with the EBI node but without the EBI driver
and see if this is handled gracefully.



In case we have an EBI node, the NFC node will be a child node of the 
EBI node.
The EBI driver will first be probed, getting all its resources and then 
it will populate all its children node (including the NFC node if this 
one is enabled). If the EBI driver is deferred because of getting one of 
its resources has failed, none of its children will be p

Re: [PATCH v4 10/10] mtd: rawnand: stm32_fmc2: get resources from parent node

2020-05-11 Thread Christophe Kerello

Hi Miquel,

On 5/11/20 2:58 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Mon, 11 May
2020 14:47:09 +0200:


Hi Miquel,

On 5/11/20 1:59 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Mon, 11 May
2020 12:21:03 +0200:
   

Hi Miquel,

On 5/11/20 11:18 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 6 May 2020
11:11:19 +0200:
>>>> FMC2 EBI support has been added. Common resources (registers base

and clock) are now shared between the 2 drivers. It means that the
common resources should now be found in the parent device when EBI
node is available.

Signed-off-by: Christophe Kerello 
---


[...]
>>>> +

+static bool stm32_fmc2_nfc_check_for_parent(struct platform_device *pdev)
+{
+   u32 i;
+   int nb_resources = 0;
+
+   /* Count the number of resources in reg property */
+   for (i = 0; i < pdev->num_resources; i++) {
+   struct resource *res = >resource[i];
+
+   if (resource_type(res) == IORESOURCE_MEM)
+   nb_resources++;
+   }
+
+   /* Each CS needs 3 resources defined (data, cmd and addr) */
+   if (nb_resources % 3)
+   return false;
+
+   return true;
+}


This function looks fragile. Why not just checking the compatible
string of the parent node?
>>

Yes, it is another way to check that we have an EBI parent node.

In this implementation, I was checking the number of reg tuples.
In case we have 6, it means that the register base address is defined in the 
parent node (EBI node).
In case we have 7, it means that the register base address is defined in the 
current node (NFC node).


Yes, I understand what you are doing, but I kind of dislike the logic.
Relying on the number of reg tuples is something that can be done (I
used it myself one time), but I think this is more a hack that you do
when you have no other way to differentiate. I guess the proper way
would be to look at the parent's compatible. If it matches what you
expect, then you can store the dev->of_node->parent->dev somewhere in
your controller's structure and then use it to initialize the clock and
regmap. This way you don't have to move anything else in the probe path.
   


OK, I will check the compatible string of the parent device using 
of_device_is_compatible API in v5.
In case of the parent is found, I will add it in the structure of the 
controller (dev_parent).
I will rely on this field only to get the common resources (the register base 
address and the clock) in the NFC node or in the EBI node.


I had something slightly different in mind: what about setting a
default value to this field as being the controller's device itself.
This way, once it is set to either the parent device or the device
itself, you can use it "blindly" in your devm_clk_get/regmap_init calls?



I will try to explain what I have in mind.

I will add a new field in the structure of the controller (not called 
dev_parent but cdev)

struct device *cdev;

Then, at probe time, this field will be assigned:
nfc->cdev = of_device_is_compatible(dev->parent->of_node, "bla bla") : 
dev->parent ? dev;


For the clock, it will be
nfc->clk = devm_clk_get(nfc->cdev, NULL);

For the register base, I need to replace:
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mmio = devm_ioremap_resource(dev, res);
if (IS_ERR(mmio))
return PTR_ERR(mmio);

nfc->regmap = devm_regmap_init_mmio(dev, mmio, _fmc2_regmap_cfg);
if (IS_ERR(nfc->regmap))
return PTR_ERR(nfc->regmap);

nfc->io_phys_addr = res->start;

With:

ret = of_address_to_resource(nfc->cdev->of_node, 0, );
if (ret)
return ret;

nfc->io_phys_addr = res.start;

nfc->regmap = device_node_to_regmap(nfc->cdev->of_node);
if (IS_ERR(nfc->regmap))
    return PTR_ERR(nfc->regmap);

I expect that you were thinking about something like this proposal.

Regards,
Christophe Kerello.


Re: [PATCH v4 10/10] mtd: rawnand: stm32_fmc2: get resources from parent node

2020-05-11 Thread Christophe Kerello

Hi Miquel,

On 5/11/20 1:59 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Mon, 11 May
2020 12:21:03 +0200:


Hi Miquel,

On 5/11/20 11:18 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 6 May 2020
11:11:19 +0200:
   

FMC2 EBI support has been added. Common resources (registers base
and clock) are now shared between the 2 drivers. It means that the
common resources should now be found in the parent device when EBI
node is available.

Signed-off-by: Christophe Kerello 
---


[...]
   

+
+static bool stm32_fmc2_nfc_check_for_parent(struct platform_device *pdev)
+{
+   u32 i;
+   int nb_resources = 0;
+
+   /* Count the number of resources in reg property */
+   for (i = 0; i < pdev->num_resources; i++) {
+   struct resource *res = >resource[i];
+
+   if (resource_type(res) == IORESOURCE_MEM)
+   nb_resources++;
+   }
+
+   /* Each CS needs 3 resources defined (data, cmd and addr) */
+   if (nb_resources % 3)
+   return false;
+
+   return true;
+}


This function looks fragile. Why not just checking the compatible
string of the parent node?
   


Yes, it is another way to check that we have an EBI parent node.

In this implementation, I was checking the number of reg tuples.
In case we have 6, it means that the register base address is defined in the 
parent node (EBI node).
In case we have 7, it means that the register base address is defined in the 
current node (NFC node).


Yes, I understand what you are doing, but I kind of dislike the logic.
Relying on the number of reg tuples is something that can be done (I
used it myself one time), but I think this is more a hack that you do
when you have no other way to differentiate. I guess the proper way
would be to look at the parent's compatible. If it matches what you
expect, then you can store the dev->of_node->parent->dev somewhere in
your controller's structure and then use it to initialize the clock and
regmap. This way you don't have to move anything else in the probe path.



OK, I will check the compatible string of the parent device using 
of_device_is_compatible API in v5.
In case of the parent is found, I will add it in the structure of the 
controller (dev_parent).
I will rely on this field only to get the common resources (the register 
base address and the clock) in the NFC node or in the EBI node.


Regards,
Christophe Kerello.



Thanks,
Miquèl



Re: [PATCH v4 00/10] add STM32 FMC2 EBI controller driver

2020-05-11 Thread Christophe Kerello

Hi Miquel,

On 5/11/20 11:22 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 6 May 2020
11:11:09 +0200:


The FMC2 functional block makes the interface with: synchronous and
asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
peripherals) and NAND flash memories.
Its main purposes are:
   - to translate AXI transactions into the appropriate external device
 protocol
   - to meet the access time requirements of the external devices
All external devices share the addresses, data and control signals with the
controller. Each external device is accessed by means of a unique Chip
Select. The FMC2 performs only one access at a time to an external device.

Changes in v4:
  - bindings:
- fix filename: st,stm32-fmc2-ebi.yaml

Changes in v3:
  - NAND:
- rename labels used on errors
- add in the commit log the reason to increase FMC2_TIMEOUT_MS (patch 3)
- add Miquel reviewed-by tag (patches 2/4/5/9)
  - EBI:
- move in memory folder
- merge MFD and BUS drivers to avoid a MFD driver
  - bindings:
- pattern name has been modified
- vendor properties have been modified
  - s/_/-/
  - add unit suffix (-ns) on timing properties

Christophe Kerello (10):
   mtd: rawnand: stm32_fmc2: manage all errors cases at probe time
   mtd: rawnand: stm32_fmc2: remove useless inline comments
   mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts
   mtd: rawnand: stm32_fmc2: cleanup
   mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros
   dt-bindings: mtd: update STM32 FMC2 NAND controller documentation
   dt-bindings: memory-controller: add STM32 FMC2 EBI controller
 documentation
   memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver
   mtd: rawnand: stm32_fmc2: use regmap APIs
   mtd: rawnand: stm32_fmc2: get resources from parent node

  .../memory-controllers/st,stm32-fmc2-ebi.yaml  |  261 +
  .../bindings/mtd/st,stm32-fmc2-nand.yaml   |   19 +-
  drivers/memory/Kconfig |   10 +
  drivers/memory/Makefile|1 +
  drivers/memory/stm32-fmc2-ebi.c| 1206 
  drivers/mtd/nand/raw/Kconfig   |1 +
  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1176 ++-
  7 files changed, 2061 insertions(+), 613 deletions(-)
  create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
  create mode 100644 drivers/memory/stm32-fmc2-ebi.c



I'm fine with the preparation patches 1-5 but the other patches need
Rob's hack and probably more changes. If it's fine with you I can apply
these patches for the next merge window and let more time to work on
the last 5.



I am fine with your proposal.

Regards,
Christophe Kerello.


Thanks,
Miquèl



Re: [PATCH v4 10/10] mtd: rawnand: stm32_fmc2: get resources from parent node

2020-05-11 Thread Christophe Kerello

Hi Miquel,

On 5/11/20 11:18 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 6 May 2020
11:11:19 +0200:


FMC2 EBI support has been added. Common resources (registers base
and clock) are now shared between the 2 drivers. It means that the
common resources should now be found in the parent device when EBI
node is available.

Signed-off-by: Christophe Kerello 
---


[...]


+
+static bool stm32_fmc2_nfc_check_for_parent(struct platform_device *pdev)
+{
+   u32 i;
+   int nb_resources = 0;
+
+   /* Count the number of resources in reg property */
+   for (i = 0; i < pdev->num_resources; i++) {
+   struct resource *res = >resource[i];
+
+   if (resource_type(res) == IORESOURCE_MEM)
+   nb_resources++;
+   }
+
+   /* Each CS needs 3 resources defined (data, cmd and addr) */
+   if (nb_resources % 3)
+   return false;
+
+   return true;
+}


This function looks fragile. Why not just checking the compatible
string of the parent node?



Yes, it is another way to check that we have an EBI parent node.

In this implementation, I was checking the number of reg tuples.
In case we have 6, it means that the register base address is defined in 
the parent node (EBI node).
In case we have 7, it means that the register base address is defined in 
the current node (NFC node).



+
  static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
  {
struct device *dev = >dev;
@@ -1824,8 +1865,8 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
struct resource *res;
struct mtd_info *mtd;
struct nand_chip *chip;
-   void __iomem *mmio;
int chip_cs, mem_region, ret, irq;
+   int num_region = 1;
  
  	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);

if (!nfc)
@@ -1834,23 +1875,19 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
nfc->dev = dev;
nand_controller_init(>base);
nfc->base.ops = _fmc2_nfc_controller_ops;
+   nfc->has_parent = stm32_fmc2_nfc_check_for_parent(pdev);
+   if (nfc->has_parent)
+   num_region = 0;
  
  	ret = stm32_fmc2_nfc_parse_dt(nfc);

if (ret)
return ret;
  
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

-   mmio = devm_ioremap_resource(dev, res);
-   if (IS_ERR(mmio))
-   return PTR_ERR(mmio);
-
-   nfc->regmap = devm_regmap_init_mmio(dev, mmio, _fmc2_regmap_cfg);
-   if (IS_ERR(nfc->regmap))
-   return PTR_ERR(nfc->regmap);
-
-   nfc->io_phys_addr = res->start;
+   ret = stm32_fmc2_nfc_set_regmap_clk(pdev, nfc);
+   if (ret)
+   return ret;


Are you sure this driver sill works without the EBI block?

This change looks suspect.



Yes, the driver works fine with current bindings and with EBI bindings.
In case we have an EBI parent node, it means that the register base 
address and the clock are defined in the parent node.
Without any EBI parent node, it means that the register base address and 
the clock are defined in the NFC node.


The new function stm32_fmc2_nfc_set_regmap_clk is looking for these 2 
resources in the NFC node or in the parent node.

static int stm32_fmc2_nfc_set_regmap_clk(struct platform_device *pdev,
 struct stm32_fmc2_nfc *nfc)
{
struct device *dev = >dev;
struct resource res;
int ret;

if (nfc->has_parent)
dev = dev->parent;

ret = of_address_to_resource(dev->of_node, 0, );
if (ret)
return ret;

nfc->io_phys_addr = res.start;

nfc->regmap = device_node_to_regmap(dev->of_node);
if (IS_ERR(nfc->regmap))
return PTR_ERR(nfc->regmap);

nfc->clk = devm_clk_get(dev, NULL);
if (IS_ERR(nfc->clk))
    return PTR_ERR(nfc->clk);

return 0;
}

Regards,
Christophe Kerello.

  
-	for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE;

+   for (chip_cs = 0, mem_region = num_region; chip_cs < FMC2_MAX_CE;
 chip_cs++, mem_region += 3) {
if (!(nfc->cs_assigned & BIT(chip_cs)))
continue;
@@ -1888,10 +1925,6 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
  
  	init_completion(>complete);
  
-	nfc->clk = devm_clk_get(dev, NULL);

-   if (IS_ERR(nfc->clk))
-   return PTR_ERR(nfc->clk);
-


Same here


ret = clk_prepare_enable(nfc->clk);
if (ret) {
dev_err(dev, "can not enable the clock\n");




Re: [PATCH v3 00/10] add STM32 FMC2 EBI controller driver

2020-05-06 Thread Christophe Kerello

Hi,

Please do not spend time to review v3.
V4 has been pushed to fix an issue in YAML bindings.

Regards,
Christophe Kerello.

On 5/5/20 7:10 PM, Christophe Kerello wrote:

The FMC2 functional block makes the interface with: synchronous and
asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
peripherals) and NAND flash memories.
Its main purposes are:
   - to translate AXI transactions into the appropriate external device
 protocol
   - to meet the access time requirements of the external devices
All external devices share the addresses, data and control signals with the
controller. Each external device is accessed by means of a unique Chip
Select. The FMC2 performs only one access at a time to an external device.

Changes in v3:
  - NAND:
- rename labels used on errors
- add in the commit log the reason to increase FMC2_TIMEOUT_MS (patch 3)
- add Miquel reviewed-by tag (patches 2/4/5/9)
  - EBI:
- move in memory folder
- merge MFD and BUS drivers to avoid a MFD driver
  - bindings:
- pattern name has been modified
- vendor properties have been modified
  - s/_/-/
  - add unit suffix (-ns) on timing properties

Christophe Kerello (10):
   mtd: rawnand: stm32_fmc2: manage all errors cases at probe time
   mtd: rawnand: stm32_fmc2: remove useless inline comments
   mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts
   mtd: rawnand: stm32_fmc2: cleanup
   mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros
   dt-bindings: mtd: update STM32 FMC2 NAND controller documentation
   dt-bindings: memory-controller: add STM32 FMC2 EBI controller
 documentation
   memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver
   mtd: rawnand: stm32_fmc2: use regmap APIs
   mtd: rawnand: stm32_fmc2: get resources from parent node

  .../memory-controllers/st,stm32-fmc2-ebi.yaml  |  261 +
  .../bindings/mtd/st,stm32-fmc2-nand.yaml   |   19 +-
  drivers/memory/Kconfig |   10 +
  drivers/memory/Makefile|1 +
  drivers/memory/stm32-fmc2-ebi.c| 1206 
  drivers/mtd/nand/raw/Kconfig   |1 +
  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1176 ++-
  7 files changed, 2061 insertions(+), 613 deletions(-)
  create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
  create mode 100644 drivers/memory/stm32-fmc2-ebi.c



[PATCH v4 05/10] mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros

2020-05-06 Thread Christophe Kerello
This patch removes custom macros and uses FIELD_PREP and FIELD_GET macros.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 177 -
 1 file changed, 85 insertions(+), 92 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 0d108fb..236bb41 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -4,6 +4,7 @@
  * Author: Christophe Kerello 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -84,20 +85,16 @@
 /* Register: FMC2_PCR */
 #define FMC2_PCR_PWAITEN   BIT(1)
 #define FMC2_PCR_PBKEN BIT(2)
-#define FMC2_PCR_PWID_MASK GENMASK(5, 4)
-#define FMC2_PCR_PWID(x)   (((x) & 0x3) << 4)
+#define FMC2_PCR_PWID  GENMASK(5, 4)
 #define FMC2_PCR_PWID_BUSWIDTH_8   0
 #define FMC2_PCR_PWID_BUSWIDTH_16  1
 #define FMC2_PCR_ECCEN BIT(6)
 #define FMC2_PCR_ECCALGBIT(8)
-#define FMC2_PCR_TCLR_MASK GENMASK(12, 9)
-#define FMC2_PCR_TCLR(x)   (((x) & 0xf) << 9)
+#define FMC2_PCR_TCLR  GENMASK(12, 9)
 #define FMC2_PCR_TCLR_DEFAULT  0xf
-#define FMC2_PCR_TAR_MASK  GENMASK(16, 13)
-#define FMC2_PCR_TAR(x)(((x) & 0xf) << 13)
+#define FMC2_PCR_TAR   GENMASK(16, 13)
 #define FMC2_PCR_TAR_DEFAULT   0xf
-#define FMC2_PCR_ECCSS_MASKGENMASK(19, 17)
-#define FMC2_PCR_ECCSS(x)  (((x) & 0x7) << 17)
+#define FMC2_PCR_ECCSS GENMASK(19, 17)
 #define FMC2_PCR_ECCSS_512 1
 #define FMC2_PCR_ECCSS_20483
 #define FMC2_PCR_BCHECCBIT(24)
@@ -107,17 +104,17 @@
 #define FMC2_SR_NWRF   BIT(6)
 
 /* Register: FMC2_PMEM */
-#define FMC2_PMEM_MEMSET(x)(((x) & 0xff) << 0)
-#define FMC2_PMEM_MEMWAIT(x)   (((x) & 0xff) << 8)
-#define FMC2_PMEM_MEMHOLD(x)   (((x) & 0xff) << 16)
-#define FMC2_PMEM_MEMHIZ(x)(((x) & 0xff) << 24)
+#define FMC2_PMEM_MEMSET   GENMASK(7, 0)
+#define FMC2_PMEM_MEMWAIT  GENMASK(15, 8)
+#define FMC2_PMEM_MEMHOLD  GENMASK(23, 16)
+#define FMC2_PMEM_MEMHIZ   GENMASK(31, 24)
 #define FMC2_PMEM_DEFAULT  0x0a0a0a0a
 
 /* Register: FMC2_PATT */
-#define FMC2_PATT_ATTSET(x)(((x) & 0xff) << 0)
-#define FMC2_PATT_ATTWAIT(x)   (((x) & 0xff) << 8)
-#define FMC2_PATT_ATTHOLD(x)   (((x) & 0xff) << 16)
-#define FMC2_PATT_ATTHIZ(x)(((x) & 0xff) << 24)
+#define FMC2_PATT_ATTSET   GENMASK(7, 0)
+#define FMC2_PATT_ATTWAIT  GENMASK(15, 8)
+#define FMC2_PATT_ATTHOLD  GENMASK(23, 16)
+#define FMC2_PATT_ATTHIZ   GENMASK(31, 24)
 #define FMC2_PATT_DEFAULT  0x0a0a0a0a
 
 /* Register: FMC2_ISR */
@@ -132,9 +129,9 @@
 /* Register: FMC2_CSQCFGR1 */
 #define FMC2_CSQCFGR1_CMD2EN   BIT(1)
 #define FMC2_CSQCFGR1_DMADEN   BIT(2)
-#define FMC2_CSQCFGR1_ACYNBR(x)(((x) & 0x7) << 4)
-#define FMC2_CSQCFGR1_CMD1(x)  (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR1_CMD2(x)  (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR1_ACYNBR   GENMASK(6, 4)
+#define FMC2_CSQCFGR1_CMD1 GENMASK(15, 8)
+#define FMC2_CSQCFGR1_CMD2 GENMASK(23, 16)
 #define FMC2_CSQCFGR1_CMD1TBIT(24)
 #define FMC2_CSQCFGR1_CMD2TBIT(25)
 
@@ -142,13 +139,13 @@
 #define FMC2_CSQCFGR2_SQSDTEN  BIT(0)
 #define FMC2_CSQCFGR2_RCMD2EN  BIT(1)
 #define FMC2_CSQCFGR2_DMASEN   BIT(2)
-#define FMC2_CSQCFGR2_RCMD1(x) (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR2_RCMD2(x) (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR2_RCMD1GENMASK(15, 8)
+#define FMC2_CSQCFGR2_RCMD2GENMASK(23, 16)
 #define FMC2_CSQCFGR2_RCMD1T   BIT(24)
 #define FMC2_CSQCFGR2_RCMD2T   BIT(25)
 
 /* Register: FMC2_CSQCFGR3 */
-#define FMC2_CSQCFGR3_SNBR(x)  (((x) & 0x1f) << 8)
+#define FMC2_CSQCFGR3_SNBR GENMASK(13, 8)
 #define FMC2_CSQCFGR3_AC1T BIT(16)
 #define FMC2_CSQCFGR3_AC2T BIT(17)
 #define FMC2_CSQCFGR3_AC3T BIT(18)
@@ -159,15 +156,15 @@
 #define FMC2_CSQCFGR3_RAC2TBIT(23)
 
 /* Register: FMC2_CSQCAR1 */
-#define FMC2_CSQCAR1_ADDC1(x)  (((x) & 0xff) << 0)
-#define FMC2_CSQCAR1_ADDC2(x)  (((x) & 0xff) << 8)
-#define FMC2_CSQCAR1_ADDC3(x)  (((x) & 0xff) << 16)
-#define FMC2_CSQCAR1_ADDC4(x)  (((x) & 0xff) <<

[PATCH v4 04/10] mtd: rawnand: stm32_fmc2: cleanup

2020-05-06 Thread Christophe Kerello
This patch renames functions and local variables.
This cleanup is done to get all functions starting by stm32_fmc2_nfc
in the FMC2 raw NAND driver when all functions will start by
stm32_fmc2_ebi in the FMC2 EBI driver.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - fix s/conf/cf/, s/nfc/NFC/
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 810 -
 1 file changed, 403 insertions(+), 407 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 5778a95..0d108fb 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -280,12 +280,12 @@ static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct 
nand_controller *base)
return container_of(base, struct stm32_fmc2_nfc, base);
 }
 
-static void stm32_fmc2_timings_init(struct nand_chip *chip)
+static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *timings = >timings;
-   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
u32 pmem, patt;
 
/* Set tclr/tar timings */
@@ -306,15 +306,15 @@ static void stm32_fmc2_timings_init(struct nand_chip 
*chip)
patt |= FMC2_PATT_ATTHOLD(timings->thold_att);
patt |= FMC2_PATT_ATTHIZ(timings->thiz);
 
-   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
-   writel_relaxed(pmem, fmc2->io_base + FMC2_PMEM);
-   writel_relaxed(patt, fmc2->io_base + FMC2_PATT);
+   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
+   writel_relaxed(pmem, nfc->io_base + FMC2_PMEM);
+   writel_relaxed(patt, nfc->io_base + FMC2_PATT);
 }
 
-static void stm32_fmc2_setup(struct nand_chip *chip)
+static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
-   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
+   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
 
/* Configure ECC algorithm (default configuration is Hamming) */
pcr &= ~FMC2_PCR_ECCALG;
@@ -335,174 +335,174 @@ static void stm32_fmc2_setup(struct nand_chip *chip)
pcr &= ~FMC2_PCR_ECCSS_MASK;
pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
 
-   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
 }
 
-static int stm32_fmc2_select_chip(struct nand_chip *chip, int chipnr)
+static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct dma_slave_config dma_cfg;
int ret;
 
-   if (nand->cs_used[chipnr] == fmc2->cs_sel)
+   if (nand->cs_used[chipnr] == nfc->cs_sel)
return 0;
 
-   fmc2->cs_sel = nand->cs_used[chipnr];
-   stm32_fmc2_setup(chip);
-   stm32_fmc2_timings_init(chip);
+   nfc->cs_sel = nand->cs_used[chipnr];
+   stm32_fmc2_nfc_setup(chip);
+   stm32_fmc2_nfc_timings_init(chip);
 
-   if (fmc2->dma_tx_ch && fmc2->dma_rx_ch) {
+   if (nfc->dma_tx_ch && nfc->dma_rx_ch) {
memset(_cfg, 0, sizeof(dma_cfg));
-   dma_cfg.src_addr = fmc2->data_phys_addr[fmc2->cs_sel];
-   dma_cfg.dst_addr = fmc2->data_phys_addr[fmc2->cs_sel];
+   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;
 
-   ret = dmaengine_slave_config(fmc2->dma_tx_ch, _cfg);
+   ret = dmaengine_slave_config(nfc->dma_tx_ch, _cfg);
if (ret) {
-   dev_err(fmc2->dev, "tx DMA engine slave config 
failed\n");
+   dev_err(nfc->dev, "tx DMA engine slave config 
failed\n");
return ret;
}
 
-   ret = dmaengine_slave_config(fmc2->dma_rx_ch, _cfg);
+   ret = dmaengine_slave_config(nfc->dma_rx_ch, _cfg);
if (ret) {
-   dev_err(fmc2->dev, "rx DMA engine slave config 
failed\n")

[PATCH v4 09/10] mtd: rawnand: stm32_fmc2: use regmap APIs

2020-05-06 Thread Christophe Kerello
This patch uses regmap APIs to access all FMC2 registers.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/Kconfig   |   2 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 268 +++--
 2 files changed, 127 insertions(+), 143 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index a80a46b..12b715a 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -419,6 +419,8 @@ config MTD_NAND_TEGRA
 config MTD_NAND_STM32_FMC2
tristate "Support for NAND controller on STM32MP SoCs"
depends on MACH_STM32MP157 || COMPILE_TEST
+   select REGMAP
+   select REGMAP_MMIO
help
  Enables support for NAND Flash chips on SoCs containing the FMC2
  NAND controller. This controller is found on STM32MP SoCs.
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 236bb41..76571da 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* Bad block marker length */
@@ -203,6 +204,16 @@
 #define FMC2_BCHDSR4_EBP7  GENMASK(12, 0)
 #define FMC2_BCHDSR4_EBP8  GENMASK(28, 16)
 
+/* Regmap registers configuration */
+#define FMC2_MAX_REGISTER  0x3fc
+
+static const struct regmap_config stm32_fmc2_regmap_cfg = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = sizeof(u32),
+   .max_register = FMC2_MAX_REGISTER,
+};
+
 enum stm32_fmc2_ecc {
FMC2_ECC_HAM = 1,
FMC2_ECC_BCH4 = 4,
@@ -242,7 +253,7 @@ struct stm32_fmc2_nfc {
struct nand_controller base;
struct stm32_fmc2_nand nand;
struct device *dev;
-   void __iomem *io_base;
+   struct regmap *regmap;
void __iomem *data_base[FMC2_MAX_CE];
void __iomem *cmd_base[FMC2_MAX_CE];
void __iomem *addr_base[FMC2_MAX_CE];
@@ -277,40 +288,37 @@ static void stm32_fmc2_nfc_timings_init(struct nand_chip 
*chip)
struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *timings = >timings;
-   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
u32 pmem, patt;
 
/* Set tclr/tar timings */
-   pcr &= ~FMC2_PCR_TCLR;
-   pcr |= FIELD_PREP(FMC2_PCR_TCLR, timings->tclr);
-   pcr &= ~FMC2_PCR_TAR;
-   pcr |= FIELD_PREP(FMC2_PCR_TAR, timings->tar);
+   regmap_update_bits(nfc->regmap, FMC2_PCR,
+  FMC2_PCR_TCLR | FMC2_PCR_TAR,
+  FIELD_PREP(FMC2_PCR_TCLR, timings->tclr) |
+  FIELD_PREP(FMC2_PCR_TAR, timings->tar));
 
/* Set tset/twait/thold/thiz timings in common bank */
pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem);
pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait);
pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem);
pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz);
+   regmap_write(nfc->regmap, FMC2_PMEM, pmem);
 
/* Set tset/twait/thold/thiz timings in attribut bank */
patt = FIELD_PREP(FMC2_PATT_ATTSET, timings->tset_att);
patt |= FIELD_PREP(FMC2_PATT_ATTWAIT, timings->twait);
patt |= FIELD_PREP(FMC2_PATT_ATTHOLD, timings->thold_att);
patt |= FIELD_PREP(FMC2_PATT_ATTHIZ, timings->thiz);
-
-   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
-   writel_relaxed(pmem, nfc->io_base + FMC2_PMEM);
-   writel_relaxed(patt, nfc->io_base + FMC2_PATT);
+   regmap_write(nfc->regmap, FMC2_PATT, patt);
 }
 
 static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
 {
struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
-   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
+   u32 pcr = 0, pcr_mask;
 
/* Configure ECC algorithm (default configuration is Hamming) */
-   pcr &= ~FMC2_PCR_ECCALG;
-   pcr &= ~FMC2_PCR_BCHECC;
+   pcr_mask = FMC2_PCR_ECCALG;
+   pcr_mask |= FMC2_PCR_BCHECC;
if (chip->ecc.strength == FMC2_ECC_BCH8) {
pcr |= FMC2_PCR_ECCALG;
pcr |= FMC2_PCR_BCHECC;
@@ -319,15 +327,15 @@ static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
}
 
/* Set buswidth */
-   pcr &= ~FMC2_PCR_PWID;
+   pcr_mask |= FMC2_PCR_PWID;
if (chip->options & NAND_BUSWIDTH_16)
pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16);
 
/* Set ECC sector size */
-   pcr &= ~FMC2_PCR_ECCSS;
+   pcr_mask |= FMC2_PCR_ECCSS;
pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_512);
 
-   writel_relaxed(

[PATCH v4 10/10] mtd: rawnand: stm32_fmc2: get resources from parent node

2020-05-06 Thread Christophe Kerello
FMC2 EBI support has been added. Common resources (registers base
and clock) are now shared between the 2 drivers. It means that the
common resources should now be found in the parent device when EBI
node is available.

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/Kconfig   |  3 +-
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 89 +++---
 2 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 12b715a..28dccd5 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -419,8 +419,7 @@ config MTD_NAND_TEGRA
 config MTD_NAND_STM32_FMC2
tristate "Support for NAND controller on STM32MP SoCs"
depends on MACH_STM32MP157 || COMPILE_TEST
-   select REGMAP
-   select REGMAP_MMIO
+   select MFD_SYSCON
help
  Enables support for NAND Flash chips on SoCs containing the FMC2
  NAND controller. This controller is found on STM32MP SoCs.
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 76571da..dfab6b1 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -11,8 +11,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -204,16 +206,6 @@
 #define FMC2_BCHDSR4_EBP7  GENMASK(12, 0)
 #define FMC2_BCHDSR4_EBP8  GENMASK(28, 16)
 
-/* Regmap registers configuration */
-#define FMC2_MAX_REGISTER  0x3fc
-
-static const struct regmap_config stm32_fmc2_regmap_cfg = {
-   .reg_bits = 32,
-   .val_bits = 32,
-   .reg_stride = sizeof(u32),
-   .max_register = FMC2_MAX_REGISTER,
-};
-
 enum stm32_fmc2_ecc {
FMC2_ECC_HAM = 1,
FMC2_ECC_BCH4 = 4,
@@ -261,6 +253,7 @@ struct stm32_fmc2_nfc {
phys_addr_t data_phys_addr[FMC2_MAX_CE];
struct clk *clk;
u8 irq_state;
+   bool has_parent;
 
struct dma_chan *dma_tx_ch;
struct dma_chan *dma_rx_ch;
@@ -1384,8 +1377,9 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc 
*nfc)
pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT);
 
/* Enable FMC2 controller */
-   regmap_update_bits(nfc->regmap, FMC2_BCR1,
-  FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN);
+   if (!nfc->has_parent)
+   regmap_update_bits(nfc->regmap, FMC2_BCR1,
+  FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN);
 
regmap_write(nfc->regmap, FMC2_PCR, pcr);
regmap_write(nfc->regmap, FMC2_PMEM, FMC2_PMEM_DEFAULT);
@@ -1815,6 +1809,53 @@ static int stm32_fmc2_nfc_parse_dt(struct stm32_fmc2_nfc 
*nfc)
return ret;
 }
 
+static int stm32_fmc2_nfc_set_regmap_clk(struct platform_device *pdev,
+struct stm32_fmc2_nfc *nfc)
+{
+   struct device *dev = >dev;
+   struct resource res;
+   int ret;
+
+   if (nfc->has_parent)
+   dev = dev->parent;
+
+   ret = of_address_to_resource(dev->of_node, 0, );
+   if (ret)
+   return ret;
+
+   nfc->io_phys_addr = res.start;
+
+   nfc->regmap = device_node_to_regmap(dev->of_node);
+   if (IS_ERR(nfc->regmap))
+   return PTR_ERR(nfc->regmap);
+
+   nfc->clk = devm_clk_get(dev, NULL);
+   if (IS_ERR(nfc->clk))
+   return PTR_ERR(nfc->clk);
+
+   return 0;
+}
+
+static bool stm32_fmc2_nfc_check_for_parent(struct platform_device *pdev)
+{
+   u32 i;
+   int nb_resources = 0;
+
+   /* Count the number of resources in reg property */
+   for (i = 0; i < pdev->num_resources; i++) {
+   struct resource *res = >resource[i];
+
+   if (resource_type(res) == IORESOURCE_MEM)
+   nb_resources++;
+   }
+
+   /* Each CS needs 3 resources defined (data, cmd and addr) */
+   if (nb_resources % 3)
+   return false;
+
+   return true;
+}
+
 static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -1824,8 +1865,8 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
struct resource *res;
struct mtd_info *mtd;
struct nand_chip *chip;
-   void __iomem *mmio;
int chip_cs, mem_region, ret, irq;
+   int num_region = 1;
 
nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
if (!nfc)
@@ -1834,23 +1875,19 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
nfc->dev = dev;
nand_controller_init(>base);
nfc->base.ops = _fmc2_nfc_controller_ops;
+   nfc->has_parent = stm32_fmc2_nfc_check_for_parent(pdev);
+   if (nfc->has_parent)
+   num_region = 0;
 
ret = stm32_fmc2_nfc_parse_dt(nfc);
if (ret

[PATCH v4 01/10] mtd: rawnand: stm32_fmc2: manage all errors cases at probe time

2020-05-06 Thread Christophe Kerello
This patch defers its probe when the expected reset control is not
yet ready. This patch also handles properly all errors cases at probe
time.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - rename labels used on errors

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b6d45cd..50a6377 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1967,7 +1967,11 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
}
 
rstc = devm_reset_control_get(dev, NULL);
-   if (!IS_ERR(rstc)) {
+   if (IS_ERR(rstc)) {
+   ret = PTR_ERR(rstc);
+   if (ret == -EPROBE_DEFER)
+   goto err_clk_disable;
+   } else {
reset_control_assert(rstc);
reset_control_deassert(rstc);
}
@@ -1975,7 +1979,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
/* DMA setup */
ret = stm32_fmc2_dma_setup(fmc2);
if (ret)
-   return ret;
+   goto err_release_dma;
 
/* FMC2 init routine */
stm32_fmc2_init(fmc2);
@@ -1997,20 +2001,20 @@ static int stm32_fmc2_probe(struct platform_device 
*pdev)
/* Scan to find existence of the device */
ret = nand_scan(chip, nand->ncs);
if (ret)
-   goto err_scan;
+   goto err_release_dma;
 
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
-   goto err_device_register;
+   goto err_nand_cleanup;
 
platform_set_drvdata(pdev, fmc2);
 
return 0;
 
-err_device_register:
+err_nand_cleanup:
nand_cleanup(chip);
 
-err_scan:
+err_release_dma:
if (fmc2->dma_ecc_ch)
dma_release_channel(fmc2->dma_ecc_ch);
if (fmc2->dma_tx_ch)
@@ -2021,6 +2025,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
sg_free_table(>dma_data_sg);
sg_free_table(>dma_ecc_sg);
 
+err_clk_disable:
clk_disable_unprepare(fmc2->clk);
 
return ret;
-- 
1.9.1



[PATCH v4 02/10] mtd: rawnand: stm32_fmc2: remove useless inline comments

2020-05-06 Thread Christophe Kerello
Remove inline comments that are useless since function label are
self explanatory.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - add Miquel reviewed-by tag

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

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 50a6377..3377fbe 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -281,7 +281,6 @@ static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct 
nand_controller *base)
return container_of(base, struct stm32_fmc2_nfc, base);
 }
 
-/* Timings configuration */
 static void stm32_fmc2_timings_init(struct nand_chip *chip)
 {
struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
@@ -313,7 +312,6 @@ static void stm32_fmc2_timings_init(struct nand_chip *chip)
writel_relaxed(patt, fmc2->io_base + FMC2_PATT);
 }
 
-/* Controller configuration */
 static void stm32_fmc2_setup(struct nand_chip *chip)
 {
struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
@@ -341,7 +339,6 @@ static void stm32_fmc2_setup(struct nand_chip *chip)
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
 }
 
-/* Select target */
 static int stm32_fmc2_select_chip(struct nand_chip *chip, int chipnr)
 {
struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
@@ -353,11 +350,7 @@ static int stm32_fmc2_select_chip(struct nand_chip *chip, 
int chipnr)
return 0;
 
fmc2->cs_sel = nand->cs_used[chipnr];
-
-   /* FMC2 setup routine */
stm32_fmc2_setup(chip);
-
-   /* Apply timings */
stm32_fmc2_timings_init(chip);
 
if (fmc2->dma_tx_ch && fmc2->dma_rx_ch) {
@@ -407,7 +400,6 @@ static int stm32_fmc2_select_chip(struct nand_chip *chip, 
int chipnr)
return 0;
 }
 
-/* Set bus width to 16-bit or 8-bit */
 static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set)
 {
u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
@@ -418,7 +410,6 @@ static void stm32_fmc2_set_buswidth_16(struct 
stm32_fmc2_nfc *fmc2, bool set)
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
 }
 
-/* Enable/disable ECC */
 static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
 {
u32 pcr = readl(fmc2->io_base + FMC2_PCR);
@@ -429,7 +420,6 @@ static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, 
bool enable)
writel(pcr, fmc2->io_base + FMC2_PCR);
 }
 
-/* Enable irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_enable_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER);
@@ -441,7 +431,6 @@ static inline void stm32_fmc2_enable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
 }
 
-/* Disable irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_disable_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER);
@@ -453,13 +442,11 @@ static inline void stm32_fmc2_disable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
fmc2->irq_state = FMC2_IRQ_UNKNOWN;
 }
 
-/* Clear irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_clear_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, fmc2->io_base + FMC2_CSQICR);
 }
 
-/* Enable irq sources in case of bch is used */
 static inline void stm32_fmc2_enable_bch_irq(struct stm32_fmc2_nfc *fmc2,
 int mode)
 {
@@ -475,7 +462,6 @@ static inline void stm32_fmc2_enable_bch_irq(struct 
stm32_fmc2_nfc *fmc2,
writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
 }
 
-/* Disable irq sources in case of bch is used */
 static inline void stm32_fmc2_disable_bch_irq(struct stm32_fmc2_nfc *fmc2)
 {
u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
@@ -488,7 +474,6 @@ static inline void stm32_fmc2_disable_bch_irq(struct 
stm32_fmc2_nfc *fmc2)
fmc2->irq_state = FMC2_IRQ_UNKNOWN;
 }
 
-/* Clear irq sources in case of bch is used */
 static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
 {
writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
@@ -549,10 +534,7 @@ static int stm32_fmc2_ham_calculate(struct nand_chip 
*chip, const u8 *data,
}
 
heccr = readl_relaxed(fmc2->io_base + FMC2_HECCR);
-
stm32_fmc2_ham_set_ecc(heccr, ecc);
-
-   /* Disable ECC */
stm32_fmc2_set_ecc(fmc2, false);
 
return 0;
@@ -654,13 +636,11 @@ static int stm32_fmc2_bch_calculate(struct nand_chip 
*chip, const u8 *data,
ecc[12] = bchpbr;
}
 
-   /* Disable ECC */
stm32_fmc2_set_ecc(fmc2, false);
 
return 0;
 }
 

[PATCH v4 03/10] mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts

2020-05-06 Thread Christophe Kerello
This patch removes the constant FMC2_TIMEOUT_US.
FMC2_TIMEOUT_MS will be used each time that we need to wait (except
when the timeout value is set by the framework).

It was seen, during stress tests with the sequencer in an overloaded
system, that we could be close to 1 second, even if we never met this
value. To be safe, FMC2_TIMEOUT_MS is set to 5 seconds.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - add in the commit log the reason to increase FMC2_TIMEOUT_MS

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

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 3377fbe..5778a95 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -37,8 +37,7 @@
 /* Max ECC buffer length */
 #define FMC2_MAX_ECC_BUF_LEN   (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
 
-#define FMC2_TIMEOUT_US1000
-#define FMC2_TIMEOUT_MS1000
+#define FMC2_TIMEOUT_MS5000
 
 /* Timings */
 #define FMC2_THIZ  1
@@ -526,8 +525,8 @@ static int stm32_fmc2_ham_calculate(struct nand_chip *chip, 
const u8 *data,
int ret;
 
ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
-sr, sr & FMC2_SR_NWRF, 10,
-FMC2_TIMEOUT_MS);
+sr, sr & FMC2_SR_NWRF, 1,
+1000 * FMC2_TIMEOUT_MS);
if (ret) {
dev_err(fmc2->dev, "ham timeout\n");
return ret;
@@ -1315,7 +1314,7 @@ static int stm32_fmc2_waitrdy(struct nand_chip *chip, 
unsigned long timeout_ms)
/* Check if there is no pending requests to the NAND flash */
if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr,
  sr & FMC2_SR_NWRF, 1,
- FMC2_TIMEOUT_US))
+ 1000 * FMC2_TIMEOUT_MS))
dev_warn(fmc2->dev, "Waitrdy timeout\n");
 
/* Wait tWB before R/B# signal is low */
-- 
1.9.1



[PATCH v4 06/10] dt-bindings: mtd: update STM32 FMC2 NAND controller documentation

2020-05-06 Thread Christophe Kerello
These bindings can be used on SOCs where the FMC2 NAND controller is
in standalone. In case that the FMC2 embeds 2 controllers (an external
bus controller and a raw NAND controller), the register base and the
clock will be defined in the parent node. It is the reason why the
register base address and the clock are now optional.

Signed-off-by: Christophe Kerello 
---
 .../devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml   | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml 
b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
index b059267..68fac1a 100644
--- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
@@ -18,13 +18,15 @@ properties:
 
   reg:
 items:
-  - description: Registers
+  - description: Registers (optional)
   - 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
+minItems: 6
+maxItems: 7
 
   interrupts:
 maxItems: 1
@@ -61,7 +63,6 @@ required:
   - compatible
   - reg
   - interrupts
-  - clocks
 
 examples:
   - |
@@ -77,13 +78,13 @@ examples:
 <0x8100 0x1000>,
 <0x8901 0x1000>,
 <0x8902 0x1000>;
-interrupts = ;
-dmas = < 20 0x10 0x12000a02 0x0 0x0>,
-   < 20 0x10 0x12000a08 0x0 0x0>,
-   < 21 0x10 0x12000a0a 0x0 0x0>;
-dma-names = "tx", "rx", "ecc";
-clocks = < FMC_K>;
-resets = < FMC_R>;
+  interrupts = ;
+  dmas = < 20 0x2 0x12000a02 0x0 0x0>,
+ < 20 0x2 0x12000a08 0x0 0x0>,
+ < 21 0x2 0x12000a0a 0x0 0x0>;
+  dma-names = "tx", "rx", "ecc";
+  clocks = < FMC_K>;
+  resets = < FMC_R>;
   #address-cells = <1>;
   #size-cells = <0>;
 
-- 
1.9.1



[PATCH v4 00/10] add STM32 FMC2 EBI controller driver

2020-05-06 Thread Christophe Kerello
The FMC2 functional block makes the interface with: synchronous and
asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
peripherals) and NAND flash memories.
Its main purposes are:
  - to translate AXI transactions into the appropriate external device
protocol
  - to meet the access time requirements of the external devices
All external devices share the addresses, data and control signals with the
controller. Each external device is accessed by means of a unique Chip
Select. The FMC2 performs only one access at a time to an external device.

Changes in v4:
 - bindings:
   - fix filename: st,stm32-fmc2-ebi.yaml

Changes in v3:
 - NAND:
   - rename labels used on errors
   - add in the commit log the reason to increase FMC2_TIMEOUT_MS (patch 3)
   - add Miquel reviewed-by tag (patches 2/4/5/9)
 - EBI:
   - move in memory folder
   - merge MFD and BUS drivers to avoid a MFD driver
 - bindings:
   - pattern name has been modified
   - vendor properties have been modified
 - s/_/-/
 - add unit suffix (-ns) on timing properties

Christophe Kerello (10):
  mtd: rawnand: stm32_fmc2: manage all errors cases at probe time
  mtd: rawnand: stm32_fmc2: remove useless inline comments
  mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts
  mtd: rawnand: stm32_fmc2: cleanup
  mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros
  dt-bindings: mtd: update STM32 FMC2 NAND controller documentation
  dt-bindings: memory-controller: add STM32 FMC2 EBI controller
documentation
  memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver
  mtd: rawnand: stm32_fmc2: use regmap APIs
  mtd: rawnand: stm32_fmc2: get resources from parent node

 .../memory-controllers/st,stm32-fmc2-ebi.yaml  |  261 +
 .../bindings/mtd/st,stm32-fmc2-nand.yaml   |   19 +-
 drivers/memory/Kconfig |   10 +
 drivers/memory/Makefile|1 +
 drivers/memory/stm32-fmc2-ebi.c| 1206 
 drivers/mtd/nand/raw/Kconfig   |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1176 ++-
 7 files changed, 2061 insertions(+), 613 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
 create mode 100644 drivers/memory/stm32-fmc2-ebi.c

-- 
1.9.1



[PATCH v4 07/10] dt-bindings: memory-controller: add STM32 FMC2 EBI controller documentation

2020-05-06 Thread Christophe Kerello
This patch adds the documentation of the device tree bindings for the STM32
FMC2 EBI controller.

Signed-off-by: Christophe Kerello 
---
Changes in v4:
 - fix filename: st,stm32-fmc2-ebi.yaml

Changes in v3:
 - pattern name has been modified
 - vendor properties have been modified
   - s/_/-/
   - add unit suffix (-ns) on timing properties

 .../memory-controllers/st,stm32-fmc2-ebi.yaml  | 261 +
 1 file changed, 261 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
new file mode 100644
index 000..bf130c3
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
@@ -0,0 +1,261 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2-ebi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings
+
+description: |
+  The FMC2 functional block makes the interface with: synchronous and
+  asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
+  peripherals) and NAND flash memories.
+  Its main purposes are:
+- to translate AXI transactions into the appropriate external device
+  protocol
+- to meet the access time requirements of the external devices
+  All external devices share the addresses, data and control signals with the
+  controller. Each external device is accessed by means of a unique Chip
+  Select. The FMC2 performs only one access at a time to an external device.
+
+maintainers:
+  - Christophe Kerello 
+
+properties:
+  compatible:
+const: st,stm32mp1-fmc2-ebi
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  resets:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 1
+
+  ranges:
+description: |
+  Reflects the memory layout with four integer values per bank. Format:
+   0  
+
+patternProperties:
+  "^.*@[0-4],[a-f0-9]+$":
+type: object
+
+properties:
+  reg:
+description: Bank number, base address and size of the device.
+
+  st,fmc2-ebi-cs-transaction-type:
+description: |
+ Select one of the transactions type supported
+   0: Asynchronous mode 1 SRAM/FRAM.
+   1: Asynchronous mode 1 PSRAM.
+   2: Asynchronous mode A SRAM/FRAM.
+   3: Asynchronous mode A PSRAM.
+   4: Asynchronous mode 2 NOR.
+   5: Asynchronous mode B NOR.
+   6: Asynchronous mode C NOR.
+   7: Asynchronous mode D NOR.
+   8: Synchronous read synchronous write PSRAM.
+   9: Synchronous read asynchronous write PSRAM.
+   10: Synchronous read synchronous write NOR.
+   11: Synchronous read asynchronous write NOR.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 11
+
+  st,fmc2-ebi-cs-cclk-enable:
+description: Continuous clock enable (first bank must be configured
+ in synchronous mode). The FMC_CLK is generated 
continuously
+ during asynchronous and synchronous access. By default, 
the
+ FMC_CLK is only generated during synchronous access.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-mux-enable:
+description: Address/Data multiplexed on databus (valid only with
+ NOR and PSRAM transactions type). By default, Address/Data
+ are not multiplexed.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-buswidth:
+description: Data bus width
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [ 8, 16 ]
+default: 16
+
+  st,fmc2-ebi-cs-waitpol-high:
+description: Wait signal polarity (NWAIT signal active high).
+ By default, NWAIT is active low.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-waitcfg-enable:
+description: The NWAIT signal indicates wheither the data from the
+ device are valid or if a wait state must be inserted when
+ accessing the device in synchronous mode. By default, the
+ NWAIT signal is active one data cycle before wait state.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-wait-enable:
+description: The NWAIT signal is enabled (its level is taken into
+ account after the programmed latency period to insert wai

[PATCH v4 08/10] memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver

2020-05-06 Thread Christophe Kerello
The driver adds the support for the STMicroelectronics FMC2 EBI controller
found on STM32MP SOCs.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - Move in memory folder
 - Merge MFD and BUS drivers to avoid a MFD driver

 drivers/memory/Kconfig  |   10 +
 drivers/memory/Makefile |1 +
 drivers/memory/stm32-fmc2-ebi.c | 1206 +++
 3 files changed, 1217 insertions(+)
 create mode 100644 drivers/memory/stm32-fmc2-ebi.c

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 9bddca2..c651aaf 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -163,6 +163,16 @@ config PL353_SMC
  This driver is for the ARM PL351/PL353 Static Memory
  Controller(SMC) module.
 
+config STM32_FMC2_EBI
+   tristate "Support for FMC2 External Bus Interface on STM32MP SoCs"
+   depends on MACH_STM32MP157 || COMPILE_TEST
+   select MFD_SYSCON
+   help
+ Select this option to enable the STM32 FMC2 External Bus Interface
+ controller. This driver configures the transactions with external
+ devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on
+ SOCs containing the FMC2 External Bus Interface.
+
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
 
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 27b4934..c7d36db 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
 obj-$(CONFIG_MTK_SMI)  += mtk-smi.o
 obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
 obj-$(CONFIG_PL353_SMC)+= pl353-smc.o
+obj-$(CONFIG_STM32_FMC2_EBI)   += stm32-fmc2-ebi.o
 
 obj-$(CONFIG_SAMSUNG_MC)   += samsung/
 obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c
new file mode 100644
index 000..4d5758c4
--- /dev/null
+++ b/drivers/memory/stm32-fmc2-ebi.c
@@ -0,0 +1,1206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2020
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_BTR1  0x4
+#define FMC2_BCR(x)((x) * 0x8 + FMC2_BCR1)
+#define FMC2_BTR(x)((x) * 0x8 + FMC2_BTR1)
+#define FMC2_PCSCNTR   0x20
+#define FMC2_BWTR1 0x104
+#define FMC2_BWTR(x)   ((x) * 0x8 + FMC2_BWTR1)
+
+/* Register: FMC2_BCR1 */
+#define FMC2_BCR1_CCLKEN   BIT(20)
+#define FMC2_BCR1_FMC2EN   BIT(31)
+
+/* Register: FMC2_BCRx */
+#define FMC2_BCR_MBKEN BIT(0)
+#define FMC2_BCR_MUXEN BIT(1)
+#define FMC2_BCR_MTYP  GENMASK(3, 2)
+#define FMC2_BCR_MWID  GENMASK(5, 4)
+#define FMC2_BCR_FACCENBIT(6)
+#define FMC2_BCR_BURSTEN   BIT(8)
+#define FMC2_BCR_WAITPOL   BIT(9)
+#define FMC2_BCR_WAITCFG   BIT(11)
+#define FMC2_BCR_WREN  BIT(12)
+#define FMC2_BCR_WAITENBIT(13)
+#define FMC2_BCR_EXTMODBIT(14)
+#define FMC2_BCR_ASYNCWAIT BIT(15)
+#define FMC2_BCR_CPSIZEGENMASK(18, 16)
+#define FMC2_BCR_CBURSTRW  BIT(19)
+#define FMC2_BCR_NBLSETGENMASK(23, 22)
+
+/* Register: FMC2_BTRx/FMC2_BWTRx */
+#define FMC2_BXTR_ADDSET   GENMASK(3, 0)
+#define FMC2_BXTR_ADDHLD   GENMASK(7, 4)
+#define FMC2_BXTR_DATAST   GENMASK(15, 8)
+#define FMC2_BXTR_BUSTURN  GENMASK(19, 16)
+#define FMC2_BTR_CLKDIVGENMASK(23, 20)
+#define FMC2_BTR_DATLATGENMASK(27, 24)
+#define FMC2_BXTR_ACCMOD   GENMASK(29, 28)
+#define FMC2_BXTR_DATAHLD  GENMASK(31, 30)
+
+/* Register: FMC2_PCSCNTR */
+#define FMC2_PCSCNTR_CSCOUNT   GENMASK(15, 0)
+#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
+
+#define FMC2_MAX_EBI_CE4
+#define FMC2_MAX_BANKS 5
+
+#define FMC2_BCR_CPSIZE_0  0x0
+#define FMC2_BCR_CPSIZE_1280x1
+#define FMC2_BCR_CPSIZE_2560x2
+#define FMC2_BCR_CPSIZE_5120x3
+#define FMC2_BCR_CPSIZE_1024   0x4
+
+#define FMC2_BCR_MWID_80x0
+#define FMC2_BCR_MWID_16   0x1
+
+#define FMC2_BCR_MTYP_SRAM 0x0
+#define FMC2_BCR_MTYP_PSRAM0x1
+#define FMC2_BCR_MTYP_NOR  0x2
+
+#define FMC2_BXTR_EXTMOD_A 0x0
+#define FMC2_BXTR_EXTMOD_B 0x1
+#define FMC2_BXTR_EXTMOD_C 0x2
+#define FMC2_BXTR_EXTMOD_D 0x3
+
+#define FMC2_BCR_NBLSET_MAX0x3

Re: [PATCH v3 07/10] dt-bindings: memory-controller: add STM32 FMC2 EBI controller documentation

2020-05-06 Thread Christophe Kerello




On 5/5/20 7:11 PM, Christophe Kerello wrote:

This patch adds the documentation of the device tree bindings for the STM32
FMC2 EBI controller.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
  - pattern name has been modified
  - vendor properties have been modified
- s/_/-/
- add unit suffix (-ns) on timing properties

  .../memory-controllers/st,stm32-fmc2-ebi.yaml  | 261 +
  1 file changed, 261 insertions(+)
  create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
new file mode 100644
index 000..3ec57d2
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
@@ -0,0 +1,261 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2.yaml#


Hi,

There is a mistake on the filename. It should be st,stm32-fmc2-ebi.yaml.
It will be solved in v4.

Regards,
Christophe Kerello.


+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings
+
+description: |
+  The FMC2 functional block makes the interface with: synchronous and
+  asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
+  peripherals) and NAND flash memories.
+  Its main purposes are:
+- to translate AXI transactions into the appropriate external device
+  protocol
+- to meet the access time requirements of the external devices
+  All external devices share the addresses, data and control signals with the
+  controller. Each external device is accessed by means of a unique Chip
+  Select. The FMC2 performs only one access at a time to an external device.
+
+maintainers:
+  - Christophe Kerello 
+
+properties:
+  compatible:
+const: st,stm32mp1-fmc2-ebi
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  resets:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 1
+
+  ranges:
+description: |
+  Reflects the memory layout with four integer values per bank. Format:
+   0  
+
+patternProperties:
+  "^.*@[0-4],[a-f0-9]+$":
+type: object
+
+properties:
+  reg:
+description: Bank number, base address and size of the device.
+
+  st,fmc2-ebi-cs-transaction-type:
+description: |
+ Select one of the transactions type supported
+   0: Asynchronous mode 1 SRAM/FRAM.
+   1: Asynchronous mode 1 PSRAM.
+   2: Asynchronous mode A SRAM/FRAM.
+   3: Asynchronous mode A PSRAM.
+   4: Asynchronous mode 2 NOR.
+   5: Asynchronous mode B NOR.
+   6: Asynchronous mode C NOR.
+   7: Asynchronous mode D NOR.
+   8: Synchronous read synchronous write PSRAM.
+   9: Synchronous read asynchronous write PSRAM.
+   10: Synchronous read synchronous write NOR.
+   11: Synchronous read asynchronous write NOR.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 11
+
+  st,fmc2-ebi-cs-cclk-enable:
+description: Continuous clock enable (first bank must be configured
+ in synchronous mode). The FMC_CLK is generated 
continuously
+ during asynchronous and synchronous access. By default, 
the
+ FMC_CLK is only generated during synchronous access.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-mux-enable:
+description: Address/Data multiplexed on databus (valid only with
+ NOR and PSRAM transactions type). By default, Address/Data
+ are not multiplexed.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-buswidth:
+description: Data bus width
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [ 8, 16 ]
+default: 16
+
+  st,fmc2-ebi-cs-waitpol-high:
+description: Wait signal polarity (NWAIT signal active high).
+ By default, NWAIT is active low.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-waitcfg-enable:
+description: The NWAIT signal indicates wheither the data from the
+ device are valid or if a wait state must be inserted when
+ accessing the device in synchronous mode. By default, the
+ NWAIT signal is active one data cycle before wait state.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-wait-enable:
+descriptio

[PATCH v3 01/10] mtd: rawnand: stm32_fmc2: manage all errors cases at probe time

2020-05-05 Thread Christophe Kerello
This patch defers its probe when the expected reset control is not
yet ready. This patch also handles properly all errors cases at probe
time.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - rename labels used on errors

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b6d45cd..50a6377 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1967,7 +1967,11 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
}
 
rstc = devm_reset_control_get(dev, NULL);
-   if (!IS_ERR(rstc)) {
+   if (IS_ERR(rstc)) {
+   ret = PTR_ERR(rstc);
+   if (ret == -EPROBE_DEFER)
+   goto err_clk_disable;
+   } else {
reset_control_assert(rstc);
reset_control_deassert(rstc);
}
@@ -1975,7 +1979,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
/* DMA setup */
ret = stm32_fmc2_dma_setup(fmc2);
if (ret)
-   return ret;
+   goto err_release_dma;
 
/* FMC2 init routine */
stm32_fmc2_init(fmc2);
@@ -1997,20 +2001,20 @@ static int stm32_fmc2_probe(struct platform_device 
*pdev)
/* Scan to find existence of the device */
ret = nand_scan(chip, nand->ncs);
if (ret)
-   goto err_scan;
+   goto err_release_dma;
 
ret = mtd_device_register(mtd, NULL, 0);
if (ret)
-   goto err_device_register;
+   goto err_nand_cleanup;
 
platform_set_drvdata(pdev, fmc2);
 
return 0;
 
-err_device_register:
+err_nand_cleanup:
nand_cleanup(chip);
 
-err_scan:
+err_release_dma:
if (fmc2->dma_ecc_ch)
dma_release_channel(fmc2->dma_ecc_ch);
if (fmc2->dma_tx_ch)
@@ -2021,6 +2025,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
sg_free_table(>dma_data_sg);
sg_free_table(>dma_ecc_sg);
 
+err_clk_disable:
clk_disable_unprepare(fmc2->clk);
 
return ret;
-- 
1.9.1



[PATCH v3 07/10] dt-bindings: memory-controller: add STM32 FMC2 EBI controller documentation

2020-05-05 Thread Christophe Kerello
This patch adds the documentation of the device tree bindings for the STM32
FMC2 EBI controller.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - pattern name has been modified
 - vendor properties have been modified
   - s/_/-/
   - add unit suffix (-ns) on timing properties

 .../memory-controllers/st,stm32-fmc2-ebi.yaml  | 261 +
 1 file changed, 261 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml

diff --git 
a/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
new file mode 100644
index 000..3ec57d2
--- /dev/null
+++ 
b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
@@ -0,0 +1,261 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/st,stm32-fmc2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings
+
+description: |
+  The FMC2 functional block makes the interface with: synchronous and
+  asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
+  peripherals) and NAND flash memories.
+  Its main purposes are:
+- to translate AXI transactions into the appropriate external device
+  protocol
+- to meet the access time requirements of the external devices
+  All external devices share the addresses, data and control signals with the
+  controller. Each external device is accessed by means of a unique Chip
+  Select. The FMC2 performs only one access at a time to an external device.
+
+maintainers:
+  - Christophe Kerello 
+
+properties:
+  compatible:
+const: st,stm32mp1-fmc2-ebi
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  resets:
+maxItems: 1
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 1
+
+  ranges:
+description: |
+  Reflects the memory layout with four integer values per bank. Format:
+   0  
+
+patternProperties:
+  "^.*@[0-4],[a-f0-9]+$":
+type: object
+
+properties:
+  reg:
+description: Bank number, base address and size of the device.
+
+  st,fmc2-ebi-cs-transaction-type:
+description: |
+ Select one of the transactions type supported
+   0: Asynchronous mode 1 SRAM/FRAM.
+   1: Asynchronous mode 1 PSRAM.
+   2: Asynchronous mode A SRAM/FRAM.
+   3: Asynchronous mode A PSRAM.
+   4: Asynchronous mode 2 NOR.
+   5: Asynchronous mode B NOR.
+   6: Asynchronous mode C NOR.
+   7: Asynchronous mode D NOR.
+   8: Synchronous read synchronous write PSRAM.
+   9: Synchronous read asynchronous write PSRAM.
+   10: Synchronous read synchronous write NOR.
+   11: Synchronous read asynchronous write NOR.
+$ref: /schemas/types.yaml#/definitions/uint32
+minimum: 0
+maximum: 11
+
+  st,fmc2-ebi-cs-cclk-enable:
+description: Continuous clock enable (first bank must be configured
+ in synchronous mode). The FMC_CLK is generated 
continuously
+ during asynchronous and synchronous access. By default, 
the
+ FMC_CLK is only generated during synchronous access.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-mux-enable:
+description: Address/Data multiplexed on databus (valid only with
+ NOR and PSRAM transactions type). By default, Address/Data
+ are not multiplexed.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-buswidth:
+description: Data bus width
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [ 8, 16 ]
+default: 16
+
+  st,fmc2-ebi-cs-waitpol-high:
+description: Wait signal polarity (NWAIT signal active high).
+ By default, NWAIT is active low.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-waitcfg-enable:
+description: The NWAIT signal indicates wheither the data from the
+ device are valid or if a wait state must be inserted when
+ accessing the device in synchronous mode. By default, the
+ NWAIT signal is active one data cycle before wait state.
+$ref: /schemas/types.yaml#/definitions/flag
+
+  st,fmc2-ebi-cs-wait-enable:
+description: The NWAIT signal is enabled (its level is taken into
+ account after the programmed latency period to insert wait
+ states if asserted)

[PATCH v3 08/10] memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver

2020-05-05 Thread Christophe Kerello
The driver adds the support for the STMicroelectronics FMC2 EBI controller
found on STM32MP SOCs.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - Move in memory folder
 - Merge MFD and BUS drivers to avoid a MFD driver

 drivers/memory/Kconfig  |   10 +
 drivers/memory/Makefile |1 +
 drivers/memory/stm32-fmc2-ebi.c | 1206 +++
 3 files changed, 1217 insertions(+)
 create mode 100644 drivers/memory/stm32-fmc2-ebi.c

diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 9bddca2..c651aaf 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -163,6 +163,16 @@ config PL353_SMC
  This driver is for the ARM PL351/PL353 Static Memory
  Controller(SMC) module.
 
+config STM32_FMC2_EBI
+   tristate "Support for FMC2 External Bus Interface on STM32MP SoCs"
+   depends on MACH_STM32MP157 || COMPILE_TEST
+   select MFD_SYSCON
+   help
+ Select this option to enable the STM32 FMC2 External Bus Interface
+ controller. This driver configures the transactions with external
+ devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on
+ SOCs containing the FMC2 External Bus Interface.
+
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
 
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 27b4934..c7d36db 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
 obj-$(CONFIG_MTK_SMI)  += mtk-smi.o
 obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
 obj-$(CONFIG_PL353_SMC)+= pl353-smc.o
+obj-$(CONFIG_STM32_FMC2_EBI)   += stm32-fmc2-ebi.o
 
 obj-$(CONFIG_SAMSUNG_MC)   += samsung/
 obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c
new file mode 100644
index 000..4d5758c4
--- /dev/null
+++ b/drivers/memory/stm32-fmc2-ebi.c
@@ -0,0 +1,1206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2020
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_BTR1  0x4
+#define FMC2_BCR(x)((x) * 0x8 + FMC2_BCR1)
+#define FMC2_BTR(x)((x) * 0x8 + FMC2_BTR1)
+#define FMC2_PCSCNTR   0x20
+#define FMC2_BWTR1 0x104
+#define FMC2_BWTR(x)   ((x) * 0x8 + FMC2_BWTR1)
+
+/* Register: FMC2_BCR1 */
+#define FMC2_BCR1_CCLKEN   BIT(20)
+#define FMC2_BCR1_FMC2EN   BIT(31)
+
+/* Register: FMC2_BCRx */
+#define FMC2_BCR_MBKEN BIT(0)
+#define FMC2_BCR_MUXEN BIT(1)
+#define FMC2_BCR_MTYP  GENMASK(3, 2)
+#define FMC2_BCR_MWID  GENMASK(5, 4)
+#define FMC2_BCR_FACCENBIT(6)
+#define FMC2_BCR_BURSTEN   BIT(8)
+#define FMC2_BCR_WAITPOL   BIT(9)
+#define FMC2_BCR_WAITCFG   BIT(11)
+#define FMC2_BCR_WREN  BIT(12)
+#define FMC2_BCR_WAITENBIT(13)
+#define FMC2_BCR_EXTMODBIT(14)
+#define FMC2_BCR_ASYNCWAIT BIT(15)
+#define FMC2_BCR_CPSIZEGENMASK(18, 16)
+#define FMC2_BCR_CBURSTRW  BIT(19)
+#define FMC2_BCR_NBLSETGENMASK(23, 22)
+
+/* Register: FMC2_BTRx/FMC2_BWTRx */
+#define FMC2_BXTR_ADDSET   GENMASK(3, 0)
+#define FMC2_BXTR_ADDHLD   GENMASK(7, 4)
+#define FMC2_BXTR_DATAST   GENMASK(15, 8)
+#define FMC2_BXTR_BUSTURN  GENMASK(19, 16)
+#define FMC2_BTR_CLKDIVGENMASK(23, 20)
+#define FMC2_BTR_DATLATGENMASK(27, 24)
+#define FMC2_BXTR_ACCMOD   GENMASK(29, 28)
+#define FMC2_BXTR_DATAHLD  GENMASK(31, 30)
+
+/* Register: FMC2_PCSCNTR */
+#define FMC2_PCSCNTR_CSCOUNT   GENMASK(15, 0)
+#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16)
+
+#define FMC2_MAX_EBI_CE4
+#define FMC2_MAX_BANKS 5
+
+#define FMC2_BCR_CPSIZE_0  0x0
+#define FMC2_BCR_CPSIZE_1280x1
+#define FMC2_BCR_CPSIZE_2560x2
+#define FMC2_BCR_CPSIZE_5120x3
+#define FMC2_BCR_CPSIZE_1024   0x4
+
+#define FMC2_BCR_MWID_80x0
+#define FMC2_BCR_MWID_16   0x1
+
+#define FMC2_BCR_MTYP_SRAM 0x0
+#define FMC2_BCR_MTYP_PSRAM0x1
+#define FMC2_BCR_MTYP_NOR  0x2
+
+#define FMC2_BXTR_EXTMOD_A 0x0
+#define FMC2_BXTR_EXTMOD_B 0x1
+#define FMC2_BXTR_EXTMOD_C 0x2
+#define FMC2_BXTR_EXTMOD_D 0x3
+
+#define FMC2_BCR_NBLSET_MAX0x3

[PATCH v3 06/10] dt-bindings: mtd: update STM32 FMC2 NAND controller documentation

2020-05-05 Thread Christophe Kerello
These bindings can be used on SOCs where the FMC2 NAND controller is
in standalone. In case that the FMC2 embeds 2 controllers (an external
bus controller and a raw NAND controller), the register base and the
clock will be defined in the parent node. It is the reason why the
register base address and the clock are now optional.

Signed-off-by: Christophe Kerello 
---
 .../devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml   | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml 
b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
index b059267..68fac1a 100644
--- a/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
+++ b/Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
@@ -18,13 +18,15 @@ properties:
 
   reg:
 items:
-  - description: Registers
+  - description: Registers (optional)
   - 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
+minItems: 6
+maxItems: 7
 
   interrupts:
 maxItems: 1
@@ -61,7 +63,6 @@ required:
   - compatible
   - reg
   - interrupts
-  - clocks
 
 examples:
   - |
@@ -77,13 +78,13 @@ examples:
 <0x8100 0x1000>,
 <0x8901 0x1000>,
 <0x8902 0x1000>;
-interrupts = ;
-dmas = < 20 0x10 0x12000a02 0x0 0x0>,
-   < 20 0x10 0x12000a08 0x0 0x0>,
-   < 21 0x10 0x12000a0a 0x0 0x0>;
-dma-names = "tx", "rx", "ecc";
-clocks = < FMC_K>;
-resets = < FMC_R>;
+  interrupts = ;
+  dmas = < 20 0x2 0x12000a02 0x0 0x0>,
+ < 20 0x2 0x12000a08 0x0 0x0>,
+ < 21 0x2 0x12000a0a 0x0 0x0>;
+  dma-names = "tx", "rx", "ecc";
+  clocks = < FMC_K>;
+  resets = < FMC_R>;
   #address-cells = <1>;
   #size-cells = <0>;
 
-- 
1.9.1



[PATCH v3 00/10] add STM32 FMC2 EBI controller driver

2020-05-05 Thread Christophe Kerello
The FMC2 functional block makes the interface with: synchronous and
asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
peripherals) and NAND flash memories.
Its main purposes are:
  - to translate AXI transactions into the appropriate external device
protocol
  - to meet the access time requirements of the external devices
All external devices share the addresses, data and control signals with the
controller. Each external device is accessed by means of a unique Chip
Select. The FMC2 performs only one access at a time to an external device.

Changes in v3:
 - NAND:
   - rename labels used on errors
   - add in the commit log the reason to increase FMC2_TIMEOUT_MS (patch 3)
   - add Miquel reviewed-by tag (patches 2/4/5/9)
 - EBI:
   - move in memory folder
   - merge MFD and BUS drivers to avoid a MFD driver
 - bindings:
   - pattern name has been modified
   - vendor properties have been modified
 - s/_/-/
 - add unit suffix (-ns) on timing properties

Christophe Kerello (10):
  mtd: rawnand: stm32_fmc2: manage all errors cases at probe time
  mtd: rawnand: stm32_fmc2: remove useless inline comments
  mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts
  mtd: rawnand: stm32_fmc2: cleanup
  mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros
  dt-bindings: mtd: update STM32 FMC2 NAND controller documentation
  dt-bindings: memory-controller: add STM32 FMC2 EBI controller
documentation
  memory: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver
  mtd: rawnand: stm32_fmc2: use regmap APIs
  mtd: rawnand: stm32_fmc2: get resources from parent node

 .../memory-controllers/st,stm32-fmc2-ebi.yaml  |  261 +
 .../bindings/mtd/st,stm32-fmc2-nand.yaml   |   19 +-
 drivers/memory/Kconfig |   10 +
 drivers/memory/Makefile|1 +
 drivers/memory/stm32-fmc2-ebi.c| 1206 
 drivers/mtd/nand/raw/Kconfig   |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1176 ++-
 7 files changed, 2061 insertions(+), 613 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-ebi.yaml
 create mode 100644 drivers/memory/stm32-fmc2-ebi.c

-- 
1.9.1



[PATCH v3 04/10] mtd: rawnand: stm32_fmc2: cleanup

2020-05-05 Thread Christophe Kerello
This patch renames functions and local variables.
This cleanup is done to get all functions starting by stm32_fmc2_nfc
in the FMC2 raw NAND driver when all functions will start by
stm32_fmc2_ebi in the FMC2 EBI driver.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - fix s/conf/cf/, s/nfc/NFC/
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 810 -
 1 file changed, 403 insertions(+), 407 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 5778a95..0d108fb 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -280,12 +280,12 @@ static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct 
nand_controller *base)
return container_of(base, struct stm32_fmc2_nfc, base);
 }
 
-static void stm32_fmc2_timings_init(struct nand_chip *chip)
+static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *timings = >timings;
-   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
u32 pmem, patt;
 
/* Set tclr/tar timings */
@@ -306,15 +306,15 @@ static void stm32_fmc2_timings_init(struct nand_chip 
*chip)
patt |= FMC2_PATT_ATTHOLD(timings->thold_att);
patt |= FMC2_PATT_ATTHIZ(timings->thiz);
 
-   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
-   writel_relaxed(pmem, fmc2->io_base + FMC2_PMEM);
-   writel_relaxed(patt, fmc2->io_base + FMC2_PATT);
+   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
+   writel_relaxed(pmem, nfc->io_base + FMC2_PMEM);
+   writel_relaxed(patt, nfc->io_base + FMC2_PATT);
 }
 
-static void stm32_fmc2_setup(struct nand_chip *chip)
+static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
-   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
+   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
 
/* Configure ECC algorithm (default configuration is Hamming) */
pcr &= ~FMC2_PCR_ECCALG;
@@ -335,174 +335,174 @@ static void stm32_fmc2_setup(struct nand_chip *chip)
pcr &= ~FMC2_PCR_ECCSS_MASK;
pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
 
-   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
 }
 
-static int stm32_fmc2_select_chip(struct nand_chip *chip, int chipnr)
+static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr)
 {
-   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct dma_slave_config dma_cfg;
int ret;
 
-   if (nand->cs_used[chipnr] == fmc2->cs_sel)
+   if (nand->cs_used[chipnr] == nfc->cs_sel)
return 0;
 
-   fmc2->cs_sel = nand->cs_used[chipnr];
-   stm32_fmc2_setup(chip);
-   stm32_fmc2_timings_init(chip);
+   nfc->cs_sel = nand->cs_used[chipnr];
+   stm32_fmc2_nfc_setup(chip);
+   stm32_fmc2_nfc_timings_init(chip);
 
-   if (fmc2->dma_tx_ch && fmc2->dma_rx_ch) {
+   if (nfc->dma_tx_ch && nfc->dma_rx_ch) {
memset(_cfg, 0, sizeof(dma_cfg));
-   dma_cfg.src_addr = fmc2->data_phys_addr[fmc2->cs_sel];
-   dma_cfg.dst_addr = fmc2->data_phys_addr[fmc2->cs_sel];
+   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;
 
-   ret = dmaengine_slave_config(fmc2->dma_tx_ch, _cfg);
+   ret = dmaengine_slave_config(nfc->dma_tx_ch, _cfg);
if (ret) {
-   dev_err(fmc2->dev, "tx DMA engine slave config 
failed\n");
+   dev_err(nfc->dev, "tx DMA engine slave config 
failed\n");
return ret;
}
 
-   ret = dmaengine_slave_config(fmc2->dma_rx_ch, _cfg);
+   ret = dmaengine_slave_config(nfc->dma_rx_ch, _cfg);
if (ret) {
-   dev_err(fmc2->dev, "rx DMA engine slave config 
failed\n")

[PATCH v3 05/10] mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros

2020-05-05 Thread Christophe Kerello
This patch removes custom macros and uses FIELD_PREP and FIELD_GET macros.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 177 -
 1 file changed, 85 insertions(+), 92 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 0d108fb..236bb41 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -4,6 +4,7 @@
  * Author: Christophe Kerello 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -84,20 +85,16 @@
 /* Register: FMC2_PCR */
 #define FMC2_PCR_PWAITEN   BIT(1)
 #define FMC2_PCR_PBKEN BIT(2)
-#define FMC2_PCR_PWID_MASK GENMASK(5, 4)
-#define FMC2_PCR_PWID(x)   (((x) & 0x3) << 4)
+#define FMC2_PCR_PWID  GENMASK(5, 4)
 #define FMC2_PCR_PWID_BUSWIDTH_8   0
 #define FMC2_PCR_PWID_BUSWIDTH_16  1
 #define FMC2_PCR_ECCEN BIT(6)
 #define FMC2_PCR_ECCALGBIT(8)
-#define FMC2_PCR_TCLR_MASK GENMASK(12, 9)
-#define FMC2_PCR_TCLR(x)   (((x) & 0xf) << 9)
+#define FMC2_PCR_TCLR  GENMASK(12, 9)
 #define FMC2_PCR_TCLR_DEFAULT  0xf
-#define FMC2_PCR_TAR_MASK  GENMASK(16, 13)
-#define FMC2_PCR_TAR(x)(((x) & 0xf) << 13)
+#define FMC2_PCR_TAR   GENMASK(16, 13)
 #define FMC2_PCR_TAR_DEFAULT   0xf
-#define FMC2_PCR_ECCSS_MASKGENMASK(19, 17)
-#define FMC2_PCR_ECCSS(x)  (((x) & 0x7) << 17)
+#define FMC2_PCR_ECCSS GENMASK(19, 17)
 #define FMC2_PCR_ECCSS_512 1
 #define FMC2_PCR_ECCSS_20483
 #define FMC2_PCR_BCHECCBIT(24)
@@ -107,17 +104,17 @@
 #define FMC2_SR_NWRF   BIT(6)
 
 /* Register: FMC2_PMEM */
-#define FMC2_PMEM_MEMSET(x)(((x) & 0xff) << 0)
-#define FMC2_PMEM_MEMWAIT(x)   (((x) & 0xff) << 8)
-#define FMC2_PMEM_MEMHOLD(x)   (((x) & 0xff) << 16)
-#define FMC2_PMEM_MEMHIZ(x)(((x) & 0xff) << 24)
+#define FMC2_PMEM_MEMSET   GENMASK(7, 0)
+#define FMC2_PMEM_MEMWAIT  GENMASK(15, 8)
+#define FMC2_PMEM_MEMHOLD  GENMASK(23, 16)
+#define FMC2_PMEM_MEMHIZ   GENMASK(31, 24)
 #define FMC2_PMEM_DEFAULT  0x0a0a0a0a
 
 /* Register: FMC2_PATT */
-#define FMC2_PATT_ATTSET(x)(((x) & 0xff) << 0)
-#define FMC2_PATT_ATTWAIT(x)   (((x) & 0xff) << 8)
-#define FMC2_PATT_ATTHOLD(x)   (((x) & 0xff) << 16)
-#define FMC2_PATT_ATTHIZ(x)(((x) & 0xff) << 24)
+#define FMC2_PATT_ATTSET   GENMASK(7, 0)
+#define FMC2_PATT_ATTWAIT  GENMASK(15, 8)
+#define FMC2_PATT_ATTHOLD  GENMASK(23, 16)
+#define FMC2_PATT_ATTHIZ   GENMASK(31, 24)
 #define FMC2_PATT_DEFAULT  0x0a0a0a0a
 
 /* Register: FMC2_ISR */
@@ -132,9 +129,9 @@
 /* Register: FMC2_CSQCFGR1 */
 #define FMC2_CSQCFGR1_CMD2EN   BIT(1)
 #define FMC2_CSQCFGR1_DMADEN   BIT(2)
-#define FMC2_CSQCFGR1_ACYNBR(x)(((x) & 0x7) << 4)
-#define FMC2_CSQCFGR1_CMD1(x)  (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR1_CMD2(x)  (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR1_ACYNBR   GENMASK(6, 4)
+#define FMC2_CSQCFGR1_CMD1 GENMASK(15, 8)
+#define FMC2_CSQCFGR1_CMD2 GENMASK(23, 16)
 #define FMC2_CSQCFGR1_CMD1TBIT(24)
 #define FMC2_CSQCFGR1_CMD2TBIT(25)
 
@@ -142,13 +139,13 @@
 #define FMC2_CSQCFGR2_SQSDTEN  BIT(0)
 #define FMC2_CSQCFGR2_RCMD2EN  BIT(1)
 #define FMC2_CSQCFGR2_DMASEN   BIT(2)
-#define FMC2_CSQCFGR2_RCMD1(x) (((x) & 0xff) << 8)
-#define FMC2_CSQCFGR2_RCMD2(x) (((x) & 0xff) << 16)
+#define FMC2_CSQCFGR2_RCMD1GENMASK(15, 8)
+#define FMC2_CSQCFGR2_RCMD2GENMASK(23, 16)
 #define FMC2_CSQCFGR2_RCMD1T   BIT(24)
 #define FMC2_CSQCFGR2_RCMD2T   BIT(25)
 
 /* Register: FMC2_CSQCFGR3 */
-#define FMC2_CSQCFGR3_SNBR(x)  (((x) & 0x1f) << 8)
+#define FMC2_CSQCFGR3_SNBR GENMASK(13, 8)
 #define FMC2_CSQCFGR3_AC1T BIT(16)
 #define FMC2_CSQCFGR3_AC2T BIT(17)
 #define FMC2_CSQCFGR3_AC3T BIT(18)
@@ -159,15 +156,15 @@
 #define FMC2_CSQCFGR3_RAC2TBIT(23)
 
 /* Register: FMC2_CSQCAR1 */
-#define FMC2_CSQCAR1_ADDC1(x)  (((x) & 0xff) << 0)
-#define FMC2_CSQCAR1_ADDC2(x)  (((x) & 0xff) << 8)
-#define FMC2_CSQCAR1_ADDC3(x)  (((x) & 0xff) << 16)
-#define FMC2_CSQCAR1_ADDC4(x)  (((x) & 0xff) <<

[PATCH v3 10/10] mtd: rawnand: stm32_fmc2: get resources from parent node

2020-05-05 Thread Christophe Kerello
FMC2 EBI support has been added. Common resources (registers base
and clock) are now shared between the 2 drivers. It means that the
common resources should now be found in the parent device when EBI
node is available.

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/Kconfig   |  3 +-
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 89 +++---
 2 files changed, 62 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 12b715a..28dccd5 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -419,8 +419,7 @@ config MTD_NAND_TEGRA
 config MTD_NAND_STM32_FMC2
tristate "Support for NAND controller on STM32MP SoCs"
depends on MACH_STM32MP157 || COMPILE_TEST
-   select REGMAP
-   select REGMAP_MMIO
+   select MFD_SYSCON
help
  Enables support for NAND Flash chips on SoCs containing the FMC2
  NAND controller. This controller is found on STM32MP SoCs.
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 76571da..dfab6b1 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -11,8 +11,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -204,16 +206,6 @@
 #define FMC2_BCHDSR4_EBP7  GENMASK(12, 0)
 #define FMC2_BCHDSR4_EBP8  GENMASK(28, 16)
 
-/* Regmap registers configuration */
-#define FMC2_MAX_REGISTER  0x3fc
-
-static const struct regmap_config stm32_fmc2_regmap_cfg = {
-   .reg_bits = 32,
-   .val_bits = 32,
-   .reg_stride = sizeof(u32),
-   .max_register = FMC2_MAX_REGISTER,
-};
-
 enum stm32_fmc2_ecc {
FMC2_ECC_HAM = 1,
FMC2_ECC_BCH4 = 4,
@@ -261,6 +253,7 @@ struct stm32_fmc2_nfc {
phys_addr_t data_phys_addr[FMC2_MAX_CE];
struct clk *clk;
u8 irq_state;
+   bool has_parent;
 
struct dma_chan *dma_tx_ch;
struct dma_chan *dma_rx_ch;
@@ -1384,8 +1377,9 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc 
*nfc)
pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT);
 
/* Enable FMC2 controller */
-   regmap_update_bits(nfc->regmap, FMC2_BCR1,
-  FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN);
+   if (!nfc->has_parent)
+   regmap_update_bits(nfc->regmap, FMC2_BCR1,
+  FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN);
 
regmap_write(nfc->regmap, FMC2_PCR, pcr);
regmap_write(nfc->regmap, FMC2_PMEM, FMC2_PMEM_DEFAULT);
@@ -1815,6 +1809,53 @@ static int stm32_fmc2_nfc_parse_dt(struct stm32_fmc2_nfc 
*nfc)
return ret;
 }
 
+static int stm32_fmc2_nfc_set_regmap_clk(struct platform_device *pdev,
+struct stm32_fmc2_nfc *nfc)
+{
+   struct device *dev = >dev;
+   struct resource res;
+   int ret;
+
+   if (nfc->has_parent)
+   dev = dev->parent;
+
+   ret = of_address_to_resource(dev->of_node, 0, );
+   if (ret)
+   return ret;
+
+   nfc->io_phys_addr = res.start;
+
+   nfc->regmap = device_node_to_regmap(dev->of_node);
+   if (IS_ERR(nfc->regmap))
+   return PTR_ERR(nfc->regmap);
+
+   nfc->clk = devm_clk_get(dev, NULL);
+   if (IS_ERR(nfc->clk))
+   return PTR_ERR(nfc->clk);
+
+   return 0;
+}
+
+static bool stm32_fmc2_nfc_check_for_parent(struct platform_device *pdev)
+{
+   u32 i;
+   int nb_resources = 0;
+
+   /* Count the number of resources in reg property */
+   for (i = 0; i < pdev->num_resources; i++) {
+   struct resource *res = >resource[i];
+
+   if (resource_type(res) == IORESOURCE_MEM)
+   nb_resources++;
+   }
+
+   /* Each CS needs 3 resources defined (data, cmd and addr) */
+   if (nb_resources % 3)
+   return false;
+
+   return true;
+}
+
 static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -1824,8 +1865,8 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
struct resource *res;
struct mtd_info *mtd;
struct nand_chip *chip;
-   void __iomem *mmio;
int chip_cs, mem_region, ret, irq;
+   int num_region = 1;
 
nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
if (!nfc)
@@ -1834,23 +1875,19 @@ static int stm32_fmc2_nfc_probe(struct platform_device 
*pdev)
nfc->dev = dev;
nand_controller_init(>base);
nfc->base.ops = _fmc2_nfc_controller_ops;
+   nfc->has_parent = stm32_fmc2_nfc_check_for_parent(pdev);
+   if (nfc->has_parent)
+   num_region = 0;
 
ret = stm32_fmc2_nfc_parse_dt(nfc);
if (ret

[PATCH v3 09/10] mtd: rawnand: stm32_fmc2: use regmap APIs

2020-05-05 Thread Christophe Kerello
This patch uses regmap APIs to access all FMC2 registers.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - add Miquel reviewed-by tag

 drivers/mtd/nand/raw/Kconfig   |   2 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 268 +++--
 2 files changed, 127 insertions(+), 143 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index a80a46b..12b715a 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -419,6 +419,8 @@ config MTD_NAND_TEGRA
 config MTD_NAND_STM32_FMC2
tristate "Support for NAND controller on STM32MP SoCs"
depends on MACH_STM32MP157 || COMPILE_TEST
+   select REGMAP
+   select REGMAP_MMIO
help
  Enables support for NAND Flash chips on SoCs containing the FMC2
  NAND controller. This controller is found on STM32MP SoCs.
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 236bb41..76571da 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* Bad block marker length */
@@ -203,6 +204,16 @@
 #define FMC2_BCHDSR4_EBP7  GENMASK(12, 0)
 #define FMC2_BCHDSR4_EBP8  GENMASK(28, 16)
 
+/* Regmap registers configuration */
+#define FMC2_MAX_REGISTER  0x3fc
+
+static const struct regmap_config stm32_fmc2_regmap_cfg = {
+   .reg_bits = 32,
+   .val_bits = 32,
+   .reg_stride = sizeof(u32),
+   .max_register = FMC2_MAX_REGISTER,
+};
+
 enum stm32_fmc2_ecc {
FMC2_ECC_HAM = 1,
FMC2_ECC_BCH4 = 4,
@@ -242,7 +253,7 @@ struct stm32_fmc2_nfc {
struct nand_controller base;
struct stm32_fmc2_nand nand;
struct device *dev;
-   void __iomem *io_base;
+   struct regmap *regmap;
void __iomem *data_base[FMC2_MAX_CE];
void __iomem *cmd_base[FMC2_MAX_CE];
void __iomem *addr_base[FMC2_MAX_CE];
@@ -277,40 +288,37 @@ static void stm32_fmc2_nfc_timings_init(struct nand_chip 
*chip)
struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
struct stm32_fmc2_nand *nand = to_fmc2_nand(chip);
struct stm32_fmc2_timings *timings = >timings;
-   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
u32 pmem, patt;
 
/* Set tclr/tar timings */
-   pcr &= ~FMC2_PCR_TCLR;
-   pcr |= FIELD_PREP(FMC2_PCR_TCLR, timings->tclr);
-   pcr &= ~FMC2_PCR_TAR;
-   pcr |= FIELD_PREP(FMC2_PCR_TAR, timings->tar);
+   regmap_update_bits(nfc->regmap, FMC2_PCR,
+  FMC2_PCR_TCLR | FMC2_PCR_TAR,
+  FIELD_PREP(FMC2_PCR_TCLR, timings->tclr) |
+  FIELD_PREP(FMC2_PCR_TAR, timings->tar));
 
/* Set tset/twait/thold/thiz timings in common bank */
pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem);
pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait);
pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem);
pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz);
+   regmap_write(nfc->regmap, FMC2_PMEM, pmem);
 
/* Set tset/twait/thold/thiz timings in attribut bank */
patt = FIELD_PREP(FMC2_PATT_ATTSET, timings->tset_att);
patt |= FIELD_PREP(FMC2_PATT_ATTWAIT, timings->twait);
patt |= FIELD_PREP(FMC2_PATT_ATTHOLD, timings->thold_att);
patt |= FIELD_PREP(FMC2_PATT_ATTHIZ, timings->thiz);
-
-   writel_relaxed(pcr, nfc->io_base + FMC2_PCR);
-   writel_relaxed(pmem, nfc->io_base + FMC2_PMEM);
-   writel_relaxed(patt, nfc->io_base + FMC2_PATT);
+   regmap_write(nfc->regmap, FMC2_PATT, patt);
 }
 
 static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
 {
struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller);
-   u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR);
+   u32 pcr = 0, pcr_mask;
 
/* Configure ECC algorithm (default configuration is Hamming) */
-   pcr &= ~FMC2_PCR_ECCALG;
-   pcr &= ~FMC2_PCR_BCHECC;
+   pcr_mask = FMC2_PCR_ECCALG;
+   pcr_mask |= FMC2_PCR_BCHECC;
if (chip->ecc.strength == FMC2_ECC_BCH8) {
pcr |= FMC2_PCR_ECCALG;
pcr |= FMC2_PCR_BCHECC;
@@ -319,15 +327,15 @@ static void stm32_fmc2_nfc_setup(struct nand_chip *chip)
}
 
/* Set buswidth */
-   pcr &= ~FMC2_PCR_PWID;
+   pcr_mask |= FMC2_PCR_PWID;
if (chip->options & NAND_BUSWIDTH_16)
pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16);
 
/* Set ECC sector size */
-   pcr &= ~FMC2_PCR_ECCSS;
+   pcr_mask |= FMC2_PCR_ECCSS;
pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_512);
 
-   writel_relaxed(

[PATCH v3 03/10] mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts

2020-05-05 Thread Christophe Kerello
This patch removes the constant FMC2_TIMEOUT_US.
FMC2_TIMEOUT_MS will be used each time that we need to wait (except
when the timeout value is set by the framework).

It was seen, during stress tests with the sequencer in an overloaded
system, that we could be close to 1 second, even if we never met this
value. To be safe, FMC2_TIMEOUT_MS is set to 5 seconds.

Signed-off-by: Christophe Kerello 
---
Changes in v3:
 - add in the commit log the reason to increase FMC2_TIMEOUT_MS

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

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 3377fbe..5778a95 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -37,8 +37,7 @@
 /* Max ECC buffer length */
 #define FMC2_MAX_ECC_BUF_LEN   (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
 
-#define FMC2_TIMEOUT_US1000
-#define FMC2_TIMEOUT_MS1000
+#define FMC2_TIMEOUT_MS5000
 
 /* Timings */
 #define FMC2_THIZ  1
@@ -526,8 +525,8 @@ static int stm32_fmc2_ham_calculate(struct nand_chip *chip, 
const u8 *data,
int ret;
 
ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
-sr, sr & FMC2_SR_NWRF, 10,
-FMC2_TIMEOUT_MS);
+sr, sr & FMC2_SR_NWRF, 1,
+1000 * FMC2_TIMEOUT_MS);
if (ret) {
dev_err(fmc2->dev, "ham timeout\n");
return ret;
@@ -1315,7 +1314,7 @@ static int stm32_fmc2_waitrdy(struct nand_chip *chip, 
unsigned long timeout_ms)
/* Check if there is no pending requests to the NAND flash */
if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr,
  sr & FMC2_SR_NWRF, 1,
- FMC2_TIMEOUT_US))
+ 1000 * FMC2_TIMEOUT_MS))
dev_warn(fmc2->dev, "Waitrdy timeout\n");
 
/* Wait tWB before R/B# signal is low */
-- 
1.9.1



[PATCH v3 02/10] mtd: rawnand: stm32_fmc2: remove useless inline comments

2020-05-05 Thread Christophe Kerello
Remove inline comments that are useless since function label are
self explanatory.

Signed-off-by: Christophe Kerello 
Reviewed-by: Miquel Raynal 
---
Changes in v3:
 - add Miquel reviewed-by tag

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

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 50a6377..3377fbe 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -281,7 +281,6 @@ static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct 
nand_controller *base)
return container_of(base, struct stm32_fmc2_nfc, base);
 }
 
-/* Timings configuration */
 static void stm32_fmc2_timings_init(struct nand_chip *chip)
 {
struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
@@ -313,7 +312,6 @@ static void stm32_fmc2_timings_init(struct nand_chip *chip)
writel_relaxed(patt, fmc2->io_base + FMC2_PATT);
 }
 
-/* Controller configuration */
 static void stm32_fmc2_setup(struct nand_chip *chip)
 {
struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
@@ -341,7 +339,6 @@ static void stm32_fmc2_setup(struct nand_chip *chip)
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
 }
 
-/* Select target */
 static int stm32_fmc2_select_chip(struct nand_chip *chip, int chipnr)
 {
struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
@@ -353,11 +350,7 @@ static int stm32_fmc2_select_chip(struct nand_chip *chip, 
int chipnr)
return 0;
 
fmc2->cs_sel = nand->cs_used[chipnr];
-
-   /* FMC2 setup routine */
stm32_fmc2_setup(chip);
-
-   /* Apply timings */
stm32_fmc2_timings_init(chip);
 
if (fmc2->dma_tx_ch && fmc2->dma_rx_ch) {
@@ -407,7 +400,6 @@ static int stm32_fmc2_select_chip(struct nand_chip *chip, 
int chipnr)
return 0;
 }
 
-/* Set bus width to 16-bit or 8-bit */
 static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set)
 {
u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
@@ -418,7 +410,6 @@ static void stm32_fmc2_set_buswidth_16(struct 
stm32_fmc2_nfc *fmc2, bool set)
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
 }
 
-/* Enable/disable ECC */
 static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
 {
u32 pcr = readl(fmc2->io_base + FMC2_PCR);
@@ -429,7 +420,6 @@ static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, 
bool enable)
writel(pcr, fmc2->io_base + FMC2_PCR);
 }
 
-/* Enable irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_enable_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER);
@@ -441,7 +431,6 @@ static inline void stm32_fmc2_enable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
 }
 
-/* Disable irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_disable_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER);
@@ -453,13 +442,11 @@ static inline void stm32_fmc2_disable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
fmc2->irq_state = FMC2_IRQ_UNKNOWN;
 }
 
-/* Clear irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_clear_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, fmc2->io_base + FMC2_CSQICR);
 }
 
-/* Enable irq sources in case of bch is used */
 static inline void stm32_fmc2_enable_bch_irq(struct stm32_fmc2_nfc *fmc2,
 int mode)
 {
@@ -475,7 +462,6 @@ static inline void stm32_fmc2_enable_bch_irq(struct 
stm32_fmc2_nfc *fmc2,
writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
 }
 
-/* Disable irq sources in case of bch is used */
 static inline void stm32_fmc2_disable_bch_irq(struct stm32_fmc2_nfc *fmc2)
 {
u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
@@ -488,7 +474,6 @@ static inline void stm32_fmc2_disable_bch_irq(struct 
stm32_fmc2_nfc *fmc2)
fmc2->irq_state = FMC2_IRQ_UNKNOWN;
 }
 
-/* Clear irq sources in case of bch is used */
 static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
 {
writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
@@ -549,10 +534,7 @@ static int stm32_fmc2_ham_calculate(struct nand_chip 
*chip, const u8 *data,
}
 
heccr = readl_relaxed(fmc2->io_base + FMC2_HECCR);
-
stm32_fmc2_ham_set_ecc(heccr, ecc);
-
-   /* Disable ECC */
stm32_fmc2_set_ecc(fmc2, false);
 
return 0;
@@ -654,13 +636,11 @@ static int stm32_fmc2_bch_calculate(struct nand_chip 
*chip, const u8 *data,
ecc[12] = bchpbr;
}
 
-   /* Disable ECC */
stm32_fmc2_set_ecc(fmc2, false);
 
return 0;
 }
 

Re: [PATCH v2 06/12] mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts

2020-04-29 Thread Christophe Kerello




On 4/29/20 12:06 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 29 Apr
2020 11:41:44 +0200:


On 4/29/20 11:35 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 29 Apr
2020 11:27:43 +0200:
   

Hi Miquèl,

On 4/27/20 8:22 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 15 Apr
2020 17:57:30 +0200:
>>>> This patch removes the constant FMC2_TIMEOUT_US.

FMC2_TIMEOUT_MS is set to 5 seconds and this constant is used
each time that we need to wait (except when the timeout value
is set by the framework)

Signed-off-by: Christophe Kerello 
---
drivers/mtd/nand/raw/stm32_fmc2_nand.c | 11 +--
1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index ab53314..f159c39 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -37,8 +37,7 @@
/* Max ECC buffer length */
#define FMC2_MAX_ECC_BUF_LEN(FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
>> -#define FMC2_TIMEOUT_US   1000
-#define FMC2_TIMEOUT_MS1000
+#define FMC2_TIMEOUT_MS5000
>>   /* Timings */
#define FMC2_THIZ   1
@@ -525,9 +524,9 @@ static int stm32_fmc2_ham_calculate(struct nand_chip *chip, 
const u8 *data,
u32 sr, heccr;
int ret;
>> -  ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
-sr, sr & FMC2_SR_NWRF, 10,
-FMC2_TIMEOUT_MS);
+   ret = readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR,
+   sr, sr & FMC2_SR_NWRF, 1,
+   1000 * FMC2_TIMEOUT_MS);


Is the _atomic suffix needed here? If yes it would deserve a separate
patch with Fixes/Stable tags.
>>

I have currently not seen any issues. So, I will remove this modification as we 
will move to regmap_read_poll_timeout in patch 10.
  

if (ret) {
dev_err(fmc2->dev, "ham timeout\n");
return ret;
@@ -1315,7 +1314,7 @@ static int stm32_fmc2_waitrdy(struct nand_chip *chip, 
unsigned long timeout_ms)
/* Check if there is no pending requests to the NAND flash */
if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr,
  sr & FMC2_SR_NWRF, 1,
- FMC2_TIMEOUT_US))
+ 1000 * FMC2_TIMEOUT_MS))
dev_warn(fmc2->dev, "Waitrdy timeout\n");
>>/* Wait tWB before R/B# signal is low */


You change the timeouts from 1ms to 5s.

Maybe 5s is a little bit too much IMHO but we don't really care as this
is a timeout. However 1ms is tight. If you are changing this value
because it triggers error (eg. when the machine is loaded), then it is
a fix and should appear like it.

Thanks,
Miquèl
>>

No errors currently happens.
During our stress tests, in a overloaded system, we have seen that we could be 
close to 1 second, even if we never met this value.
So, to be safe, I have set this timeout to 5 seconds.
As it is just a timeout value, I have not seen any side effect.
I am using the same timeout constant to avoid to have one timeout per cases.


Something is wrong in my mind:
You say you observe delays of almost up to 1 second, but the polling
currently happens on 1000 us = 1ms, either you had timeouts or I
misread something?

Thanks,
Miquèl
   


Hi Miquèl,

My fault. For this polling, we never met 1 ms.
The 1 second observed was on the sequencer when we read/write a page (as it the 
same timeout value that is used)


OK I get it. So perhaps you can give these details in the commit log to
explain why you use 5 seconds instead of one.

Thanks,
Miquèl



Hi Miquèl,

A proposal could also be to split this patch:
 - a first patch that is using only one timeout value.
 - a second patch that is increasing the value to 5 seconds.

Regards,
Christophe Kerello.


Re: [PATCH v2 06/12] mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts

2020-04-29 Thread Christophe Kerello




On 4/29/20 11:35 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 29 Apr
2020 11:27:43 +0200:


Hi Miquèl,

On 4/27/20 8:22 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 15 Apr
2020 17:57:30 +0200:
   

This patch removes the constant FMC2_TIMEOUT_US.
FMC2_TIMEOUT_MS is set to 5 seconds and this constant is used
each time that we need to wait (except when the timeout value
is set by the framework)

Signed-off-by: Christophe Kerello 
---
   drivers/mtd/nand/raw/stm32_fmc2_nand.c | 11 +--
   1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index ab53314..f159c39 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -37,8 +37,7 @@
   /* Max ECC buffer length */
   #define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
   >> -#define FMC2_TIMEOUT_US1000
-#define FMC2_TIMEOUT_MS1000
+#define FMC2_TIMEOUT_MS5000
   >>   /* Timings */
   #define FMC2_THIZ1
@@ -525,9 +524,9 @@ static int stm32_fmc2_ham_calculate(struct nand_chip *chip, 
const u8 *data,
u32 sr, heccr;
int ret;
   >> -   ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
-sr, sr & FMC2_SR_NWRF, 10,
-FMC2_TIMEOUT_MS);
+   ret = readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR,
+   sr, sr & FMC2_SR_NWRF, 1,
+   1000 * FMC2_TIMEOUT_MS);


Is the _atomic suffix needed here? If yes it would deserve a separate
patch with Fixes/Stable tags.
   


I have currently not seen any issues. So, I will remove this modification as we 
will move to regmap_read_poll_timeout in patch 10.


if (ret) {
dev_err(fmc2->dev, "ham timeout\n");
return ret;
@@ -1315,7 +1314,7 @@ static int stm32_fmc2_waitrdy(struct nand_chip *chip, 
unsigned long timeout_ms)
/* Check if there is no pending requests to the NAND flash */
if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr,
  sr & FMC2_SR_NWRF, 1,
- FMC2_TIMEOUT_US))
+ 1000 * FMC2_TIMEOUT_MS))
dev_warn(fmc2->dev, "Waitrdy timeout\n");
   >> /* Wait tWB before R/B# signal is low */


You change the timeouts from 1ms to 5s.

Maybe 5s is a little bit too much IMHO but we don't really care as this
is a timeout. However 1ms is tight. If you are changing this value
because it triggers error (eg. when the machine is loaded), then it is
a fix and should appear like it.

Thanks,
Miquèl
   


No errors currently happens.
During our stress tests, in a overloaded system, we have seen that we could be 
close to 1 second, even if we never met this value.
So, to be safe, I have set this timeout to 5 seconds.
As it is just a timeout value, I have not seen any side effect.
I am using the same timeout constant to avoid to have one timeout per cases.


Something is wrong in my mind:
You say you observe delays of almost up to 1 second, but the polling
currently happens on 1000 us = 1ms, either you had timeouts or I
misread something?

Thanks,
Miquèl



Hi Miquèl,

My fault. For this polling, we never met 1 ms.
The 1 second observed was on the sequencer when we read/write a page (as 
it the same timeout value that is used)


Regards,
Christophe Kerello.


Re: [PATCH v2 01/12] dt-bindings: mfd: stm32-fmc2: add STM32 FMC2 controller documentation

2020-04-29 Thread Christophe Kerello

Hi rob,

On 4/28/20 5:28 PM, Rob Herring wrote:

On Wed, Apr 15, 2020 at 05:57:25PM +0200, Christophe Kerello wrote:

This patch adds the documentation of the device tree bindings for the STM32
FMC2 controller.

Signed-off-by: Christophe Kerello 
---
  .../devicetree/bindings/mfd/st,stm32-fmc2.yaml | 370 +
  1 file changed, 370 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-fmc2.yaml

diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-fmc2.yaml 
b/Documentation/devicetree/bindings/mfd/st,stm32-fmc2.yaml
new file mode 100644
index 000..0ce1340
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-fmc2.yaml
@@ -0,0 +1,370 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/st,stm32-fmc2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics Flexible Memory Controller 2 (FMC2) Bindings
+
+description: |
+  The FMC2 functional block makes the interface with: synchronous and
+  asynchronous static devices (such as PSNOR, PSRAM or other memory-mapped
+  peripherals) and NAND flash memories.
+  Its main purposes are:
+- to translate AXI transactions into the appropriate external device
+  protocol
+- to meet the access time requirements of the external devices
+  All external devices share the addresses, data and control signals with the
+  controller. Each external device is accessed by means of a unique Chip
+  Select. The FMC2 performs only one access at a time to an external device.
+
+maintainers:
+  - Christophe Kerello 
+
+properties:
+  compatible:
+const: st,stm32mp1-fmc2
+
+  reg:
+maxItems: 1
+
+  clocks:
+maxItems: 1
+
+  resets:
+maxItems: 1
+
+  "#address-cells":
+const: 1
+
+  "#size-cells":
+const: 1
+
+  ranges: true
+
+patternProperties:
+  "^ebi(@.*)?":
+type: object
+
+properties:
+  compatible:
+const: st,stm32mp1-fmc2-ebi
+
+  "#address-cells":
+const: 2
+
+  "#size-cells":
+const: 1
+
+  ranges: true
+
+patternProperties:
+  "^[a-zA-Z]*-ebi@[a-f0-9,]*$":


These nodes should be named based on the device connected and we can be
a bit more precise on the unit-address:

"@[0-9a-f],[0-9a-f]+$"

Adjust for how many chip selects there are. 15 seems unlikely.



Ok. It will be modified in v3.


+type: object
+
+properties:
+  reg:
+maxItems: 1
+
+  st,fmc2_ebi_cs_transaction_type:


s/_/-/

And for the rest of the vendor properties...



Ok. It will be modified in v3.


+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - minimum: 0
+maximum: 11
+description: |
+ Select one of the transactions type supported
+   0: Asynchronous mode 1 SRAM/FRAM
+   1: Asynchronous mode 1 PSRAM.
+   2: Asynchronous mode A SRAM/FRAM.
+   3: Asynchronous mode A PSRAM.
+   4: Asynchronous mode 2 NOR.
+   5: Asynchronous mode B NOR.
+   6: Asynchronous mode C NOR.
+   7: Asynchronous mode D NOR.
+   8: Synchronous read synchronous write PSRAM.
+   9: Synchronous read asynchronous write PSRAM.
+   10: Synchronous read synchronous write NOR.
+   11: Synchronous read asynchronous write NOR.
+
+  st,fmc2_ebi_cs_cclk_enable:
+$ref: /schemas/types.yaml#/definitions/flag
+description: Continuous clock enable (first bank must be configured
+ in synchronous mode). The FMC_CLK is generated 
continuously
+ during asynchronous and synchronous access. By 
default, the
+ FMC_CLK is only generated during synchronous access.
+
+  st,fmc2_ebi_cs_mux_enable:
+$ref: /schemas/types.yaml#/definitions/flag
+description: Address/Data multiplexed on databus (valid only with
+ NOR and PSRAM transactions type). By default, 
Address/Data are
+ not multiplexed.
+
+  st,fmc2_ebi_cs_buswidth:
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [ 8, 16 ]
+  - default: 16
+description: Data bus width
+
+  st,fmc2_ebi_cs_waitpol_high:
+$ref: /schemas/types.yaml#/definitions/flag
+description: Wait signal polarity (NWAIT signal active high).
+ By default, NWAIT is active low.
+
+  st,fmc2_ebi_cs_waitcfg_enable:
+$ref: /schemas/types.yaml#

Re: [PATCH v2 07/12] mtd: rawnand: stm32_fmc2: cleanup

2020-04-29 Thread Christophe Kerello

Hi Miquèl,

On 4/27/20 8:33 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 15 Apr
2020 17:57:31 +0200:


This patch renames functions and local variables to be ready to use
stm32_fmc2 structure.

Signed-off-by: Christophe Kerello 
---



-static int stm32_fmc2_setup_interface(struct nand_chip *chip, int chipnr,
- const struct nand_data_interface *conf)
+static int stm32_fmc2_nfc_setup_interface(struct nand_chip *chip, int chipnr,
+ const struct nand_data_interface *cf)


I suppose you s/conf/cf/ because of the 80 chars boundary. In this case
I don't mind crossing it, I don't think it is better to rename the
conf parameter for this reason.



Yes, you are right. I have modified it because of 80 chars boundary.
I will keep conf in v3.


  {
const struct nand_sdr_timings *sdrt;
  
-	sdrt = nand_get_sdr_timings(conf);

+   sdrt = nand_get_sdr_timings(cf);
if (IS_ERR(sdrt))
return PTR_ERR(sdrt);
  
  	if (chipnr == NAND_DATA_IFACE_CHECK_ONLY)

return 0;
  
-	stm32_fmc2_calc_timings(chip, sdrt);

-   stm32_fmc2_timings_init(chip);
+   stm32_fmc2_nfc_calc_timings(chip, sdrt);
+   stm32_fmc2_nfc_timings_init(chip);
  
  	return 0;

  }
  


[...]

  
-static struct platform_driver stm32_fmc2_driver = {

-   .probe  = stm32_fmc2_probe,
-   .remove = stm32_fmc2_remove,
+static struct platform_driver stm32_fmc2_nfc_driver = {
+   .probe  = stm32_fmc2_nfc_probe,
+   .remove = stm32_fmc2_nfc_remove,
.driver = {
-   .name = "stm32_fmc2_nand",
-   .of_match_table = stm32_fmc2_match,
-   .pm = _fmc2_pm_ops,
+   .name = "stm32_fmc2_nfc",
+   .of_match_table = stm32_fmc2_nfc_match,
+   .pm = _fmc2_nfc_pm_ops,
},
  };
-module_platform_driver(stm32_fmc2_driver);
+module_platform_driver(stm32_fmc2_nfc_driver);
  
-MODULE_ALIAS("platform:stm32_fmc2_nand");

+MODULE_ALIAS("platform:stm32_fmc2_nfc");
  MODULE_AUTHOR("Christophe Kerello ");
-MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 nand driver");
+MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 nfc driver");


I would prefer: s/nfc/NFC/ here please.



It will be modified in v3.

Regards,
Christophe Kerello.


  MODULE_LICENSE("GPL v2");


With these two nits,

Reviewed-by: Miquel Raynal 

Thanks,
Miquèl



Re: [PATCH v2 06/12] mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts

2020-04-29 Thread Christophe Kerello

Hi Miquèl,

On 4/27/20 8:22 PM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Wed, 15 Apr
2020 17:57:30 +0200:


This patch removes the constant FMC2_TIMEOUT_US.
FMC2_TIMEOUT_MS is set to 5 seconds and this constant is used
each time that we need to wait (except when the timeout value
is set by the framework)

Signed-off-by: Christophe Kerello 
---
  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 11 +--
  1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index ab53314..f159c39 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -37,8 +37,7 @@
  /* Max ECC buffer length */
  #define FMC2_MAX_ECC_BUF_LEN  (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
  
-#define FMC2_TIMEOUT_US			1000

-#define FMC2_TIMEOUT_MS1000
+#define FMC2_TIMEOUT_MS5000
  
  /* Timings */

  #define FMC2_THIZ 1
@@ -525,9 +524,9 @@ static int stm32_fmc2_ham_calculate(struct nand_chip *chip, 
const u8 *data,
u32 sr, heccr;
int ret;
  
-	ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,

-sr, sr & FMC2_SR_NWRF, 10,
-FMC2_TIMEOUT_MS);
+   ret = readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR,
+   sr, sr & FMC2_SR_NWRF, 1,
+   1000 * FMC2_TIMEOUT_MS);


Is the _atomic suffix needed here? If yes it would deserve a separate
patch with Fixes/Stable tags.



I have currently not seen any issues. So, I will remove this 
modification as we will move to regmap_read_poll_timeout in patch 10.



if (ret) {
dev_err(fmc2->dev, "ham timeout\n");
return ret;
@@ -1315,7 +1314,7 @@ static int stm32_fmc2_waitrdy(struct nand_chip *chip, 
unsigned long timeout_ms)
/* Check if there is no pending requests to the NAND flash */
if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr,
  sr & FMC2_SR_NWRF, 1,
- FMC2_TIMEOUT_US))
+ 1000 * FMC2_TIMEOUT_MS))
dev_warn(fmc2->dev, "Waitrdy timeout\n");
  
  	/* Wait tWB before R/B# signal is low */


You change the timeouts from 1ms to 5s.

Maybe 5s is a little bit too much IMHO but we don't really care as this
is a timeout. However 1ms is tight. If you are changing this value
because it triggers error (eg. when the machine is loaded), then it is
a fix and should appear like it.

Thanks,
Miquèl



No errors currently happens.
During our stress tests, in a overloaded system, we have seen that we 
could be close to 1 second, even if we never met this value.

So, to be safe, I have set this timeout to 5 seconds.
As it is just a timeout value, I have not seen any side effect.
I am using the same timeout constant to avoid to have one timeout per 
cases.


Regards,
Christophe Kerello.


Re: [PATCH v2 04/12] mtd: rawnand: stm32_fmc2: manage all errors cases at probe time

2020-04-29 Thread Christophe Kerello

Hi Miquèl,

On 4/27/20 10:08 PM, Miquel Raynal wrote:
[...]

btw would it make sense to split the first three patches of this series
into a separate series ? This rawnand part seems more like an unrelated
cleanup.

As it seems that the MFD discussion can take longer, then I would say
yes, at least for the cleanup/misc changes part.

Right



I think that it is better to only have one set of patches as there is 
different maintainers that will review the whole set of patches.
I expect to be able to propose a v3 next week to add the EBI driver and 
the updates on NAND driver (as some patches are linked)
A proposal could be to put all the NAND patches that you have started to 
review at the beginning of the set of patches (patch 4/5/6/7/8).
You will be free to apply them after the review and I will only resubmit 
the patches that have not been applied in the next version.


Regards,
Christophe Kerello.


Re: [PATCH v2 04/12] mtd: rawnand: stm32_fmc2: manage all errors cases at probe time

2020-04-29 Thread Christophe Kerello




On 4/27/20 10:10 PM, Marek Vasut wrote:

On 4/27/20 10:08 PM, Miquel Raynal wrote:

Hi Marek,

Marek Vasut  wrote on Mon, 27 Apr 2020 21:46:44 +0200:


On 4/27/20 8:08 PM, Miquel Raynal wrote:
[...]

/* FMC2 init routine */
stm32_fmc2_init(fmc2);
@@ -1997,7 +2001,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
/* Scan to find existence of the device */
ret = nand_scan(chip, nand->ncs);
if (ret)
-   goto err_scan;
+   goto err_dma_setup;
  
  	ret = mtd_device_register(mtd, NULL, 0);

if (ret)
@@ -2010,7 +2014,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
  err_device_register:
nand_cleanup(chip);
  
-err_scan:

+err_dma_setup:
if (fmc2->dma_ecc_ch)
dma_release_channel(fmc2->dma_ecc_ch);
if (fmc2->dma_tx_ch)
@@ -2021,6 +2025,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
sg_free_table(>dma_data_sg);
sg_free_table(>dma_ecc_sg);
  
+err_clk_disable:

clk_disable_unprepare(fmc2->clk);
  
  	return ret;


I didn't spot it during my earlier reviews but I really prefer using
labels explaining what you do than having the same name of the function
which failed. This way you don't have to rework the error path when
you handle an additional error.

So, would you mind doing this in two steps:

1/
Replace

 err_scan:

with, eg.

 release_dma_objs:


The ^err_ prefix in failpath labels is useful, since it's easily
possible to match on it with regexes ; not so much on arbitrary label name.


I guess so, but is it actually useful to catch labels in a regex? (real
question)


I find it useful to have a unified way to find those labels, e.g.
err_because_foo:
err_because_bar:
err_last_one:
is much nicer than:
foo_failed:
bar_also_failed:
its_total_randomness:


My point being, Christophe, you can use err_ as a prefix but I think
it's better to use:

 err_do_this_cleanup

than

err_this_failed


That's fine either way.


Hi Miquel,

I will rename the label in v3:
 - err_device_register => err_nand_cleanup
 - err_dma_setup => err_release_dma
 - err_clk_disable => will keep this one

Regards,
Christophe Kerello.




Any way I suppose catching ":\n" is already a good approximation to
find labels?


Not very practical with git grep (^err.*: works nicely though)


I suppose ^.*:$ would work the same ;)


Try and see how much other irrelevant stuff that sucks in ;-)



[PATCH v2] mtd: rawnand: stm32_fmc2: avoid warnings when building with W=1 option

2019-07-09 Thread Christophe Kerello
This patch solves warnings detected by setting W=1 when building.

Warnings type detected:
drivers/mtd/nand/raw/stm32_fmc2_nand.c: In function ‘stm32_fmc2_calc_timings’:
drivers/mtd/nand/raw/stm32_fmc2_nand.c:1417:23: warning: comparison is
always false due to limited range of data type [-Wtype-limits]
  else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK)

Signed-off-by: Christophe Kerello 
Cc: sta...@vger.kernel.org
Fixes: 2cd457f328c1 ("mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash
controller driver")
---
Changes in v2:
  - Fixes/stable tag added

 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 90 +++---
 1 file changed, 29 insertions(+), 61 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index e63acc0..8cc852d 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1427,21 +1427,16 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
struct stm32_fmc2_timings *tims = >timings;
unsigned long hclk = clk_get_rate(fmc2->clk);
unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000);
-   int tar, tclr, thiz, twait, tset_mem, tset_att, thold_mem, thold_att;
-
-   tar = hclkp;
-   if (tar < sdrt->tAR_min)
-   tar = sdrt->tAR_min;
-   tims->tar = DIV_ROUND_UP(tar, hclkp) - 1;
-   if (tims->tar > FMC2_PCR_TIMING_MASK)
-   tims->tar = FMC2_PCR_TIMING_MASK;
-
-   tclr = hclkp;
-   if (tclr < sdrt->tCLR_min)
-   tclr = sdrt->tCLR_min;
-   tims->tclr = DIV_ROUND_UP(tclr, hclkp) - 1;
-   if (tims->tclr > FMC2_PCR_TIMING_MASK)
-   tims->tclr = FMC2_PCR_TIMING_MASK;
+   unsigned long timing, tar, tclr, thiz, twait;
+   unsigned long tset_mem, tset_att, thold_mem, thold_att;
+
+   tar = max_t(unsigned long, hclkp, sdrt->tAR_min);
+   timing = DIV_ROUND_UP(tar, hclkp) - 1;
+   tims->tar = min_t(unsigned long, timing, FMC2_PCR_TIMING_MASK);
+
+   tclr = max_t(unsigned long, hclkp, sdrt->tCLR_min);
+   timing = DIV_ROUND_UP(tclr, hclkp) - 1;
+   tims->tclr = min_t(unsigned long, timing, FMC2_PCR_TIMING_MASK);
 
tims->thiz = FMC2_THIZ;
thiz = (tims->thiz + 1) * hclkp;
@@ -1451,18 +1446,11 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
 * tWAIT > tWP
 * tWAIT > tREA + tIO
 */
-   twait = hclkp;
-   if (twait < sdrt->tRP_min)
-   twait = sdrt->tRP_min;
-   if (twait < sdrt->tWP_min)
-   twait = sdrt->tWP_min;
-   if (twait < sdrt->tREA_max + FMC2_TIO)
-   twait = sdrt->tREA_max + FMC2_TIO;
-   tims->twait = DIV_ROUND_UP(twait, hclkp);
-   if (tims->twait == 0)
-   tims->twait = 1;
-   else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK)
-   tims->twait = FMC2_PMEM_PATT_TIMING_MASK;
+   twait = max_t(unsigned long, hclkp, sdrt->tRP_min);
+   twait = max_t(unsigned long, twait, sdrt->tWP_min);
+   twait = max_t(unsigned long, twait, sdrt->tREA_max + FMC2_TIO);
+   timing = DIV_ROUND_UP(twait, hclkp);
+   tims->twait = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK);
 
/*
 * tSETUP_MEM > tCS - tWAIT
@@ -1477,20 +1465,15 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
if (twait > thiz && (sdrt->tDS_min > twait - thiz) &&
(tset_mem < sdrt->tDS_min - (twait - thiz)))
tset_mem = sdrt->tDS_min - (twait - thiz);
-   tims->tset_mem = DIV_ROUND_UP(tset_mem, hclkp);
-   if (tims->tset_mem == 0)
-   tims->tset_mem = 1;
-   else if (tims->tset_mem > FMC2_PMEM_PATT_TIMING_MASK)
-   tims->tset_mem = FMC2_PMEM_PATT_TIMING_MASK;
+   timing = DIV_ROUND_UP(tset_mem, hclkp);
+   tims->tset_mem = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK);
 
/*
 * tHOLD_MEM > tCH
 * tHOLD_MEM > tREH - tSETUP_MEM
 * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT)
 */
-   thold_mem = hclkp;
-   if (thold_mem < sdrt->tCH_min)
-   thold_mem = sdrt->tCH_min;
+   thold_mem = max_t(unsigned long, hclkp, sdrt->tCH_min);
if (sdrt->tREH_min > tset_mem &&
(thold_mem < sdrt->tREH_min - tset_mem))
thold_mem = sdrt->tREH_min - tset_mem;
@@ -1500,11 +1483,8 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
if ((sdrt->tWC_min > tset_mem + twait) &&
(thold_mem < sdrt->tWC_min - (tset_mem + twait)))
thold_mem = sdrt->tWC_min - (tset_mem + twait);
-   tims->thold_mem = DIV_ROUND_UP(thold_mem, hclkp);
-  

Re: [PATCH] mtd: rawnand: stm32_fmc2: avoid warnings when building with W=1 option

2019-07-09 Thread Christophe Kerello




On 7/1/19 9:11 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Fri, 21 Jun
2019 16:43:09 +0200:


This patch solves warnings detected by setting W=1 when building.

Warnings type detected:
drivers/mtd/nand/raw/stm32_fmc2_nand.c: In function ‘stm32_fmc2_calc_timings’:
drivers/mtd/nand/raw/stm32_fmc2_nand.c:1417:23: warning: comparison is
always false due to limited range of data type [-Wtype-limits]
   else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK)

Signed-off-by: Christophe Kerello 
---


Applied to nand/next, thanks.


Hi Miquel,

After fetching nand/next, I do not see this patch applied.

Regards,
Christophe Kerello.



Miquèl



[PATCH v2] mtd: rawnand: stm32_fmc2: increase DMA completion timeouts

2019-06-28 Thread Christophe Kerello
From: Amelie Delaunay 

When the system is overloaded, DMA data transfer completion occurs after
100ms. Increase the timeouts to let it the time to complete.

Signed-off-by: Amelie Delaunay 
Signed-off-by: Christophe Kerello 
---
Changes in v2:
  - Replace the author of the patch.
  - Define FMC2_TIMEOUT_MS to 1000.

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

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 4aabea2..e63acc0 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -37,6 +37,8 @@
 /* Max ECC buffer length */
 #define FMC2_MAX_ECC_BUF_LEN   (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
 
+#define FMC2_TIMEOUT_MS1000
+
 /* Timings */
 #define FMC2_THIZ  1
 #define FMC2_TIO   8000
@@ -530,7 +532,8 @@ static int stm32_fmc2_ham_calculate(struct nand_chip *chip, 
const u8 *data,
int ret;
 
ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
-sr, sr & FMC2_SR_NWRF, 10, 1000);
+sr, sr & FMC2_SR_NWRF, 10,
+FMC2_TIMEOUT_MS);
if (ret) {
dev_err(fmc2->dev, "ham timeout\n");
return ret;
@@ -611,7 +614,7 @@ static int stm32_fmc2_bch_calculate(struct nand_chip *chip, 
const u8 *data,
 
/* Wait until the BCH code is ready */
if (!wait_for_completion_timeout(>complete,
-msecs_to_jiffies(1000))) {
+msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
dev_err(fmc2->dev, "bch timeout\n");
stm32_fmc2_disable_bch_irq(fmc2);
return -ETIMEDOUT;
@@ -696,7 +699,7 @@ static int stm32_fmc2_bch_correct(struct nand_chip *chip, 
u8 *dat,
 
/* Wait until the decoding error is ready */
if (!wait_for_completion_timeout(>complete,
-msecs_to_jiffies(1000))) {
+msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
dev_err(fmc2->dev, "bch timeout\n");
stm32_fmc2_disable_bch_irq(fmc2);
return -ETIMEDOUT;
@@ -969,7 +972,7 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 
*buf,
 
/* Wait end of sequencer transfer */
if (!wait_for_completion_timeout(>complete,
-msecs_to_jiffies(1000))) {
+msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
dev_err(fmc2->dev, "seq timeout\n");
stm32_fmc2_disable_seq_irq(fmc2);
dmaengine_terminate_all(dma_ch);
@@ -981,7 +984,7 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 
*buf,
 
/* Wait DMA data transfer completion */
if (!wait_for_completion_timeout(>dma_data_complete,
-msecs_to_jiffies(100))) {
+msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
dev_err(fmc2->dev, "data DMA timeout\n");
dmaengine_terminate_all(dma_ch);
ret = -ETIMEDOUT;
@@ -990,7 +993,7 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 
*buf,
/* Wait DMA ECC transfer completion */
if (!write_data && !raw) {
if (!wait_for_completion_timeout(>dma_ecc_complete,
-msecs_to_jiffies(100))) {
+   msecs_to_jiffies(FMC2_TIMEOUT_MS))) {
dev_err(fmc2->dev, "ECC DMA timeout\n");
dmaengine_terminate_all(fmc2->dma_ecc_ch);
ret = -ETIMEDOUT;
-- 
1.9.1



[PATCH 4/4] ARM: multi_v7_defconfig: add FMC2 NAND controller support

2019-06-21 Thread Christophe Kerello
This patch adds FMC2 NAND controller support used by STM32MP SOCs.

Signed-off-by: Christophe Kerello 
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index e386f35..092255c 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -197,6 +197,7 @@ CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_BRCMNAND=y
 CONFIG_MTD_NAND_VF610_NFC=y
 CONFIG_MTD_NAND_DAVINCI=y
+CONFIG_MTD_NAND_STM32_FMC2=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
-- 
1.9.1



[PATCH 3/4] ARM: dts: stm32: enable FMC2 NAND controller on stm32mp157c-ev1

2019-06-21 Thread Christophe Kerello
This patch enables FMC2 NAND controller used on stm32mp157c-ev1.

Signed-off-by: Christophe Kerello 
---
 arch/arm/boot/dts/stm32mp157c-ev1.dts | 16 
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp157c-ev1.dts 
b/arch/arm/boot/dts/stm32mp157c-ev1.dts
index feb8f77..9ab25da 100644
--- a/arch/arm/boot/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ev1.dts
@@ -157,6 +157,22 @@
};
 };
 
+ {
+   pinctrl-names = "default", "sleep";
+   pinctrl-0 = <_pins_a>;
+   pinctrl-1 = <_sleep_pins_a>;
+   status = "okay";
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nand@0 {
+   reg = <0>;
+   nand-on-flash-bbt;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
1.9.1



[PATCH 2/4] ARM: dts: stm32: add FMC2 NAND controller pins muxing on stm32mp157c-ev1

2019-06-21 Thread Christophe Kerello
This patch adds FMC2 NAND controller pins muxing used on stm32mp157c-ev1.

Signed-off-by: Christophe Kerello 
---
 arch/arm/boot/dts/stm32mp157-pinctrl.dtsi | 44 +++
 1 file changed, 44 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi 
b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
index df64701..c4f2b23 100644
--- a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
@@ -276,6 +276,50 @@
};
};
 
+   fmc_pins_a: fmc-0 {
+   pins1 {
+   pinmux = , 
/* FMC_NOE */
+, 
/* FMC_NWE */
+, 
/* FMC_A16_FMC_CLE */
+, 
/* FMC_A17_FMC_ALE */
+, 
/* FMC_D0 */
+, 
/* FMC_D1 */
+, 
/* FMC_D2 */
+, 
/* FMC_D3 */
+, 
/* FMC_D4 */
+, 
/* FMC_D5 */
+, 
/* FMC_D6 */
+, 
/* FMC_D7 */
+; 
/* FMC_NE2_FMC_NCE */
+   bias-disable;
+   drive-push-pull;
+   slew-rate = <1>;
+   };
+   pins2 {
+   pinmux = ; 
/* FMC_NWAIT */
+   bias-pull-up;
+   };
+   };
+
+   fmc_sleep_pins_a: fmc-sleep-0 {
+   pins {
+   pinmux = , /* FMC_NOE */
+, /* FMC_NWE */
+, /* FMC_A16_FMC_CLE */
+, /* FMC_A17_FMC_ALE */
+, /* FMC_D0 */
+, /* FMC_D1 */
+, /* FMC_D2 */
+, /* FMC_D3 */
+, /* FMC_D4 */
+, /* FMC_D5 */
+, /* FMC_D6 */
+, /* FMC_D7 */
+, /* FMC_NWAIT */
+; /* FMC_NE2_FMC_NCE */
+   };
+   };
+
i2c1_pins_a: i2c1-0 {
pins {
pinmux = , 
/* I2C1_SCL */
-- 
1.9.1



[PATCH 1/4] ARM: dts: stm32: add FMC2 NAND controller support on stm32mp157c

2019-06-21 Thread Christophe Kerello
This patch adds FMC2 NAND controller support used by stm32mp157c SOC.

Signed-off-by: Christophe Kerello 
---
 arch/arm/boot/dts/stm32mp157c.dtsi | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi 
b/arch/arm/boot/dts/stm32mp157c.dtsi
index 0c4e6eb..f2bda28 100644
--- a/arch/arm/boot/dts/stm32mp157c.dtsi
+++ b/arch/arm/boot/dts/stm32mp157c.dtsi
@@ -1239,6 +1239,25 @@
dma-requests = <48>;
};
 
+   fmc: nand-controller@58002000 {
+   compatible = "st,stm32mp15-fmc2";
+   reg = <0x58002000 0x1000>,
+ <0x8000 0x1000>,
+ <0x8801 0x1000>,
+ <0x8802 0x1000>,
+ <0x8100 0x1000>,
+ <0x8901 0x1000>,
+ <0x8902 0x1000>;
+   interrupts = ;
+   dmas = < 20 0x10 0x12000A02 0x0 0x0>,
+  < 20 0x10 0x12000A08 0x0 0x0>,
+  < 21 0x10 0x12000A0A 0x0 0x0>;
+   dma-names = "tx", "rx", "ecc";
+   clocks = < FMC_K>;
+   resets = < FMC_R>;
+   status = "disabled";
+   };
+
qspi: spi@58003000 {
compatible = "st,stm32f469-qspi";
reg = <0x58003000 0x1000>, <0x7000 0x1000>;
-- 
1.9.1



[PATCH 0/4] ARM: dts: stm32: enable FMC2 NAND controller on stm32mp157c-ev1

2019-06-21 Thread Christophe Kerello
This patchset adds and enables FMC2 NAND controller used on
stm32mp157c-ev1.

Christophe Kerello (4):
  ARM: dts: stm32: add FMC2 NAND controller support on stm32mp157c
  ARM: dts: stm32: add FMC2 NAND controller pins muxing on
stm32mp157c-ev1
  ARM: dts: stm32: enable FMC2 NAND controller on stm32mp157c-ev1
  ARM: multi_v7_defconfig: add FMC2 NAND  controller support

 arch/arm/boot/dts/stm32mp157-pinctrl.dtsi | 44 +++
 arch/arm/boot/dts/stm32mp157c-ev1.dts | 16 +++
 arch/arm/boot/dts/stm32mp157c.dtsi| 19 +
 arch/arm/configs/multi_v7_defconfig   |  1 +
 4 files changed, 80 insertions(+)

-- 
1.9.1



[PATCH] mtd: rawnand: stm32_fmc2: increase DMA completion timeouts

2019-06-21 Thread Christophe Kerello
When the system is overloaded, DMA data transfer completion occurs after
100ms. Increase the timeouts to let it the time to complete.

Signed-off-by: Amelie Delaunay 
Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 4aabea2..c7f7c6f 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -981,7 +981,7 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 
*buf,
 
/* Wait DMA data transfer completion */
if (!wait_for_completion_timeout(>dma_data_complete,
-msecs_to_jiffies(100))) {
+msecs_to_jiffies(500))) {
dev_err(fmc2->dev, "data DMA timeout\n");
dmaengine_terminate_all(dma_ch);
ret = -ETIMEDOUT;
@@ -990,7 +990,7 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 
*buf,
/* Wait DMA ECC transfer completion */
if (!write_data && !raw) {
if (!wait_for_completion_timeout(>dma_ecc_complete,
-msecs_to_jiffies(100))) {
+msecs_to_jiffies(500))) {
dev_err(fmc2->dev, "ECC DMA timeout\n");
dmaengine_terminate_all(fmc2->dma_ecc_ch);
ret = -ETIMEDOUT;
-- 
1.9.1



[PATCH] mtd: rawnand: stm32_fmc2: avoid warnings when building with W=1 option

2019-06-21 Thread Christophe Kerello
This patch solves warnings detected by setting W=1 when building.

Warnings type detected:
drivers/mtd/nand/raw/stm32_fmc2_nand.c: In function ‘stm32_fmc2_calc_timings’:
drivers/mtd/nand/raw/stm32_fmc2_nand.c:1417:23: warning: comparison is
always false due to limited range of data type [-Wtype-limits]
  else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK)

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 90 +++---
 1 file changed, 29 insertions(+), 61 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 4aabea2..ed6e7e2 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1424,21 +1424,16 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
struct stm32_fmc2_timings *tims = >timings;
unsigned long hclk = clk_get_rate(fmc2->clk);
unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000);
-   int tar, tclr, thiz, twait, tset_mem, tset_att, thold_mem, thold_att;
-
-   tar = hclkp;
-   if (tar < sdrt->tAR_min)
-   tar = sdrt->tAR_min;
-   tims->tar = DIV_ROUND_UP(tar, hclkp) - 1;
-   if (tims->tar > FMC2_PCR_TIMING_MASK)
-   tims->tar = FMC2_PCR_TIMING_MASK;
-
-   tclr = hclkp;
-   if (tclr < sdrt->tCLR_min)
-   tclr = sdrt->tCLR_min;
-   tims->tclr = DIV_ROUND_UP(tclr, hclkp) - 1;
-   if (tims->tclr > FMC2_PCR_TIMING_MASK)
-   tims->tclr = FMC2_PCR_TIMING_MASK;
+   unsigned long timing, tar, tclr, thiz, twait;
+   unsigned long tset_mem, tset_att, thold_mem, thold_att;
+
+   tar = max_t(unsigned long, hclkp, sdrt->tAR_min);
+   timing = DIV_ROUND_UP(tar, hclkp) - 1;
+   tims->tar = min_t(unsigned long, timing, FMC2_PCR_TIMING_MASK);
+
+   tclr = max_t(unsigned long, hclkp, sdrt->tCLR_min);
+   timing = DIV_ROUND_UP(tclr, hclkp) - 1;
+   tims->tclr = min_t(unsigned long, timing, FMC2_PCR_TIMING_MASK);
 
tims->thiz = FMC2_THIZ;
thiz = (tims->thiz + 1) * hclkp;
@@ -1448,18 +1443,11 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
 * tWAIT > tWP
 * tWAIT > tREA + tIO
 */
-   twait = hclkp;
-   if (twait < sdrt->tRP_min)
-   twait = sdrt->tRP_min;
-   if (twait < sdrt->tWP_min)
-   twait = sdrt->tWP_min;
-   if (twait < sdrt->tREA_max + FMC2_TIO)
-   twait = sdrt->tREA_max + FMC2_TIO;
-   tims->twait = DIV_ROUND_UP(twait, hclkp);
-   if (tims->twait == 0)
-   tims->twait = 1;
-   else if (tims->twait > FMC2_PMEM_PATT_TIMING_MASK)
-   tims->twait = FMC2_PMEM_PATT_TIMING_MASK;
+   twait = max_t(unsigned long, hclkp, sdrt->tRP_min);
+   twait = max_t(unsigned long, twait, sdrt->tWP_min);
+   twait = max_t(unsigned long, twait, sdrt->tREA_max + FMC2_TIO);
+   timing = DIV_ROUND_UP(twait, hclkp);
+   tims->twait = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK);
 
/*
 * tSETUP_MEM > tCS - tWAIT
@@ -1474,20 +1462,15 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
if (twait > thiz && (sdrt->tDS_min > twait - thiz) &&
(tset_mem < sdrt->tDS_min - (twait - thiz)))
tset_mem = sdrt->tDS_min - (twait - thiz);
-   tims->tset_mem = DIV_ROUND_UP(tset_mem, hclkp);
-   if (tims->tset_mem == 0)
-   tims->tset_mem = 1;
-   else if (tims->tset_mem > FMC2_PMEM_PATT_TIMING_MASK)
-   tims->tset_mem = FMC2_PMEM_PATT_TIMING_MASK;
+   timing = DIV_ROUND_UP(tset_mem, hclkp);
+   tims->tset_mem = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK);
 
/*
 * tHOLD_MEM > tCH
 * tHOLD_MEM > tREH - tSETUP_MEM
 * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT)
 */
-   thold_mem = hclkp;
-   if (thold_mem < sdrt->tCH_min)
-   thold_mem = sdrt->tCH_min;
+   thold_mem = max_t(unsigned long, hclkp, sdrt->tCH_min);
if (sdrt->tREH_min > tset_mem &&
(thold_mem < sdrt->tREH_min - tset_mem))
thold_mem = sdrt->tREH_min - tset_mem;
@@ -1497,11 +1480,8 @@ static void stm32_fmc2_calc_timings(struct nand_chip 
*chip,
if ((sdrt->tWC_min > tset_mem + twait) &&
(thold_mem < sdrt->tWC_min - (tset_mem + twait)))
thold_mem = sdrt->tWC_min - (tset_mem + twait);
-   tims->thold_mem = DIV_ROUND_UP(thold_mem, hclkp);
-   if (tims->thold_mem == 0)
-   tims->thold_mem = 1;
-   else if (tims->thold_mem > FMC2_PMEM_PATT_TIMING_MASK)
-   tims->thold_mem =

Re: [PATCH] mtd: rawnand: stm32_fmc2: manage the get_irq error case

2019-04-25 Thread Christophe Kerello




On 4/24/19 4:49 PM, Fabien Dessenne wrote:

During probe, check the "get_irq" error value.

Signed-off-by: Fabien Dessenne 


Acked-by: Christophe Kerello 


---
  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 999ca6a..4aabea2 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1909,6 +1909,12 @@ static int stm32_fmc2_probe(struct platform_device *pdev)
}
  
  	irq = platform_get_irq(pdev, 0);

+   if (irq < 0) {
+   if (irq != -EPROBE_DEFER)
+   dev_err(dev, "IRQ error missing or invalid\n");
+   return irq;
+   }
+
ret = devm_request_irq(dev, irq, stm32_fmc2_irq, 0,
   dev_name(dev), fmc2);
if (ret) {



[PATCH v4 3/3] mtd: rawnand: stm32_fmc2: add polling mode

2018-12-14 Thread Christophe Kerello
This patch adds the polling mode, a basic mode that do not need
any DMA channels. This mode is also useful for debug purpose.

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 329 +
 1 file changed, 297 insertions(+), 32 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b62b052..e057282 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -207,6 +207,12 @@ enum stm32_fmc2_ecc {
FMC2_ECC_BCH8 = 8
 };
 
+enum stm32_fmc2_irq_state {
+   FMC2_IRQ_UNKNOWN = 0,
+   FMC2_IRQ_BCH,
+   FMC2_IRQ_SEQ
+};
+
 struct stm32_fmc2_timings {
u8 tclr;
u8 tar;
@@ -241,6 +247,7 @@ struct stm32_fmc2_nfc {
phys_addr_t io_phys_addr;
phys_addr_t data_phys_addr[FMC2_MAX_CE];
struct clk *clk;
+   u8 irq_state;
 
struct dma_chan *dma_tx_ch;
struct dma_chan *dma_rx_ch;
@@ -400,6 +407,17 @@ static void stm32_fmc2_set_buswidth_16(struct 
stm32_fmc2_nfc *fmc2, bool set)
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
 }
 
+/* Enable/disable ECC */
+static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
+{
+   u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+
+   pcr &= ~FMC2_PCR_ECCEN;
+   if (enable)
+   pcr |= FMC2_PCR_ECCEN;
+   writel(pcr, fmc2->io_base + FMC2_PCR);
+}
+
 /* Enable irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_enable_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
@@ -407,6 +425,8 @@ static inline void stm32_fmc2_enable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
 
csqier |= FMC2_CSQIER_TCIE;
 
+   fmc2->irq_state = FMC2_IRQ_SEQ;
+
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
 }
 
@@ -418,6 +438,8 @@ static inline void stm32_fmc2_disable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
csqier &= ~FMC2_CSQIER_TCIE;
 
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
+
+   fmc2->irq_state = FMC2_IRQ_UNKNOWN;
 }
 
 /* Clear irq sources in case of the sequencer is used */
@@ -426,6 +448,68 @@ static inline void stm32_fmc2_clear_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, fmc2->io_base + FMC2_CSQICR);
 }
 
+/* Enable irq sources in case of bch is used */
+static inline void stm32_fmc2_enable_bch_irq(struct stm32_fmc2_nfc *fmc2,
+int mode)
+{
+   u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+
+   if (mode == NAND_ECC_WRITE)
+   bchier |= FMC2_BCHIER_EPBRIE;
+   else
+   bchier |= FMC2_BCHIER_DERIE;
+
+   fmc2->irq_state = FMC2_IRQ_BCH;
+
+   writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+}
+
+/* Disable irq sources in case of bch is used */
+static inline void stm32_fmc2_disable_bch_irq(struct stm32_fmc2_nfc *fmc2)
+{
+   u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+
+   bchier &= ~FMC2_BCHIER_DERIE;
+   bchier &= ~FMC2_BCHIER_EPBRIE;
+
+   writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+
+   fmc2->irq_state = FMC2_IRQ_UNKNOWN;
+}
+
+/* Clear irq sources in case of bch is used */
+static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
+{
+   writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
+}
+
+/*
+ * Enable ECC logic and reset syndrome/parity bits previously calculated
+ * Syndrome/parity bits is cleared by setting the ECCEN bit to 0
+ */
+static void stm32_fmc2_hwctl(struct nand_chip *chip, int mode)
+{
+   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+
+   stm32_fmc2_set_ecc(fmc2, false);
+
+   if (chip->ecc.strength != FMC2_ECC_HAM) {
+   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+
+   if (mode == NAND_ECC_WRITE)
+   pcr |= FMC2_PCR_WEN;
+   else
+   pcr &= ~FMC2_PCR_WEN;
+   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+
+   reinit_completion(>complete);
+   stm32_fmc2_clear_bch_irq(fmc2);
+   stm32_fmc2_enable_bch_irq(fmc2, mode);
+   }
+
+   stm32_fmc2_set_ecc(fmc2, true);
+}
+
 /*
  * ECC Hamming calculation
  * ECC is 3 bytes for 512 bytes of data (supports error correction up to
@@ -438,6 +522,30 @@ static inline void stm32_fmc2_ham_set_ecc(const u32 
ecc_sta, u8 *ecc)
ecc[2] = ecc_sta >> 16;
 }
 
+static int stm32_fmc2_ham_calculate(struct nand_chip *chip, const u8 *data,
+   u8 *ecc)
+{
+   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   u32 sr, heccr;
+   int ret;
+
+   ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
+sr, sr &am

[PATCH v4 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-12-14 Thread Christophe Kerello
The driver adds the support for the STMicroelectronics FMC2 NAND
Controller found on STM32MP SOCs.

This patch is based on FMC2 command sequencer.
The purpose of the command sequencer is to facilitate the programming
and the reading of NAND flash pages with the ECC and to free the CPU
of sequencing tasks.
It requires one DMA channel for write and two DMA channels for read
operations.

Only NAND_ECC_HW mode is actually supported.
The driver supports a maximum 8k page size.
The following ECC strength and step size are currently supported:
 - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
 - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
 - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended ECC
   based on Hamming)

This patch has been tested on Micron MT29F8G08ABACAH4 and
MT29F8G16ABACAH4

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/Kconfig   |9 +
 drivers/mtd/nand/raw/Makefile  |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1808 
 3 files changed, 1818 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 1a55d3e..0f479be 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -541,4 +541,13 @@ config MTD_NAND_TEGRA
  is supported. Extra OOB bytes when using HW ECC are currently
  not supported.
 
+config MTD_NAND_STM32_FMC2
+   tristate "Support for NAND controller on STM32MP SoCs"
+   depends on MACH_STM32MP157 || COMPILE_TEST
+   help
+ Enables support for NAND Flash chips on SoCs containing the FMC2
+ NAND controller. This controller is found on STM32MP SoCs.
+ The controller supports a maximum 8k page size and supports
+ a maximum 8-bit correction error per sector of 512 bytes.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 57159b3..325bc9e 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND)   += brcmnand/
 obj-$(CONFIG_MTD_NAND_QCOM)+= qcom_nandc.o
 obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
 obj-$(CONFIG_MTD_NAND_TEGRA)   += tegra_nand.o
+obj-$(CONFIG_MTD_NAND_STM32_FMC2)  += stm32_fmc2_nand.o
 
 nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
 nand-objs += nand_onfi.o
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
new file mode 100644
index 000..b62b052
--- /dev/null
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -0,0 +1,1808 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018
+ * Author: Christophe Kerello 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Bad block marker length */
+#define FMC2_BBM_LEN   2
+
+/* ECC step size */
+#define FMC2_ECC_STEP_SIZE 512
+
+/* BCHDSRx registers length */
+#define FMC2_BCHDSRS_LEN   20
+
+/* HECCR length */
+#define FMC2_HECCR_LEN 4
+
+/* Max requests done for a 8k nand page size */
+#define FMC2_MAX_SG16
+
+/* Max chip enable */
+#define FMC2_MAX_CE2
+
+/* Max ECC buffer length */
+#define FMC2_MAX_ECC_BUF_LEN   (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
+
+/* Timings */
+#define FMC2_THIZ  1
+#define FMC2_TIO   8000
+#define FMC2_TSYNC 3000
+#define FMC2_PCR_TIMING_MASK   0xf
+#define FMC2_PMEM_PATT_TIMING_MASK 0xff
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_PCR   0x80
+#define FMC2_SR0x84
+#define FMC2_PMEM  0x88
+#define FMC2_PATT  0x8c
+#define FMC2_HECCR 0x94
+#define FMC2_CSQCR 0x200
+#define FMC2_CSQCFGR1  0x204
+#define FMC2_CSQCFGR2  0x208
+#define FMC2_CSQCFGR3  0x20c
+#define FMC2_CSQAR10x210
+#define FMC2_CSQAR20x214
+#define FMC2_CSQIER0x220
+#define FMC2_CSQISR0x224
+#define FMC2_CSQICR0x228
+#define FMC2_CSQEMSR   0x230
+#define FMC2_BCHIER0x250
+#define FMC2_BCHISR0x254
+#define FMC2_BCHICR0x258
+#define FMC2_BCHPBR1   0x260
+#define FMC2_BCHPBR2   0x264
+#define FMC2_BCHPBR3   0x268
+#define FMC2_BCHPBR4   0x26c
+#define FMC2_BCHDSR0   0x27c
+#define FMC2_BCHDSR1   0x280

[PATCH v4 0/3] mtd: rawnand: add STM32 FMC2 NAND flash controller driver

2018-12-14 Thread Christophe Kerello
This patchset adds the support for the STMicroelectronics FMC2 NAND flash
controller found on STM32MP SOCs.

This patchset supports:
  - the command sequencer feature, a hardware accelerator for read/write
within a page
  - the manual mode feature, useful for debug purpose
  - a maximum 8k page size
  - following ECC strength and step size
- nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
- nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
- nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended
  ecc based on HAMMING)

This patchset has been tested on Micron MT29F8G08ABACAH4 (8-bit SLC NAND)
and MT29F8G16ABACAH4 (16-bit SLC NAND)

Changes v4:
 - rebase on nand/next
 - replace "manual mode" by "polling mode"

Changes v3:
 - modify clocks property description
 - add NAND reg property description
 - stm32_fmc2_nfc inherits from nand_controller structure
 - rewrite stm32_fmc2_read_data/stm32_fmc2_write_data functions
   to handle aligned and not aligned buffers
 - replace uint8_t by u8
 - use of NAND_ROW_ADDR_3 option

Changes v2:
 - separate the controller structure and the NAND chip structure
 - remove timings description from the device tree
 - fix typo issues
 - fix kbuildrobot issues

Christophe Kerello (3):
  dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller
documentation
  mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver
  mtd: rawnand: stm32_fmc2: add polling mode

 .../devicetree/bindings/mtd/stm32-fmc2-nand.txt|   61 +
 drivers/mtd/nand/raw/Kconfig   |9 +
 drivers/mtd/nand/raw/Makefile  |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 2073 
 4 files changed, 2144 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
 create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c

-- 
1.9.1



[PATCH v4 1/3] dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller documentation

2018-12-14 Thread Christophe Kerello
This patch adds the documentation of the device tree bindings for the STM32
FMC2 NAND controller.

Signed-off-by: Christophe Kerello 
---
 .../devicetree/bindings/mtd/stm32-fmc2-nand.txt| 61 ++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt 
b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
new file mode 100644
index 000..ad2bef8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
@@ -0,0 +1,61 @@
+STMicroelectronics Flexible Memory Controller 2 (FMC2)
+NAND Interface
+
+Required properties:
+- compatible: Should be one of:
+  * st,stm32mp15-fmc2
+- reg: NAND flash controller memory areas.
+   First region contains the register location.
+   Regions 2 to 4 respectively contain the data, command,
+   and address space for CS0.
+   Regions 5 to 7 contain the same areas for CS1.
+- interrupts: The interrupt number
+- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
+- clocks: The clock needed by the NAND flash controller
+
+Optional properties:
+- resets: Reference to a reset controller asserting the FMC controller
+- dmas: DMA specifiers (see: dma/stm32-mdma.txt)
+- dma-names: Must be "tx", "rx" and "ecc"
+
+* NAND device bindings:
+
+Required properties:
+- reg: describes the CS lines assigned to the NAND device.
+
+Optional properties:
+- nand-on-flash-bbt: see nand.txt
+- nand-ecc-strength: see nand.txt
+- nand-ecc-step-size: see nand.txt
+
+The following ECC strength and step size are currently supported:
+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming)
+ - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
+ - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default)
+
+Example:
+
+   fmc: nand-controller@58002000 {
+   compatible = "st,stm32mp15-fmc2";
+   reg = <0x58002000 0x1000>,
+ <0x8000 0x1000>,
+ <0x8801 0x1000>,
+ <0x8802 0x1000>,
+ <0x8100 0x1000>,
+ <0x8901 0x1000>,
+ <0x8902 0x1000>;
+   interrupts = ;
+   clocks = < FMC_K>;
+   resets = < FMC_R>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nand@0 {
+   reg = <0>;
+   nand-on-flash-bbt;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
+   };
-- 
1.9.1



Re: [ v3 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-12-07 Thread Christophe Kerello

On 12/7/18 10:06 AM, Linus Walleij wrote:

Hi Christophe,

On Thu, Nov 29, 2018 at 5:42 PM Christophe Kerello
 wrote:


+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_PCR   0x80

(...)

+/* Register: FMC2_BCR1 */
+#define FMC2_BCR1_FMC2EN   BIT(31)


Well this looks like an especially clever register map and a specific choice
of bit 31 in the fist register to activate FMC2. Registers 0x04 thru
0x7c are completely unused save for one bit.

It's almost like this is the good old FSMC integrated in parallel with FMC2,
so that if you don't set bit 31, this becomes something that can be used
with drivers/mtd/nand/raw/fsmc_nand.c, and FMC2 mode is activated
by setting this bit, activating all the new registers.

It wouldn't surprise me given how HW designers like to work.

Is this the case?



Hi Linus,

Based on FMC2 datasheet,
The FMC2 controller includes 2 memory controllers:
 - the NOR/PSRAM memory controller
 - the NAND memory controller

The NOR/PSRAM controller mapping is starting at 0.
The NAND controller mapping is starting at 0x80.

We have only planned to develop a driver for the NAND memory controller.
There is currently no customer request to develop the NOR/PSRAM memory 
controller.


The bit FMC2_BCR1_FMC2EN is not used to switch from an IP version to 
another. After reset, the FMC2 controller is disabled. Once all the used 
memory controllers are configured, the FMC2 controller must be enabled 
by setting the FMC2EN bit in the FMC2_BCR1 register. If this bit is not 
set, the controller stays in disabled state.


Regards,
Christophe Kerello.


If that is the case I think it should at least be mentioned in commit
logs and DT bindings and possibly in a comment on the driver
itself.

Yours,
Linus Walleij



Re: [ v3 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-12-07 Thread Christophe Kerello

On 12/7/18 10:06 AM, Linus Walleij wrote:

Hi Christophe,

On Thu, Nov 29, 2018 at 5:42 PM Christophe Kerello
 wrote:


+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_PCR   0x80

(...)

+/* Register: FMC2_BCR1 */
+#define FMC2_BCR1_FMC2EN   BIT(31)


Well this looks like an especially clever register map and a specific choice
of bit 31 in the fist register to activate FMC2. Registers 0x04 thru
0x7c are completely unused save for one bit.

It's almost like this is the good old FSMC integrated in parallel with FMC2,
so that if you don't set bit 31, this becomes something that can be used
with drivers/mtd/nand/raw/fsmc_nand.c, and FMC2 mode is activated
by setting this bit, activating all the new registers.

It wouldn't surprise me given how HW designers like to work.

Is this the case?



Hi Linus,

Based on FMC2 datasheet,
The FMC2 controller includes 2 memory controllers:
 - the NOR/PSRAM memory controller
 - the NAND memory controller

The NOR/PSRAM controller mapping is starting at 0.
The NAND controller mapping is starting at 0x80.

We have only planned to develop a driver for the NAND memory controller.
There is currently no customer request to develop the NOR/PSRAM memory 
controller.


The bit FMC2_BCR1_FMC2EN is not used to switch from an IP version to 
another. After reset, the FMC2 controller is disabled. Once all the used 
memory controllers are configured, the FMC2 controller must be enabled 
by setting the FMC2EN bit in the FMC2_BCR1 register. If this bit is not 
set, the controller stays in disabled state.


Regards,
Christophe Kerello.


If that is the case I think it should at least be mentioned in commit
logs and DT bindings and possibly in a comment on the driver
itself.

Yours,
Linus Walleij



Re: [ v3 3/3] mtd: rawnand: stm32_fmc2: add manual mode

2018-12-07 Thread Christophe Kerello

Hi Linus,

It is correct.
I will replace "manual mode" by "polling mode" in next patchset.

Regards,
Christophe Kerello.

On 12/7/18 10:16 AM, Linus Walleij wrote:

On Thu, Nov 29, 2018 at 5:42 PM Christophe Kerello
 wrote:


This patch adds the manual mode, a basic mode that do not need
any DMA channels. This mode is also useful for debug purpose.

Signed-off-by: Christophe Kerello 


This is a bit of drive-by comment, but "manual mode" usually
means there is a person "a man" pulling levers and pushing
buttons. There is nothing manual inside a computer system.

I think the more appropriate term is "polling mode" which is
what we call code that read registers directly waiting for status
flags rather than relying on IRQs or DMA flows.

Yours,
Linus Walleij



Re: [ v3 3/3] mtd: rawnand: stm32_fmc2: add manual mode

2018-12-07 Thread Christophe Kerello

Hi Linus,

It is correct.
I will replace "manual mode" by "polling mode" in next patchset.

Regards,
Christophe Kerello.

On 12/7/18 10:16 AM, Linus Walleij wrote:

On Thu, Nov 29, 2018 at 5:42 PM Christophe Kerello
 wrote:


This patch adds the manual mode, a basic mode that do not need
any DMA channels. This mode is also useful for debug purpose.

Signed-off-by: Christophe Kerello 


This is a bit of drive-by comment, but "manual mode" usually
means there is a person "a man" pulling levers and pushing
buttons. There is nothing manual inside a computer system.

I think the more appropriate term is "polling mode" which is
what we call code that read registers directly waiting for status
flags rather than relying on IRQs or DMA flows.

Yours,
Linus Walleij



Re: [ v3 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-12-07 Thread Christophe Kerello

Hi Miquèl,

This patchset already takes into account new framework modifications 
done by Boris (3rd batch of cleanups).


The select_chip hook is not used any more in this patchset and 
exec_op/setup_data_interface hooks have been moved to 
nand_controller_ops structure.


static const struct nand_controller_ops stm32_fmc2_nand_controller_ops = {
.attach_chip = stm32_fmc2_attach_chip,
.exec_op = stm32_fmc2_exec_op,
.setup_data_interface = stm32_fmc2_setup_interface,
};

Regards,
Christophe Kerello.

On 12/7/18 11:18 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Thu, 29 Nov
2018 17:41:02 +0100:


The driver adds the support for the STMicroelectronics FMC2 NAND
Controller found on STM32MP SOCs.

This patch is based on FMC2 command sequencer.
The purpose of the command sequencer is to facilitate the programming
and the reading of NAND flash pages with the ECC and to free the CPU
of sequencing tasks.
It requires one DMA channel for write and two DMA channels for read
operations.

Only NAND_ECC_HW mode is actually supported.
The driver supports a maximum 8k page size.
The following ECC strength and step size are currently supported:
  - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
  - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
  - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended ECC
based on Hamming)

This patch has been tested on Micron MT29F8G08ABACAH4 and
MT29F8G16ABACAH4

Signed-off-by: Christophe Kerello 
---


The driver look's good to me. However, Boris contributed new
cleanups that I would like you to take into account before doing
another 'deep' review. Please rebase on top of nand/next and have
a look at the followingcommits. For the ->select_chip() hook, it
should not be exposed anymore and switches should be handled
locally by the driver (you have examples).

7a08dbaedd36 mtd: rawnand: Move ->setup_data_interface() to nand_controller_ops
f2abfeb2078b mtd: rawnand: Move the ->exec_op() method to nand_controller_ops
7d6c37e90cf9 mtd: rawnand: Deprecate the ->select_chip() hook
1770022ffa85 mtd: rawnand: ams-delta: Stop implementing ->select_chip()
653c57c7da08 mtd: rawnand: vf610: Stop implementing ->select_chip()
2ace451cae22 mtd: rawnand: tegra: Stop implementing ->select_chip()
b25251414f6e mtd: rawnand: marvell: Stop implementing ->select_chip()
550b9fc4e3af mtd: rawnand: fsmc: Stop implementing ->select_chip()
02b4a52604a4 mtd: rawnand: Make ->select_chip() optional when ->exec_op() is 
implemented
ae2294b10b0f mtd: rawnand: Pass the CS line to be selected in struct 
nand_operation
1d0178593d14 mtd: rawnand: Add nand_[de]select_target() helpers

While at it, could you also address Linus W. comments.

Thanks,
Miquèl



Re: [ v3 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-12-07 Thread Christophe Kerello

Hi Miquèl,

This patchset already takes into account new framework modifications 
done by Boris (3rd batch of cleanups).


The select_chip hook is not used any more in this patchset and 
exec_op/setup_data_interface hooks have been moved to 
nand_controller_ops structure.


static const struct nand_controller_ops stm32_fmc2_nand_controller_ops = {
.attach_chip = stm32_fmc2_attach_chip,
.exec_op = stm32_fmc2_exec_op,
.setup_data_interface = stm32_fmc2_setup_interface,
};

Regards,
Christophe Kerello.

On 12/7/18 11:18 AM, Miquel Raynal wrote:

Hi Christophe,

Christophe Kerello  wrote on Thu, 29 Nov
2018 17:41:02 +0100:


The driver adds the support for the STMicroelectronics FMC2 NAND
Controller found on STM32MP SOCs.

This patch is based on FMC2 command sequencer.
The purpose of the command sequencer is to facilitate the programming
and the reading of NAND flash pages with the ECC and to free the CPU
of sequencing tasks.
It requires one DMA channel for write and two DMA channels for read
operations.

Only NAND_ECC_HW mode is actually supported.
The driver supports a maximum 8k page size.
The following ECC strength and step size are currently supported:
  - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
  - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
  - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended ECC
based on Hamming)

This patch has been tested on Micron MT29F8G08ABACAH4 and
MT29F8G16ABACAH4

Signed-off-by: Christophe Kerello 
---


The driver look's good to me. However, Boris contributed new
cleanups that I would like you to take into account before doing
another 'deep' review. Please rebase on top of nand/next and have
a look at the followingcommits. For the ->select_chip() hook, it
should not be exposed anymore and switches should be handled
locally by the driver (you have examples).

7a08dbaedd36 mtd: rawnand: Move ->setup_data_interface() to nand_controller_ops
f2abfeb2078b mtd: rawnand: Move the ->exec_op() method to nand_controller_ops
7d6c37e90cf9 mtd: rawnand: Deprecate the ->select_chip() hook
1770022ffa85 mtd: rawnand: ams-delta: Stop implementing ->select_chip()
653c57c7da08 mtd: rawnand: vf610: Stop implementing ->select_chip()
2ace451cae22 mtd: rawnand: tegra: Stop implementing ->select_chip()
b25251414f6e mtd: rawnand: marvell: Stop implementing ->select_chip()
550b9fc4e3af mtd: rawnand: fsmc: Stop implementing ->select_chip()
02b4a52604a4 mtd: rawnand: Make ->select_chip() optional when ->exec_op() is 
implemented
ae2294b10b0f mtd: rawnand: Pass the CS line to be selected in struct 
nand_operation
1d0178593d14 mtd: rawnand: Add nand_[de]select_target() helpers

While at it, could you also address Linus W. comments.

Thanks,
Miquèl



[ v3 3/3] mtd: rawnand: stm32_fmc2: add manual mode

2018-11-29 Thread Christophe Kerello
This patch adds the manual mode, a basic mode that do not need
any DMA channels. This mode is also useful for debug purpose.

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 329 +
 1 file changed, 297 insertions(+), 32 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b62b052..9b8bb8f 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -207,6 +207,12 @@ enum stm32_fmc2_ecc {
FMC2_ECC_BCH8 = 8
 };
 
+enum stm32_fmc2_irq_state {
+   FMC2_IRQ_UNKNOWN = 0,
+   FMC2_IRQ_BCH,
+   FMC2_IRQ_SEQ
+};
+
 struct stm32_fmc2_timings {
u8 tclr;
u8 tar;
@@ -241,6 +247,7 @@ struct stm32_fmc2_nfc {
phys_addr_t io_phys_addr;
phys_addr_t data_phys_addr[FMC2_MAX_CE];
struct clk *clk;
+   u8 irq_state;
 
struct dma_chan *dma_tx_ch;
struct dma_chan *dma_rx_ch;
@@ -400,6 +407,17 @@ static void stm32_fmc2_set_buswidth_16(struct 
stm32_fmc2_nfc *fmc2, bool set)
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
 }
 
+/* Enable/disable ECC */
+static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
+{
+   u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+
+   pcr &= ~FMC2_PCR_ECCEN;
+   if (enable)
+   pcr |= FMC2_PCR_ECCEN;
+   writel(pcr, fmc2->io_base + FMC2_PCR);
+}
+
 /* Enable irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_enable_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
@@ -407,6 +425,8 @@ static inline void stm32_fmc2_enable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
 
csqier |= FMC2_CSQIER_TCIE;
 
+   fmc2->irq_state = FMC2_IRQ_SEQ;
+
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
 }
 
@@ -418,6 +438,8 @@ static inline void stm32_fmc2_disable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
csqier &= ~FMC2_CSQIER_TCIE;
 
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
+
+   fmc2->irq_state = FMC2_IRQ_UNKNOWN;
 }
 
 /* Clear irq sources in case of the sequencer is used */
@@ -426,6 +448,68 @@ static inline void stm32_fmc2_clear_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, fmc2->io_base + FMC2_CSQICR);
 }
 
+/* Enable irq sources in case of bch is used */
+static inline void stm32_fmc2_enable_bch_irq(struct stm32_fmc2_nfc *fmc2,
+int mode)
+{
+   u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+
+   if (mode == NAND_ECC_WRITE)
+   bchier |= FMC2_BCHIER_EPBRIE;
+   else
+   bchier |= FMC2_BCHIER_DERIE;
+
+   fmc2->irq_state = FMC2_IRQ_BCH;
+
+   writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+}
+
+/* Disable irq sources in case of bch is used */
+static inline void stm32_fmc2_disable_bch_irq(struct stm32_fmc2_nfc *fmc2)
+{
+   u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+
+   bchier &= ~FMC2_BCHIER_DERIE;
+   bchier &= ~FMC2_BCHIER_EPBRIE;
+
+   writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+
+   fmc2->irq_state = FMC2_IRQ_UNKNOWN;
+}
+
+/* Clear irq sources in case of bch is used */
+static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
+{
+   writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
+}
+
+/*
+ * Enable ECC logic and reset syndrome/parity bits previously calculated
+ * Syndrome/parity bits is cleared by setting the ECCEN bit to 0
+ */
+static void stm32_fmc2_hwctl(struct nand_chip *chip, int mode)
+{
+   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+
+   stm32_fmc2_set_ecc(fmc2, false);
+
+   if (chip->ecc.strength != FMC2_ECC_HAM) {
+   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+
+   if (mode == NAND_ECC_WRITE)
+   pcr |= FMC2_PCR_WEN;
+   else
+   pcr &= ~FMC2_PCR_WEN;
+   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+
+   reinit_completion(>complete);
+   stm32_fmc2_clear_bch_irq(fmc2);
+   stm32_fmc2_enable_bch_irq(fmc2, mode);
+   }
+
+   stm32_fmc2_set_ecc(fmc2, true);
+}
+
 /*
  * ECC Hamming calculation
  * ECC is 3 bytes for 512 bytes of data (supports error correction up to
@@ -438,6 +522,30 @@ static inline void stm32_fmc2_ham_set_ecc(const u32 
ecc_sta, u8 *ecc)
ecc[2] = ecc_sta >> 16;
 }
 
+static int stm32_fmc2_ham_calculate(struct nand_chip *chip, const u8 *data,
+   u8 *ecc)
+{
+   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   u32 sr, heccr;
+   int ret;
+
+   ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
+sr, sr &am

[ v3 0/3] mtd: rawnand: add STM32 FMC2 NAND flash controller driver

2018-11-29 Thread Christophe Kerello
This patchset adds the support for the STMicroelectronics FMC2 NAND flash
controller found on STM32MP SOCs.

This patchset supports:
  - the command sequencer feature, a hardware accelerator for read/write
within a page
  - the manual mode feature, useful for debug purpose
  - a maximum 8k page size
  - following ECC strength and step size
- nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
- nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
- nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended
  ecc based on HAMMING)

This patchset has been tested on Micron MT29F8G08ABACAH4 (8-bit SLC NAND)
and MT29F8G16ABACAH4 (16-bit SLC NAND)

Changes v3:
 - modify clocks property description
 - add NAND reg property description
 - stm32_fmc2_nfc inherits from nand_controller structure
 - rewrite stm32_fmc2_read_data/stm32_fmc2_write_data functions
   to handle aligned and not aligned buffers
 - replace uint8_t by u8
 - use of NAND_ROW_ADDR_3 option

Changes v2:
 - separate the controller structure and the NAND chip structure
 - remove timings description from the device tree
 - fix typo issues
 - fix kbuildrobot issues

Christophe Kerello (3):
  dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller
documentation
  mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver
  mtd: rawnand: stm32_fmc2: add manual mode

 .../devicetree/bindings/mtd/stm32-fmc2-nand.txt|   61 +
 drivers/mtd/nand/raw/Kconfig   |9 +
 drivers/mtd/nand/raw/Makefile  |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 2073 
 4 files changed, 2144 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
 create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c

-- 
1.9.1



[ v3 3/3] mtd: rawnand: stm32_fmc2: add manual mode

2018-11-29 Thread Christophe Kerello
This patch adds the manual mode, a basic mode that do not need
any DMA channels. This mode is also useful for debug purpose.

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 329 +
 1 file changed, 297 insertions(+), 32 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index b62b052..9b8bb8f 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -207,6 +207,12 @@ enum stm32_fmc2_ecc {
FMC2_ECC_BCH8 = 8
 };
 
+enum stm32_fmc2_irq_state {
+   FMC2_IRQ_UNKNOWN = 0,
+   FMC2_IRQ_BCH,
+   FMC2_IRQ_SEQ
+};
+
 struct stm32_fmc2_timings {
u8 tclr;
u8 tar;
@@ -241,6 +247,7 @@ struct stm32_fmc2_nfc {
phys_addr_t io_phys_addr;
phys_addr_t data_phys_addr[FMC2_MAX_CE];
struct clk *clk;
+   u8 irq_state;
 
struct dma_chan *dma_tx_ch;
struct dma_chan *dma_rx_ch;
@@ -400,6 +407,17 @@ static void stm32_fmc2_set_buswidth_16(struct 
stm32_fmc2_nfc *fmc2, bool set)
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
 }
 
+/* Enable/disable ECC */
+static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable)
+{
+   u32 pcr = readl(fmc2->io_base + FMC2_PCR);
+
+   pcr &= ~FMC2_PCR_ECCEN;
+   if (enable)
+   pcr |= FMC2_PCR_ECCEN;
+   writel(pcr, fmc2->io_base + FMC2_PCR);
+}
+
 /* Enable irq sources in case of the sequencer is used */
 static inline void stm32_fmc2_enable_seq_irq(struct stm32_fmc2_nfc *fmc2)
 {
@@ -407,6 +425,8 @@ static inline void stm32_fmc2_enable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
 
csqier |= FMC2_CSQIER_TCIE;
 
+   fmc2->irq_state = FMC2_IRQ_SEQ;
+
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
 }
 
@@ -418,6 +438,8 @@ static inline void stm32_fmc2_disable_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
csqier &= ~FMC2_CSQIER_TCIE;
 
writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER);
+
+   fmc2->irq_state = FMC2_IRQ_UNKNOWN;
 }
 
 /* Clear irq sources in case of the sequencer is used */
@@ -426,6 +448,68 @@ static inline void stm32_fmc2_clear_seq_irq(struct 
stm32_fmc2_nfc *fmc2)
writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, fmc2->io_base + FMC2_CSQICR);
 }
 
+/* Enable irq sources in case of bch is used */
+static inline void stm32_fmc2_enable_bch_irq(struct stm32_fmc2_nfc *fmc2,
+int mode)
+{
+   u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+
+   if (mode == NAND_ECC_WRITE)
+   bchier |= FMC2_BCHIER_EPBRIE;
+   else
+   bchier |= FMC2_BCHIER_DERIE;
+
+   fmc2->irq_state = FMC2_IRQ_BCH;
+
+   writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+}
+
+/* Disable irq sources in case of bch is used */
+static inline void stm32_fmc2_disable_bch_irq(struct stm32_fmc2_nfc *fmc2)
+{
+   u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER);
+
+   bchier &= ~FMC2_BCHIER_DERIE;
+   bchier &= ~FMC2_BCHIER_EPBRIE;
+
+   writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER);
+
+   fmc2->irq_state = FMC2_IRQ_UNKNOWN;
+}
+
+/* Clear irq sources in case of bch is used */
+static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2)
+{
+   writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR);
+}
+
+/*
+ * Enable ECC logic and reset syndrome/parity bits previously calculated
+ * Syndrome/parity bits is cleared by setting the ECCEN bit to 0
+ */
+static void stm32_fmc2_hwctl(struct nand_chip *chip, int mode)
+{
+   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+
+   stm32_fmc2_set_ecc(fmc2, false);
+
+   if (chip->ecc.strength != FMC2_ECC_HAM) {
+   u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
+
+   if (mode == NAND_ECC_WRITE)
+   pcr |= FMC2_PCR_WEN;
+   else
+   pcr &= ~FMC2_PCR_WEN;
+   writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
+
+   reinit_completion(>complete);
+   stm32_fmc2_clear_bch_irq(fmc2);
+   stm32_fmc2_enable_bch_irq(fmc2, mode);
+   }
+
+   stm32_fmc2_set_ecc(fmc2, true);
+}
+
 /*
  * ECC Hamming calculation
  * ECC is 3 bytes for 512 bytes of data (supports error correction up to
@@ -438,6 +522,30 @@ static inline void stm32_fmc2_ham_set_ecc(const u32 
ecc_sta, u8 *ecc)
ecc[2] = ecc_sta >> 16;
 }
 
+static int stm32_fmc2_ham_calculate(struct nand_chip *chip, const u8 *data,
+   u8 *ecc)
+{
+   struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller);
+   u32 sr, heccr;
+   int ret;
+
+   ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR,
+sr, sr &am

[ v3 0/3] mtd: rawnand: add STM32 FMC2 NAND flash controller driver

2018-11-29 Thread Christophe Kerello
This patchset adds the support for the STMicroelectronics FMC2 NAND flash
controller found on STM32MP SOCs.

This patchset supports:
  - the command sequencer feature, a hardware accelerator for read/write
within a page
  - the manual mode feature, useful for debug purpose
  - a maximum 8k page size
  - following ECC strength and step size
- nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
- nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
- nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended
  ecc based on HAMMING)

This patchset has been tested on Micron MT29F8G08ABACAH4 (8-bit SLC NAND)
and MT29F8G16ABACAH4 (16-bit SLC NAND)

Changes v3:
 - modify clocks property description
 - add NAND reg property description
 - stm32_fmc2_nfc inherits from nand_controller structure
 - rewrite stm32_fmc2_read_data/stm32_fmc2_write_data functions
   to handle aligned and not aligned buffers
 - replace uint8_t by u8
 - use of NAND_ROW_ADDR_3 option

Changes v2:
 - separate the controller structure and the NAND chip structure
 - remove timings description from the device tree
 - fix typo issues
 - fix kbuildrobot issues

Christophe Kerello (3):
  dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller
documentation
  mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver
  mtd: rawnand: stm32_fmc2: add manual mode

 .../devicetree/bindings/mtd/stm32-fmc2-nand.txt|   61 +
 drivers/mtd/nand/raw/Kconfig   |9 +
 drivers/mtd/nand/raw/Makefile  |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 2073 
 4 files changed, 2144 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
 create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c

-- 
1.9.1



[ v3 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-11-29 Thread Christophe Kerello
The driver adds the support for the STMicroelectronics FMC2 NAND
Controller found on STM32MP SOCs.

This patch is based on FMC2 command sequencer.
The purpose of the command sequencer is to facilitate the programming
and the reading of NAND flash pages with the ECC and to free the CPU
of sequencing tasks.
It requires one DMA channel for write and two DMA channels for read
operations.

Only NAND_ECC_HW mode is actually supported.
The driver supports a maximum 8k page size.
The following ECC strength and step size are currently supported:
 - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
 - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
 - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended ECC
   based on Hamming)

This patch has been tested on Micron MT29F8G08ABACAH4 and
MT29F8G16ABACAH4

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/Kconfig   |9 +
 drivers/mtd/nand/raw/Makefile  |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1808 
 3 files changed, 1818 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 1a55d3e..0f479be 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -541,4 +541,13 @@ config MTD_NAND_TEGRA
  is supported. Extra OOB bytes when using HW ECC are currently
  not supported.
 
+config MTD_NAND_STM32_FMC2
+   tristate "Support for NAND controller on STM32MP SoCs"
+   depends on MACH_STM32MP157 || COMPILE_TEST
+   help
+ Enables support for NAND Flash chips on SoCs containing the FMC2
+ NAND controller. This controller is found on STM32MP SoCs.
+ The controller supports a maximum 8k page size and supports
+ a maximum 8-bit correction error per sector of 512 bytes.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 57159b3..325bc9e 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND)   += brcmnand/
 obj-$(CONFIG_MTD_NAND_QCOM)+= qcom_nandc.o
 obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
 obj-$(CONFIG_MTD_NAND_TEGRA)   += tegra_nand.o
+obj-$(CONFIG_MTD_NAND_STM32_FMC2)  += stm32_fmc2_nand.o
 
 nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
 nand-objs += nand_onfi.o
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
new file mode 100644
index 000..b62b052
--- /dev/null
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -0,0 +1,1808 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018
+ * Author: Christophe Kerello 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Bad block marker length */
+#define FMC2_BBM_LEN   2
+
+/* ECC step size */
+#define FMC2_ECC_STEP_SIZE 512
+
+/* BCHDSRx registers length */
+#define FMC2_BCHDSRS_LEN   20
+
+/* HECCR length */
+#define FMC2_HECCR_LEN 4
+
+/* Max requests done for a 8k nand page size */
+#define FMC2_MAX_SG16
+
+/* Max chip enable */
+#define FMC2_MAX_CE2
+
+/* Max ECC buffer length */
+#define FMC2_MAX_ECC_BUF_LEN   (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
+
+/* Timings */
+#define FMC2_THIZ  1
+#define FMC2_TIO   8000
+#define FMC2_TSYNC 3000
+#define FMC2_PCR_TIMING_MASK   0xf
+#define FMC2_PMEM_PATT_TIMING_MASK 0xff
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_PCR   0x80
+#define FMC2_SR0x84
+#define FMC2_PMEM  0x88
+#define FMC2_PATT  0x8c
+#define FMC2_HECCR 0x94
+#define FMC2_CSQCR 0x200
+#define FMC2_CSQCFGR1  0x204
+#define FMC2_CSQCFGR2  0x208
+#define FMC2_CSQCFGR3  0x20c
+#define FMC2_CSQAR10x210
+#define FMC2_CSQAR20x214
+#define FMC2_CSQIER0x220
+#define FMC2_CSQISR0x224
+#define FMC2_CSQICR0x228
+#define FMC2_CSQEMSR   0x230
+#define FMC2_BCHIER0x250
+#define FMC2_BCHISR0x254
+#define FMC2_BCHICR0x258
+#define FMC2_BCHPBR1   0x260
+#define FMC2_BCHPBR2   0x264
+#define FMC2_BCHPBR3   0x268
+#define FMC2_BCHPBR4   0x26c
+#define FMC2_BCHDSR0   0x27c
+#define FMC2_BCHDSR1   0x280

[ v3 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-11-29 Thread Christophe Kerello
The driver adds the support for the STMicroelectronics FMC2 NAND
Controller found on STM32MP SOCs.

This patch is based on FMC2 command sequencer.
The purpose of the command sequencer is to facilitate the programming
and the reading of NAND flash pages with the ECC and to free the CPU
of sequencing tasks.
It requires one DMA channel for write and two DMA channels for read
operations.

Only NAND_ECC_HW mode is actually supported.
The driver supports a maximum 8k page size.
The following ECC strength and step size are currently supported:
 - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
 - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
 - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended ECC
   based on Hamming)

This patch has been tested on Micron MT29F8G08ABACAH4 and
MT29F8G16ABACAH4

Signed-off-by: Christophe Kerello 
---
 drivers/mtd/nand/raw/Kconfig   |9 +
 drivers/mtd/nand/raw/Makefile  |1 +
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1808 
 3 files changed, 1818 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 1a55d3e..0f479be 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -541,4 +541,13 @@ config MTD_NAND_TEGRA
  is supported. Extra OOB bytes when using HW ECC are currently
  not supported.
 
+config MTD_NAND_STM32_FMC2
+   tristate "Support for NAND controller on STM32MP SoCs"
+   depends on MACH_STM32MP157 || COMPILE_TEST
+   help
+ Enables support for NAND Flash chips on SoCs containing the FMC2
+ NAND controller. This controller is found on STM32MP SoCs.
+ The controller supports a maximum 8k page size and supports
+ a maximum 8-bit correction error per sector of 512 bytes.
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 57159b3..325bc9e 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND)   += brcmnand/
 obj-$(CONFIG_MTD_NAND_QCOM)+= qcom_nandc.o
 obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o
 obj-$(CONFIG_MTD_NAND_TEGRA)   += tegra_nand.o
+obj-$(CONFIG_MTD_NAND_STM32_FMC2)  += stm32_fmc2_nand.o
 
 nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
 nand-objs += nand_onfi.o
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
new file mode 100644
index 000..b62b052
--- /dev/null
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -0,0 +1,1808 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018
+ * Author: Christophe Kerello 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Bad block marker length */
+#define FMC2_BBM_LEN   2
+
+/* ECC step size */
+#define FMC2_ECC_STEP_SIZE 512
+
+/* BCHDSRx registers length */
+#define FMC2_BCHDSRS_LEN   20
+
+/* HECCR length */
+#define FMC2_HECCR_LEN 4
+
+/* Max requests done for a 8k nand page size */
+#define FMC2_MAX_SG16
+
+/* Max chip enable */
+#define FMC2_MAX_CE2
+
+/* Max ECC buffer length */
+#define FMC2_MAX_ECC_BUF_LEN   (FMC2_BCHDSRS_LEN * FMC2_MAX_SG)
+
+/* Timings */
+#define FMC2_THIZ  1
+#define FMC2_TIO   8000
+#define FMC2_TSYNC 3000
+#define FMC2_PCR_TIMING_MASK   0xf
+#define FMC2_PMEM_PATT_TIMING_MASK 0xff
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_PCR   0x80
+#define FMC2_SR0x84
+#define FMC2_PMEM  0x88
+#define FMC2_PATT  0x8c
+#define FMC2_HECCR 0x94
+#define FMC2_CSQCR 0x200
+#define FMC2_CSQCFGR1  0x204
+#define FMC2_CSQCFGR2  0x208
+#define FMC2_CSQCFGR3  0x20c
+#define FMC2_CSQAR10x210
+#define FMC2_CSQAR20x214
+#define FMC2_CSQIER0x220
+#define FMC2_CSQISR0x224
+#define FMC2_CSQICR0x228
+#define FMC2_CSQEMSR   0x230
+#define FMC2_BCHIER0x250
+#define FMC2_BCHISR0x254
+#define FMC2_BCHICR0x258
+#define FMC2_BCHPBR1   0x260
+#define FMC2_BCHPBR2   0x264
+#define FMC2_BCHPBR3   0x268
+#define FMC2_BCHPBR4   0x26c
+#define FMC2_BCHDSR0   0x27c
+#define FMC2_BCHDSR1   0x280

[ v3 1/3] dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller documentation

2018-11-29 Thread Christophe Kerello
This patch adds the documentation of the device tree bindings for the STM32
FMC2 NAND controller.

Signed-off-by: Christophe Kerello 
---
 .../devicetree/bindings/mtd/stm32-fmc2-nand.txt| 61 ++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt 
b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
new file mode 100644
index 000..ad2bef8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
@@ -0,0 +1,61 @@
+STMicroelectronics Flexible Memory Controller 2 (FMC2)
+NAND Interface
+
+Required properties:
+- compatible: Should be one of:
+  * st,stm32mp15-fmc2
+- reg: NAND flash controller memory areas.
+   First region contains the register location.
+   Regions 2 to 4 respectively contain the data, command,
+   and address space for CS0.
+   Regions 5 to 7 contain the same areas for CS1.
+- interrupts: The interrupt number
+- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
+- clocks: The clock needed by the NAND flash controller
+
+Optional properties:
+- resets: Reference to a reset controller asserting the FMC controller
+- dmas: DMA specifiers (see: dma/stm32-mdma.txt)
+- dma-names: Must be "tx", "rx" and "ecc"
+
+* NAND device bindings:
+
+Required properties:
+- reg: describes the CS lines assigned to the NAND device.
+
+Optional properties:
+- nand-on-flash-bbt: see nand.txt
+- nand-ecc-strength: see nand.txt
+- nand-ecc-step-size: see nand.txt
+
+The following ECC strength and step size are currently supported:
+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming)
+ - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
+ - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default)
+
+Example:
+
+   fmc: nand-controller@58002000 {
+   compatible = "st,stm32mp15-fmc2";
+   reg = <0x58002000 0x1000>,
+ <0x8000 0x1000>,
+ <0x8801 0x1000>,
+ <0x8802 0x1000>,
+ <0x8100 0x1000>,
+ <0x8901 0x1000>,
+ <0x8902 0x1000>;
+   interrupts = ;
+   clocks = < FMC_K>;
+   resets = < FMC_R>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nand@0 {
+   reg = <0>;
+   nand-on-flash-bbt;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
+   };
-- 
1.9.1



[ v3 1/3] dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller documentation

2018-11-29 Thread Christophe Kerello
This patch adds the documentation of the device tree bindings for the STM32
FMC2 NAND controller.

Signed-off-by: Christophe Kerello 
---
 .../devicetree/bindings/mtd/stm32-fmc2-nand.txt| 61 ++
 1 file changed, 61 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt 
b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
new file mode 100644
index 000..ad2bef8
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
@@ -0,0 +1,61 @@
+STMicroelectronics Flexible Memory Controller 2 (FMC2)
+NAND Interface
+
+Required properties:
+- compatible: Should be one of:
+  * st,stm32mp15-fmc2
+- reg: NAND flash controller memory areas.
+   First region contains the register location.
+   Regions 2 to 4 respectively contain the data, command,
+   and address space for CS0.
+   Regions 5 to 7 contain the same areas for CS1.
+- interrupts: The interrupt number
+- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
+- clocks: The clock needed by the NAND flash controller
+
+Optional properties:
+- resets: Reference to a reset controller asserting the FMC controller
+- dmas: DMA specifiers (see: dma/stm32-mdma.txt)
+- dma-names: Must be "tx", "rx" and "ecc"
+
+* NAND device bindings:
+
+Required properties:
+- reg: describes the CS lines assigned to the NAND device.
+
+Optional properties:
+- nand-on-flash-bbt: see nand.txt
+- nand-ecc-strength: see nand.txt
+- nand-ecc-step-size: see nand.txt
+
+The following ECC strength and step size are currently supported:
+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming)
+ - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
+ - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default)
+
+Example:
+
+   fmc: nand-controller@58002000 {
+   compatible = "st,stm32mp15-fmc2";
+   reg = <0x58002000 0x1000>,
+ <0x8000 0x1000>,
+ <0x8801 0x1000>,
+ <0x8802 0x1000>,
+ <0x8100 0x1000>,
+ <0x8901 0x1000>,
+ <0x8902 0x1000>;
+   interrupts = ;
+   clocks = < FMC_K>;
+   resets = < FMC_R>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nand@0 {
+   reg = <0>;
+   nand-on-flash-bbt;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
+   };
-- 
1.9.1



Re: [PATCH v2 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-11-07 Thread Christophe Kerello
ve checked the framework after Miquèl comment sent on v1 => "If you 
selected BOUNCE_BUFFER in the options, buf is supposedly

aligned, or am I missing something?".

After checking the framework, my understanding was:
 - In case of 8-bit access is requested, the framework provides no 
guarantee on buf. To avoid any issue, I write byte per byte.
 - In case of 8-bit access is not requested, it means that the 
framework will try to write data in the page or in the oob. When writing 
to oob, chip->oob_poi will be used and this buffer is aligned. When 
writing to the page, as the driver enables NAND_USE_BOUNCE_BUFFER 
option, buf is guarantee aligned.


But, I agree that it would be safe to reconfigure the bus width in 8-bit 
before writing byte per byte in case of a 16-bit NAND is used.


write_8bit:
if (chip->options & NAND_BUSWIDTH_16) {
/* Reconfigure bus width to 8-bit */
pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
pcr &= ~FMC2_PCR_PWID_MASK;
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
}

for (i = 0; i < len; i++)
writeb_relaxed(p[i], io_addr_w);

if (chip->options & NAND_BUSWIDTH_16) {
/* Reconfigure bus width to 16-bit */
pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
    pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
}

Regards,
Christophe Kerello.


+}


Regards,

Boris



Re: [PATCH v2 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-11-07 Thread Christophe Kerello
ve checked the framework after Miquèl comment sent on v1 => "If you 
selected BOUNCE_BUFFER in the options, buf is supposedly

aligned, or am I missing something?".

After checking the framework, my understanding was:
 - In case of 8-bit access is requested, the framework provides no 
guarantee on buf. To avoid any issue, I write byte per byte.
 - In case of 8-bit access is not requested, it means that the 
framework will try to write data in the page or in the oob. When writing 
to oob, chip->oob_poi will be used and this buffer is aligned. When 
writing to the page, as the driver enables NAND_USE_BOUNCE_BUFFER 
option, buf is guarantee aligned.


But, I agree that it would be safe to reconfigure the bus width in 8-bit 
before writing byte per byte in case of a 16-bit NAND is used.


write_8bit:
if (chip->options & NAND_BUSWIDTH_16) {
/* Reconfigure bus width to 8-bit */
pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
pcr &= ~FMC2_PCR_PWID_MASK;
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
}

for (i = 0; i < len; i++)
writeb_relaxed(p[i], io_addr_w);

if (chip->options & NAND_BUSWIDTH_16) {
/* Reconfigure bus width to 16-bit */
pcr = readl_relaxed(fmc2->io_base + FMC2_PCR);
    pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16);
writel_relaxed(pcr, fmc2->io_base + FMC2_PCR);
}

Regards,
Christophe Kerello.


+}


Regards,

Boris



Re: [PATCH v2 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-10-15 Thread Christophe Kerello




On 10/05/2018 11:58 AM, Boris Brezillon wrote:

On Fri, 5 Oct 2018 11:41:59 +0200
 wrote:


+struct stm32_fmc2 {


You should inherit from nand_controller even if the nand_chip already
embeds a dummy nand controller object.

struct nand_controller base;



Hi Boris,

Ok, i will add and handle the nand controller structure.

Regards,
Christophe Kerello.


+   struct stm32_fmc2_nand nand;
+   struct device *dev;
+   void __iomem *io_base;
+   void __iomem *data_base[FMC2_MAX_CE];
+   void __iomem *cmd_base[FMC2_MAX_CE];
+   void __iomem *addr_base[FMC2_MAX_CE];
+   phys_addr_t io_phys_addr;
+   phys_addr_t data_phys_addr[FMC2_MAX_CE];
+   struct clk *clk;
+
+   struct dma_chan *dma_tx_ch;
+   struct dma_chan *dma_rx_ch;
+   struct dma_chan *dma_ecc_ch;
+   struct sg_table dma_data_sg;
+   struct sg_table dma_ecc_sg;
+   u8 *ecc_buf;
+   int dma_ecc_len;
+
+   struct completion complete;
+   struct completion dma_data_complete;
+   struct completion dma_ecc_complete;
+
+   u8 cs_assigned;
+   int cs_sel;
+};


Re: [PATCH v2 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-10-15 Thread Christophe Kerello




On 10/05/2018 11:58 AM, Boris Brezillon wrote:

On Fri, 5 Oct 2018 11:41:59 +0200
 wrote:


+struct stm32_fmc2 {


You should inherit from nand_controller even if the nand_chip already
embeds a dummy nand controller object.

struct nand_controller base;



Hi Boris,

Ok, i will add and handle the nand controller structure.

Regards,
Christophe Kerello.


+   struct stm32_fmc2_nand nand;
+   struct device *dev;
+   void __iomem *io_base;
+   void __iomem *data_base[FMC2_MAX_CE];
+   void __iomem *cmd_base[FMC2_MAX_CE];
+   void __iomem *addr_base[FMC2_MAX_CE];
+   phys_addr_t io_phys_addr;
+   phys_addr_t data_phys_addr[FMC2_MAX_CE];
+   struct clk *clk;
+
+   struct dma_chan *dma_tx_ch;
+   struct dma_chan *dma_rx_ch;
+   struct dma_chan *dma_ecc_ch;
+   struct sg_table dma_data_sg;
+   struct sg_table dma_ecc_sg;
+   u8 *ecc_buf;
+   int dma_ecc_len;
+
+   struct completion complete;
+   struct completion dma_data_complete;
+   struct completion dma_ecc_complete;
+
+   u8 cs_assigned;
+   int cs_sel;
+};


Re: [PATCH v2 1/3] dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller documentation

2018-10-15 Thread Christophe Kerello




On 10/12/2018 10:32 PM, Rob Herring wrote:

On Fri, Oct 05, 2018 at 11:41:58AM +0200, christophe.kere...@st.com wrote:

From: Christophe Kerello 

This patch adds the documentation of the device tree bindings for the STM32
FMC2 NAND controller.

Signed-off-by: Christophe Kerello 
---
  .../devicetree/bindings/mtd/stm32-fmc2-nand.txt| 59 ++
  1 file changed, 59 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt 
b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
new file mode 100644
index 000..b620176
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
@@ -0,0 +1,59 @@
+STMicroelectronics Flexible Memory Controller 2 (FMC2)
+NAND Interface
+
+Required properties:
+- compatible: Should be one of:
+  * st,stm32mp15-fmc2
+- reg: NAND flash controller memory areas.
+   First region contains the register location.
+   Regions 2 to 4 respectively contain the data, command,
+   and address space for CS0.
+   Regions 5 to 7 contain the same areas for CS1.
+- interrupts: The interrupt number
+- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
+- clocks: Use common clock framework


How many? 'common clock framework' is a Linux thing, not part of
bindings.



Hi Rob,

Only one clock is needed.
I will replace this comment by:
 - clocks: the clock needed by the NAND flash controller.

Regards,
Christophe Kerello.


+
+Optional properties:
+- resets: Reference to a reset controller asserting the FMC controller
+- dmas: DMA specifiers (see: dma/stm32-mdma.txt)
+- dma-names: Must be "tx", "rx" and "ecc"
+
+Optional children nodes:
+Children nodes represent the available NAND chips.
+
+Optional properties:
+- nand-on-flash-bbt: see nand.txt
+- nand-ecc-strength: see nand.txt
+- nand-ecc-step-size: see nand.txt
+
+The following ECC strength and step size are currently supported:
+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming)
+ - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
+ - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default)
+
+Example:
+
+   fmc: nand-controller@58002000 {
+   compatible = "st,stm32mp15-fmc2";
+   reg = <0x58002000 0x1000>,
+ <0x8000 0x1000>,
+ <0x8801 0x1000>,
+ <0x8802 0x1000>,
+ <0x8100 0x1000>,
+ <0x8901 0x1000>,
+ <0x8902 0x1000>;
+   interrupts = ;
+   clocks = < FMC_K>;
+   resets = < FMC_R>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nand@0 {
+   reg = <0>;
+   nand-on-flash-bbt;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
+   };
--
1.9.1



Re: [PATCH v2 1/3] dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller documentation

2018-10-15 Thread Christophe Kerello




On 10/12/2018 10:32 PM, Rob Herring wrote:

On Fri, Oct 05, 2018 at 11:41:58AM +0200, christophe.kere...@st.com wrote:

From: Christophe Kerello 

This patch adds the documentation of the device tree bindings for the STM32
FMC2 NAND controller.

Signed-off-by: Christophe Kerello 
---
  .../devicetree/bindings/mtd/stm32-fmc2-nand.txt| 59 ++
  1 file changed, 59 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt

diff --git a/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt 
b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
new file mode 100644
index 000..b620176
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/stm32-fmc2-nand.txt
@@ -0,0 +1,59 @@
+STMicroelectronics Flexible Memory Controller 2 (FMC2)
+NAND Interface
+
+Required properties:
+- compatible: Should be one of:
+  * st,stm32mp15-fmc2
+- reg: NAND flash controller memory areas.
+   First region contains the register location.
+   Regions 2 to 4 respectively contain the data, command,
+   and address space for CS0.
+   Regions 5 to 7 contain the same areas for CS1.
+- interrupts: The interrupt number
+- pinctrl-0: Standard Pinctrl phandle (see: pinctrl/pinctrl-bindings.txt)
+- clocks: Use common clock framework


How many? 'common clock framework' is a Linux thing, not part of
bindings.



Hi Rob,

Only one clock is needed.
I will replace this comment by:
 - clocks: the clock needed by the NAND flash controller.

Regards,
Christophe Kerello.


+
+Optional properties:
+- resets: Reference to a reset controller asserting the FMC controller
+- dmas: DMA specifiers (see: dma/stm32-mdma.txt)
+- dma-names: Must be "tx", "rx" and "ecc"
+
+Optional children nodes:
+Children nodes represent the available NAND chips.
+
+Optional properties:
+- nand-on-flash-bbt: see nand.txt
+- nand-ecc-strength: see nand.txt
+- nand-ecc-step-size: see nand.txt
+
+The following ECC strength and step size are currently supported:
+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Hamming)
+ - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
+ - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8) (default)
+
+Example:
+
+   fmc: nand-controller@58002000 {
+   compatible = "st,stm32mp15-fmc2";
+   reg = <0x58002000 0x1000>,
+ <0x8000 0x1000>,
+ <0x8801 0x1000>,
+ <0x8802 0x1000>,
+ <0x8100 0x1000>,
+ <0x8901 0x1000>,
+ <0x8902 0x1000>;
+   interrupts = ;
+   clocks = < FMC_K>;
+   resets = < FMC_R>;
+   pinctrl-names = "default";
+   pinctrl-0 = <_pins_a>;
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   nand@0 {
+   reg = <0>;
+   nand-on-flash-bbt;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   };
+   };
--
1.9.1



Re: [PATCH 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-09-25 Thread Christophe Kerello

Hi Boris,

On 09/24/2018 07:23 PM, Boris Brezillon wrote:

Hi Christophe,

On Mon, 17 Sep 2018 17:47:39 +0200
 wrote:


+struct stm32_fmc2 {
+   struct nand_chip chip;
+   struct device *dev;
+   void __iomem *io_base;
+   void __iomem *data_base[FMC2_MAX_CE];
+   void __iomem *cmd_base[FMC2_MAX_CE];
+   void __iomem *addr_base[FMC2_MAX_CE];
+   phys_addr_t io_phys_addr;
+   phys_addr_t data_phys_addr[FMC2_MAX_CE];
+   struct clk *clk;
+
+   struct dma_chan *dma_tx_ch;
+   struct dma_chan *dma_rx_ch;
+   struct dma_chan *dma_ecc_ch;
+   struct sg_table dma_data_sg;
+   struct sg_table dma_ecc_sg;
+   u8 *ecc_buf;
+   int dma_ecc_len;
+
+   struct completion complete;
+   struct completion dma_data_complete;
+   struct completion dma_ecc_complete;
+
+   struct stm32_fmc2_timings timings;
+   u8 cs_assigned;
+   int cs_sel;
+   int ncs;
+   int cs_used[FMC2_MAX_CE];
+};


Can we have a clear separation between the NAND controller and NAND
chip structures. I know you only support a single chip per-controller
right now, but I prefer to have things clearly separated from the
beginning.


Yes, I can create 2 structures: one for the controller (stm32_fmc2) and 
one for the NAND chip (stm32_fmc2_nand_chip).


Regards,
Christophe Kerello.



Regards,

Boris



Re: [PATCH 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-09-25 Thread Christophe Kerello

Hi Boris,

On 09/24/2018 07:23 PM, Boris Brezillon wrote:

Hi Christophe,

On Mon, 17 Sep 2018 17:47:39 +0200
 wrote:


+struct stm32_fmc2 {
+   struct nand_chip chip;
+   struct device *dev;
+   void __iomem *io_base;
+   void __iomem *data_base[FMC2_MAX_CE];
+   void __iomem *cmd_base[FMC2_MAX_CE];
+   void __iomem *addr_base[FMC2_MAX_CE];
+   phys_addr_t io_phys_addr;
+   phys_addr_t data_phys_addr[FMC2_MAX_CE];
+   struct clk *clk;
+
+   struct dma_chan *dma_tx_ch;
+   struct dma_chan *dma_rx_ch;
+   struct dma_chan *dma_ecc_ch;
+   struct sg_table dma_data_sg;
+   struct sg_table dma_ecc_sg;
+   u8 *ecc_buf;
+   int dma_ecc_len;
+
+   struct completion complete;
+   struct completion dma_data_complete;
+   struct completion dma_ecc_complete;
+
+   struct stm32_fmc2_timings timings;
+   u8 cs_assigned;
+   int cs_sel;
+   int ncs;
+   int cs_used[FMC2_MAX_CE];
+};


Can we have a clear separation between the NAND controller and NAND
chip structures. I know you only support a single chip per-controller
right now, but I prefer to have things clearly separated from the
beginning.


Yes, I can create 2 structures: one for the controller (stm32_fmc2) and 
one for the NAND chip (stm32_fmc2_nand_chip).


Regards,
Christophe Kerello.



Regards,

Boris



Re: [PATCH 1/3] dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller documentation

2018-09-25 Thread Christophe Kerello

Hi Boris,

On 09/24/2018 07:17 PM, Boris Brezillon wrote:

Hi Christophe,

On Mon, 24 Sep 2018 18:36:27 +0200
Christophe Kerello  wrote:


+- st,fmc2_timings: array of 8 bytes for NAND timings. The meanings of
+  these bytes are:
+  byte 0 TCLR  : CLE to RE delay in number of AHB clock cycles, only 4 bits
+ are valid. Zero means one clock cycle, 15 means 16 clock
+ cycles.
+  byte 1 TAR   : ALE to RE delay, 4 bits are valid. Same format as TCLR.
+  byte 2 THIZ  : number of HCLK clock cycles during which the data bus is
+ kept in Hi-Z (tristate) after the start of a write access.
+ Only valid for write transactions. Zero means 1 cycle,
+ 255 means 256 cycles.
+  byte 3 TWAIT : number of HCLK clock cycles to assert the command to the
+ NAND flash in response to SMWAITn. Zero means 1 cycle,
+ 255 means 256 cycles.
+  byte 4 THOLD_MEM : common memory space timing
+ number of HCLK clock cycles to hold the address (and data
+ when writing) after the command deassertion. Zero means
+ 1 cycle, 255 means 256 cycles.
+  byte 5 TSET_MEM  : common memory space timing
+ number of HCLK clock cycles to assert the address before
+ the command is asserted. Zero means 1 cycle, 255 means 256
+ cycles.
+  byte 6 THOLD_ATT : attribute memory space timing
+ number of HCLK clock cycles to hold the address (and data
+ when writing) after the command deassertion. Zero means
+ 1 cycle, 255 means 256 cycles.
+  byte 7 TSET_ATT  : attribute memory space timing
+ number of HCLK clock cycles to assert the address before
+ the command is asserted. Zero means 1 cycle, 255 means 256
+ cycles.


Let me review the driver but this array of timings is really
suspicious. I am pretty sure you don't need it in the DT.


"st,fmc2-timings" is an optional property that allow the end user to
overwrite the timings calculated by setup_data_interface callback. By
setting this property in the NAND flash memory device tree node, the end
user could have a better throughput. For NON ONFI SLC NAND, timing mode
0 is often used.


Exactly the kind of tweaking I'd like to avoid. If the NAND is not ONFI,
the vendor driver (nand_.c) can overwrite
chip->default_onfi_timing_mode, and if the ONFI timings modes are not
exactly matching the NAND spec and you need the exact timings, then we
should consider adding a manufacturer hook to let the manufacturer
driver tweak the timings. In any case, I'm not willing to accept
timings description in the DT.



Ok, I understand the way it should work. This property will be removed 
from the device tree bindings and the timings will be only calculated by 
calling setup_data_interface callback in the driver.


Regards,
Christophe Kerello.


Regards,

Boris

__
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/



Re: [PATCH 1/3] dt-bindings: mtd: stm32_fmc2: add STM32 FMC2 NAND controller documentation

2018-09-25 Thread Christophe Kerello

Hi Boris,

On 09/24/2018 07:17 PM, Boris Brezillon wrote:

Hi Christophe,

On Mon, 24 Sep 2018 18:36:27 +0200
Christophe Kerello  wrote:


+- st,fmc2_timings: array of 8 bytes for NAND timings. The meanings of
+  these bytes are:
+  byte 0 TCLR  : CLE to RE delay in number of AHB clock cycles, only 4 bits
+ are valid. Zero means one clock cycle, 15 means 16 clock
+ cycles.
+  byte 1 TAR   : ALE to RE delay, 4 bits are valid. Same format as TCLR.
+  byte 2 THIZ  : number of HCLK clock cycles during which the data bus is
+ kept in Hi-Z (tristate) after the start of a write access.
+ Only valid for write transactions. Zero means 1 cycle,
+ 255 means 256 cycles.
+  byte 3 TWAIT : number of HCLK clock cycles to assert the command to the
+ NAND flash in response to SMWAITn. Zero means 1 cycle,
+ 255 means 256 cycles.
+  byte 4 THOLD_MEM : common memory space timing
+ number of HCLK clock cycles to hold the address (and data
+ when writing) after the command deassertion. Zero means
+ 1 cycle, 255 means 256 cycles.
+  byte 5 TSET_MEM  : common memory space timing
+ number of HCLK clock cycles to assert the address before
+ the command is asserted. Zero means 1 cycle, 255 means 256
+ cycles.
+  byte 6 THOLD_ATT : attribute memory space timing
+ number of HCLK clock cycles to hold the address (and data
+ when writing) after the command deassertion. Zero means
+ 1 cycle, 255 means 256 cycles.
+  byte 7 TSET_ATT  : attribute memory space timing
+ number of HCLK clock cycles to assert the address before
+ the command is asserted. Zero means 1 cycle, 255 means 256
+ cycles.


Let me review the driver but this array of timings is really
suspicious. I am pretty sure you don't need it in the DT.


"st,fmc2-timings" is an optional property that allow the end user to
overwrite the timings calculated by setup_data_interface callback. By
setting this property in the NAND flash memory device tree node, the end
user could have a better throughput. For NON ONFI SLC NAND, timing mode
0 is often used.


Exactly the kind of tweaking I'd like to avoid. If the NAND is not ONFI,
the vendor driver (nand_.c) can overwrite
chip->default_onfi_timing_mode, and if the ONFI timings modes are not
exactly matching the NAND spec and you need the exact timings, then we
should consider adding a manufacturer hook to let the manufacturer
driver tweak the timings. In any case, I'm not willing to accept
timings description in the DT.



Ok, I understand the way it should work. This property will be removed 
from the device tree bindings and the timings will be only calculated by 
calling setup_data_interface callback in the driver.


Regards,
Christophe Kerello.


Regards,

Boris

__
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/



Re: [PATCH 2/3] mtd: rawnand: stm32_fmc2: add STM32 FMC2 NAND flash controller driver

2018-09-24 Thread Christophe Kerello

Hi Miquèl,

On 09/22/2018 03:48 PM, Miquel Raynal wrote:

Hi Christophe,

I suppose you received the kbuildrobot issues already, please have a
look at them.


Yes, kbuidroot issues will be solved in the v2 patchset.



The driver looks well, some comments below.

 wrote on Mon, 17 Sep 2018 17:47:39 +0200:


From: Christophe Kerello 

The driver adds the support for the STMicroelectronics FMC2 NAND
Controller found on STM32MP SOCs.

This patch is based on FMC2 command sequencer.
The purpose of the command sequencer is to facilitate the programming
and the reading of NAND flash pages with the ECC and to free the CPU
of sequencing tasks.
It requires one DMA channel for write and two DMA channels for read
operations.

Only NAND_ECC_HW mode is actually supported.
The driver supports a maximum 8k page size.
The following ECC strength and step size are currently supported:
  - nand-ecc-strength = <8>, nand-ecc-step-size = <512> (BCH8)
  - nand-ecc-strength = <4>, nand-ecc-step-size = <512> (BCH4)
  - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (Extended ecc
based on HAMMING)

This patch has been tested on Micron MT29F8G08ABACAH4 and
MT29F8G16ABACAH4

Signed-off-by: Christophe Kerello 
---
  drivers/mtd/nand/raw/Kconfig   |9 +
  drivers/mtd/nand/raw/Makefile  |1 +
  drivers/mtd/nand/raw/stm32_fmc2_nand.c | 1729 
  3 files changed, 1739 insertions(+)
  create mode 100644 drivers/mtd/nand/raw/stm32_fmc2_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index c7efc31..863662c 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -541,4 +541,13 @@ config MTD_NAND_TEGRA
  is supported. Extra OOB bytes when using HW ECC are currently
  not supported.
  
+config MTD_NAND_STM32_FMC2

+   tristate "Support for NAND controller on STM32MP SoCs"
+   depends on MACH_STM32MP157 || COMPILE_TEST
+   help
+ Enables support for NAND Flash chips on SoCs containing the FMC2
+ NAND controller. This controller is found on STM32MP SoCs.
+ The driver supports a maximum 8k page size. HW ECC is enabled and
+ supports a maximum 8-bit correction error per sector of 512 bytes.


HW ECC should not be enabled by default. 8-bit/512B of correctability
is good but not that high and people might want to use software ECC in
conjunction with raw accesses.


Yes, I agree. The driver only supports NAND_ECC_HW mode. NAND_ECC_SOFT 
mode was not requested by customers and was not implemented. The driver 
could be improved later to support mode like NAND_ECC_SOFT or 
NAND_ECC_ON_DIE. Should I remove "HW ECC is enabled" from Kconfig 
description?





+
  endif # MTD_NAND
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index a6ef067..8c437e3 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND)   += brcmnand/
  obj-$(CONFIG_MTD_NAND_QCOM)   += qcom_nandc.o
  obj-$(CONFIG_MTD_NAND_MTK)+= mtk_ecc.o mtk_nand.o
  obj-$(CONFIG_MTD_NAND_TEGRA)  += tegra_nand.o
+obj-$(CONFIG_MTD_NAND_STM32_FMC2)  += stm32_fmc2_nand.o
  
  nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o

  nand-objs += nand_amd.o
diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c 
b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
new file mode 100644
index 000..dd5762a
--- /dev/null
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -0,0 +1,1729 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Christophe Kerello  for 
STMicroelectronics


I'm not sure the "All rights reserved" has a meaning here.

But you definitely not have to add "for STMicroelectronics" because it
is already in the copyright.


Ok.




+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Bad block marker length */
+#define FMC2_BBM_LEN   2
+
+/* ECC step size */
+#define FMC2_ECC_STEP_SIZE 512
+
+/* BCHDSRx registers length */
+#define FMC2_BCHDSRS_LEN   20
+
+/* HECCR length */
+#define FMC2_HECCR_LEN 4
+
+/* Max requests done for a 8k nand page size */
+#define FMC2_MAX_SG_COUNT  16
+
+/* Max chip enable */
+#define FMC2_MAX_CE2
+
+/* Timings */
+#define FMC2_THIZ  1
+#define FMC2_TIO   8000
+#define FMC2_TSYNC 3000
+#define FMC2_PCR_TIMING_MASK   0xf
+#define FMC2_PMEM_PATT_TIMING_MASK 0xff
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1  0x0
+#define FMC2_PCR   0x80
+#define FMC2_SR0x84
+#define FMC2_PMEM   

  1   2   >