[PATCH v2 1/4] mtd: rawnand: denali_dt: insert udelay() after reset deassert

When the reset signal is de-asserted, the HW-controlled bootstrap starts running unless it is disabled in the SoC integration. It issues some commands to detect a NAND chip, and sets up registers automatically. Until this process finishes, software should avoid any register access.
Without this delay function, some of UniPhier boards hangs up while executing nand_scan_ident(). (denali_read_byte() is blocked)
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com ---
Changes in v2: None
drivers/mtd/nand/raw/denali_dt.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 91d0f20aae..1afc61f876 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -136,11 +136,19 @@ static int denali_dt_probe(struct udevice *dev) }
ret = reset_get_bulk(dev, &resets); - if (ret) + if (ret) { dev_warn(dev, "Can't get reset: %d\n", ret); - else + } else { reset_deassert_bulk(&resets);
+ /* + * When the reset is deasserted, the initialization sequence is + * kicked (bootstrap process). The driver must wait until it is + * finished. Otherwise, it will result in unpredictable behavior. + */ + udelay(200); + } + return denali_init(denali); }

Currently, the denali NAND driver in U-Boot configures the SPARE_AREA_SKIP_BYTES based on the CONFIG option.
Recently, Linux kernel merged a patch that associates the proper value for this register with the DT compatible string.
Do likewise in U-Boot too.
The denali_spl.c still uses CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com ---
Changes in v2: None
drivers/mtd/nand/raw/denali.c | 15 +++++++++++---- drivers/mtd/nand/raw/denali_dt.c | 16 +++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 8537c609fb..be1b3627ad 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -1069,11 +1069,18 @@ static void denali_hw_init(struct denali_nand_info *denali) denali->revision = swab16(ioread32(denali->reg + REVISION));
/* - * tell driver how many bit controller will skip before writing - * ECC code in OOB. This is normally used for bad block marker + * Set how many bytes should be skipped before writing data in OOB. + * If a platform requests a non-zero value, set it to the register. + * Otherwise, read the value out, expecting it has already been set up + * by firmware. */ - denali->oob_skip_bytes = CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES; - iowrite32(denali->oob_skip_bytes, denali->reg + SPARE_AREA_SKIP_BYTES); + if (denali->oob_skip_bytes) + iowrite32(denali->oob_skip_bytes, + denali->reg + SPARE_AREA_SKIP_BYTES); + else + denali->oob_skip_bytes = ioread32(denali->reg + + SPARE_AREA_SKIP_BYTES); + denali_detect_max_banks(denali); iowrite32(0x0F, denali->reg + RB_PIN_ENABLED); iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE); diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 1afc61f876..587e480faa 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -16,6 +16,7 @@ struct denali_dt_data { unsigned int revision; unsigned int caps; + unsigned int oob_skip_bytes; const struct nand_ecc_caps *ecc_caps; };
@@ -23,6 +24,7 @@ NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes, 512, 8, 15); static const struct denali_dt_data denali_socfpga_data = { .caps = DENALI_CAP_HW_ECC_FIXUP, + .oob_skip_bytes = 2, .ecc_caps = &denali_socfpga_ecc_caps, };
@@ -31,6 +33,7 @@ NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes, static const struct denali_dt_data denali_uniphier_v5a_data = { .caps = DENALI_CAP_HW_ECC_FIXUP | DENALI_CAP_DMA_64BIT, + .oob_skip_bytes = 8, .ecc_caps = &denali_uniphier_v5a_ecc_caps, };
@@ -40,6 +43,7 @@ static const struct denali_dt_data denali_uniphier_v5b_data = { .revision = 0x0501, .caps = DENALI_CAP_HW_ECC_FIXUP | DENALI_CAP_DMA_64BIT, + .oob_skip_bytes = 8, .ecc_caps = &denali_uniphier_v5b_ecc_caps, };
@@ -69,11 +73,13 @@ static int denali_dt_probe(struct udevice *dev) int ret;
data = (void *)dev_get_driver_data(dev); - if (data) { - denali->revision = data->revision; - denali->caps = data->caps; - denali->ecc_caps = data->ecc_caps; - } + if (WARN_ON(!data)) + return -EINVAL; + + denali->revision = data->revision; + denali->caps = data->caps; + denali->oob_skip_bytes = data->oob_skip_bytes; + denali->ecc_caps = data->ecc_caps;
denali->dev = dev;

