Merge tag 'uniphier-v2020.04-2' of https://gitlab.denx.de/u-boot/custodians/u-boot-uniphier

UniPhier SoC updates for v2020.04 (2nd)

Denali NAND driver changes:
 - Set up more registers in denali-spl for SOCFPGA
 - Make clocks optional
 - Do not assert reset signals in the remove hook
 - associate SPARE_AREA_SKIP_BYTES with DT compatible
 - switch to UCLASS_MTD

UniPhier platform changes:
 - fix a bug in dram_init()
 - specify loadaddr for "source" command
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1236315..f04b6a6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1548,6 +1548,7 @@
 	select DM_GPIO
 	select DM_I2C
 	select DM_MMC
+	select DM_MTD
 	select DM_RESET
 	select DM_SERIAL
 	select DM_USB
diff --git a/arch/arm/mach-uniphier/board_init.c b/arch/arm/mach-uniphier/board_init.c
index 7535f91..99727a3 100644
--- a/arch/arm/mach-uniphier/board_init.c
+++ b/arch/arm/mach-uniphier/board_init.c
@@ -40,7 +40,6 @@
 		.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 @@
 		.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 d12f49e..c49e447 100644
--- a/arch/arm/mach-uniphier/clk/Makefile
+++ b/arch/arm/mach-uniphier/clk/Makefile
@@ -11,9 +11,9 @@
 
 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 0393942..0000000
--- 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 2b364dc..798128b 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 874964b..36006fd 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 8cb4f87..c2a75ce 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 @@
 	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/dram_init.c b/arch/arm/mach-uniphier/dram_init.c
index 13821a9..5f9d90f 100644
--- a/arch/arm/mach-uniphier/dram_init.c
+++ b/arch/arm/mach-uniphier/dram_init.c
@@ -248,12 +248,7 @@
 
 		max_size = (1ULL << 32) - dram_map[i].base;
 
-		if (dram_map[i].size > max_size) {
-			gd->ram_size += max_size;
-			break;
-		}
-
-		gd->ram_size += dram_map[i].size;
+		gd->ram_size = min(dram_map[i].size, max_size);
 
 		if (!valid_bank_found)
 			gd->ram_base = dram_map[i].base;
diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h
index b37ab2f..9dc5b88 100644
--- a/arch/arm/mach-uniphier/init.h
+++ b/arch/arm/mach-uniphier/init.h
@@ -90,7 +90,6 @@
 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);
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 7814d84..23201ca 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -116,7 +116,7 @@
 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.c b/drivers/mtd/nand/raw/denali.c
index 8537c60..be1b362 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1069,11 +1069,18 @@
 		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.h b/drivers/mtd/nand/raw/denali.h
index 63ae828..019deda 100644
--- a/drivers/mtd/nand/raw/denali.h
+++ b/drivers/mtd/nand/raw/denali.h
@@ -10,7 +10,6 @@
 #include <linux/bitops.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/types.h>
-#include <reset.h>
 
 #define DEVICE_RESET				0x0
 #define     DEVICE_RESET__BANK(bank)			BIT(bank)
@@ -316,7 +315,6 @@
 	void (*host_write)(struct denali_nand_info *denali, u32 addr, u32 data);
 	void (*setup_dma)(struct denali_nand_info *denali, dma_addr_t dma_addr,
 			  int page, int write);
-	struct reset_ctl_bulk resets;
 };
 
 #define DENALI_CAP_HW_ECC_FIXUP			BIT(0)
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c
index 0ce8132..759ad40 100644
--- a/drivers/mtd/nand/raw/denali_dt.c
+++ b/drivers/mtd/nand/raw/denali_dt.c
@@ -9,12 +9,14 @@
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/printk.h>
+#include <reset.h>
 
 #include "denali.h"
 
 struct denali_dt_data {
 	unsigned int revision;
 	unsigned int caps;
+	unsigned int oob_skip_bytes;
 	const struct nand_ecc_caps *ecc_caps;
 };
 
@@ -22,6 +24,7 @@
 		     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,
 };
 
@@ -30,6 +33,7 @@
 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,
 };
 
@@ -39,6 +43,7 @@
 	.revision = 0x0501,
 	.caps = DENALI_CAP_HW_ECC_FIXUP |
 		DENALI_CAP_DMA_64BIT,
