Skip to contentSkip to conversation

ARM: uniphier: UniPhier SoC updates for v2017.03 (3rd round)

PATCH New Masahiro Yamada 2 participants 20 messages Jan 27, 2017 – Jan 31, 2017

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover ARM: uniphier: UniPhier SoC updates for v2017.03 (3rd round)

- Fix clk driver
- Optimize DRAM init code for LD20 SoC
- Get DRAM information from more reliable source
- Clean up SoC init code
- Allow to use Image.gz for booting ARM64 Linux
- Tidy up environments to use with ATF
- Clean up I2C drivers

Masahiro Yamada (16):
clk: uniphier: fix compatible strings for Pro5, PXs2, LD20 SD clock
ARM: uniphier: shrink arrays of DDR-PHY parameters for LD20 SoC
ARM: uniphier: detect RAM size by decoding HW register instead of DT
ARM: uniphier: use gd->bd->bi_dram for memory reserve on LD20 SoC
ARM: uniphier: refactor cmd_ddrphy
ARM: uniphier: clean up UMC init for PXs2 SoC
ARM: uniphier: refactor cmd_ddrmphy
ARM: uniphier: compile board data only for SPL
ARM: uniphier: collect SPL CONFIG symbols to the bottom of header
ARM: uniphier: use Image.gz instead Image for booting ARM64 Linux
ARM: uniphier: set initrd_high environment to skip initrd relocation
ARM: uniphier: change the offset to environment storage area
ARM: uniphier: change CONFIG_SPL_PAD_TO to 128KB
ARM: uniphier: make update commands more flexible for ATF
i2c: uniphier(-f): remove unneeded #include <dm/root.h>
i2c: uniphier-f: use readl_poll_timeout() to poll registers

 arch/arm/mach-uniphier/Makefile            |   2 +-
 arch/arm/mach-uniphier/dram/cmd_ddrmphy.c  | 234 ++++++++++++++-----------
 arch/arm/mach-uniphier/dram/cmd_ddrphy.c   | 156 +++++++++--------
 arch/arm/mach-uniphier/dram/ddrmphy-regs.h | 262 ++++++++++++++--------------
 arch/arm/mach-uniphier/dram/umc-ld20.c     | 254 +++++++++-------------------
 arch/arm/mach-uniphier/dram/umc-pxs2.c     | 253 +++++++++++++--------------
 arch/arm/mach-uniphier/dram_init.c         | 263 ++++++++++++++++++++++-------
 arch/arm/mach-uniphier/init.h              |   1 +
 common/spl/Kconfig                         |   3 +-
 drivers/clk/uniphier/clk-uniphier-core.c   |   6 +-
 drivers/i2c/i2c-uniphier-f.c               |  35 ++--
 drivers/i2c/i2c-uniphier.c                 |   1 -
 include/configs/uniphier.h                 | 104 ++++++++----
 13 files changed, 839 insertions(+), 735 deletions(-)
Signature · 1 line
2.7.4
#1 lore raw

PATCH 1/16 clk: uniphier: fix compatible strings for Pro5, PXs2, LD20 SD clock

I missed to update them when DT files were resynced with Linux.

---

 drivers/clk/uniphier/clk-uniphier-core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/uniphier/clk-uniphier-core.c +3 -3