On Thu, Jan 30, 2020 at 12:57 AM Masahiro Yamada yamada.masahiro@socionext.com wrote:
Currently, the denali NAND driver in U-Boot configures the SPARE_AREA_SKIP_BYTES based on the CONFIG option.
Recently, Linux kernel merged a patch that associates the proper value for this register with the DT compatible string.
Do likewise in U-Boot too.
The denali_spl.c still uses CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Applied to u-boot-uniphier.
Changes in v2: None
drivers/mtd/nand/raw/denali.c | 15 +++++++++++---- drivers/mtd/nand/raw/denali_dt.c | 16 +++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 8537c609fb..be1b3627ad 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -1069,11 +1069,18 @@ static void denali_hw_init(struct denali_nand_info *denali) denali->revision = swab16(ioread32(denali->reg + REVISION));
/*
* tell driver how many bit controller will skip before writing
* ECC code in OOB. This is normally used for bad block marker
* Set how many bytes should be skipped before writing data in OOB.
* If a platform requests a non-zero value, set it to the register.
* Otherwise, read the value out, expecting it has already been set up
* by firmware. */
denali->oob_skip_bytes = CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES;
iowrite32(denali->oob_skip_bytes, denali->reg + SPARE_AREA_SKIP_BYTES);
if (denali->oob_skip_bytes)
iowrite32(denali->oob_skip_bytes,
denali->reg + SPARE_AREA_SKIP_BYTES);
else
denali->oob_skip_bytes = ioread32(denali->reg +
SPARE_AREA_SKIP_BYTES);
denali_detect_max_banks(denali); iowrite32(0x0F, denali->reg + RB_PIN_ENABLED); iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE);
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 1afc61f876..587e480faa 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -16,6 +16,7 @@ struct denali_dt_data { unsigned int revision; unsigned int caps;
unsigned int oob_skip_bytes; const struct nand_ecc_caps *ecc_caps;
};
@@ -23,6 +24,7 @@ NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes, 512, 8, 15); static const struct denali_dt_data denali_socfpga_data = { .caps = DENALI_CAP_HW_ECC_FIXUP,
.oob_skip_bytes = 2, .ecc_caps = &denali_socfpga_ecc_caps,
};
@@ -31,6 +33,7 @@ NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes, static const struct denali_dt_data denali_uniphier_v5a_data = { .caps = DENALI_CAP_HW_ECC_FIXUP | DENALI_CAP_DMA_64BIT,
.oob_skip_bytes = 8, .ecc_caps = &denali_uniphier_v5a_ecc_caps,
};
@@ -40,6 +43,7 @@ static const struct denali_dt_data denali_uniphier_v5b_data = { .revision = 0x0501, .caps = DENALI_CAP_HW_ECC_FIXUP | DENALI_CAP_DMA_64BIT,
.oob_skip_bytes = 8, .ecc_caps = &denali_uniphier_v5b_ecc_caps,
};
@@ -69,11 +73,13 @@ static int denali_dt_probe(struct udevice *dev) int ret;
data = (void *)dev_get_driver_data(dev);
if (data) {
denali->revision = data->revision;
denali->caps = data->caps;
denali->ecc_caps = data->ecc_caps;
}
if (WARN_ON(!data))
return -EINVAL;
denali->revision = data->revision;
denali->caps = data->caps;
denali->oob_skip_bytes = data->oob_skip_bytes;
denali->ecc_caps = data->ecc_caps; denali->dev = dev;
-- 2.17.1