+	.oob_skip_bytes = 8,
 	.ecc_caps = &denali_uniphier_v5b_ecc_caps,
 };
 
@@ -63,15 +68,18 @@
 	struct denali_nand_info *denali = dev_get_priv(dev);
 	const struct denali_dt_data *data;
 	struct clk clk, clk_x, clk_ecc;
+	struct reset_ctl_bulk resets;
 	struct resource res;
 	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;
 
@@ -91,7 +99,7 @@
 	if (ret)
 		ret = clk_get_by_index(dev, 0, &clk);
 	if (ret)
-		return ret;
+		clk.dev = NULL;
 
 	ret = clk_get_by_name(dev, "nand_x", &clk_x);
 	if (ret)
@@ -101,9 +109,11 @@
 	if (ret)
 		clk_ecc.dev = NULL;
 
-	ret = clk_enable(&clk);
-	if (ret)
-		return ret;
+	if (clk.dev) {
+		ret = clk_enable(&clk);
+		if (ret)
+			return ret;
+	}
 
 	if (clk_x.dev) {
 		ret = clk_enable(&clk_x);
@@ -131,30 +141,29 @@
 		denali->clk_x_rate = 200000000;
 	}
 
-	ret = reset_get_bulk(dev, &denali->resets);
-	if (ret)
+	ret = reset_get_bulk(dev, &resets);
+	if (ret) {
 		dev_warn(dev, "Can't get reset: %d\n", ret);
-	else
-		reset_deassert_bulk(&denali->resets);
-
-	return denali_init(denali);
-}
+	} else {
+		reset_deassert_bulk(&resets);
 
-static int denali_dt_remove(struct udevice *dev)
-{
-	struct denali_nand_info *denali = dev_get_priv(dev);
+		/*
+		 * 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 reset_release_bulk(&denali->resets);
+	return denali_init(denali);
 }
 
 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),
-	.remove = denali_dt_remove,
-	.flags = DM_FLAG_OS_PREPARE,
 };
 
 void board_nand_init(void)
@@ -162,7 +171,7 @@
 	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)
diff --git a/drivers/mtd/nand/raw/denali_spl.c b/drivers/mtd/nand/raw/denali_spl.c
index dbaba3c..b8b2981 100644
--- a/drivers/mtd/nand/raw/denali_spl.c
+++ b/drivers/mtd/nand/raw/denali_spl.c
@@ -173,6 +173,13 @@
 	page_size = readl(denali_flash_reg + DEVICE_MAIN_AREA_SIZE);
 	oob_size = readl(denali_flash_reg + DEVICE_SPARE_AREA_SIZE);
 	pages_per_block = readl(denali_flash_reg + PAGES_PER_BLOCK);
+
+	/* Do as denali_hw_init() does. */
+	writel(CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES,
+	       denali_flash_reg + SPARE_AREA_SKIP_BYTES);
+	writel(0x0F, denali_flash_reg + RB_PIN_ENABLED);
+	writel(CHIP_EN_DONT_CARE__FLAG, denali_flash_reg + CHIP_ENABLE_DONT_CARE);
+	writel(0xffff, denali_flash_reg + SPARE_AREA_MARKER);
 }
 
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h
index 2986666..b95fb9c 100644
--- a/include/configs/uniphier.h
+++ b/include/configs/uniphier.h
@@ -169,17 +169,17 @@
 		"ubi part UBI && " \
 		"ubifsmount ubi0:boot && " \
 		"ubifsload ${loadaddr} ${script} && " \
-		"source\0" \
+		"source $loadaddr\0" \
 	"norscript=echo Running ${script} from tftp ... && " \
 		"tftpboot ${script} &&" \
-		"source\0" \
+		"source $loadaddr\0" \
 	"usbscript=usb start && " \
 		"setenv devtype usb && " \
 		"setenv devnum 0 && " \
 		"run loadscript_fat\0" \
 	"loadscript_fat=echo Running ${script} from ${devtype}${devnum} ... && " \
 		"load ${devtype} ${devnum}:1 ${loadaddr} ${script} && " \
-		"source\0" \
+		"source $loadaddr\0" \
 	"sramupdate=setexpr tmp_addr $nor_base + 0x50000 &&"	\
 		"tftpboot $tmp_addr $second_image && " \
 		"setexpr tmp_addr $nor_base + 0x70000 && " \