index 8ad0242..bcb2d2e 100644
@@ -163,11 +163,11 @@ static const struct udevice_id uniphier_clk_match[] = {
 		.data = (ulong)&uniphier_mio_clk_data,
 	},
 	{
-		.compatible = "socionext,uniphier-pro5-mio-clock",
+		.compatible = "socionext,uniphier-pro5-sd-clock",
 		.data = (ulong)&uniphier_mio_clk_data,
 	},
 	{
-		.compatible = "socionext,uniphier-pxs2-mio-clock",
+		.compatible = "socionext,uniphier-pxs2-sd-clock",
 		.data = (ulong)&uniphier_mio_clk_data,
 	},
 	{
@@ -175,7 +175,7 @@ static const struct udevice_id uniphier_clk_match[] = {
 		.data = (ulong)&uniphier_mio_clk_data,
 	},
 	{
-		.compatible = "socionext,uniphier-ld20-mio-clock",
+		.compatible = "socionext,uniphier-ld20-sd-clock",
 		.data = (ulong)&uniphier_mio_clk_data,
 	},
 	{ /* sentinel */ }
Signature · 1 line
2.7.4
#2 lore raw

PATCH 2/16 ARM: uniphier: shrink arrays of DDR-PHY parameters for LD20 SoC

In reply to Masahiro Yamada

The two arrays ddrphy_{op,ip}_dq_shift_val, occupy more than 3.8 KB memory footprint, which is significant in SPL.

There are PHY parameters for 5 boards, but they are actually not board specific, but SoC specific. After all, we just need to have 2 patterns, for LD20 and LD21. Also, the shift values are small enough to become "short" type instead of "int". This change will save about 3 KB memory footprint.

---

 arch/arm/mach-uniphier/dram/umc-ld20.c | 254 ++++++++++-----------------------
 1 file changed, 79 insertions(+), 175 deletions(-)
arch/arm/mach-uniphier/dram/umc-ld20.c +79 -175
index 61f62ae..157b915 100644
@@ -1,7 +1,7 @@
 /*
- * Copyright (C) 2016 Socionext Inc.
+ * Copyright (C) 2016-2017 Socionext Inc.
  *
- * based on commit 1f6feb76e7f9753f51955444e422486521f9b3a3 of Diag
+ * based on commit e732175d0b0dbc2a3855cb8ac791c538666b6fd4 of Diag
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -77,191 +77,95 @@ static const u32 ddrphy_scl_gate_timing[DRAM_CH_NR] = {
 	0x00000140, 0x00000180, 0x00000140
 };
 
-static const int ddrphy_op_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
-	{ /* LD20 reference */
-		{
-			2, 1, 0, 1, 2, 1, 1, 1,
-			2, 1, 1, 2, 1, 1, 1, 1,
-			1, 2, 1, 1, 1, 2, 1, 1,
-			2, 2, 0, 1, 1, 2, 2, 1,
-		},
-		{
-			1, 1, 0, 1, 2, 2, 1, 1,
-			1, 1, 1, 1, 1, 1, 1, 1,
-			1, 1, 0, 0, 1, 1, 0, 0,
-			0, 1, 1, 1, 2, 1, 2, 1,
-		},
-		{
-			2, 2, 0, 2, 1, 1, 2, 1,
-			1, 1, 0, 1, 1, -1, 1, 1,
-			2, 2, 2, 2, 1, 1, 1, 1,
-			1, 1, 1, 0, 2, 2, 1, 2,
-		},
+static const short ddrphy_op_dq_shift_val_ld20[DRAM_CH_NR][32] = {
+	{
+		2, 1, 0, 1, 2, 1, 1, 1,
+		2, 1, 1, 2, 1, 1, 1, 1,
+		1, 2, 1, 1, 1, 2, 1, 1,
+		2, 2, 0, 1, 1, 2, 2, 1,
 	},
-	{ /* LD20 TV */
-		{
-			2, 1, 0, 1, 2, 1, 1, 1,
-			2, 1, 1, 2, 1, 1, 1, 1,
-			1, 2, 1, 1, 1, 2, 1, 1,
-			2, 2, 0, 1, 1, 2, 2, 1,
-		},
-		{
-			1, 1, 0, 1, 2, 2, 1, 1,
-			1, 1, 1, 1, 1, 1, 1, 1,
-			1, 1, 0, 0, 1, 1, 0, 0,
-			0, 1, 1, 1, 2, 1, 2, 1,
-		},
-		{
-			2, 2, 0, 2, 1, 1, 2, 1,
-			1, 1, 0, 1, 1, -1, 1, 1,
-			2, 2, 2, 2, 1, 1, 1, 1,
-			1, 1, 1, 0, 2, 2, 1, 2,
-		},
+	{
+		1, 1, 0, 1, 2, 2, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 0, 0, 1, 1, 0, 0,
+		0, 1, 1, 1, 2, 1, 2, 1,
 	},
-	{ /* LD20 TV C1 */
-		{
-			2, 1, 0, 1, 2, 1, 1, 1,
-			2, 1, 1, 2, 1, 1, 1, 1,
-			1, 2, 1, 1, 1, 2, 1, 1,
-			2, 2, 0, 1, 1, 2, 2, 1,
-		},
-		{
-			1, 1, 0, 1, 2, 2, 1, 1,
-			1, 1, 1, 1, 1, 1, 1, 1,
-			1, 1, 0, 0, 1, 1, 0, 0,
-			0, 1, 1, 1, 2, 1, 2, 1,
-		},
-		{
-			2, 2, 0, 2, 1, 1, 2, 1,
-			1, 1, 0, 1, 1, -1, 1, 1,
-			2, 2, 2, 2, 1, 1, 1, 1,
-			1, 1, 1, 0, 2, 2, 1, 2,
-		},
+	{
+		2, 2, 0, 2, 1, 1, 2, 1,
+		1, 1, 0, 1, 1, -1, 1, 1,
+		2, 2, 2, 2, 1, 1, 1, 1,
+		1, 1, 1, 0, 2, 2, 1, 2,
 	},
-	{ /* LD21 reference */
-		{
-			1, 1, 0, 1, 1, 1, 1, 1,
-			1, 0, 0, 0, 1, 1, 0, 2,
-			1, 1, 0, 0, 1, 1, 1, 1,
-			1, 0, 0, 0, 1, 0, 0, 1,
-		},
-		{	1, 0, 2, 1, 1, 1, 1, 0,
-			1, 0, 0, 1, 0, 1, 0, 0,
-			1, 0, 1, 0, 1, 1, 1, 0,
-			1, 1, 1, 1, 0, 1, 0, 0,
-		},
-		/* No CH2 */
+};
+
+static const short ddrphy_op_dq_shift_val_ld21[DRAM_CH_NR][32] = {
+	{
+		1, 1, 0, 1, 1, 1, 1, 1,
+		1, 0, 0, 0, 1, 1, 0, 2,
+		1, 1, 0, 0, 1, 1, 1, 1,
+		1, 0, 0, 0, 1, 0, 0, 1,
 	},
-	{ /* LD21 TV */
-		{
-			1, 1, 0, 1, 1, 1, 1, 1,
-			1, 0, 0, 0, 1, 1, 0, 2,
-			1, 1, 0, 0, 1, 1, 1, 1,
-			1, 0, 0, 0, 1, 0, 0, 1,
-		},
-		{	1, 0, 2, 1, 1, 1, 1, 0,
-			1, 0, 0, 1, 0, 1, 0, 0,
-			1, 0, 1, 0, 1, 1, 1, 0,
-			1, 1, 1, 1, 0, 1, 0, 0,
-		},
-		/* No CH2 */
+	{	1, 0, 2, 1, 1, 1, 1, 0,
+		1, 0, 0, 1, 0, 1, 0, 0,
+		1, 0, 1, 0, 1, 1, 1, 0,
+		1, 1, 1, 1, 0, 1, 0, 0,
 	},
+	/* No CH2 */
+};
+
+static const short (* const ddrphy_op_dq_shift_val[DRAM_BOARD_NR])[32] = {
+	ddrphy_op_dq_shift_val_ld20,	/* LD20 reference */
+	ddrphy_op_dq_shift_val_ld20,	/* LD20 TV */
+	ddrphy_op_dq_shift_val_ld20,	/* LD20 TV C */
+	ddrphy_op_dq_shift_val_ld21,	/* LD21 reference */
+	ddrphy_op_dq_shift_val_ld21,	/* LD21 TV */
 };
 
-static int ddrphy_ip_dq_shift_val[DRAM_BOARD_NR][DRAM_CH_NR][32] = {
-	{ /* LD20 reference */
-		{
-			3, 3, 3, 2, 3, 2, 0, 2,
-			2, 3, 3, 1, 2, 2, 2, 2,
-			2, 2, 2, 2, 0, 1, 1, 1,
-			2, 2, 2, 2, 3, 0, 2, 2,
-		},
-		{
-			2, 2, 1, 1, -1, 1, 1, 1,
-			2, 0, 2, 2, 2, 1, 0, 2,
-			2, 1, 2, 1, 0, 1, 1, 1,
-			2, 2, 2, 2, 2, 2, 2, 2,
-		},
-		{
-			2, 2, 3, 2, 1, 2, 2, 2,
-			2, 3, 4, 2, 3, 4, 3, 3,
-			2, 2, 1, 2, 1, 1, 1, 1,
-			2, 2, 2, 2, 1, 2, 2, 1,
-		},
+static const short ddrphy_ip_dq_shift_val_ld20[DRAM_CH_NR][32] = {
+	{
+		3, 3, 3, 2, 3, 2, 0, 2,
+		2, 3, 3, 1, 2, 2, 2, 2,
+		2, 2, 2, 2, 0, 1, 1, 1,
+		2, 2, 2, 2, 3, 0, 2, 2,
 	},
-	{ /* LD20 TV */
-		{
-			3, 3, 3, 2, 3, 2, 0, 2,
-			2, 3, 3, 1, 2, 2, 2, 2,
-			2, 2, 2, 2, 0, 1, 1, 1,
-			2, 2, 2, 2, 3, 0, 2, 2,
-		},
-		{
-			2, 2, 1, 1, -1, 1, 1, 1,
-			2, 0, 2, 2, 2, 1, 0, 2,
-			2, 1, 2, 1, 0, 1, 1, 1,
-			2, 2, 2, 2, 2, 2, 2, 2,
-		},
-		{
-			2, 2, 3, 2, 1, 2, 2, 2,
-			2, 3, 4, 2, 3, 4, 3, 3,
-			2, 2, 1, 2, 1, 1, 1, 1,
-			2, 2, 2, 2, 1, 2, 2, 1,
-		},
+	{
+		2, 2, 1, 1, -1, 1, 1, 1,
+		2, 0, 2, 2, 2, 1, 0, 2,
+		2, 1, 2, 1, 0, 1, 1, 1,
+		2, 2, 2, 2, 2, 2, 2, 2,
 	},
-	{ /* LD20 TV C1 */
-		{
-			3, 3, 3, 2, 3, 2, 0, 2,
-			2, 3, 3, 1, 2, 2, 2, 2,
-			2, 2, 2, 2, 0, 1, 1, 1,
-			2, 2, 2, 2, 3, 0, 2, 2,
-		},
-		{
-			2, 2, 1, 1, -1, 1, 1, 1,
-			2, 0, 2, 2, 2, 1, 0, 2,
-			2, 1, 2, 1, 0, 1, 1, 1,
-			2, 2, 2, 2, 2, 2, 2, 2,
-		},
-		{
-			2, 2, 3, 2, 1, 2, 2, 2,
-			2, 3, 4, 2, 3, 4, 3, 3,
-			2, 2, 1, 2, 1, 1, 1, 1,
-			2, 2, 2, 2, 1, 2, 2, 1,
-		},
+	{
+		2, 2, 3, 2, 1, 2, 2, 2,
+		2, 3, 4, 2, 3, 4, 3, 3,
+		2, 2, 1, 2, 1, 1, 1, 1,
+		2, 2, 2, 2, 1, 2, 2, 1,
 	},
-	{ /* LD21 reference */
-		{
-			2, 2, 2, 2, 1, 2, 2, 2,
-			2, 3, 3, 2, 2, 2, 2, 2,
-			2, 1, 2, 2, 1, 1, 1, 1,
-			2, 2, 2, 3, 1, 2, 2, 2,
-		},
-		{
-			3, 4, 4, 1, 0, 1, 1, 1,
-			1, 2, 1, 2, 2, 3, 3, 2,
-			1, 0, 2, 1, 1, 0, 1, 0,
-			0, 1, 0, 0, 1, 1, 0, 1,
-		},
-		/* No CH2 */
+};
+
+static const short ddrphy_ip_dq_shift_val_ld21[DRAM_CH_NR][32] = {
+	{
+		2, 2, 2, 2, 1, 2, 2, 2,
+		2, 3, 3, 2, 2, 2, 2, 2,
+		2, 1, 2, 2, 1, 1, 1, 1,
+		2, 2, 2, 3, 1, 2, 2, 2,
 	},
-	{ /* LD21 TV */
-		{
-			2, 2, 2, 2, 1, 2, 2, 2,
-			2, 3, 3, 2, 2, 2, 2, 2,
-			2, 1, 2, 2, 1, 1, 1, 1,
-			2, 2, 2, 3, 1, 2, 2, 2,
-		},
-		{
-			3, 4, 4, 1, 0, 1, 1, 1,
-			1, 2, 1, 2, 2, 3, 3, 2,
-			1, 0, 2, 1, 1, 0, 1, 0,
-			0, 1, 0, 0, 1, 1, 0, 1,
-		},
-		/* No CH2 */
+	{
+		3, 4, 4, 1, 0, 1, 1, 1,
+		1, 2, 1, 2, 2, 3, 3, 2,
+		1, 0, 2, 1, 1, 0, 1, 0,
+		0, 1, 0, 0, 1, 1, 0, 1,
 	},
+	/* No CH2 */
+};
+
+static const short (* const ddrphy_ip_dq_shift_val[DRAM_BOARD_NR])[32] = {
+	ddrphy_ip_dq_shift_val_ld20,	/* LD20 reference */
+	ddrphy_ip_dq_shift_val_ld20,	/* LD20 TV */
+	ddrphy_ip_dq_shift_val_ld20,	/* LD20 TV C */
+	ddrphy_ip_dq_shift_val_ld21,	/* LD21 reference */
+	ddrphy_ip_dq_shift_val_ld21,	/* LD21 TV */
 };
 
-/* DDR PHY */
 static void ddrphy_select_lane(void __iomem *phy_base, unsigned int lane,
 			       unsigned int bit)
 {
@@ -380,7 +284,7 @@ static void ddrphy_init_tail(void __iomem *phy_base, enum dram_board board,
 }
 
 static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
-				u32 mask, u32 incr, int shift_val)
+				u32 mask, u32 incr, short shift_val)
 {
 	u32 tmp;
 	int val;
@@ -403,7 +307,7 @@ static void ddrphy_shift_one_dq(void __iomem *phy_base, unsigned int reg,
 
 static void ddrphy_shift_dq(void __iomem *phy_base, unsigned int reg,
 			    u32 mask, u32 incr, u32 override,
-			    const int *shift_val_array)
+			    const short *shift_val_array)
 {
 	u32 tmp;
 	int dx, bit;
Signature · 1 line
2.7.4
#3 lore raw

PATCH 3/16 ARM: uniphier: detect RAM size by decoding HW register instead of DT

In reply to Masahiro Yamada

U-Boot needs to set up available memory area(s) in dram_init() and dram_init_banksize(). It is platform-dependent how to detect the memory banks. Currently, UniPhier adopts the memory banks _alleged_ by DT. This is based on the assumption that users bind a correct DT in their build process.

Come to think of it, the DRAM controller has already been set up before U-Boot is entered (because U-Boot runs on DRAM). So, the DRAM controller setup register seems a more reliable source of any information about DRAM stuff. The DRAM banks are initialized by preliminary firmware (SPL, ARM Trusted Firmware BL2, or whatever), so this means the source of the reliability is shifted from Device Tree to such early-stage firmware. However, if the DRAM controller is wrongly configured, the system will crash. If your system is running, the DRAM setup register is very likely to provide the correct DRAM mapping.

Decode the SG_MEMCONF register to get the available DRAM banks. The dram_init() and dram_init_banksize() need similar decoding. It would be nice if dram_init_banksize() could reuse the outcome of dram_init(), but global variables are unavailable at this stage because the .bss section is available only after the relocation. As a result, SG_MEMCONF must be checked twice, but a new helper uniphier_memconf_decode() will help to avoid code duplication.

---

 arch/arm/mach-uniphier/dram_init.c | 250 ++++++++++++++++++++++++++++++-------
 arch/arm/mach-uniphier/init.h      |   1 +
 include/configs/uniphier.h         |   2 +-
 3 files changed, 204 insertions(+), 49 deletions(-)
arch/arm/mach-uniphier/dram_init.c +202 -48
index 2cf5f36..43fe6a5 100644
@@ -5,83 +5,237 @@
  */
 
 #include <common.h>
-#include <libfdt.h>
 #include <fdtdec.h>
 #include <linux/errno.h>
+#include <linux/sizes.h>
 
 #include "init.h"
+#include "sg-regs.h"
 #include "soc-info.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const void *get_memory_reg_prop(const void *fdt, int *lenp)
+struct uniphier_memif_data {
+	unsigned int soc_id;
+	unsigned long sparse_ch1_base;
+	int have_ch2;
+};
+
+static const struct uniphier_memif_data uniphier_memif_data[] = {
+	{
+		.soc_id = UNIPHIER_SLD3_ID,
+		.sparse_ch1_base = 0xc0000000,
+		/*
+		 * In fact, SLD3 has DRAM ch2, but the memory regions for ch1
+		 * and ch2 overlap, and host cannot get access to them at the
+		 * same time.  Hide the ch2 from U-Boot.
+		 */
+	},
+	{
+		.soc_id = UNIPHIER_LD4_ID,
+		.sparse_ch1_base = 0xc0000000,
+	},
+	{
+		.soc_id = UNIPHIER_PRO4_ID,
+		.sparse_ch1_base = 0xa0000000,
+	},
+	{
+		.soc_id = UNIPHIER_SLD8_ID,
+		.sparse_ch1_base = 0xc0000000,
+	},
+	{
+		.soc_id = UNIPHIER_PRO5_ID,
+		.sparse_ch1_base = 0xc0000000,
+	},
+	{
+		.soc_id = UNIPHIER_PXS2_ID,
+		.sparse_ch1_base = 0xc0000000,
+		.have_ch2 = 1,
+	},
+	{
+		.soc_id = UNIPHIER_LD6B_ID,
+		.sparse_ch1_base = 0xc0000000,
+		.have_ch2 = 1,
+	},
+	{
+		.soc_id = UNIPHIER_LD11_ID,
+		.sparse_ch1_base = 0xc0000000,
+	},
+	{
+		.soc_id = UNIPHIER_LD20_ID,
+		.sparse_ch1_base = 0xc0000000,
+		.have_ch2 = 1,
+	},
+	{
+		.soc_id = UNIPHIER_PXS3_ID,
+		.sparse_ch1_base = 0xc0000000,
+		.have_ch2 = 1,
+	},
+};
+UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_memif_data, uniphier_memif_data)
+
+static int uniphier_memconf_decode(struct uniphier_dram_ch *dram_ch)
 {
-	int offset;
+	const struct uniphier_memif_data *data;
+	unsigned long size;
+	u32 val;
 
-	offset = fdt_path_offset(fdt, "/memory");
-	if (offset < 0)
-		return NULL;
+	data = uniphier_get_memif_data();
+	if (!data) {
+		pr_err("unsupported SoC\n");
+		return -EINVAL;
+	}
 
-	return fdt_getprop(fdt, offset, "reg", lenp);
-}
+	val = readl(SG_MEMCONF);
 
-int dram_init(void)
-{
-	const void *fdt = gd->fdt_blob;
-	const fdt32_t *val;
-	int ac, sc, len;
-
-	ac = fdt_address_cells(fdt, 0);
-	sc = fdt_size_cells(fdt, 0);
-	if (ac < 0 || sc < 1 || sc > 2) {
-		printf("invalid address/size cells\n");
+	/* set up ch0 */
+	dram_ch[0].base = CONFIG_SYS_SDRAM_BASE;
+
+	switch (val & SG_MEMCONF_CH0_SZ_MASK) {
+	case SG_MEMCONF_CH0_SZ_64M:
+		size = SZ_64M;
+		break;
+	case SG_MEMCONF_CH0_SZ_128M:
+		size = SZ_128M;
+		break;
+	case SG_MEMCONF_CH0_SZ_256M:
+		size = SZ_256M;
+		break;
+	case SG_MEMCONF_CH0_SZ_512M:
+		size = SZ_512M;
+		break;
+	case SG_MEMCONF_CH0_SZ_1G:
+		size = SZ_1G;
+		break;
+	default:
+		pr_err("error: invald value is set to MEMCONF ch0 size\n");
 		return -EINVAL;
 	}
 
-	val = get_memory_reg_prop(fdt, &len);
-	if (len / sizeof(*val) < ac + sc)
+	if ((val & SG_MEMCONF_CH0_NUM_MASK) == SG_MEMCONF_CH0_NUM_2)
+		size *= 2;
+
+	dram_ch[0].size = size;
+
+	/* set up ch1 */
+	dram_ch[1].base = dram_ch[0].base + size;
+
+	if (val & SG_MEMCONF_SPARSEMEM) {
+		if (dram_ch[1].base > data->sparse_ch1_base) {
+			pr_warn("Sparse mem is enabled, but ch0 and ch1 overlap\n");
+			pr_warn("Only ch0 is available\n");
+			dram_ch[1].base = 0;
+			return 0;
+		}
+
+		dram_ch[1].base = data->sparse_ch1_base;
+	}
+
+	switch (val & SG_MEMCONF_CH1_SZ_MASK) {
+	case SG_MEMCONF_CH1_SZ_64M:
+		size = SZ_64M;
+		break;
+	case SG_MEMCONF_CH1_SZ_128M:
+		size = SZ_128M;
+		break;
+	case SG_MEMCONF_CH1_SZ_256M:
+		size = SZ_256M;
+		break;
+	case SG_MEMCONF_CH1_SZ_512M:
+		size = SZ_512M;
+		break;
+	case SG_MEMCONF_CH1_SZ_1G:
+		size = SZ_1G;
+		break;
+	default:
+		pr_err("error: invald value is set to MEMCONF ch1 size\n");
 		return -EINVAL;
+	}
+
+	if ((val & SG_MEMCONF_CH1_NUM_MASK) == SG_MEMCONF_CH1_NUM_2)
+		size *= 2;
 
-	val += ac;
+	dram_ch[1].size = size;
 
-	gd->ram_size = fdtdec_get_number(val, sc);
+	if (!data->have_ch2)
+		return 0;
 
-	debug("DRAM size = %08lx\n", (unsigned long)gd->ram_size);
+	/* set up ch2 */
+	dram_ch[2].base = dram_ch[1].base + size;
+
+	switch (val & SG_MEMCONF_CH2_SZ_MASK) {
+	case SG_MEMCONF_CH2_SZ_64M:
+		size = SZ_64M;
+		break;
+	case SG_MEMCONF_CH2_SZ_128M:
+		size = SZ_128M;
+		break;
+	case SG_MEMCONF_CH2_SZ_256M:
+		size = SZ_256M;
+		break;
+	case SG_MEMCONF_CH2_SZ_512M:
+		size = SZ_512M;
+		break;
+	case SG_MEMCONF_CH2_SZ_1G:
+		size = SZ_1G;
+		break;
+	default:
+		pr_err("error: invald value is set to MEMCONF ch2 size\n");
+		return -EINVAL;
+	}
+
+	if ((val & SG_MEMCONF_CH2_NUM_MASK) == SG_MEMCONF_CH2_NUM_2)
+		size *= 2;
+
+	dram_ch[2].size = size;
 
 	return 0;
 }
 
-void dram_init_banksize(void)
+int dram_init(void)
 {
-	const void *fdt = gd->fdt_blob;
-	const fdt32_t *val;
-	int ac, sc, cells, len, i;
-
-	val = get_memory_reg_prop(fdt, &len);
-	if (len < 0)
-		return;
-
-	ac = fdt_address_cells(fdt, 0);
-	sc = fdt_size_cells(fdt, 0);
-	if (ac < 1 || sc > 2 || sc < 1 || sc > 2) {
-		printf("invalid address/size cells\n");
-		return;
+	struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH] = {};
+	int ret, i;
+
+	gd->ram_size = 0;
+
+	ret = uniphier_memconf_decode(dram_ch);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < ARRAY_SIZE(dram_ch); i++) {
+
+		if (!dram_ch[i].size)
+			break;
+
+		/*
+		 * U-Boot relocates itself to the tail of the memory region,
+		 * but it does not expect sparse memory.  We use the first
+		 * contiguous chunk here.
+		 */
+		if (i > 0 &&
+		    dram_ch[i - 1].base + dram_ch[i - 1].size < dram_ch[i].base)
+			break;
+
+		gd->ram_size += dram_ch[i].size;
 	}
 
-	cells = ac + sc;
+	return 0;
+}
+
+void dram_init_banksize(void)
+{
+	struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH] = {};
+	int i;
 
-	len /= sizeof(*val);
+	uniphier_memconf_decode(dram_ch);
 
-	for (i = 0; i < CONFIG_NR_DRAM_BANKS && len >= cells;
-	     i++, len -= cells) {
-		gd->bd->bi_dram[i].start = fdtdec_get_number(val, ac);
-		val += ac;
-		gd->bd->bi_dram[i].size = fdtdec_get_number(val, sc);
-		val += sc;
+	for (i = 0; i < ARRAY_SIZE(dram_ch); i++) {
+		if (i >= ARRAY_SIZE(gd->bd->bi_dram))
+			break;
 
-		debug("DRAM bank %d: start = %08lx, size = %08lx\n",
-		      i, (unsigned long)gd->bd->bi_dram[i].start,
-		      (unsigned long)gd->bd->bi_dram[i].size);
+		gd->bd->bi_dram[i].start = dram_ch[i].base;
+		gd->bd->bi_dram[i].size = dram_ch[i].size;
 	}
 }
 
arch/arm/mach-uniphier/init.h +1 -0
index 3aeb5b1..453e68a 100644
@@ -124,6 +124,7 @@ int uniphier_pin_init(const char *pinconfig_name);
 void uniphier_smp_kick_all_cpus(void);
 void cci500_init(int nr_slaves);
 
+#define pr_warn(fmt, args...)	printf(fmt, ##args)
 #define pr_err(fmt, args...)	printf(fmt, ##args)
 
 #endif /* __MACH_INIT_H */
include/configs/uniphier.h +1 -1
index 487d3de..ef5b019 100644
@@ -237,7 +237,7 @@
 #define CONFIG_SYS_BOOTMAPSZ			0x20000000
 
 #define CONFIG_SYS_SDRAM_BASE		0x80000000
-#define CONFIG_NR_DRAM_BANKS		2
+#define CONFIG_NR_DRAM_BANKS		3
 /* for LD20; the last 64 byte is used for dynamic DDR PHY training */
 #define CONFIG_SYS_MEM_TOP_HIDE		64
 
Signature · 1 line
2.7.4
#4 lore raw

PATCH 4/16 ARM: uniphier: use gd->bd->bi_dram for memory reserve on LD20 SoC

In reply to Masahiro Yamada

For LD20 SoC, the last 64 byte of each DRAM bank is used for the dynamic training of DRAM PHY. The regions must be reserved in DT to prevent the kernel from using them. Now gd->bd->bi_dram reflects the actual memory banks. Just use it instead of getting access to the board parameters.

---

 arch/arm/mach-uniphier/dram_init.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)
arch/arm/mach-uniphier/dram_init.c +3 -10
index 43fe6a5..e55e1f8 100644
@@ -246,22 +246,15 @@ void dram_init_banksize(void)
  */
 int ft_board_setup(void *fdt, bd_t *bd)
 {
-	const struct uniphier_board_data *param;
 	unsigned long rsv_addr;
 	const unsigned long rsv_size = 64;
-	int ch, ret;
+	int i, ret;
 
 	if (uniphier_get_soc_id() != UNIPHIER_LD20_ID)
 		return 0;
 
-	param = uniphier_get_board_param();
-	if (!param) {
-		printf("failed to get board parameter\n");
-		return -ENODEV;
-	}
-
-	for (ch = 0; ch < param->dram_nr_ch; ch++) {
-		rsv_addr = param->dram_ch[ch].base + param->dram_ch[ch].size;
+	for (i = 0; i < ARRAY_SIZE(gd->bd->bi_dram); i++) {
+		rsv_addr = gd->bd->bi_dram[i].start + gd->bd->bi_dram[i].size;
 		rsv_addr -= rsv_size;
 
 		ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size);
Signature · 1 line
2.7.4
#5 lore raw

PATCH 5/16 ARM: uniphier: refactor cmd_ddrphy

In reply to Masahiro Yamada

It seems more readable to use arrays to get SoC specific parameters instead of the crappy switch statement.

---

 arch/arm/mach-uniphier/dram/cmd_ddrphy.c | 156 ++++++++++++++++---------------
 1 file changed, 83 insertions(+), 73 deletions(-)
arch/arm/mach-uniphier/dram/cmd_ddrphy.c +83 -73
index d6d9db3..26b35f6 100644
@@ -24,35 +24,53 @@
 
 #define ptr_to_uint(p)	((unsigned int)(unsigned long)(p))
 
-struct phy_param {
-	resource_size_t base;
-	unsigned int nr_dx;
+#define UNIPHIER_MAX_NR_DDRPHY		4
+
+struct uniphier_ddrphy_param {
+	unsigned int soc_id;
+	unsigned int nr_phy;
+	struct {
+		resource_size_t base;
+		unsigned int nr_dx;
+	} phy[UNIPHIER_MAX_NR_DDRPHY];
 };
 
-static const struct phy_param uniphier_ld4_phy_param[] = {
-	{ .base = 0x5bc01000, .nr_dx = 2, },
-	{ .base = 0x5be01000, .nr_dx = 2, },
-	{ /* sentinel */ }
-};
-
-static const struct phy_param uniphier_pro4_phy_param[] = {
-	{ .base = 0x5bc01000, .nr_dx = 2, },
-	{ .base = 0x5bc02000, .nr_dx = 2, },
-	{ .base = 0x5be01000, .nr_dx = 2, },
-	{ .base = 0x5be02000, .nr_dx = 2, },
-	{ /* sentinel */ }
-};
-
-static const struct phy_param uniphier_sld8_phy_param[] = {
-	{ .base = 0x5bc01000, .nr_dx = 2, },
-	{ .base = 0x5be01000, .nr_dx = 2, },
-	{ /* sentinel */ }
-};
-
-static const struct phy_param uniphier_ld11_phy_param[] = {
-	{ .base = 0x5bc01000, .nr_dx = 4, },
-	{ /* sentinel */ }
+static const struct uniphier_ddrphy_param uniphier_ddrphy_param[] = {
+	{
+		.soc_id = UNIPHIER_LD4_ID,
+		.nr_phy = 2,
+		.phy = {
+			{ .base = 0x5bc01000, .nr_dx = 2, },
+			{ .base = 0x5be01000, .nr_dx = 2, },
+		},
+	},
+	{
+		.soc_id = UNIPHIER_PRO4_ID,
+		.nr_phy = 4,
+		.phy = {
+			{ .base = 0x5bc01000, .nr_dx = 2, },
+			{ .base = 0x5bc02000, .nr_dx = 2, },
+			{ .base = 0x5be01000, .nr_dx = 2, },
+			{ .base = 0x5be02000, .nr_dx = 2, },
+		},
+	},
+	{
+		.soc_id = UNIPHIER_SLD8_ID,
+		.nr_phy = 2,
+		.phy = {
+			{ .base = 0x5bc01000, .nr_dx = 2, },
+			{ .base = 0x5be01000, .nr_dx = 2, },
+		},
+	},
+	{
+		.soc_id = UNIPHIER_LD11_ID,
+		.nr_phy = 1,
+		.phy = {
+			{ .base = 0x5bc01000, .nr_dx = 4, },
+		},
+	},
 };
+UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_ddrphy_param, uniphier_ddrphy_param)
 
 static void print_bdl(void __iomem *reg, int n)
 {
@@ -63,18 +81,18 @@ static void print_bdl(void __iomem *reg, int n)
 		printf(FS PRINTF_FORMAT, (val >> i * 6) & 0x3f);
 }
 
-static void dump_loop(const struct phy_param *phy_param,
+static void dump_loop(const struct uniphier_ddrphy_param *param,
 		      void (*callback)(void __iomem *))
 {
 	void __iomem *phy_base, *dx_base;
-	int p, dx;
+	int phy, dx;
 
-	for (p = 0; phy_param->base; phy_param++, p++) {
-		phy_base = ioremap(phy_param->base, SZ_4K);
+	for (phy = 0; phy < param->nr_phy; phy++) {
+		phy_base = ioremap(param->phy[phy].base, SZ_4K);
 		dx_base = phy_base + PHY_DX_BASE;
 
-		for (dx = 0; dx < phy_param->nr_dx; dx++) {
-			printf("PHY%dDX%d:", p, dx);
+		for (dx = 0; dx < param->phy[phy].nr_dx; dx++) {
+			printf("PHY%dDX%d:", phy, dx);
 			(*callback)(dx_base);
 			dx_base += PHY_DX_STRIDE;
 			printf("\n");
@@ -93,12 +111,12 @@ static void __wbdl_dump(void __iomem *dx_base)
 	       readl(dx_base + PHY_DX_LCDLR1) & 0xff);
 }
 
-static void wbdl_dump(const struct phy_param *phy_param)
+static void wbdl_dump(const struct uniphier_ddrphy_param *param)
 {
 	printf("\n--- Write Bit Delay Line ---\n");
 	printf("           DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  DQS  (WDQD)\n");
 
-	dump_loop(phy_param, &__wbdl_dump);
+	dump_loop(param, &__wbdl_dump);
 }
 
 static void __rbdl_dump(void __iomem *dx_base)
@@ -110,12 +128,12 @@ static void __rbdl_dump(void __iomem *dx_base)
 	       (readl(dx_base + PHY_DX_LCDLR1) >> 8) & 0xff);
 }
 
-static void rbdl_dump(const struct phy_param *phy_param)
+static void rbdl_dump(const struct uniphier_ddrphy_param *param)
 {
 	printf("\n--- Read Bit Delay Line ---\n");
 	printf("           DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  (RDQSD)\n");
 
-	dump_loop(phy_param, &__rbdl_dump);
+	dump_loop(param, &__rbdl_dump);
 }
 
 static void __wld_dump(void __iomem *dx_base)
@@ -133,12 +151,12 @@ static void __wld_dump(void __iomem *dx_base)
 	}
 }
 
-static void wld_dump(const struct phy_param *phy_param)
+static void wld_dump(const struct uniphier_ddrphy_param *param)
 {
 	printf("\n--- Write Leveling Delay ---\n");
-	printf("            Rank0   Rank1   Rank2   Rank3\n");
+	printf("           Rank0   Rank1   Rank2   Rank3\n");
 
-	dump_loop(phy_param, &__wld_dump);
+	dump_loop(param, &__wld_dump);
 }
 
 static void __dqsgd_dump(void __iomem *dx_base)
@@ -155,28 +173,29 @@ static void __dqsgd_dump(void __iomem *dx_base)
 	}
 }
 
-static void dqsgd_dump(const struct phy_param *phy_param)
+static void dqsgd_dump(const struct uniphier_ddrphy_param *param)
 {
 	printf("\n--- DQS Gating Delay ---\n");
-	printf("            Rank0   Rank1   Rank2   Rank3\n");
+	printf("           Rank0   Rank1   Rank2   Rank3\n");
 
-	dump_loop(phy_param, &__dqsgd_dump);
+	dump_loop(param, &__dqsgd_dump);
 }
 
 static void __mdl_dump(void __iomem *dx_base)
 {
 	int i;
 	u32 mdl = readl(dx_base + PHY_DX_MDLR);
+
 	for (i = 0; i < 3; i++)
 		printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff);
 }
 
-static void mdl_dump(const struct phy_param *phy_param)
+static void mdl_dump(const struct uniphier_ddrphy_param *param)
 {
 	printf("\n--- Master Delay Line ---\n");
 	printf("          IPRD TPRD MDLD\n");
 
-	dump_loop(phy_param, &__mdl_dump);
+	dump_loop(param, &__mdl_dump);
 }
 
 #define REG_DUMP(x)							\
@@ -193,17 +212,18 @@ static void mdl_dump(const struct phy_param *phy_param)
 		       ofst >> PHY_REG_SHIFT, (dx), #x,			\
 		       ptr_to_uint(reg), readl(reg)); }
 
-static void reg_dump(const struct phy_param *phy_param)
+static void reg_dump(const struct uniphier_ddrphy_param *param)
 {
 	void __iomem *phy_base;
-	int p, dx;
+	int phy, dx;
 
 	printf("\n--- DDR PHY registers ---\n");
 
-	for (p = 0; phy_param->base; phy_param++, p++) {
-		phy_base = ioremap(phy_param->base, SZ_4K);
+	for (phy = 0; phy < param->nr_phy; phy++) {
+		phy_base = ioremap(param->phy[phy].base, SZ_4K);
 
-		printf("== PHY%d (base: %08x) ==\n", p, ptr_to_uint(phy_base));
+		printf("== PHY%d (base: %08x) ==\n",
+		       phy, ptr_to_uint(phy_base));
 		printf(" No: Name      : Address  : Data\n");
 
 		REG_DUMP(RIDR);
@@ -231,7 +251,7 @@ static void reg_dump(const struct phy_param *phy_param)
 		REG_DUMP(MR2);
 		REG_DUMP(MR3);
 
-		for (dx = 0; dx < phy_param->nr_dx; dx++) {
+		for (dx = 0; dx < param->phy[phy].nr_dx; dx++) {
 			DX_REG_DUMP(dx, GCR);
 			DX_REG_DUMP(dx, GTR);
 		}
@@ -242,47 +262,37 @@ static void reg_dump(const struct phy_param *phy_param)
 
 static int do_ddr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	char *cmd = argv[1];
-	const struct phy_param *phy_param;
-
-	switch (uniphier_get_soc_id()) {
-	case UNIPHIER_LD4_ID:
-		phy_param = uniphier_ld4_phy_param;
-		break;
-	case UNIPHIER_PRO4_ID:
-		phy_param = uniphier_pro4_phy_param;
-		break;
-	case UNIPHIER_SLD8_ID:
-		phy_param = uniphier_sld8_phy_param;
-		break;
-	case UNIPHIER_LD11_ID:
-		phy_param = uniphier_ld11_phy_param;
-		break;
-	default:
+	const struct uniphier_ddrphy_param *param;
+	char *cmd;
+
+	param = uniphier_get_ddrphy_param();
+	if (!param) {
 		printf("unsupported SoC\n");
 		return CMD_RET_FAILURE;
 	}
 
 	if (argc == 1)
 		cmd = "all";
+	else
+		cmd = argv[1];
 
 	if (!strcmp(cmd, "wbdl") || !strcmp(cmd, "all"))
-		wbdl_dump(phy_param);
+		wbdl_dump(param);
 
 	if (!strcmp(cmd, "rbdl") || !strcmp(cmd, "all"))
-		rbdl_dump(phy_param);
+		rbdl_dump(param);
 
 	if (!strcmp(cmd, "wld") || !strcmp(cmd, "all"))
-		wld_dump(phy_param);
+		wld_dump(param);
 
 	if (!strcmp(cmd, "dqsgd") || !strcmp(cmd, "all"))
-		dqsgd_dump(phy_param);
+		dqsgd_dump(param);
 
 	if (!strcmp(cmd, "mdl") || !strcmp(cmd, "all"))
-		mdl_dump(phy_param);
+		mdl_dump(param);
 
 	if (!strcmp(cmd, "reg") || !strcmp(cmd, "all"))
-		reg_dump(phy_param);
+		reg_dump(param);
 
 	return CMD_RET_SUCCESS;
 }
Signature · 1 line
2.7.4
#6 lore raw

PATCH 6/16 ARM: uniphier: clean up UMC init for PXs2 SoC

In reply to Masahiro Yamada

Just cosmetic changes:
- Rename prefix DMPHY_ to MPHY_ for consistency
- Move UMC parameters below for complete decouple of PHY and UMC
- Remove redundant whitespaces

---

 arch/arm/mach-uniphier/dram/cmd_ddrmphy.c  |  50 +++---
 arch/arm/mach-uniphier/dram/ddrmphy-regs.h | 262 ++++++++++++++---------------
 arch/arm/mach-uniphier/dram/umc-pxs2.c     | 253 ++++++++++++++--------------
 3 files changed, 283 insertions(+), 282 deletions(-)
arch/arm/mach-uniphier/dram/cmd_ddrmphy.c +25 -25
index 47cee6f..4e66162 100644
@@ -55,13 +55,13 @@ static void dump_loop(void (*callback)(void __iomem *))
 	nr_ch = get_nr_ch();
 
 	for (ch = 0; ch < nr_ch; ch++) {
-		dx_base = get_phy_base(ch) + DMPHY_DX_BASE;
+		dx_base = get_phy_base(ch) + MPHY_DX_BASE;
 		nr_dx = get_nr_datx8(ch);
 
 		for (dx = 0; dx < nr_dx; dx++) {
 			printf("CH%dDX%d:", ch, dx);
 			(*callback)(dx_base);
-			dx_base += DMPHY_DX_STRIDE;
+			dx_base += MPHY_DX_STRIDE;
 			printf("\n");
 		}
 	}
@@ -79,25 +79,25 @@ static void zq_dump(void)
 	nr_ch = get_nr_ch();
 
 	for (ch = 0; ch < nr_ch; ch++) {
-		zq_base = get_phy_base(ch) + DMPHY_ZQ_BASE;
+		zq_base = get_phy_base(ch) + MPHY_ZQ_BASE;
 		nr_zq = 3;
 
 		for (zq = 0; zq < nr_zq; zq++) {
 			printf("CH%dZQ%d:", ch, zq);
 
-			dr = readl(zq_base + DMPHY_ZQ_DR);
+			dr = readl(zq_base + MPHY_ZQ_DR);
 			for (i = 0; i < 4; i++) {
 				printf(FS PRINTF_FORMAT, dr & 0x7f);
 				dr >>= 7;
 			}
 
-			pr = readl(zq_base + DMPHY_ZQ_PR);
+			pr = readl(zq_base + MPHY_ZQ_PR);
 			for (i = 0; i < 2; i++) {
 				printf(FS PRINTF_FORMAT, pr & 0xf);
 				pr >>= 4;
 			}
 
-			zq_base += DMPHY_ZQ_STRIDE;
+			zq_base += MPHY_ZQ_STRIDE;
 			printf("\n");
 		}
 	}
@@ -105,12 +105,12 @@ static void zq_dump(void)
 
 static void __wbdl_dump(void __iomem *dx_base)
 {
-	print_bdl(dx_base + DMPHY_DX_BDLR0, 4);
-	print_bdl(dx_base + DMPHY_DX_BDLR1, 4);
-	print_bdl(dx_base + DMPHY_DX_BDLR2, 2);
+	print_bdl(dx_base + MPHY_DX_BDLR0, 4);
+	print_bdl(dx_base + MPHY_DX_BDLR1, 4);
+	print_bdl(dx_base + MPHY_DX_BDLR2, 2);
 
 	printf(FS "(+" PRINTF_FORMAT ")",
-	       readl(dx_base + DMPHY_DX_LCDLR1) & 0xff);
+	       readl(dx_base + MPHY_DX_LCDLR1) & 0xff);
 }
 
 static void wbdl_dump(void)
@@ -123,15 +123,15 @@ static void wbdl_dump(void)
 
 static void __rbdl_dump(void __iomem *dx_base)
 {
-	print_bdl(dx_base + DMPHY_DX_BDLR3, 4);
-	print_bdl(dx_base + DMPHY_DX_BDLR4, 4);
-	print_bdl(dx_base + DMPHY_DX_BDLR5, 1);
+	print_bdl(dx_base + MPHY_DX_BDLR3, 4);
+	print_bdl(dx_base + MPHY_DX_BDLR4, 4);
+	print_bdl(dx_base + MPHY_DX_BDLR5, 1);
 
 	printf(FS "(+" PRINTF_FORMAT ")",
-	       (readl(dx_base + DMPHY_DX_LCDLR1) >> 8) & 0xff);
+	       (readl(dx_base + MPHY_DX_LCDLR1) >> 8) & 0xff);
 
 	printf(FS "(+" PRINTF_FORMAT ")",
-	       (readl(dx_base + DMPHY_DX_LCDLR1) >> 16) & 0xff);
+	       (readl(dx_base + MPHY_DX_LCDLR1) >> 16) & 0xff);
 }
 
 static void rbdl_dump(void)
@@ -145,8 +145,8 @@ static void rbdl_dump(void)
 static void __wld_dump(void __iomem *dx_base)
 {
 	int rank;
-	u32 lcdlr0 = readl(dx_base + DMPHY_DX_LCDLR0);
-	u32 gtr = readl(dx_base + DMPHY_DX_GTR);
+	u32 lcdlr0 = readl(dx_base + MPHY_DX_LCDLR0);
+	u32 gtr = readl(dx_base + MPHY_DX_GTR);
 
 	for (rank = 0; rank < 4; rank++) {
 		u32 wld = (lcdlr0 >> (8 * rank)) & 0xff; /* Delay */
@@ -168,8 +168,8 @@ static void wld_dump(void)
 static void __dqsgd_dump(void __iomem *dx_base)
 {
 	int rank;
-	u32 lcdlr2 = readl(dx_base + DMPHY_DX_LCDLR2);
-	u32 gtr = readl(dx_base + DMPHY_DX_GTR);
+	u32 lcdlr2 = readl(dx_base + MPHY_DX_LCDLR2);
+	u32 gtr = readl(dx_base + MPHY_DX_GTR);
 
 	for (rank = 0; rank < 4; rank++) {
 		u32 dqsgd = (lcdlr2 >> (8 * rank)) & 0xff; /* Delay */
@@ -190,7 +190,7 @@ static void dqsgd_dump(void)
 static void __mdl_dump(void __iomem *dx_base)
 {
 	int i;
-	u32 mdl = readl(dx_base + DMPHY_DX_MDLR);
+	u32 mdl = readl(dx_base + MPHY_DX_MDLR);
 
 	for (i = 0; i < 3; i++)
 		printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff);
@@ -205,16 +205,16 @@ static void mdl_dump(void)
 }
 
 #define REG_DUMP(x)							\
-	{ int ofst = DMPHY_ ## x; void __iomem *reg = phy_base + ofst;	\
+	{ int ofst = MPHY_ ## x; void __iomem *reg = phy_base + ofst;	\
 		printf("%3d: %-10s: %p : %08x\n",			\
-		       ofst >> DMPHY_SHIFT, #x, reg, readl(reg)); }
+		       ofst >> MPHY_SHIFT, #x, reg, readl(reg)); }
 
 #define DX_REG_DUMP(dx, x)						\
-	{ int ofst = DMPHY_DX_BASE + DMPHY_DX_STRIDE * (dx) +		\
-			DMPHY_DX_## x;					\
+	{ int ofst = MPHY_DX_BASE + MPHY_DX_STRIDE * (dx) +		\
+			MPHY_DX_## x;					\
 		void __iomem *reg = phy_base + ofst;			\
 		printf("%3d: DX%d%-7s: %p : %08x\n",			\
-		       ofst >> DMPHY_SHIFT, (dx), #x, reg, readl(reg)); }
+		       ofst >> MPHY_SHIFT, (dx), #x, reg, readl(reg)); }
 
 static void reg_dump(void)
 {
arch/arm/mach-uniphier/dram/ddrmphy-regs.h +131 -131

272 lines not on this page · raw message

arch/arm/mach-uniphier/dram/umc-pxs2.c +127 -126

414 lines not on this page · raw message

Signature · 1 line
2.7.4
#7 lore raw

PATCH 7/16 ARM: uniphier: refactor cmd_ddrmphy

In reply to Masahiro Yamada

Make it look like cmd_ddrphy.

---

 arch/arm/mach-uniphier/dram/cmd_ddrmphy.c | 192 +++++++++++++++++-------------
 1 file changed, 110 insertions(+), 82 deletions(-)
arch/arm/mach-uniphier/dram/cmd_ddrmphy.c +110 -82
index 4e66162..5ca0a65 100644
@@ -6,8 +6,9 @@
 
 #include <common.h>
 #include <linux/io.h>
+#include <linux/sizes.h>
 
-#include "../init.h"
+#include "../soc-info.h"
 #include "ddrmphy-regs.h"
 
 /* Select either decimal or hexadecimal */
@@ -19,24 +20,41 @@
 /* field separator */
 #define FS "   "
 
-static void __iomem *get_phy_base(int ch)
-{
-	return (void __iomem *)(0x5b830000 + ch * 0x00200000);
-}
-
-static int get_nr_ch(void)
-{
-	const struct uniphier_board_data *bd = uniphier_get_board_param();
-
-	return bd->dram_ch[2].size ? 3 : 2;
-}
-
-static int get_nr_datx8(int ch)
-{
-	const struct uniphier_board_data *bd = uniphier_get_board_param();
-
-	return bd->dram_ch[ch].width / 8;
-}
+#define ptr_to_uint(p)	((unsigned int)(unsigned long)(p))
+
+#define UNIPHIER_MAX_NR_DDRMPHY		3
+
+struct uniphier_ddrmphy_param {
+	unsigned int soc_id;
+	unsigned int nr_phy;
+	struct {
+		resource_size_t base;
+		unsigned int nr_zq;
+		unsigned int nr_dx;
+	} phy[UNIPHIER_MAX_NR_DDRMPHY];
+};
+
+static const struct uniphier_ddrmphy_param uniphier_ddrmphy_param[] = {
+	{
+		.soc_id = UNIPHIER_PXS2_ID,
+		.nr_phy = 3,
+		.phy = {
+			{ .base = 0x5b830000, .nr_zq = 3, .nr_dx = 4, },
+			{ .base = 0x5ba30000, .nr_zq = 3, .nr_dx = 4, },
+			{ .base = 0x5bc30000, .nr_zq = 2, .nr_dx = 2, },
+		},
+	},
+	{
+		.soc_id = UNIPHIER_LD6B_ID,
+		.nr_phy = 3,
+		.phy = {
+			{ .base = 0x5b830000, .nr_zq = 3, .nr_dx = 4, },
+			{ .base = 0x5ba30000, .nr_zq = 3, .nr_dx = 4, },
+			{ .base = 0x5bc30000, .nr_zq = 2, .nr_dx = 2, },
+		},
+	},
+};
+UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_ddrmphy_param, uniphier_ddrmphy_param)
 
 static void print_bdl(void __iomem *reg, int n)
 {
@@ -47,59 +65,60 @@ static void print_bdl(void __iomem *reg, int n)
 		printf(FS PRINTF_FORMAT, (val >> i * 8) & 0x1f);
 }
 
-static void dump_loop(void (*callback)(void __iomem *))
+static void dump_loop(const struct uniphier_ddrmphy_param *param,
+		      void (*callback)(void __iomem *))
 {
-	int ch, dx, nr_ch, nr_dx;
-	void __iomem *dx_base;
-
-	nr_ch = get_nr_ch();
+	void __iomem *phy_base, *dx_base;
+	int phy, dx;
 
-	for (ch = 0; ch < nr_ch; ch++) {
-		dx_base = get_phy_base(ch) + MPHY_DX_BASE;
-		nr_dx = get_nr_datx8(ch);
+	for (phy = 0; phy < param->nr_phy; phy++) {
+		phy_base = ioremap(param->phy[phy].base, SZ_4K);
+		dx_base = phy_base + MPHY_DX_BASE;
 
-		for (dx = 0; dx < nr_dx; dx++) {
-			printf("CH%dDX%d:", ch, dx);
+		for (dx = 0; dx < param->phy[phy].nr_dx; dx++) {
+			printf("PHY%dDX%d:", phy, dx);
 			(*callback)(dx_base);
 			dx_base += MPHY_DX_STRIDE;
 			printf("\n");
 		}
+
+		iounmap(phy_base);
 	}
 }
 
-static void zq_dump(void)
+static void zq_dump(const struct uniphier_ddrmphy_param *param)
 {
-	int ch, zq, nr_ch, nr_zq, i;
-	void __iomem *zq_base;
-	u32 dr, pr;
+	void __iomem *phy_base, *zq_base;
+	u32 val;
+	int phy, zq, i;
 
 	printf("\n--- Impedance Data ---\n");
-	printf("         ZPD  ZPU  OPD  OPU  ZDV  ODV\n");
+	printf("           ZPD  ZPU  OPD  OPU  ZDV  ODV\n");
 
-	nr_ch = get_nr_ch();
+	for (phy = 0; phy < param->nr_phy; phy++) {
+		phy_base = ioremap(param->phy[phy].base, SZ_4K);
+		zq_base = phy_base + MPHY_ZQ_BASE;
 
-	for (ch = 0; ch < nr_ch; ch++) {
-		zq_base = get_phy_base(ch) + MPHY_ZQ_BASE;
-		nr_zq = 3;
+		for (zq = 0; zq < param->phy[phy].nr_zq; zq++) {
+			printf("PHY%dZQ%d:", phy, zq);
 
-		for (zq = 0; zq < nr_zq; zq++) {
-			printf("CH%dZQ%d:", ch, zq);
-
-			dr = readl(zq_base + MPHY_ZQ_DR);
+			val = readl(zq_base + MPHY_ZQ_DR);
 			for (i = 0; i < 4; i++) {
-				printf(FS PRINTF_FORMAT, dr & 0x7f);
-				dr >>= 7;
+				printf(FS PRINTF_FORMAT, val & 0x7f);
+				val >>= 7;
 			}
 
-			pr = readl(zq_base + MPHY_ZQ_PR);
+			val = readl(zq_base + MPHY_ZQ_PR);
 			for (i = 0; i < 2; i++) {
-				printf(FS PRINTF_FORMAT, pr & 0xf);
-				pr >>= 4;
+				printf(FS PRINTF_FORMAT, val & 0xf);
+				val >>= 4;
 			}
 
 			zq_base += MPHY_ZQ_STRIDE;
 			printf("\n");
 		}
+
+		iounmap(phy_base);
 	}
 }
 
@@ -113,12 +132,12 @@ static void __wbdl_dump(void __iomem *dx_base)
 	       readl(dx_base + MPHY_DX_LCDLR1) & 0xff);
 }
 
-static void wbdl_dump(void)
+static void wbdl_dump(const struct uniphier_ddrmphy_param *param)
 {
 	printf("\n--- Write Bit Delay Line ---\n");
-	printf("         DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  DQS  (WDQD)\n");
+	printf("           DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  DQS  (WDQD)\n");
 
-	dump_loop(&__wbdl_dump);
+	dump_loop(param, &__wbdl_dump);
 }
 
 static void __rbdl_dump(void __iomem *dx_base)
@@ -134,12 +153,12 @@ static void __rbdl_dump(void __iomem *dx_base)
 	       (readl(dx_base + MPHY_DX_LCDLR1) >> 16) & 0xff);
 }
 
-static void rbdl_dump(void)
+static void rbdl_dump(const struct uniphier_ddrmphy_param *param)
 {
 	printf("\n--- Read Bit Delay Line ---\n");
-	printf("         DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  (RDQSD) (RDQSND)\n");
+	printf("           DQ0  DQ1  DQ2  DQ3  DQ4  DQ5  DQ6  DQ7   DM  (RDQSD) (RDQSND)\n");
 
-	dump_loop(&__rbdl_dump);
+	dump_loop(param, &__rbdl_dump);
 }
 
 static void __wld_dump(void __iomem *dx_base)
@@ -157,12 +176,12 @@ static void __wld_dump(void __iomem *dx_base)
 	}
 }
 
-static void wld_dump(void)
+static void wld_dump(const struct uniphier_ddrmphy_param *param)
 {
 	printf("\n--- Write Leveling Delay ---\n");
-	printf("          Rank0   Rank1   Rank2   Rank3\n");
+	printf("           Rank0   Rank1   Rank2   Rank3\n");
 
-	dump_loop(&__wld_dump);
+	dump_loop(param, &__wld_dump);
 }
 
 static void __dqsgd_dump(void __iomem *dx_base)
@@ -179,12 +198,12 @@ static void __dqsgd_dump(void __iomem *dx_base)
 	}
 }
 
-static void dqsgd_dump(void)
+static void dqsgd_dump(const struct uniphier_ddrmphy_param *param)
 {
 	printf("\n--- DQS Gating Delay ---\n");
-	printf("          Rank0   Rank1   Rank2   Rank3\n");
+	printf("           Rank0   Rank1   Rank2   Rank3\n");
 
-	dump_loop(&__dqsgd_dump);
+	dump_loop(param, &__dqsgd_dump);
 }
 
 static void __mdl_dump(void __iomem *dx_base)
@@ -196,12 +215,12 @@ static void __mdl_dump(void __iomem *dx_base)
 		printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff);
 }
 
-static void mdl_dump(void)
+static void mdl_dump(const struct uniphier_ddrmphy_param *param)
 {
 	printf("\n--- Master Delay Line ---\n");
-	printf("        IPRD TPRD MDLD\n");
+	printf("          IPRD TPRD MDLD\n");
 
-	dump_loop(&__mdl_dump);
+	dump_loop(param, &__mdl_dump);
 }
 
 #define REG_DUMP(x)							\
@@ -216,20 +235,18 @@ static void mdl_dump(void)
 		printf("%3d: DX%d%-7s: %p : %08x\n",			\
 		       ofst >> MPHY_SHIFT, (dx), #x, reg, readl(reg)); }
 
-static void reg_dump(void)
+static void reg_dump(const struct uniphier_ddrmphy_param *param)
 {
-	int ch, dx, nr_ch, nr_dx;
 	void __iomem *phy_base;
+	int phy, dx;
 
-	printf("\n--- DDR PHY registers ---\n");
+	printf("\n--- DDR Multi PHY registers ---\n");
 
-	nr_ch = get_nr_ch();
+	for (phy = 0; phy < param->nr_phy; phy++) {
+		phy_base = ioremap(param->phy[phy].base, SZ_4K);
 
-	for (ch = 0; ch < nr_ch; ch++) {
-		phy_base = get_phy_base(ch);
-		nr_dx = get_nr_datx8(ch);
-
-		printf("== Ch%d ==\n", ch);
+		printf("== PHY%d (base: %08x) ==\n", phy,
+		       ptr_to_uint(phy_base));
 		printf(" No: Name      : Address  : Data\n");
 
 		REG_DUMP(RIDR);
@@ -260,50 +277,61 @@ static void reg_dump(void)
 		REG_DUMP(MR2);
 		REG_DUMP(MR3);
 
-		for (dx = 0; dx < nr_dx; dx++) {
+		for (dx = 0; dx < param->phy[phy].nr_dx; dx++) {
 			DX_REG_DUMP(dx, GCR0);
 			DX_REG_DUMP(dx, GCR1);
 			DX_REG_DUMP(dx, GCR2);
 			DX_REG_DUMP(dx, GCR3);
 			DX_REG_DUMP(dx, GTR);
 		}
+
+		iounmap(phy_base);
 	}
 }
 
 static int do_ddrm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	char *cmd = argv[1];
+	const struct uniphier_ddrmphy_param *param;
+	char *cmd;
+
+	param = uniphier_get_ddrmphy_param();
+	if (!param) {
+		printf("unsupported SoC\n");
+		return CMD_RET_FAILURE;
+	}
 
 	if (argc == 1)
 		cmd = "all";
+	else
+		cmd = argv[1];
 
 	if (!strcmp(cmd, "zq") || !strcmp(cmd, "all"))
-		zq_dump();
+		zq_dump(param);
 
 	if (!strcmp(cmd, "wbdl") || !strcmp(cmd, "all"))
-		wbdl_dump();
+		wbdl_dump(param);
 
 	if (!strcmp(cmd, "rbdl") || !strcmp(cmd, "all"))
-		rbdl_dump();
+		rbdl_dump(param);
 
 	if (!strcmp(cmd, "wld") || !strcmp(cmd, "all"))
-		wld_dump();
+		wld_dump(param);
 
 	if (!strcmp(cmd, "dqsgd") || !strcmp(cmd, "all"))
-		dqsgd_dump();
+		dqsgd_dump(param);
 
 	if (!strcmp(cmd, "mdl") || !strcmp(cmd, "all"))
-		mdl_dump();
+		mdl_dump(param);
 
 	if (!strcmp(cmd, "reg") || !strcmp(cmd, "all"))
-		reg_dump();
+		reg_dump(param);
 
-	return 0;
+	return CMD_RET_SUCCESS;
 }
 
 U_BOOT_CMD(
 	ddrm,	2,	1,	do_ddrm,
-	"UniPhier DDR PHY parameters dumper",
+	"UniPhier DDR Multi PHY parameters dumper",
 	"- dump all of the following\n"
 	"ddrm zq - dump Impedance Data\n"
 	"ddrm wbdl - dump Write Bit Delay\n"
Signature · 1 line
2.7.4
#8 lore raw

PATCH 8/16 ARM: uniphier: compile board data only for SPL

In reply to Masahiro Yamada

Now U-Boot proper need not get the uniphier_boards array. Compile it only for SPL.

---

 arch/arm/mach-uniphier/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-uniphier/Makefile +1 -1
index abfdccc..166b41f 100644
@@ -4,6 +4,7 @@
 
 ifdef CONFIG_SPL_BUILD
 
+obj-y += boards.o
 obj-y += spl_board_init.o
 obj-y += memconf.o
 obj-y += bcu/
@@ -21,7 +22,6 @@ obj-y += pinctrl-glue.o
 
 endif
 
-obj-y += boards.o
 obj-y += soc-info.o
 obj-y += boot-mode/
 obj-y += clk/
Signature · 1 line
2.7.4
#9 lore raw

PATCH 9/16 ARM: uniphier: collect SPL CONFIG symbols to the bottom of header

In reply to Masahiro Yamada

For clarification, move CONFIG symbols that affect SPL building into a single place. Drop #ifdef CONFIG_SPL ... #endif since it is harmless to define CONFIG_SPL_... during U-Boot proper building.

---

 include/configs/uniphier.h | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
include/configs/uniphier.h +5 -6
index ef5b019..94d87c3 100644
@@ -98,7 +98,6 @@
 #define CONFIG_SYS_TIMER_RATE			1000000
 #endif
 
-
 #define CONFIG_SYS_MAX_NAND_DEVICE			1
 #define CONFIG_SYS_NAND_MAX_CHIPS			2
 #define CONFIG_SYS_NAND_ONFI_DETECTION
@@ -241,6 +240,11 @@
 /* for LD20; the last 64 byte is used for dynamic DDR PHY training */
 #define CONFIG_SYS_MEM_TOP_HIDE		64
 
+#define CONFIG_PANIC_HANG
+
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE)
+
+/* only for SPL */
 #if defined(CONFIG_ARM64)
 #define CONFIG_SPL_TEXT_BASE		0x30000000
 #elif defined(CONFIG_ARCH_UNIPHIER_SLD3) || \
@@ -258,9 +262,6 @@
 #else
 #define CONFIG_SPL_STACK		(0x00100000)
 #endif
-#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_TEXT_BASE)
-
-#define CONFIG_PANIC_HANG
 
 #define CONFIG_SPL_FRAMEWORK
 #ifdef CONFIG_ARM64
@@ -274,7 +275,6 @@
 /* subtract sizeof(struct image_header) */
 #define CONFIG_SYS_UBOOT_BASE			(0x60000 - 0x40)
 
-#ifdef CONFIG_SPL
 #define CONFIG_SPL_TARGET			"u-boot-with-spl.bin"
 #define CONFIG_SPL_MAX_FOOTPRINT		0x10000
 #define CONFIG_SPL_MAX_SIZE			0x10000
@@ -284,6 +284,5 @@
 #define CONFIG_SPL_BSS_START_ADDR		0x30016000
 #endif
 #define CONFIG_SPL_BSS_MAX_SIZE			0x2000
-#endif
 
 #endif /* __CONFIG_UNIPHIER_COMMON_H__ */
Signature · 1 line
2.7.4
#10 lore raw

PATCH 10/16 ARM: uniphier: use Image.gz instead Image for booting ARM64 Linux

In reply to Masahiro Yamada

The ARM64 Linux raw image now amounts to 15MB and it is getting bigger and bigger. Using Image.gz saves about 8MB. The cost of unzip is smaller than what we get by saving the kernel loading from non-volatile devices.

The ARM32 Linux still uses zImage, a self-decompressor image, so it should not be affected.

---

 include/configs/uniphier.h | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)
include/configs/uniphier.h +22 -14
index 94d87c3..b6dc76e 100644
@@ -15,6 +15,10 @@
 
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  10
 
+#ifdef CONFIG_ARM64
+#define CONFIG_CMD_UNZIP
+#endif
+
 /*-----------------------------------------------------------------------
  * MMU and Cache Setting
  *----------------------------------------------------------------------*/
@@ -167,46 +171,50 @@
 	"__nfsboot=run tftpboot\0"
 #else
 #ifdef CONFIG_ARM64
-#define CONFIG_BOOTFILE			"Image"
+#define CONFIG_BOOTFILE			"Image.gz"
 #define LINUXBOOT_CMD			"booti"
+#define KERNEL_ADDR_LOAD		"kernel_addr_load=0x84200000\0"
 #define KERNEL_ADDR_R			"kernel_addr_r=0x80080000\0"
-#define KERNEL_SIZE			"kernel_size=0x00c00000\0"
-#define RAMDISK_ADDR			"ramdisk_addr=0x00e00000\0"
 #else
 #define CONFIG_BOOTFILE			"zImage"
 #define LINUXBOOT_CMD			"bootz"
+#define KERNEL_ADDR_LOAD		"kernel_addr_load=0x80208000\0"
 #define KERNEL_ADDR_R			"kernel_addr_r=0x80208000\0"
-#define KERNEL_SIZE			"kernel_size=0x00800000\0"
-#define RAMDISK_ADDR			"ramdisk_addr=0x00a00000\0"
 #endif
 #define LINUXBOOT_ENV_SETTINGS \
 	"fdt_addr=0x00100000\0" \
 	"fdt_addr_r=0x84100000\0" \
 	"fdt_size=0x00008000\0" \
 	"kernel_addr=0x00200000\0" \
+	KERNEL_ADDR_LOAD \
 	KERNEL_ADDR_R \
-	KERNEL_SIZE \
-	RAMDISK_ADDR \
+	"kernel_size=0x00800000\0" \
+	"ramdisk_addr=0x00a00000\0" \
 	"ramdisk_addr_r=0x84a00000\0" \
 	"ramdisk_size=0x00600000\0" \
 	"ramdisk_file=rootfs.cpio.uboot\0" \
-	"boot_common=setexpr bootm_low $kernel_addr_r '&' fe000000 &&" \
+	"boot_common=setexpr bootm_low $kernel_addr_r '&' fe000000 && " \
+		"if test $kernel_addr_load = $kernel_addr_r; then " \
+			"true; " \
+		"else " \
+			"unzip $kernel_addr_load $kernel_addr_r; " \
+		"fi && " \
 		LINUXBOOT_CMD " $kernel_addr_r $ramdisk_addr_r $fdt_addr_r\0" \
-	"norboot=setexpr kernel_addr $nor_base + $kernel_addr &&" \
-		"setexpr kernel_size $kernel_size / 4 &&" \
-		"cp $kernel_addr $kernel_addr_r $kernel_size &&" \
+	"norboot=setexpr kernel_addr_nor $nor_base + $kernel_addr && " \
+		"setexpr kernel_size_div4 $kernel_size / 4 && " \
+		"cp $kernel_addr_nor $kernel_addr_load $kernel_size_div4 && " \
 		"setexpr ramdisk_addr_r $nor_base + $ramdisk_addr &&" \
 		"setexpr fdt_addr_r $nor_base + $fdt_addr &&" \
 		"run boot_common\0" \
-	"nandboot=nand read $kernel_addr_r $kernel_addr $kernel_size &&" \
+	"nandboot=nand read $kernel_addr_load $kernel_addr $kernel_size && " \
 		"nand read $ramdisk_addr_r $ramdisk_addr $ramdisk_size &&" \
 		"nand read $fdt_addr_r $fdt_addr $fdt_size &&" \
 		"run boot_common\0" \
-	"tftpboot=tftpboot $kernel_addr_r $bootfile &&" \
+	"tftpboot=tftpboot $kernel_addr_load $bootfile && " \
 		"tftpboot $ramdisk_addr_r $ramdisk_file &&" \
 		"tftpboot $fdt_addr_r $fdt_file &&" \
 		"run boot_common\0" \
-	"__nfsboot=tftpboot $kernel_addr_r $bootfile &&" \
+	"__nfsboot=tftpboot $kernel_addr_load $bootfile && " \
 		"tftpboot $fdt_addr_r $fdt_file &&" \
 		"setenv ramdisk_addr_r - &&" \
 		"run boot_common\0"
Signature · 1 line
2.7.4
#11 lore raw

PATCH 11/16 ARM: uniphier: set initrd_high environment to skip initrd relocation

In reply to Masahiro Yamada

The boot_ramdisk_high() checks the environment "initrd_high" and, if it is set to (ulong)-1, skip the initrd relocation. This is useful for faster booting when we know the initrd is already located within the reach of the kernel.

Change "norboot" to copy images in order to make it work without depending on the automatic relocation.

---

 include/configs/uniphier.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
include/configs/uniphier.h +7 -2
index b6dc76e..0ffd507 100644
@@ -203,8 +203,12 @@
 	"norboot=setexpr kernel_addr_nor $nor_base + $kernel_addr && " \
 		"setexpr kernel_size_div4 $kernel_size / 4 && " \
 		"cp $kernel_addr_nor $kernel_addr_load $kernel_size_div4 && " \
-		"setexpr ramdisk_addr_r $nor_base + $ramdisk_addr &&" \
-		"setexpr fdt_addr_r $nor_base + $fdt_addr &&" \
+		"setexpr ramdisk_addr_nor $nor_base + $ramdisk_addr && " \
+		"setexpr ramdisk_size_div4 $ramdisk_size / 4 && " \
+		"cp $ramdisk_addr_nor $ramdisk_addr_r $ramdisk_size_div4 && " \
+		"setexpr fdt_addr_nor $nor_base + $fdt_addr && " \
+		"setexpr fdt_size_div4 $fdt_size / 4 && " \
+		"cp $fdt_addr_nor $fdt_addr_r $fdt_size_div4 && " \
 		"run boot_common\0" \
 	"nandboot=nand read $kernel_addr_load $kernel_addr $kernel_size && " \
 		"nand read $ramdisk_addr_r $ramdisk_addr $ramdisk_size &&" \
@@ -223,6 +227,7 @@
 #define	CONFIG_EXTRA_ENV_SETTINGS				\
 	"netdev=eth0\0"						\
 	"verify=n\0"						\
+	"initrd_high=0xffffffffffffffff\0"			\
 	"nor_base=0x42000000\0"					\
 	"sramupdate=setexpr tmp_addr $nor_base + 0x50000 &&"	\
 		"tftpboot $tmp_addr u-boot-spl.bin &&"		\
Signature · 1 line
2.7.4
#12 lore raw

PATCH 12/16 ARM: uniphier: change the offset to environment storage area

In reply to Masahiro Yamada

When ARM Trusted Firmware is used, bl1.bin + fip.bin exceeds 512KB, so the boot image and the current environment area will overlap. Move the environment storage to 1MB offset.

---

 include/configs/uniphier.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/uniphier.h +1 -1
index 0ffd507..a53d2e3 100644
@@ -80,7 +80,7 @@
 /* #define CONFIG_ENV_IS_NOWHERE */
 /* #define CONFIG_ENV_IS_IN_NAND */
 #define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET			0x80000
+#define CONFIG_ENV_OFFSET			0x100000
 #define CONFIG_ENV_SIZE				0x2000
 /* #define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE) */
 
Signature · 1 line
2.7.4
#13 lore raw

PATCH 13/16 ARM: uniphier: change CONFIG_SPL_PAD_TO to 128KB

In reply to Masahiro Yamada

The Boot ROM supports authentication feature to prevent malformed software from being run on products. The signature is added at the tail of the second stage loader (= SPL in U-boot terminology).

The size of the second stage loader was 64KB, and it was consistent across SoCs. The situation changed when LD20 SoC appeared; it loads 80KB second stage loader, and it is the only exception.

Currently, CONFIG_SPL_PAD_TO is set to 64KB and U-Boot proper is loaded from the 64KB offset of non-volatile devices. This means the signature of LD20 SoC (located at 80KB offset) corrupts the U-Boot proper image.

Let's move the U-Boot proper image to 128KB offset. It uses 48KB for nothing but padding, and we could actually locate the U-Boot proper at 80KB offset. However, the power of 2 generally seems a better choice for the offset address.

---

 common/spl/Kconfig         |  3 +--
 include/configs/uniphier.h | 20 +++++++++++++-------
 2 files changed, 14 insertions(+), 9 deletions(-)
common/spl/Kconfig +1 -2
index b1aa148..b2ba492 100644
@@ -86,9 +86,8 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
 	depends on SPL && SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
 	default 0x50 if ARCH_SUNXI
 	default 0x75 if ARCH_DAVINCI
-	default 0x80 if ARCH_UNIPHIER
 	default 0x8a if ARCH_MX6
-	default 0x100 if ARCH_ROCKCHIP
+	default 0x100 if ARCH_ROCKCHIP || ARCH_UNIPHIER
 	default 0x140 if ARCH_MVEBU
 	default 0x200 if ARCH_SOCFPGA || ARCH_AT91
 	default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || OMAP44XX || \
include/configs/uniphier.h +13 -7
index a53d2e3..a8a1849 100644
@@ -231,19 +231,19 @@
 	"nor_base=0x42000000\0"					\
 	"sramupdate=setexpr tmp_addr $nor_base + 0x50000 &&"	\
 		"tftpboot $tmp_addr u-boot-spl.bin &&"		\
-		"setexpr tmp_addr $nor_base + 0x60000 &&"	\
+		"setexpr tmp_addr $nor_base + 0x70000 && " \
 		"tftpboot $tmp_addr u-boot.bin\0"		\
 	"emmcupdate=mmcsetn &&"					\
 		"mmc partconf $mmc_first_dev 0 1 1 &&"		\
 		"tftpboot u-boot-spl.bin &&"			\
-		"mmc write $loadaddr 0 80 &&"			\
+		"mmc write $loadaddr 0 100 && " \
 		"tftpboot u-boot.bin &&"			\
-		"mmc write $loadaddr 80 780\0"			\
+		"mmc write $loadaddr 100 700\0" \
 	"nandupdate=nand erase 0 0x00100000 &&"			\
 		"tftpboot u-boot-spl.bin &&"			\
-		"nand write $loadaddr 0 0x00010000 &&"		\
+		"nand write $loadaddr 0 0x00020000 && " \
 		"tftpboot u-boot.bin &&"			\
-		"nand write $loadaddr 0x00010000 0x000f0000\0"	\
+		"nand write $loadaddr 0x00020000 0x000e0000\0" \
 	LINUXBOOT_ENV_SETTINGS
 
 #define CONFIG_SYS_BOOTMAPSZ			0x20000000
@@ -283,14 +283,18 @@
 
 #define CONFIG_SPL_BOARD_INIT
 
-#define CONFIG_SYS_NAND_U_BOOT_OFFS		0x10000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS		0x20000
 
 /* subtract sizeof(struct image_header) */
-#define CONFIG_SYS_UBOOT_BASE			(0x60000 - 0x40)
+#define CONFIG_SYS_UBOOT_BASE			(0x70000 - 0x40)
 
 #define CONFIG_SPL_TARGET			"u-boot-with-spl.bin"
 #define CONFIG_SPL_MAX_FOOTPRINT		0x10000
+#if defined(CONFIG_ARCH_UNIPHIER_LD20)
+#define CONFIG_SPL_MAX_SIZE			0x14000
+#else
 #define CONFIG_SPL_MAX_SIZE			0x10000
+#endif
 #if defined(CONFIG_ARCH_UNIPHIER_LD11)
 #define CONFIG_SPL_BSS_START_ADDR		0x30012000
 #elif defined(CONFIG_ARCH_UNIPHIER_LD20)
@@ -298,4 +302,6 @@
 #endif
 #define CONFIG_SPL_BSS_MAX_SIZE			0x2000
 
+#define CONFIG_SPL_PAD_TO			0x20000
+
 #endif /* __CONFIG_UNIPHIER_COMMON_H__ */
Signature · 1 line
2.7.4
#14 lore raw

PATCH 14/16 ARM: uniphier: make update commands more flexible for ATF

In reply to Masahiro Yamada

Currently, SPL (u-boot-spl.bin) and U-Boot (u-boot.bin) are stored in non-volatile devices, and some environments are defined to update the images easily.

When ARM Trusted Firmware is fully used, SPL is not used. U-Boot proper is contained as BL33 into FIP (Firmware Image Package), which is standard container used by ATF. Allow to use it.

---

 include/configs/uniphier.h | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
include/configs/uniphier.h +18 -6
index a8a1849..da7639f 100644
@@ -147,6 +147,17 @@
 
 #define CONFIG_CMDLINE_EDITING		/* add command line history	*/
 
+#if defined(CONFIG_ARM64) && !defined(CONFIG_ARMV8_MULTIENTRY)
+/* ARM Trusted Firmware */
+#define BOOT_IMAGES \
+	"second_image=bl1.bin\0" \
+	"third_image=fip.bin\0"
+#else
+#define BOOT_IMAGES \
+	"second_image=u-boot-spl.bin\0" \
+	"third_image=u-boot.bin\0"
+#endif
+
 #define CONFIG_BOOTCOMMAND		"run $bootmode"
 
 #define CONFIG_ROOTPATH			"/nfs/root/path"
@@ -230,20 +241,21 @@
 	"initrd_high=0xffffffffffffffff\0"			\
 	"nor_base=0x42000000\0"					\
 	"sramupdate=setexpr tmp_addr $nor_base + 0x50000 &&"	\
-		"tftpboot $tmp_addr u-boot-spl.bin &&"		\
+		"tftpboot $tmp_addr $second_image && " \
 		"setexpr tmp_addr $nor_base + 0x70000 && " \
-		"tftpboot $tmp_addr u-boot.bin\0"		\
+		"tftpboot $tmp_addr $third_image\0" \
 	"emmcupdate=mmcsetn &&"					\
 		"mmc partconf $mmc_first_dev 0 1 1 &&"		\
-		"tftpboot u-boot-spl.bin &&"			\
+		"tftpboot $second_image && " \
 		"mmc write $loadaddr 0 100 && " \
-		"tftpboot u-boot.bin &&"			\
+		"tftpboot $third_image && " \
 		"mmc write $loadaddr 100 700\0" \
 	"nandupdate=nand erase 0 0x00100000 &&"			\
-		"tftpboot u-boot-spl.bin &&"			\
+		"tftpboot $second_image && " \
 		"nand write $loadaddr 0 0x00020000 && " \
-		"tftpboot u-boot.bin &&"			\
+		"tftpboot $third_image && " \
 		"nand write $loadaddr 0x00020000 0x000e0000\0" \
+	BOOT_IMAGES \
 	LINUXBOOT_ENV_SETTINGS
 
 #define CONFIG_SYS_BOOTMAPSZ			0x20000000
Signature · 1 line
2.7.4
#15 lore raw

PATCH 15/16 i2c: uniphier(-f): remove unneeded #include <dm/root.h>

In reply to Masahiro Yamada

This include is unnecessary for low-level drivers.

---

 drivers/i2c/i2c-uniphier-f.c | 1 -
 drivers/i2c/i2c-uniphier.c   | 1 -
 2 files changed, 2 deletions(-)
drivers/i2c/i2c-uniphier-f.c +0 -1
index 8bfa916..e212c13 100644
@@ -12,7 +12,6 @@
 #include <linux/sizes.h>
 #include <linux/errno.h>
 #include <dm/device.h>
-#include <dm/root.h>
 #include <i2c.h>
 #include <fdtdec.h>
 
drivers/i2c/i2c-uniphier.c +0 -1
index f391f11..73575e9 100644
@@ -12,7 +12,6 @@
 #include <linux/sizes.h>
 #include <linux/errno.h>
 #include <dm/device.h>
-#include <dm/root.h>
 #include <i2c.h>
 #include <fdtdec.h>
 
Signature · 1 line
2.7.4
#16 lore raw

PATCH 15/16 i2c: uniphier(-f): remove unneeded #include <dm/root.h>

Hello Masahiro,

Am 27.01.2017 um 22:53 schrieb Masahiro Yamada:

Quoted 8 lines

This include is unnecessary for low-level drivers.

---

  drivers/i2c/i2c-uniphier-f.c | 1 -
  drivers/i2c/i2c-uniphier.c   | 1 -
  2 files changed, 2 deletions(-)

bye,
Heiko

Quoted 26 lines
drivers/i2c/i2c-uniphier-f.c +0 -1
index 8bfa916..e212c13 100644
@@ -12,7 +12,6 @@
  #include <linux/sizes.h>
  #include <linux/errno.h>
  #include <dm/device.h>
-#include <dm/root.h>
  #include <i2c.h>
  #include <fdtdec.h>
 
drivers/i2c/i2c-uniphier.c +0 -1
index f391f11..73575e9 100644
@@ -12,7 +12,6 @@
  #include <linux/sizes.h>
  #include <linux/errno.h>
  #include <dm/device.h>
-#include <dm/root.h>
  #include <i2c.h>
  #include <fdtdec.h>
 
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#17 lore raw

PATCH 16/16 i2c: uniphier-f: use readl_poll_timeout() to poll registers

In reply to Masahiro Yamada

The readl_poll_timeout() is a useful helper to poll registers and error out if the condition is not met.

---

 drivers/i2c/i2c-uniphier-f.c | 34 ++++++++++------------------------
 1 file changed, 10 insertions(+), 24 deletions(-)
drivers/i2c/i2c-uniphier-f.c +10 -24
index e212c13..9f0df59 100644
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <linux/types.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/sizes.h>
 #include <linux/errno.h>
 #include <dm/device.h>
@@ -69,26 +70,14 @@ struct uniphier_fi2c_dev {
 	unsigned long timeout;			/* time out (us) */
 };
 
-static int poll_status(u32 __iomem *reg, u32 flag)
-{
-	int wait = 1000000; /* 1 sec is long enough */
-
-	while (readl(reg) & flag) {
-		if (wait-- < 0)
-			return -EREMOTEIO;
-		udelay(1);
-	}
-
-	return 0;
-}
-
 static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
 {
+	u32 val;
 	int ret;
 
 	/* bus forcible reset */
 	writel(I2C_RST_RST, &regs->rst);
-	ret = poll_status(&regs->rst, I2C_RST_RST);
+	ret = readl_poll_timeout(&regs->rst, val, !(val & I2C_RST_RST), 1);
 	if (ret < 0)
 		debug("error: fail to reset I2C controller\n");
 
@@ -97,9 +86,10 @@ static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
 
 static int check_device_busy(struct uniphier_fi2c_regs __iomem *regs)
 {
+	u32 val;
 	int ret;
 
-	ret = poll_status(&regs->sr, I2C_SR_DB);
+	ret = readl_poll_timeout(&regs->sr, val, !(val & I2C_SR_DB), 100);
 	if (ret < 0) {
 		debug("error: device busy too long. reset...\n");
 		ret = reset_bus(regs);
@@ -138,15 +128,11 @@ static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,
 			bool *stop)
 {
 	u32 irq;
-	unsigned long wait = dev->timeout;
-	int ret = -EREMOTEIO;
-
-	do {
-		udelay(1);
-		irq = readl(&dev->regs->intr);
-	} while (!(irq & flags) && wait--);
+	int ret;
 
-	if (wait < 0) {
+	ret = readl_poll_timeout(&dev->regs->intr, irq, irq & flags,
+				 dev->timeout);
+	if (ret < 0) {
 		debug("error: time out\n");
 		return ret;
 	}
@@ -172,7 +158,7 @@ static int issue_stop(struct uniphier_fi2c_dev *dev, int old_ret)
 	debug("stop condition\n");
 	writel(I2C_CR_MST | I2C_CR_STO, &dev->regs->cr);
 
-	ret = poll_status(&dev->regs->sr, I2C_SR_DB);
+	ret = check_device_busy(dev->regs);
 	if (ret < 0)
 		debug("error: device busy after operation\n");
 
Signature · 1 line
2.7.4
#18 lore raw

PATCH 16/16 i2c: uniphier-f: use readl_poll_timeout() to poll registers

Hello Masahiro,

Am 27.01.2017 um 22:53 schrieb Masahiro Yamada:

Quoted 8 lines

The readl_poll_timeout() is a useful helper to poll registers and error out if the condition is not met.

---

  drivers/i2c/i2c-uniphier-f.c | 34 ++++++++++------------------------
  1 file changed, 10 insertions(+), 24 deletions(-)

bye,
Heiko

Quoted 84 lines
drivers/i2c/i2c-uniphier-f.c +10 -24
index e212c13..9f0df59 100644
@@ -9,6 +9,7 @@
  #include <common.h>
  #include <linux/types.h>
  #include <linux/io.h>
+#include <linux/iopoll.h>
  #include <linux/sizes.h>
  #include <linux/errno.h>
  #include <dm/device.h>
@@ -69,26 +70,14 @@ struct uniphier_fi2c_dev {
  	unsigned long timeout;			/* time out (us) */
  };
 
-static int poll_status(u32 __iomem *reg, u32 flag)
-{
-	int wait = 1000000; /* 1 sec is long enough */
-
-	while (readl(reg) & flag) {
-		if (wait-- < 0)
-			return -EREMOTEIO;
-		udelay(1);
-	}
-
-	return 0;
-}
-
  static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
  {
+	u32 val;
  	int ret;
 
  	/* bus forcible reset */
  	writel(I2C_RST_RST, &regs->rst);
-	ret = poll_status(&regs->rst, I2C_RST_RST);
+	ret = readl_poll_timeout(&regs->rst, val, !(val & I2C_RST_RST), 1);
  	if (ret < 0)
  		debug("error: fail to reset I2C controller\n");
 
@@ -97,9 +86,10 @@ static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
 
  static int check_device_busy(struct uniphier_fi2c_regs __iomem *regs)
  {
+	u32 val;
  	int ret;
 
-	ret = poll_status(&regs->sr, I2C_SR_DB);
+	ret = readl_poll_timeout(&regs->sr, val, !(val & I2C_SR_DB), 100);
  	if (ret < 0) {
  		debug("error: device busy too long. reset...\n");
  		ret = reset_bus(regs);
@@ -138,15 +128,11 @@ static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,
  			bool *stop)
  {
  	u32 irq;
-	unsigned long wait = dev->timeout;
-	int ret = -EREMOTEIO;
-
-	do {
-		udelay(1);
-		irq = readl(&dev->regs->intr);
-	} while (!(irq & flags) && wait--);
+	int ret;
 
-	if (wait < 0) {
+	ret = readl_poll_timeout(&dev->regs->intr, irq, irq & flags,
+				 dev->timeout);
+	if (ret < 0) {
  		debug("error: time out\n");
  		return ret;
  	}
@@ -172,7 +158,7 @@ static int issue_stop(struct uniphier_fi2c_dev *dev, int old_ret)
  	debug("stop condition\n");
  	writel(I2C_CR_MST | I2C_CR_STO, &dev->regs->cr);
 
-	ret = poll_status(&dev->regs->sr, I2C_SR_DB);
+	ret = check_device_busy(dev->regs);
  	if (ret < 0)
  		debug("error: device busy after operation\n");
 
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#19 lore raw

cover ARM: uniphier: UniPhier SoC updates for v2017.03 (3rd round)

In reply to Masahiro Yamada

2017-01-28 6:53 GMT+09:00 Masahiro Yamada <[email protected]>:

Quoted 19 lines

- Fix clk driver
- Optimize DRAM init code for LD20 SoC
- Get DRAM information from more reliable source
- Clean up SoC init code
- Allow to use Image.gz for booting ARM64 Linux
- Tidy up environments to use with ATF
- Clean up I2C drivers

Masahiro Yamada (16):
clk: uniphier: fix compatible strings for Pro5, PXs2, LD20 SD clock
ARM: uniphier: shrink arrays of DDR-PHY parameters for LD20 SoC
ARM: uniphier: detect RAM size by decoding HW register instead of DT
ARM: uniphier: use gd->bd->bi_dram for memory reserve on LD20 SoC
ARM: uniphier: refactor cmd_ddrphy
ARM: uniphier: clean up UMC init for PXs2 SoC
ARM: uniphier: refactor cmd_ddrmphy
ARM: uniphier: compile board data only for SPL

Quoted 8 lines

ARM: uniphier: collect SPL CONFIG symbols to the bottom of header
ARM: uniphier: use Image.gz instead Image for booting ARM64 Linux
ARM: uniphier: set initrd_high environment to skip initrd relocation
ARM: uniphier: change the offset to environment storage area
ARM: uniphier: change CONFIG_SPL_PAD_TO to 128KB
ARM: uniphier: make update commands more flexible for ATF
i2c: uniphier(-f): remove unneeded #include <dm/root.h>
i2c: uniphier-f: use readl_poll_timeout() to poll registers

Series, applied to u-boot-uniphier/master.

Signature · 2 lines
Best Regards
Masahiro Yamada