UCLASS_MTD is a better fit for NAND drivers.
Make NAND_DENALI_DT depend on DM_MTD, which is needed to compile drivers/mtd/mtd-uclass.c
Also, make ARCH_SOCFPGA and ARCH_UNIPHIER select DM_MTD because they use this driver.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com ---
Changes in v2: - new patch
arch/arm/Kconfig | 2 ++ drivers/mtd/nand/raw/Kconfig | 2 +- drivers/mtd/nand/raw/denali_dt.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1236315168..d1c58667c7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -935,6 +935,7 @@ config ARCH_SOCFPGA select ARM64 if TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX select CPU_V7A if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 select DM + select DM_MTD select DM_SERIAL select ENABLE_ARM_SOC_BOOT0_HOOK if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 select OF_CONTROL @@ -1548,6 +1549,7 @@ config ARCH_UNIPHIER select DM_GPIO select DM_I2C select DM_MMC + select DM_MTD select DM_RESET select DM_SERIAL select DM_USB diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 7814d84ba0..23201ca720 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -116,7 +116,7 @@ config NAND_DENALI config NAND_DENALI_DT bool "Support Denali NAND controller as a DT device" select NAND_DENALI - depends on OF_CONTROL && DM + depends on OF_CONTROL && DM_MTD help Enable the driver for NAND flash on platforms using a Denali NAND controller as a DT device. diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 587e480faa..759ad40e51 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -160,7 +160,7 @@ static int denali_dt_probe(struct udevice *dev)
U_BOOT_DRIVER(denali_nand_dt) = { .name = "denali-nand-dt", - .id = UCLASS_MISC, + .id = UCLASS_MTD, .of_match = denali_nand_dt_ids, .probe = denali_dt_probe, .priv_auto_alloc_size = sizeof(struct denali_nand_info), @@ -171,7 +171,7 @@ void board_nand_init(void) struct udevice *dev; int ret;
- ret = uclass_get_device_by_driver(UCLASS_MISC, + ret = uclass_get_device_by_driver(UCLASS_MTD, DM_GET_DRIVER(denali_nand_dt), &dev); if (ret && ret != -ENODEV)

Hi Masahiro,
Masahiro Yamada yamada.masahiro@socionext.com wrote on Thu, 30 Jan 2020 00:55:56 +0900:
UCLASS_MTD is a better fit for NAND drivers.
Make NAND_DENALI_DT depend on DM_MTD, which is needed to compile drivers/mtd/mtd-uclass.c
Also, make ARCH_SOCFPGA and ARCH_UNIPHIER select DM_MTD because they use this driver.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Reviewed-by: Miquel Raynal miquel.raynal@bootlin.com
Thanks, Miquèl

Am 29.01.2020 um 16:55 schrieb Masahiro Yamada:
UCLASS_MTD is a better fit for NAND drivers.
Make NAND_DENALI_DT depend on DM_MTD, which is needed to compile drivers/mtd/mtd-uclass.c
Also, make ARCH_SOCFPGA and ARCH_UNIPHIER select DM_MTD because they use this driver.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Changes in v2:
- new patch
arch/arm/Kconfig | 2 ++ drivers/mtd/nand/raw/Kconfig | 2 +- drivers/mtd/nand/raw/denali_dt.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1236315168..d1c58667c7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -935,6 +935,7 @@ config ARCH_SOCFPGA select ARM64 if TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX select CPU_V7A if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 select DM
- select DM_MTD
Does any socfpga actually enable the denali driver? Do we need to default to this instead of enabling it in a defconfig?
If we need it, could you please change that to 'imply'? Not all configs will need this.
Thanks, Simon
select DM_SERIAL select ENABLE_ARM_SOC_BOOT0_HOOK if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 select OF_CONTROL @@ -1548,6 +1549,7 @@ config ARCH_UNIPHIER select DM_GPIO select DM_I2C select DM_MMC
- select DM_MTD select DM_RESET select DM_SERIAL select DM_USB
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 7814d84ba0..23201ca720 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -116,7 +116,7 @@ config NAND_DENALI config NAND_DENALI_DT bool "Support Denali NAND controller as a DT device" select NAND_DENALI
- depends on OF_CONTROL && DM
- depends on OF_CONTROL && DM_MTD help Enable the driver for NAND flash on platforms using a Denali NAND controller as a DT device.
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 587e480faa..759ad40e51 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -160,7 +160,7 @@ static int denali_dt_probe(struct udevice *dev)
U_BOOT_DRIVER(denali_nand_dt) = { .name = "denali-nand-dt",
- .id = UCLASS_MISC,
- .id = UCLASS_MTD, .of_match = denali_nand_dt_ids, .probe = denali_dt_probe, .priv_auto_alloc_size = sizeof(struct denali_nand_info),
@@ -171,7 +171,7 @@ void board_nand_init(void) struct udevice *dev; int ret;
- ret = uclass_get_device_by_driver(UCLASS_MISC,
- ret = uclass_get_device_by_driver(UCLASS_MTD, DM_GET_DRIVER(denali_nand_dt), &dev); if (ret && ret != -ENODEV)

On 1/29/20 6:08 PM, Simon Goldschmidt wrote:
Am 29.01.2020 um 16:55 schrieb Masahiro Yamada:
UCLASS_MTD is a better fit for NAND drivers.
Make NAND_DENALI_DT depend on DM_MTD, which is needed to compile drivers/mtd/mtd-uclass.c
Also, make ARCH_SOCFPGA and ARCH_UNIPHIER select DM_MTD because they use this driver.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Changes in v2: - new patch
arch/arm/Kconfig | 2 ++ drivers/mtd/nand/raw/Kconfig | 2 +- drivers/mtd/nand/raw/denali_dt.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1236315168..d1c58667c7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -935,6 +935,7 @@ config ARCH_SOCFPGA select ARM64 if TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX select CPU_V7A if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 select DM + select DM_MTD
Does any socfpga actually enable the denali driver? Do we need to default to this instead of enabling it in a defconfig?
If we need it, could you please change that to 'imply'? Not all configs will need this.
No SoCFPGA enables the Denali NAND, because support for that was completely broken and I was waiting until the Denali NAND patches make it in before sending that platform which will use it.
Indeed, DM_MTD should be enabled in platform config, not in general.

Hi Marek,
On Thu, Jan 30, 2020 at 7:03 AM Marek Vasut marex@denx.de wrote:
On 1/29/20 6:08 PM, Simon Goldschmidt wrote:
Am 29.01.2020 um 16:55 schrieb Masahiro Yamada:
UCLASS_MTD is a better fit for NAND drivers.
Make NAND_DENALI_DT depend on DM_MTD, which is needed to compile drivers/mtd/mtd-uclass.c
Also, make ARCH_SOCFPGA and ARCH_UNIPHIER select DM_MTD because they use this driver.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Changes in v2:
- new patch
arch/arm/Kconfig | 2 ++ drivers/mtd/nand/raw/Kconfig | 2 +- drivers/mtd/nand/raw/denali_dt.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1236315168..d1c58667c7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -935,6 +935,7 @@ config ARCH_SOCFPGA select ARM64 if TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX select CPU_V7A if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 select DM
- select DM_MTD
Does any socfpga actually enable the denali driver? Do we need to default to this instead of enabling it in a defconfig?
If we need it, could you please change that to 'imply'? Not all configs will need this.
No SoCFPGA enables the Denali NAND, because support for that was completely broken and I was waiting until the Denali NAND patches make it in before sending that platform which will use it.
Indeed, DM_MTD should be enabled in platform config, not in general.
Right. None of ARCH_SOCFPGA boards enables the Denali, It is up to you whichever defconfig you add the CONFIG option to.
I still prefer "select DM_MTD" for ARCH_UNIPHIER because all uniphier_*_defconfig enables the Denali driver.
I will drop "select DM_MTD" from ARCH_SOCFPGA.
Is this OK for you ?

On 1/30/20 6:34 AM, Masahiro Yamada wrote:
Hi Marek,
Hi,
On Thu, Jan 30, 2020 at 7:03 AM Marek Vasut marex@denx.de wrote:
On 1/29/20 6:08 PM, Simon Goldschmidt wrote:
Am 29.01.2020 um 16:55 schrieb Masahiro Yamada:
UCLASS_MTD is a better fit for NAND drivers.
Make NAND_DENALI_DT depend on DM_MTD, which is needed to compile drivers/mtd/mtd-uclass.c
Also, make ARCH_SOCFPGA and ARCH_UNIPHIER select DM_MTD because they use this driver.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Changes in v2:
- new patch
arch/arm/Kconfig | 2 ++ drivers/mtd/nand/raw/Kconfig | 2 +- drivers/mtd/nand/raw/denali_dt.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1236315168..d1c58667c7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -935,6 +935,7 @@ config ARCH_SOCFPGA select ARM64 if TARGET_SOCFPGA_STRATIX10 || TARGET_SOCFPGA_AGILEX select CPU_V7A if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 select DM
- select DM_MTD
Does any socfpga actually enable the denali driver? Do we need to default to this instead of enabling it in a defconfig?
If we need it, could you please change that to 'imply'? Not all configs will need this.
No SoCFPGA enables the Denali NAND, because support for that was completely broken and I was waiting until the Denali NAND patches make it in before sending that platform which will use it.
Indeed, DM_MTD should be enabled in platform config, not in general.
Right. None of ARCH_SOCFPGA boards enables the Denali, It is up to you whichever defconfig you add the CONFIG option to.
I still prefer "select DM_MTD" for ARCH_UNIPHIER because all uniphier_*_defconfig enables the Denali driver.
I will drop "select DM_MTD" from ARCH_SOCFPGA.
Is this OK for you ?
Yes, thanks.

Now that the reset controlling of the Denali NAND driver (denali_dt.c) works for this platform, remove the adhoc reset deassert code.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com ---
Changes in v2: - more clean-up
arch/arm/mach-uniphier/board_init.c | 2 -- arch/arm/mach-uniphier/clk/Makefile | 4 ++-- arch/arm/mach-uniphier/clk/clk-ld4.c | 32 --------------------------- arch/arm/mach-uniphier/clk/clk-pro4.c | 14 ++---------- arch/arm/mach-uniphier/clk/clk-pro5.c | 14 ++---------- arch/arm/mach-uniphier/clk/clk-pxs2.c | 14 ++---------- arch/arm/mach-uniphier/init.h | 1 - 7 files changed, 8 insertions(+), 73 deletions(-) delete mode 100644 arch/arm/mach-uniphier/clk/clk-ld4.c
diff --git a/arch/arm/mach-uniphier/board_init.c b/arch/arm/mach-uniphier/board_init.c index 7535f91528..99727a3004 100644 --- a/arch/arm/mach-uniphier/board_init.c +++ b/arch/arm/mach-uniphier/board_init.c @@ -40,7 +40,6 @@ static const struct uniphier_initdata uniphier_initdata[] = { .soc_id = UNIPHIER_LD4_ID, .sbc_init = uniphier_ld4_sbc_init, .pll_init = uniphier_ld4_pll_init, - .clk_init = uniphier_ld4_clk_init, }, #endif #if defined(CONFIG_ARCH_UNIPHIER_PRO4) @@ -56,7 +55,6 @@ static const struct uniphier_initdata uniphier_initdata[] = { .soc_id = UNIPHIER_SLD8_ID, .sbc_init = uniphier_ld4_sbc_init, .pll_init = uniphier_ld4_pll_init, - .clk_init = uniphier_ld4_clk_init, }, #endif #if defined(CONFIG_ARCH_UNIPHIER_PRO5) diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile index d12f49e523..c49e44754c 100644 --- a/arch/arm/mach-uniphier/clk/Makefile +++ b/arch/arm/mach-uniphier/clk/Makefile @@ -11,9 +11,9 @@ obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += clk-early-ld4.o clk-dram-pxs2.o dpll-pxs2.o
else
-obj-$(CONFIG_ARCH_UNIPHIER_LD4) += clk-ld4.o pll-ld4.o dpll-tail.o +obj-$(CONFIG_ARCH_UNIPHIER_LD4) += pll-ld4.o dpll-tail.o obj-$(CONFIG_ARCH_UNIPHIER_PRO4) += clk-pro4.o pll-pro4.o dpll-tail.o -obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += clk-ld4.o pll-ld4.o dpll-tail.o +obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += pll-ld4.o dpll-tail.o obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += clk-pro5.o obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += clk-pxs2.o obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += clk-pxs2.o diff --git a/arch/arm/mach-uniphier/clk/clk-ld4.c b/arch/arm/mach-uniphier/clk/clk-ld4.c deleted file mode 100644 index 0393942503..0000000000 --- a/arch/arm/mach-uniphier/clk/clk-ld4.c +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2011-2015 Panasonic Corporation - * Copyright (C) 2015-2016 Socionext Inc. - * Author: Masahiro Yamada yamada.masahiro@socionext.com - */ - -#include <linux/io.h> - -#include "../init.h" -#include "../sc-regs.h" - -void uniphier_ld4_clk_init(void) -{ - u32 tmp; - - /* deassert reset */ - tmp = readl(sc_base + SC_RSTCTRL); -#ifdef CONFIG_NAND_DENALI - tmp |= SC_RSTCTRL_NRST_NAND; -#endif - writel(tmp, sc_base + SC_RSTCTRL); - readl(sc_base + SC_RSTCTRL); /* dummy read */ - - /* provide clocks */ - tmp = readl(sc_base + SC_CLKCTRL); -#ifdef CONFIG_NAND_DENALI - tmp |= SC_CLKCTRL_CEN_NAND; -#endif - writel(tmp, sc_base + SC_CLKCTRL); - readl(sc_base + SC_CLKCTRL); /* dummy read */ -} diff --git a/arch/arm/mach-uniphier/clk/clk-pro4.c b/arch/arm/mach-uniphier/clk/clk-pro4.c index 2b364dca41..798128b302 100644 --- a/arch/arm/mach-uniphier/clk/clk-pro4.c +++ b/arch/arm/mach-uniphier/clk/clk-pro4.c @@ -12,36 +12,26 @@
void uniphier_pro4_clk_init(void) { +#ifdef CONFIG_USB_DWC3_UNIPHIER u32 tmp;
/* deassert reset */ tmp = readl(sc_base + SC_RSTCTRL); -#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_USB3C0 | SC_RSTCTRL_NRST_GIO; -#endif -#ifdef CONFIG_NAND_DENALI - tmp |= SC_RSTCTRL_NRST_NAND; -#endif writel(tmp, sc_base + SC_RSTCTRL); readl(sc_base + SC_RSTCTRL); /* dummy read */
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp = readl(sc_base + SC_RSTCTRL2); tmp |= SC_RSTCTRL2_NRST_USB3B1 | SC_RSTCTRL2_NRST_USB3C1; writel(tmp, sc_base + SC_RSTCTRL2); readl(sc_base + SC_RSTCTRL2); /* dummy read */ -#endif
/* provide clocks */ tmp = readl(sc_base + SC_CLKCTRL); -#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | SC_CLKCTRL_CEN_GIO; -#endif -#ifdef CONFIG_NAND_DENALI - tmp |= SC_CLKCTRL_CEN_NAND; -#endif writel(tmp, sc_base + SC_CLKCTRL); readl(sc_base + SC_CLKCTRL); /* dummy read */ +#endif } diff --git a/arch/arm/mach-uniphier/clk/clk-pro5.c b/arch/arm/mach-uniphier/clk/clk-pro5.c index 874964b2d5..36006fd256 100644 --- a/arch/arm/mach-uniphier/clk/clk-pro5.c +++ b/arch/arm/mach-uniphier/clk/clk-pro5.c @@ -10,35 +10,25 @@
void uniphier_pro5_clk_init(void) { +#ifdef CONFIG_USB_DWC3_UNIPHIER u32 tmp;
/* deassert reset */ tmp = readl(sc_base + SC_RSTCTRL); -#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_GIO; -#endif -#ifdef CONFIG_NAND_DENALI - tmp |= SC_RSTCTRL_NRST_NAND; -#endif writel(tmp, sc_base + SC_RSTCTRL); readl(sc_base + SC_RSTCTRL); /* dummy read */
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp = readl(sc_base + SC_RSTCTRL2); tmp |= SC_RSTCTRL2_NRST_USB3B1; writel(tmp, sc_base + SC_RSTCTRL2); readl(sc_base + SC_RSTCTRL2); /* dummy read */ -#endif
/* provide clocks */ tmp = readl(sc_base + SC_CLKCTRL); -#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | SC_CLKCTRL_CEN_GIO; -#endif -#ifdef CONFIG_NAND_DENALI - tmp |= SC_CLKCTRL_CEN_NAND; -#endif writel(tmp, sc_base + SC_CLKCTRL); readl(sc_base + SC_CLKCTRL); /* dummy read */ +#endif } diff --git a/arch/arm/mach-uniphier/clk/clk-pxs2.c b/arch/arm/mach-uniphier/clk/clk-pxs2.c index 8cb4f87ae5..c2a75ce000 100644 --- a/arch/arm/mach-uniphier/clk/clk-pxs2.c +++ b/arch/arm/mach-uniphier/clk/clk-pxs2.c @@ -11,20 +11,15 @@
void uniphier_pxs2_clk_init(void) { +#ifdef CONFIG_USB_DWC3_UNIPHIER u32 tmp;
/* deassert reset */ tmp = readl(sc_base + SC_RSTCTRL); -#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_GIO; -#endif -#ifdef CONFIG_NAND_DENALI - tmp |= SC_RSTCTRL_NRST_NAND; -#endif writel(tmp, sc_base + SC_RSTCTRL); readl(sc_base + SC_RSTCTRL); /* dummy read */
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp = readl(sc_base + SC_RSTCTRL2); tmp |= SC_RSTCTRL2_NRST_USB3B1; writel(tmp, sc_base + SC_RSTCTRL2); @@ -33,17 +28,12 @@ void uniphier_pxs2_clk_init(void) tmp = readl(sc_base + SC_RSTCTRL6); tmp |= 0x37; writel(tmp, sc_base + SC_RSTCTRL6); -#endif
/* provide clocks */ tmp = readl(sc_base + SC_CLKCTRL); -#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= BIT(20) | BIT(19) | SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | SC_CLKCTRL_CEN_GIO; -#endif -#ifdef CONFIG_NAND_DENALI - tmp |= SC_CLKCTRL_CEN_NAND; -#endif writel(tmp, sc_base + SC_CLKCTRL); readl(sc_base + SC_CLKCTRL); /* dummy read */ +#endif } diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h index b37ab2fa50..9dc5b885a5 100644 --- a/arch/arm/mach-uniphier/init.h +++ b/arch/arm/mach-uniphier/init.h @@ -90,7 +90,6 @@ void uniphier_ld11_pll_init(void); void uniphier_ld20_pll_init(void); void uniphier_pxs3_pll_init(void);
-void uniphier_ld4_clk_init(void); void uniphier_pro4_clk_init(void); void uniphier_pro5_clk_init(void); void uniphier_pxs2_clk_init(void);

On Thu, Jan 30, 2020 at 12:57 AM Masahiro Yamada yamada.masahiro@socionext.com wrote:
Now that the reset controlling of the Denali NAND driver (denali_dt.c) works for this platform, remove the adhoc reset deassert code.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Applied to u-boot-uniphier.
Changes in v2:
- more clean-up
arch/arm/mach-uniphier/board_init.c | 2 -- arch/arm/mach-uniphier/clk/Makefile | 4 ++-- arch/arm/mach-uniphier/clk/clk-ld4.c | 32 --------------------------- arch/arm/mach-uniphier/clk/clk-pro4.c | 14 ++---------- arch/arm/mach-uniphier/clk/clk-pro5.c | 14 ++---------- arch/arm/mach-uniphier/clk/clk-pxs2.c | 14 ++---------- arch/arm/mach-uniphier/init.h | 1 - 7 files changed, 8 insertions(+), 73 deletions(-) delete mode 100644 arch/arm/mach-uniphier/clk/clk-ld4.c
diff --git a/arch/arm/mach-uniphier/board_init.c b/arch/arm/mach-uniphier/board_init.c index 7535f91528..99727a3004 100644 --- a/arch/arm/mach-uniphier/board_init.c +++ b/arch/arm/mach-uniphier/board_init.c @@ -40,7 +40,6 @@ static const struct uniphier_initdata uniphier_initdata[] = { .soc_id = UNIPHIER_LD4_ID, .sbc_init = uniphier_ld4_sbc_init, .pll_init = uniphier_ld4_pll_init,
.clk_init = uniphier_ld4_clk_init, },
#endif #if defined(CONFIG_ARCH_UNIPHIER_PRO4) @@ -56,7 +55,6 @@ static const struct uniphier_initdata uniphier_initdata[] = { .soc_id = UNIPHIER_SLD8_ID, .sbc_init = uniphier_ld4_sbc_init, .pll_init = uniphier_ld4_pll_init,
.clk_init = uniphier_ld4_clk_init, },
#endif #if defined(CONFIG_ARCH_UNIPHIER_PRO5) diff --git a/arch/arm/mach-uniphier/clk/Makefile b/arch/arm/mach-uniphier/clk/Makefile index d12f49e523..c49e44754c 100644 --- a/arch/arm/mach-uniphier/clk/Makefile +++ b/arch/arm/mach-uniphier/clk/Makefile @@ -11,9 +11,9 @@ obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += clk-early-ld4.o clk-dram-pxs2.o dpll-pxs2.o
else
-obj-$(CONFIG_ARCH_UNIPHIER_LD4) += clk-ld4.o pll-ld4.o dpll-tail.o +obj-$(CONFIG_ARCH_UNIPHIER_LD4) += pll-ld4.o dpll-tail.o obj-$(CONFIG_ARCH_UNIPHIER_PRO4) += clk-pro4.o pll-pro4.o dpll-tail.o -obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += clk-ld4.o pll-ld4.o dpll-tail.o +obj-$(CONFIG_ARCH_UNIPHIER_SLD8) += pll-ld4.o dpll-tail.o obj-$(CONFIG_ARCH_UNIPHIER_PRO5) += clk-pro5.o obj-$(CONFIG_ARCH_UNIPHIER_PXS2) += clk-pxs2.o obj-$(CONFIG_ARCH_UNIPHIER_LD6B) += clk-pxs2.o diff --git a/arch/arm/mach-uniphier/clk/clk-ld4.c b/arch/arm/mach-uniphier/clk/clk-ld4.c deleted file mode 100644 index 0393942503..0000000000 --- a/arch/arm/mach-uniphier/clk/clk-ld4.c +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/*
- Copyright (C) 2011-2015 Panasonic Corporation
- Copyright (C) 2015-2016 Socionext Inc.
- Author: Masahiro Yamada yamada.masahiro@socionext.com
- */
-#include <linux/io.h>
-#include "../init.h" -#include "../sc-regs.h"
-void uniphier_ld4_clk_init(void) -{
u32 tmp;
/* deassert reset */
tmp = readl(sc_base + SC_RSTCTRL);
-#ifdef CONFIG_NAND_DENALI
tmp |= SC_RSTCTRL_NRST_NAND;
-#endif
writel(tmp, sc_base + SC_RSTCTRL);
readl(sc_base + SC_RSTCTRL); /* dummy read */
/* provide clocks */
tmp = readl(sc_base + SC_CLKCTRL);
-#ifdef CONFIG_NAND_DENALI
tmp |= SC_CLKCTRL_CEN_NAND;
-#endif
writel(tmp, sc_base + SC_CLKCTRL);
readl(sc_base + SC_CLKCTRL); /* dummy read */
-} diff --git a/arch/arm/mach-uniphier/clk/clk-pro4.c b/arch/arm/mach-uniphier/clk/clk-pro4.c index 2b364dca41..798128b302 100644 --- a/arch/arm/mach-uniphier/clk/clk-pro4.c +++ b/arch/arm/mach-uniphier/clk/clk-pro4.c @@ -12,36 +12,26 @@
void uniphier_pro4_clk_init(void) { +#ifdef CONFIG_USB_DWC3_UNIPHIER u32 tmp;
/* deassert reset */ tmp = readl(sc_base + SC_RSTCTRL);
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_USB3C0 | SC_RSTCTRL_NRST_GIO; -#endif -#ifdef CONFIG_NAND_DENALI
tmp |= SC_RSTCTRL_NRST_NAND;
-#endif writel(tmp, sc_base + SC_RSTCTRL); readl(sc_base + SC_RSTCTRL); /* dummy read */
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp = readl(sc_base + SC_RSTCTRL2); tmp |= SC_RSTCTRL2_NRST_USB3B1 | SC_RSTCTRL2_NRST_USB3C1; writel(tmp, sc_base + SC_RSTCTRL2); readl(sc_base + SC_RSTCTRL2); /* dummy read */ -#endif
/* provide clocks */ tmp = readl(sc_base + SC_CLKCTRL);
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | SC_CLKCTRL_CEN_GIO; -#endif -#ifdef CONFIG_NAND_DENALI
tmp |= SC_CLKCTRL_CEN_NAND;
-#endif writel(tmp, sc_base + SC_CLKCTRL); readl(sc_base + SC_CLKCTRL); /* dummy read */ +#endif } diff --git a/arch/arm/mach-uniphier/clk/clk-pro5.c b/arch/arm/mach-uniphier/clk/clk-pro5.c index 874964b2d5..36006fd256 100644 --- a/arch/arm/mach-uniphier/clk/clk-pro5.c +++ b/arch/arm/mach-uniphier/clk/clk-pro5.c @@ -10,35 +10,25 @@
void uniphier_pro5_clk_init(void) { +#ifdef CONFIG_USB_DWC3_UNIPHIER u32 tmp;
/* deassert reset */ tmp = readl(sc_base + SC_RSTCTRL);
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_GIO; -#endif -#ifdef CONFIG_NAND_DENALI
tmp |= SC_RSTCTRL_NRST_NAND;
-#endif writel(tmp, sc_base + SC_RSTCTRL); readl(sc_base + SC_RSTCTRL); /* dummy read */
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp = readl(sc_base + SC_RSTCTRL2); tmp |= SC_RSTCTRL2_NRST_USB3B1; writel(tmp, sc_base + SC_RSTCTRL2); readl(sc_base + SC_RSTCTRL2); /* dummy read */ -#endif
/* provide clocks */ tmp = readl(sc_base + SC_CLKCTRL);
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | SC_CLKCTRL_CEN_GIO; -#endif -#ifdef CONFIG_NAND_DENALI
tmp |= SC_CLKCTRL_CEN_NAND;
-#endif writel(tmp, sc_base + SC_CLKCTRL); readl(sc_base + SC_CLKCTRL); /* dummy read */ +#endif } diff --git a/arch/arm/mach-uniphier/clk/clk-pxs2.c b/arch/arm/mach-uniphier/clk/clk-pxs2.c index 8cb4f87ae5..c2a75ce000 100644 --- a/arch/arm/mach-uniphier/clk/clk-pxs2.c +++ b/arch/arm/mach-uniphier/clk/clk-pxs2.c @@ -11,20 +11,15 @@
void uniphier_pxs2_clk_init(void) { +#ifdef CONFIG_USB_DWC3_UNIPHIER u32 tmp;
/* deassert reset */ tmp = readl(sc_base + SC_RSTCTRL);
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= SC_RSTCTRL_NRST_USB3B0 | SC_RSTCTRL_NRST_GIO; -#endif -#ifdef CONFIG_NAND_DENALI
tmp |= SC_RSTCTRL_NRST_NAND;
-#endif writel(tmp, sc_base + SC_RSTCTRL); readl(sc_base + SC_RSTCTRL); /* dummy read */
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp = readl(sc_base + SC_RSTCTRL2); tmp |= SC_RSTCTRL2_NRST_USB3B1; writel(tmp, sc_base + SC_RSTCTRL2); @@ -33,17 +28,12 @@ void uniphier_pxs2_clk_init(void) tmp = readl(sc_base + SC_RSTCTRL6); tmp |= 0x37; writel(tmp, sc_base + SC_RSTCTRL6); -#endif
/* provide clocks */ tmp = readl(sc_base + SC_CLKCTRL);
-#ifdef CONFIG_USB_DWC3_UNIPHIER tmp |= BIT(20) | BIT(19) | SC_CLKCTRL_CEN_USB31 | SC_CLKCTRL_CEN_USB30 | SC_CLKCTRL_CEN_GIO; -#endif -#ifdef CONFIG_NAND_DENALI
tmp |= SC_CLKCTRL_CEN_NAND;
-#endif writel(tmp, sc_base + SC_CLKCTRL); readl(sc_base + SC_CLKCTRL); /* dummy read */ +#endif } diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h index b37ab2fa50..9dc5b885a5 100644 --- a/arch/arm/mach-uniphier/init.h +++ b/arch/arm/mach-uniphier/init.h @@ -90,7 +90,6 @@ void uniphier_ld11_pll_init(void); void uniphier_ld20_pll_init(void); void uniphier_pxs3_pll_init(void);
-void uniphier_ld4_clk_init(void); void uniphier_pro4_clk_init(void); void uniphier_pro5_clk_init(void); void uniphier_pxs2_clk_init(void); -- 2.17.1

On Thu, Jan 30, 2020 at 12:57 AM Masahiro Yamada yamada.masahiro@socionext.com wrote:
When the reset signal is de-asserted, the HW-controlled bootstrap starts running unless it is disabled in the SoC integration. It issues some commands to detect a NAND chip, and sets up registers automatically. Until this process finishes, software should avoid any register access.
Without this delay function, some of UniPhier boards hangs up while executing nand_scan_ident(). (denali_read_byte() is blocked)
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Applied to u-boot-uniphier.
Changes in v2: None
drivers/mtd/nand/raw/denali_dt.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 91d0f20aae..1afc61f876 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c @@ -136,11 +136,19 @@ static int denali_dt_probe(struct udevice *dev) }
ret = reset_get_bulk(dev, &resets);
if (ret)
if (ret) { dev_warn(dev, "Can't get reset: %d\n", ret);
else
} else { reset_deassert_bulk(&resets);
/*
* When the reset is deasserted, the initialization sequence is
* kicked (bootstrap process). The driver must wait until it is
* finished. Otherwise, it will result in unpredictable behavior.
*/
udelay(200);
}
return denali_init(denali);
}
-- 2.17.1
participants (5)
-
Marek Vasut
-
Masahiro Yamada
-
Masahiro Yamada
-
Miquel Raynal
-
Simon Goldschmidt