ARM: uniphier: UniPhier SoC updates for v2017.03 (3rd round)
Subsystems (5)
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
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
@@ -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
PATCH 2/16 ARM: uniphier: shrink arrays of DDR-PHY parameters for LD20 SoC
In reply to Masahiro YamadaThe 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
@@ -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
PATCH 3/16 ARM: uniphier: detect RAM size by decoding HW register instead of DT
In reply to Masahiro YamadaU-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
@@ -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
@@ -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
@@ -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
PATCH 4/16 ARM: uniphier: use gd->bd->bi_dram for memory reserve on LD20 SoC
In reply to Masahiro YamadaFor 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
@@ -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
PATCH 5/16 ARM: uniphier: refactor cmd_ddrphy
In reply to Masahiro YamadaIt 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
@@ -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
PATCH 6/16 ARM: uniphier: clean up UMC init for PXs2 SoC
In reply to Masahiro YamadaJust 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
@@ -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
PATCH 7/16 ARM: uniphier: refactor cmd_ddrmphy
In reply to Masahiro YamadaMake 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
@@ -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
PATCH 8/16 ARM: uniphier: compile board data only for SPL
In reply to Masahiro YamadaNow 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
@@ -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
PATCH 9/16 ARM: uniphier: collect SPL CONFIG symbols to the bottom of header
In reply to Masahiro YamadaFor 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
@@ -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
PATCH 10/16 ARM: uniphier: use Image.gz instead Image for booting ARM64 Linux
In reply to Masahiro YamadaThe 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
@@ -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
PATCH 11/16 ARM: uniphier: set initrd_high environment to skip initrd relocation
In reply to Masahiro YamadaThe 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
@@ -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
PATCH 12/16 ARM: uniphier: change the offset to environment storage area
In reply to Masahiro YamadaWhen 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
@@ -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
PATCH 13/16 ARM: uniphier: change CONFIG_SPL_PAD_TO to 128KB
In reply to Masahiro YamadaThe 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
@@ -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
@@ -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
PATCH 14/16 ARM: uniphier: make update commands more flexible for ATF
In reply to Masahiro YamadaCurrently, 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
@@ -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
PATCH 15/16 i2c: uniphier(-f): remove unneeded #include <dm/root.h>
In reply to Masahiro YamadaThis 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
@@ -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
@@ -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
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.
Signed-off-by Masahiro Yamada <[email protected]>---
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@@ -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@@ -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
PATCH 16/16 i2c: uniphier-f: use readl_poll_timeout() to poll registers
In reply to Masahiro YamadaThe 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
@@ -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 , ®s->rst); - ret =poll_status (®s->rst,I2C_RST_RST ); + ret =readl_poll_timeout (®s->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 (®s->sr,I2C_SR_DB ); + ret =readl_poll_timeout (®s->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
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.Signed-off-by Masahiro Yamada <[email protected]>---
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@@ -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 , ®s->rst); - ret =poll_status (®s->rst,I2C_RST_RST ); + ret =readl_poll_timeout (®s->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 (®s->sr,I2C_SR_DB ); + ret =readl_poll_timeout (®s->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
cover ARM: uniphier: UniPhier SoC updates for v2017.03 (3rd round)
In reply to Masahiro Yamada2017-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 driversMasahiro 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: usegd->bd->bi_dramfor memory reserve on LD20 SoC
ARM: uniphier: refactorcmd_ddrphy
ARM: uniphier: clean up UMC init for PXs2 SoC
ARM: uniphier: refactorcmd_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: setinitrd_highenvironment to skip initrd relocation
ARM: uniphier: change the offset to environment storage area
ARM: uniphier: changeCONFIG_SPL_PAD_TOto 128KB
ARM: uniphier: make update commands more flexible for ATF
i2c: uniphier(-f): remove unneeded #include <dm/root.h>
i2c: uniphier-f: usereadl_poll_timeout()to poll registers
Series, applied to u-boot-uniphier/master.
Signature · 2 lines
Best Regards Masahiro Yamada