From 4c642e68295604787e59afd7beb52a130728f36d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:41 +0900 Subject: [PATCH 01/16] clk: uniphier: fix compatible strings for Pro5, PXs2, LD20 SD clock I missed to update them when DT files were resynced with Linux. Signed-off-by: Masahiro Yamada --- drivers/clk/uniphier/clk-uniphier-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c index 8ad0242d2a..bcb2d2edb7 100644 --- a/drivers/clk/uniphier/clk-uniphier-core.c +++ b/drivers/clk/uniphier/clk-uniphier-core.c @@ -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 */ } From 773f5f63dc0db5e39b4782947e761479ecf1bef2 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:42 +0900 Subject: [PATCH 02/16] ARM: uniphier: shrink arrays of DDR-PHY parameters for LD20 SoC 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. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/dram/umc-ld20.c | 258 ++++++++----------------- 1 file changed, 81 insertions(+), 177 deletions(-) diff --git a/arch/arm/mach-uniphier/dram/umc-ld20.c b/arch/arm/mach-uniphier/dram/umc-ld20.c index 61f62ae6d7..157b915a7b 100644 --- a/arch/arm/mach-uniphier/dram/umc-ld20.c +++ b/arch/arm/mach-uniphier/dram/umc-ld20.c @@ -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, - }, - }, - { /* 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 */ - }, - { /* 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 */ + { + 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 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_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, }, - { /* 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, - }, + { 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, }, - { /* 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, - }, + /* 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 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, }, - { /* 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 */ + { + 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, }, - { /* 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 */ + { + 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, }, }; -/* DDR PHY */ +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, + }, + { + 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 */ +}; + 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; From 3e9952be23e1fdc8b576dfeed80e442d3045cd87 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:43 +0900 Subject: [PATCH 03/16] ARM: uniphier: detect RAM size by decoding HW register instead of DT 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. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/dram_init.c | 260 +++++++++++++++++++++++------ arch/arm/mach-uniphier/init.h | 1 + include/configs/uniphier.h | 2 +- 3 files changed, 210 insertions(+), 53 deletions(-) diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c index 2cf5f36e8b..b78ca72013 100644 --- a/arch/arm/mach-uniphier/dram_init.c +++ b/arch/arm/mach-uniphier/dram_init.c @@ -1,87 +1,243 @@ /* - * Copyright (C) 2012-2015 Masahiro Yamada + * Copyright (C) 2012-2015 Panasonic Corporation + * Copyright (C) 2015-2017 Socionext Inc. + * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ */ #include -#include #include #include +#include #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); + + /* 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; + } + + 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; + + dram_ch[1].size = size; + + if (!data->have_ch2) + return 0; + + /* 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; } int dram_init(void) { - const void *fdt = gd->fdt_blob; - const fdt32_t *val; - int ac, sc, len; + struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH] = {}; + int ret, i; - 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"); - return -EINVAL; + 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; } - val = get_memory_reg_prop(fdt, &len); - if (len / sizeof(*val) < ac + sc) - return -EINVAL; - - val += ac; - - gd->ram_size = fdtdec_get_number(val, sc); - - debug("DRAM size = %08lx\n", (unsigned long)gd->ram_size); - return 0; } void dram_init_banksize(void) { - const void *fdt = gd->fdt_blob; - const fdt32_t *val; - int ac, sc, cells, len, i; + struct uniphier_dram_ch dram_ch[UNIPHIER_MAX_NR_DRAM_CH] = {}; + int i; - val = get_memory_reg_prop(fdt, &len); - if (len < 0) - return; + uniphier_memconf_decode(dram_ch); - 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; - } + for (i = 0; i < ARRAY_SIZE(dram_ch); i++) { + if (i >= ARRAY_SIZE(gd->bd->bi_dram)) + break; - cells = ac + sc; - - len /= sizeof(*val); - - 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; - - 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; } } diff --git a/arch/arm/mach-uniphier/init.h b/arch/arm/mach-uniphier/init.h index 3aeb5b1079..453e68a43e 100644 --- a/arch/arm/mach-uniphier/init.h +++ b/arch/arm/mach-uniphier/init.h @@ -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 */ diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index c991b2dbdd..a6deda8425 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -236,7 +236,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 From c995f3a3c5263c2e424064fac81f169846b6d25e Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:44 +0900 Subject: [PATCH 04/16] ARM: uniphier: use gd->bd->bi_dram for memory reserve on LD20 SoC 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. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/dram_init.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c index b78ca72013..881062d9b6 100644 --- a/arch/arm/mach-uniphier/dram_init.c +++ b/arch/arm/mach-uniphier/dram_init.c @@ -248,22 +248,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); From bf52091786bd80368e54d33babe04534192805ed Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:45 +0900 Subject: [PATCH 05/16] ARM: uniphier: refactor cmd_ddrphy It seems more readable to use arrays to get SoC specific parameters instead of the crappy switch statement. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/dram/cmd_ddrphy.c | 156 ++++++++++++----------- 1 file changed, 83 insertions(+), 73 deletions(-) diff --git a/arch/arm/mach-uniphier/dram/cmd_ddrphy.c b/arch/arm/mach-uniphier/dram/cmd_ddrphy.c index d6d9db3e2c..a71f704b0c 100644 --- a/arch/arm/mach-uniphier/dram/cmd_ddrphy.c +++ b/arch/arm/mach-uniphier/dram/cmd_ddrphy.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 Panasonic Corporation - * Copyright (C) 2015-2016 Socionext Inc. + * Copyright (C) 2015-2017 Socionext Inc. * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ @@ -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; + const struct uniphier_ddrphy_param *param; + char *cmd; - 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: + 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; } From fada9eafe1fe871b4053254e5322613adff98478 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:46 +0900 Subject: [PATCH 06/16] ARM: uniphier: clean up UMC init for PXs2 SoC Just cosmetic changes: - Rename prefix DMPHY_ to MPHY_ for consistency - Move UMC parameters below for complete decouple of PHY and UMC - Remove redundant whitespaces Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/dram/cmd_ddrmphy.c | 50 ++-- arch/arm/mach-uniphier/dram/ddrmphy-regs.h | 264 ++++++++++----------- arch/arm/mach-uniphier/dram/umc-pxs2.c | 243 +++++++++---------- 3 files changed, 279 insertions(+), 278 deletions(-) diff --git a/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c b/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c index 47cee6fb31..4e6616208c 100644 --- a/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c +++ b/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c @@ -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) { diff --git a/arch/arm/mach-uniphier/dram/ddrmphy-regs.h b/arch/arm/mach-uniphier/dram/ddrmphy-regs.h index 569504d657..e13ccf8a72 100644 --- a/arch/arm/mach-uniphier/dram/ddrmphy-regs.h +++ b/arch/arm/mach-uniphier/dram/ddrmphy-regs.h @@ -1,146 +1,146 @@ /* * UniPhier DDR MultiPHY registers * - * Copyright (C) 2015 Masahiro Yamada + * Copyright (C) 2015-2017 Socionext Inc. * * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef ARCH_DDRMPHY_REGS_H -#define ARCH_DDRMPHY_REGS_H +#ifndef UNIPHIER_DDRMPHY_REGS_H +#define UNIPHIER_DDRMPHY_REGS_H #include -#define DMPHY_SHIFT 2 +#define MPHY_SHIFT 2 -#define DMPHY_RIDR (0x000 << DMPHY_SHIFT) -#define DMPHY_PIR (0x001 << DMPHY_SHIFT) -#define DMPHY_PIR_INIT BIT(0) /* Initialization Trigger */ -#define DMPHY_PIR_ZCAL BIT(1) /* Impedance Calibration */ -#define DMPHY_PIR_PLLINIT BIT(4) /* PLL Initialization */ -#define DMPHY_PIR_DCAL BIT(5) /* DDL Calibration */ -#define DMPHY_PIR_PHYRST BIT(6) /* PHY Reset */ -#define DMPHY_PIR_DRAMRST BIT(7) /* DRAM Reset */ -#define DMPHY_PIR_DRAMINIT BIT(8) /* DRAM Initialization */ -#define DMPHY_PIR_WL BIT(9) /* Write Leveling */ -#define DMPHY_PIR_QSGATE BIT(10) /* Read DQS Gate Training */ -#define DMPHY_PIR_WLADJ BIT(11) /* Write Leveling Adjust */ -#define DMPHY_PIR_RDDSKW BIT(12) /* Read Data Bit Deskew */ -#define DMPHY_PIR_WRDSKW BIT(13) /* Write Data Bit Deskew */ -#define DMPHY_PIR_RDEYE BIT(14) /* Read Data Eye Training */ -#define DMPHY_PIR_WREYE BIT(15) /* Write Data Eye Training */ -#define DMPHY_PIR_ZCALBYP BIT(30) /* Impedance Calib Bypass */ -#define DMPHY_PIR_INITBYP BIT(31) /* Initialization Bypass */ -#define DMPHY_PGCR0 (0x002 << DMPHY_SHIFT) -#define DMPHY_PGCR0_PHYFRST BIT(26) /* PHY FIFO Reset */ -#define DMPHY_PGCR1 (0x003 << DMPHY_SHIFT) -#define DMPHY_PGCR1_INHVT BIT(26) /* VT Calculation Inhibit */ -#define DMPHY_PGCR2 (0x004 << DMPHY_SHIFT) -#define DMPHY_PGCR2_DUALCHN BIT(28) /* Dual Channel Configuration*/ -#define DMPHY_PGCR2_ACPDDC BIT(29) /* AC Power-Down with Dual Ch*/ -#define DMPHY_PGCR3 (0x005 << DMPHY_SHIFT) -#define DMPHY_PGSR0 (0x006 << DMPHY_SHIFT) -#define DMPHY_PGSR0_IDONE BIT(0) /* Initialization Done */ -#define DMPHY_PGSR0_PLDONE BIT(1) /* PLL Lock Done */ -#define DMPHY_PGSR0_DCDONE BIT(2) /* DDL Calibration Done */ -#define DMPHY_PGSR0_ZCDONE BIT(3) /* Impedance Calibration Done */ -#define DMPHY_PGSR0_DIDONE BIT(4) /* DRAM Initialization Done */ -#define DMPHY_PGSR0_WLDONE BIT(5) /* Write Leveling Done */ -#define DMPHY_PGSR0_QSGDONE BIT(6) /* DQS Gate Training Done */ -#define DMPHY_PGSR0_WLADONE BIT(7) /* Write Leveling Adjust Done */ -#define DMPHY_PGSR0_RDDONE BIT(8) /* Read Bit Deskew Done */ -#define DMPHY_PGSR0_WDDONE BIT(9) /* Write Bit Deskew Done */ -#define DMPHY_PGSR0_REDONE BIT(10) /* Read Eye Training Done */ -#define DMPHY_PGSR0_WEDONE BIT(11) /* Write Eye Training Done */ -#define DMPHY_PGSR0_ZCERR BIT(20) /* Impedance Calib Error */ -#define DMPHY_PGSR0_WLERR BIT(21) /* Write Leveling Error */ -#define DMPHY_PGSR0_QSGERR BIT(22) /* DQS Gate Training Error */ -#define DMPHY_PGSR0_WLAERR BIT(23) /* Write Leveling Adj Error */ -#define DMPHY_PGSR0_RDERR BIT(24) /* Read Bit Deskew Error */ -#define DMPHY_PGSR0_WDERR BIT(25) /* Write Bit Deskew Error */ -#define DMPHY_PGSR0_REERR BIT(26) /* Read Eye Training Error */ -#define DMPHY_PGSR0_WEERR BIT(27) /* Write Eye Training Error */ -#define DMPHY_PGSR1 (0x007 << DMPHY_SHIFT) -#define DMPHY_PGSR1_VTSTOP BIT(30) /* VT Stop */ -#define DMPHY_PLLCR (0x008 << DMPHY_SHIFT) -#define DMPHY_PTR0 (0x009 << DMPHY_SHIFT) -#define DMPHY_PTR1 (0x00A << DMPHY_SHIFT) -#define DMPHY_PTR2 (0x00B << DMPHY_SHIFT) -#define DMPHY_PTR3 (0x00C << DMPHY_SHIFT) -#define DMPHY_PTR4 (0x00D << DMPHY_SHIFT) -#define DMPHY_ACMDLR (0x00E << DMPHY_SHIFT) -#define DMPHY_ACLCDLR (0x00F << DMPHY_SHIFT) -#define DMPHY_ACBDLR0 (0x010 << DMPHY_SHIFT) -#define DMPHY_ACBDLR1 (0x011 << DMPHY_SHIFT) -#define DMPHY_ACBDLR2 (0x012 << DMPHY_SHIFT) -#define DMPHY_ACBDLR3 (0x013 << DMPHY_SHIFT) -#define DMPHY_ACBDLR4 (0x014 << DMPHY_SHIFT) -#define DMPHY_ACBDLR5 (0x015 << DMPHY_SHIFT) -#define DMPHY_ACBDLR6 (0x016 << DMPHY_SHIFT) -#define DMPHY_ACBDLR7 (0x017 << DMPHY_SHIFT) -#define DMPHY_ACBDLR8 (0x018 << DMPHY_SHIFT) -#define DMPHY_ACBDLR9 (0x019 << DMPHY_SHIFT) -#define DMPHY_ACIOCR0 (0x01A << DMPHY_SHIFT) -#define DMPHY_ACIOCR1 (0x01B << DMPHY_SHIFT) -#define DMPHY_ACIOCR2 (0x01C << DMPHY_SHIFT) -#define DMPHY_ACIOCR3 (0x01D << DMPHY_SHIFT) -#define DMPHY_ACIOCR4 (0x01E << DMPHY_SHIFT) -#define DMPHY_ACIOCR5 (0x01F << DMPHY_SHIFT) -#define DMPHY_DXCCR (0x020 << DMPHY_SHIFT) -#define DMPHY_DSGCR (0x021 << DMPHY_SHIFT) -#define DMPHY_DCR (0x022 << DMPHY_SHIFT) -#define DMPHY_DTPR0 (0x023 << DMPHY_SHIFT) -#define DMPHY_DTPR1 (0x024 << DMPHY_SHIFT) -#define DMPHY_DTPR2 (0x025 << DMPHY_SHIFT) -#define DMPHY_DTPR3 (0x026 << DMPHY_SHIFT) -#define DMPHY_MR0 (0x027 << DMPHY_SHIFT) -#define DMPHY_MR1 (0x028 << DMPHY_SHIFT) -#define DMPHY_MR2 (0x029 << DMPHY_SHIFT) -#define DMPHY_MR3 (0x02A << DMPHY_SHIFT) -#define DMPHY_ODTCR (0x02B << DMPHY_SHIFT) -#define DMPHY_DTCR (0x02C << DMPHY_SHIFT) -#define DMPHY_DTCR_RANKEN_SHIFT 24 /* Rank Enable */ -#define DMPHY_DTCR_RANKEN_MASK (0xf << (DMPHY_DTCR_RANKEN_SHIFT)) -#define DMPHY_DTAR0 (0x02D << DMPHY_SHIFT) -#define DMPHY_DTAR1 (0x02E << DMPHY_SHIFT) -#define DMPHY_DTAR2 (0x02F << DMPHY_SHIFT) -#define DMPHY_DTAR3 (0x030 << DMPHY_SHIFT) -#define DMPHY_DTDR0 (0x031 << DMPHY_SHIFT) -#define DMPHY_DTDR1 (0x032 << DMPHY_SHIFT) -#define DMPHY_DTEDR0 (0x033 << DMPHY_SHIFT) -#define DMPHY_DTEDR1 (0x034 << DMPHY_SHIFT) -#define DMPHY_ZQCR (0x090 << DMPHY_SHIFT) -#define DMPHY_ZQCR_AVGEN BIT(16) /* Average Algorithm */ -#define DMPHY_ZQCR_FORCE_ZCAL_VT_UPDATE BIT(27) /* force VT update */ +#define MPHY_RIDR (0x000 << MPHY_SHIFT) +#define MPHY_PIR (0x001 << MPHY_SHIFT) +#define MPHY_PIR_INIT BIT(0) /* Initialization Trigger */ +#define MPHY_PIR_ZCAL BIT(1) /* Impedance Calibration */ +#define MPHY_PIR_PLLINIT BIT(4) /* PLL Initialization */ +#define MPHY_PIR_DCAL BIT(5) /* DDL Calibration */ +#define MPHY_PIR_PHYRST BIT(6) /* PHY Reset */ +#define MPHY_PIR_DRAMRST BIT(7) /* DRAM Reset */ +#define MPHY_PIR_DRAMINIT BIT(8) /* DRAM Initialization */ +#define MPHY_PIR_WL BIT(9) /* Write Leveling */ +#define MPHY_PIR_QSGATE BIT(10) /* Read DQS Gate Training */ +#define MPHY_PIR_WLADJ BIT(11) /* Write Leveling Adjust */ +#define MPHY_PIR_RDDSKW BIT(12) /* Read Data Bit Deskew */ +#define MPHY_PIR_WRDSKW BIT(13) /* Write Data Bit Deskew */ +#define MPHY_PIR_RDEYE BIT(14) /* Read Data Eye Training */ +#define MPHY_PIR_WREYE BIT(15) /* Write Data Eye Training */ +#define MPHY_PIR_ZCALBYP BIT(30) /* Impedance Calib Bypass */ +#define MPHY_PIR_INITBYP BIT(31) /* Initialization Bypass */ +#define MPHY_PGCR0 (0x002 << MPHY_SHIFT) +#define MPHY_PGCR0_PHYFRST BIT(26) /* PHY FIFO Reset */ +#define MPHY_PGCR1 (0x003 << MPHY_SHIFT) +#define MPHY_PGCR1_INHVT BIT(26) /* VT Calculation Inhibit */ +#define MPHY_PGCR2 (0x004 << MPHY_SHIFT) +#define MPHY_PGCR2_DUALCHN BIT(28) /* Dual Channel Configuration*/ +#define MPHY_PGCR2_ACPDDC BIT(29) /* AC Power-Down with Dual Ch*/ +#define MPHY_PGCR3 (0x005 << MPHY_SHIFT) +#define MPHY_PGSR0 (0x006 << MPHY_SHIFT) +#define MPHY_PGSR0_IDONE BIT(0) /* Initialization Done */ +#define MPHY_PGSR0_PLDONE BIT(1) /* PLL Lock Done */ +#define MPHY_PGSR0_DCDONE BIT(2) /* DDL Calibration Done */ +#define MPHY_PGSR0_ZCDONE BIT(3) /* Impedance Calibration Done */ +#define MPHY_PGSR0_DIDONE BIT(4) /* DRAM Initialization Done */ +#define MPHY_PGSR0_WLDONE BIT(5) /* Write Leveling Done */ +#define MPHY_PGSR0_QSGDONE BIT(6) /* DQS Gate Training Done */ +#define MPHY_PGSR0_WLADONE BIT(7) /* Write Leveling Adjust Done */ +#define MPHY_PGSR0_RDDONE BIT(8) /* Read Bit Deskew Done */ +#define MPHY_PGSR0_WDDONE BIT(9) /* Write Bit Deskew Done */ +#define MPHY_PGSR0_REDONE BIT(10) /* Read Eye Training Done */ +#define MPHY_PGSR0_WEDONE BIT(11) /* Write Eye Training Done */ +#define MPHY_PGSR0_ZCERR BIT(20) /* Impedance Calib Error */ +#define MPHY_PGSR0_WLERR BIT(21) /* Write Leveling Error */ +#define MPHY_PGSR0_QSGERR BIT(22) /* DQS Gate Training Error */ +#define MPHY_PGSR0_WLAERR BIT(23) /* Write Leveling Adj Error */ +#define MPHY_PGSR0_RDERR BIT(24) /* Read Bit Deskew Error */ +#define MPHY_PGSR0_WDERR BIT(25) /* Write Bit Deskew Error */ +#define MPHY_PGSR0_REERR BIT(26) /* Read Eye Training Error */ +#define MPHY_PGSR0_WEERR BIT(27) /* Write Eye Training Error */ +#define MPHY_PGSR1 (0x007 << MPHY_SHIFT) +#define MPHY_PGSR1_VTSTOP BIT(30) /* VT Stop */ +#define MPHY_PLLCR (0x008 << MPHY_SHIFT) +#define MPHY_PTR0 (0x009 << MPHY_SHIFT) +#define MPHY_PTR1 (0x00A << MPHY_SHIFT) +#define MPHY_PTR2 (0x00B << MPHY_SHIFT) +#define MPHY_PTR3 (0x00C << MPHY_SHIFT) +#define MPHY_PTR4 (0x00D << MPHY_SHIFT) +#define MPHY_ACMDLR (0x00E << MPHY_SHIFT) +#define MPHY_ACLCDLR (0x00F << MPHY_SHIFT) +#define MPHY_ACBDLR0 (0x010 << MPHY_SHIFT) +#define MPHY_ACBDLR1 (0x011 << MPHY_SHIFT) +#define MPHY_ACBDLR2 (0x012 << MPHY_SHIFT) +#define MPHY_ACBDLR3 (0x013 << MPHY_SHIFT) +#define MPHY_ACBDLR4 (0x014 << MPHY_SHIFT) +#define MPHY_ACBDLR5 (0x015 << MPHY_SHIFT) +#define MPHY_ACBDLR6 (0x016 << MPHY_SHIFT) +#define MPHY_ACBDLR7 (0x017 << MPHY_SHIFT) +#define MPHY_ACBDLR8 (0x018 << MPHY_SHIFT) +#define MPHY_ACBDLR9 (0x019 << MPHY_SHIFT) +#define MPHY_ACIOCR0 (0x01A << MPHY_SHIFT) +#define MPHY_ACIOCR1 (0x01B << MPHY_SHIFT) +#define MPHY_ACIOCR2 (0x01C << MPHY_SHIFT) +#define MPHY_ACIOCR3 (0x01D << MPHY_SHIFT) +#define MPHY_ACIOCR4 (0x01E << MPHY_SHIFT) +#define MPHY_ACIOCR5 (0x01F << MPHY_SHIFT) +#define MPHY_DXCCR (0x020 << MPHY_SHIFT) +#define MPHY_DSGCR (0x021 << MPHY_SHIFT) +#define MPHY_DCR (0x022 << MPHY_SHIFT) +#define MPHY_DTPR0 (0x023 << MPHY_SHIFT) +#define MPHY_DTPR1 (0x024 << MPHY_SHIFT) +#define MPHY_DTPR2 (0x025 << MPHY_SHIFT) +#define MPHY_DTPR3 (0x026 << MPHY_SHIFT) +#define MPHY_MR0 (0x027 << MPHY_SHIFT) +#define MPHY_MR1 (0x028 << MPHY_SHIFT) +#define MPHY_MR2 (0x029 << MPHY_SHIFT) +#define MPHY_MR3 (0x02A << MPHY_SHIFT) +#define MPHY_ODTCR (0x02B << MPHY_SHIFT) +#define MPHY_DTCR (0x02C << MPHY_SHIFT) +#define MPHY_DTCR_RANKEN_SHIFT 24 /* Rank Enable */ +#define MPHY_DTCR_RANKEN_MASK (0xf << (MPHY_DTCR_RANKEN_SHIFT)) +#define MPHY_DTAR0 (0x02D << MPHY_SHIFT) +#define MPHY_DTAR1 (0x02E << MPHY_SHIFT) +#define MPHY_DTAR2 (0x02F << MPHY_SHIFT) +#define MPHY_DTAR3 (0x030 << MPHY_SHIFT) +#define MPHY_DTDR0 (0x031 << MPHY_SHIFT) +#define MPHY_DTDR1 (0x032 << MPHY_SHIFT) +#define MPHY_DTEDR0 (0x033 << MPHY_SHIFT) +#define MPHY_DTEDR1 (0x034 << MPHY_SHIFT) +#define MPHY_ZQCR (0x090 << MPHY_SHIFT) +#define MPHY_ZQCR_AVGEN BIT(16) /* Average Algorithm */ +#define MPHY_ZQCR_FORCE_ZCAL_VT_UPDATE BIT(27) /* force VT update */ /* ZQ */ -#define DMPHY_ZQ_BASE (0x091 << DMPHY_SHIFT) -#define DMPHY_ZQ_STRIDE (0x004 << DMPHY_SHIFT) -#define DMPHY_ZQ_PR (0x000 << DMPHY_SHIFT) -#define DMPHY_ZQ_DR (0x001 << DMPHY_SHIFT) -#define DMPHY_ZQ_SR (0x002 << DMPHY_SHIFT) +#define MPHY_ZQ_BASE (0x091 << MPHY_SHIFT) +#define MPHY_ZQ_STRIDE (0x004 << MPHY_SHIFT) +#define MPHY_ZQ_PR (0x000 << MPHY_SHIFT) +#define MPHY_ZQ_DR (0x001 << MPHY_SHIFT) +#define MPHY_ZQ_SR (0x002 << MPHY_SHIFT) /* DATX8 */ -#define DMPHY_DX_BASE (0x0A0 << DMPHY_SHIFT) -#define DMPHY_DX_STRIDE (0x020 << DMPHY_SHIFT) -#define DMPHY_DX_GCR0 (0x000 << DMPHY_SHIFT) -#define DMPHY_DX_GCR0_WLRKEN_SHIFT 26 /* Write Level Rank Enable */ -#define DMPHY_DX_GCR0_WLRKEN_MASK (0xf << (DMPHY_DX_GCR0_WLRKEN_SHIFT)) -#define DMPHY_DX_GCR1 (0x001 << DMPHY_SHIFT) -#define DMPHY_DX_GCR2 (0x002 << DMPHY_SHIFT) -#define DMPHY_DX_GCR3 (0x003 << DMPHY_SHIFT) -#define DMPHY_DX_GSR0 (0x004 << DMPHY_SHIFT) -#define DMPHY_DX_GSR1 (0x005 << DMPHY_SHIFT) -#define DMPHY_DX_GSR2 (0x006 << DMPHY_SHIFT) -#define DMPHY_DX_BDLR0 (0x007 << DMPHY_SHIFT) -#define DMPHY_DX_BDLR1 (0x008 << DMPHY_SHIFT) -#define DMPHY_DX_BDLR2 (0x009 << DMPHY_SHIFT) -#define DMPHY_DX_BDLR3 (0x00A << DMPHY_SHIFT) -#define DMPHY_DX_BDLR4 (0x00B << DMPHY_SHIFT) -#define DMPHY_DX_BDLR5 (0x00C << DMPHY_SHIFT) -#define DMPHY_DX_BDLR6 (0x00D << DMPHY_SHIFT) -#define DMPHY_DX_LCDLR0 (0x00E << DMPHY_SHIFT) -#define DMPHY_DX_LCDLR1 (0x00F << DMPHY_SHIFT) -#define DMPHY_DX_LCDLR2 (0x010 << DMPHY_SHIFT) -#define DMPHY_DX_MDLR (0x011 << DMPHY_SHIFT) -#define DMPHY_DX_GTR (0x012 << DMPHY_SHIFT) +#define MPHY_DX_BASE (0x0A0 << MPHY_SHIFT) +#define MPHY_DX_STRIDE (0x020 << MPHY_SHIFT) +#define MPHY_DX_GCR0 (0x000 << MPHY_SHIFT) +#define MPHY_DX_GCR0_WLRKEN_SHIFT 26 /* Write Level Rank Enable */ +#define MPHY_DX_GCR0_WLRKEN_MASK (0xf << (MPHY_DX_GCR0_WLRKEN_SHIFT)) +#define MPHY_DX_GCR1 (0x001 << MPHY_SHIFT) +#define MPHY_DX_GCR2 (0x002 << MPHY_SHIFT) +#define MPHY_DX_GCR3 (0x003 << MPHY_SHIFT) +#define MPHY_DX_GSR0 (0x004 << MPHY_SHIFT) +#define MPHY_DX_GSR1 (0x005 << MPHY_SHIFT) +#define MPHY_DX_GSR2 (0x006 << MPHY_SHIFT) +#define MPHY_DX_BDLR0 (0x007 << MPHY_SHIFT) +#define MPHY_DX_BDLR1 (0x008 << MPHY_SHIFT) +#define MPHY_DX_BDLR2 (0x009 << MPHY_SHIFT) +#define MPHY_DX_BDLR3 (0x00A << MPHY_SHIFT) +#define MPHY_DX_BDLR4 (0x00B << MPHY_SHIFT) +#define MPHY_DX_BDLR5 (0x00C << MPHY_SHIFT) +#define MPHY_DX_BDLR6 (0x00D << MPHY_SHIFT) +#define MPHY_DX_LCDLR0 (0x00E << MPHY_SHIFT) +#define MPHY_DX_LCDLR1 (0x00F << MPHY_SHIFT) +#define MPHY_DX_LCDLR2 (0x010 << MPHY_SHIFT) +#define MPHY_DX_MDLR (0x011 << MPHY_SHIFT) +#define MPHY_DX_GTR (0x012 << MPHY_SHIFT) -#endif /* ARCH_DDRMPHY_REGS_H */ +#endif /* UNIPHIER_DDRMPHY_REGS_H */ diff --git a/arch/arm/mach-uniphier/dram/umc-pxs2.c b/arch/arm/mach-uniphier/dram/umc-pxs2.c index 9aeda64ef1..05a62de45a 100644 --- a/arch/arm/mach-uniphier/dram/umc-pxs2.c +++ b/arch/arm/mach-uniphier/dram/umc-pxs2.c @@ -33,6 +33,7 @@ enum dram_size { DRAM_SZ_NR, }; +/* PHY */ static u32 ddrphy_pgcr2[DRAM_FREQ_NR] = {0x00FC7E5D, 0x00FC90AB}; static u32 ddrphy_ptr0[DRAM_FREQ_NR] = {0x0EA09205, 0x10C0A6C6}; static u32 ddrphy_ptr1[DRAM_FREQ_NR] = {0x0DAC041B, 0x0FA104B1}; @@ -48,23 +49,6 @@ static u32 ddrphy_mr2[DRAM_FREQ_NR] = {0x000002a0, 0x000002a8}; /* dependent on package and board design */ static u32 ddrphy_acbdlr0[DRAM_CH_NR] = {0x0000000c, 0x0000000c, 0x00000009}; -static u32 umc_cmdctla[DRAM_FREQ_NR] = {0x66DD131D, 0x77EE1722}; -/* - * The ch2 is a different generation UMC core. - * The register spec is different, unfortunately. - */ -static u32 umc_cmdctlb_ch01[DRAM_FREQ_NR] = {0x13E87C44, 0x18F88C44}; -static u32 umc_cmdctlb_ch2[DRAM_FREQ_NR] = {0x19E8DC44, 0x1EF8EC44}; -static u32 umc_spcctla[DRAM_FREQ_NR][DRAM_SZ_NR] = { - {0x004A071D, 0x0078071D}, - {0x0055081E, 0x0089081E}, -}; - -static u32 umc_spcctlb[] = {0x00FF000A, 0x00FF000B}; -/* The ch2 is different for some reason only hardware guys know... */ -static u32 umc_flowctla_ch01[] = {0x0800001E, 0x08000022}; -static u32 umc_flowctla_ch2[] = {0x0800001E, 0x0800001E}; - /* DDR multiPHY */ static inline int ddrphy_get_rank(int dx) { @@ -75,14 +59,14 @@ static void ddrphy_fifo_reset(void __iomem *phy_base) { u32 tmp; - tmp = readl(phy_base + DMPHY_PGCR0); - tmp &= ~DMPHY_PGCR0_PHYFRST; - writel(tmp, phy_base + DMPHY_PGCR0); + tmp = readl(phy_base + MPHY_PGCR0); + tmp &= ~MPHY_PGCR0_PHYFRST; + writel(tmp, phy_base + MPHY_PGCR0); udelay(1); - tmp |= DMPHY_PGCR0_PHYFRST; - writel(tmp, phy_base + DMPHY_PGCR0); + tmp |= MPHY_PGCR0_PHYFRST; + writel(tmp, phy_base + MPHY_PGCR0); udelay(1); } @@ -91,17 +75,17 @@ static void ddrphy_vt_ctrl(void __iomem *phy_base, int enable) { u32 tmp; - tmp = readl(phy_base + DMPHY_PGCR1); + tmp = readl(phy_base + MPHY_PGCR1); if (enable) - tmp &= ~DMPHY_PGCR1_INHVT; + tmp &= ~MPHY_PGCR1_INHVT; else - tmp |= DMPHY_PGCR1_INHVT; + tmp |= MPHY_PGCR1_INHVT; - writel(tmp, phy_base + DMPHY_PGCR1); + writel(tmp, phy_base + MPHY_PGCR1); if (!enable) { - while (!(readl(phy_base + DMPHY_PGSR1) & DMPHY_PGSR1_VTSTOP)) + while (!(readl(phy_base + MPHY_PGSR1) & MPHY_PGSR1_VTSTOP)) cpu_relax(); } } @@ -110,18 +94,18 @@ static void ddrphy_dqs_delay_fixup(void __iomem *phy_base, int nr_dx, int step) { int dx; u32 lcdlr1, rdqsd; - void __iomem *dx_base = phy_base + DMPHY_DX_BASE; + void __iomem *dx_base = phy_base + MPHY_DX_BASE; ddrphy_vt_ctrl(phy_base, 0); for (dx = 0; dx < nr_dx; dx++) { - lcdlr1 = readl(dx_base + DMPHY_DX_LCDLR1); + lcdlr1 = readl(dx_base + MPHY_DX_LCDLR1); rdqsd = (lcdlr1 >> 8) & 0xff; rdqsd = clamp(rdqsd + step, 0U, 0xffU); lcdlr1 = (lcdlr1 & ~(0xff << 8)) | (rdqsd << 8); - writel(lcdlr1, dx_base + DMPHY_DX_LCDLR1); - readl(dx_base + DMPHY_DX_LCDLR1); /* relax */ - dx_base += DMPHY_DX_STRIDE; + writel(lcdlr1, dx_base + MPHY_DX_LCDLR1); + readl(dx_base + MPHY_DX_LCDLR1); /* relax */ + dx_base += MPHY_DX_STRIDE; } ddrphy_vt_ctrl(phy_base, 1); @@ -129,14 +113,14 @@ static void ddrphy_dqs_delay_fixup(void __iomem *phy_base, int nr_dx, int step) static int ddrphy_get_system_latency(void __iomem *phy_base, int width) { - void __iomem *dx_base = phy_base + DMPHY_DX_BASE; + void __iomem *dx_base = phy_base + MPHY_DX_BASE; const int nr_dx = width / 8; int dx, rank; u32 gtr; int dgsl, dgsl_min = INT_MAX, dgsl_max = 0; for (dx = 0; dx < nr_dx; dx++) { - gtr = readl(dx_base + DMPHY_DX_GTR); + gtr = readl(dx_base + MPHY_DX_GTR); for (rank = 0; rank < 4; rank++) { dgsl = gtr & 0x7; /* if dgsl is zero, this rank was not trained. skip. */ @@ -146,7 +130,7 @@ static int ddrphy_get_system_latency(void __iomem *phy_base, int width) } gtr >>= 3; } - dx_base += DMPHY_DX_STRIDE; + dx_base += MPHY_DX_STRIDE; } if (dgsl_min != dgsl_max) @@ -165,86 +149,86 @@ static void ddrphy_init(void __iomem *phy_base, enum dram_freq freq, int width, nr_dx = width / 8; - writel(DMPHY_PIR_ZCALBYP, phy_base + DMPHY_PIR); + writel(MPHY_PIR_ZCALBYP, phy_base + MPHY_PIR); /* * Disable RGLVT bit (Read DQS Gating LCDL Delay VT Compensation) * to avoid read error issue. */ - writel(0x07d81e37, phy_base + DMPHY_PGCR0); - writel(0x0200c4e0, phy_base + DMPHY_PGCR1); + writel(0x07d81e37, phy_base + MPHY_PGCR0); + writel(0x0200c4e0, phy_base + MPHY_PGCR1); tmp = ddrphy_pgcr2[freq]; if (width >= 32) - tmp |= DMPHY_PGCR2_DUALCHN | DMPHY_PGCR2_ACPDDC; - writel(tmp, phy_base + DMPHY_PGCR2); + tmp |= MPHY_PGCR2_DUALCHN | MPHY_PGCR2_ACPDDC; + writel(tmp, phy_base + MPHY_PGCR2); - writel(ddrphy_ptr0[freq], phy_base + DMPHY_PTR0); - writel(ddrphy_ptr1[freq], phy_base + DMPHY_PTR1); - writel(0x00083def, phy_base + DMPHY_PTR2); - writel(ddrphy_ptr3[freq], phy_base + DMPHY_PTR3); - writel(ddrphy_ptr4[freq], phy_base + DMPHY_PTR4); + writel(ddrphy_ptr0[freq], phy_base + MPHY_PTR0); + writel(ddrphy_ptr1[freq], phy_base + MPHY_PTR1); + writel(0x00083def, phy_base + MPHY_PTR2); + writel(ddrphy_ptr3[freq], phy_base + MPHY_PTR3); + writel(ddrphy_ptr4[freq], phy_base + MPHY_PTR4); - writel(ddrphy_acbdlr0[ch], phy_base + DMPHY_ACBDLR0); + writel(ddrphy_acbdlr0[ch], phy_base + MPHY_ACBDLR0); - writel(0x55555555, phy_base + DMPHY_ACIOCR1); - writel(0x00000000, phy_base + DMPHY_ACIOCR2); - writel(0x55555555, phy_base + DMPHY_ACIOCR3); - writel(0x00000000, phy_base + DMPHY_ACIOCR4); - writel(0x00000055, phy_base + DMPHY_ACIOCR5); - writel(0x00181aa4, phy_base + DMPHY_DXCCR); + writel(0x55555555, phy_base + MPHY_ACIOCR1); + writel(0x00000000, phy_base + MPHY_ACIOCR2); + writel(0x55555555, phy_base + MPHY_ACIOCR3); + writel(0x00000000, phy_base + MPHY_ACIOCR4); + writel(0x00000055, phy_base + MPHY_ACIOCR5); + writel(0x00181aa4, phy_base + MPHY_DXCCR); - writel(0x0024641e, phy_base + DMPHY_DSGCR); - writel(0x0000040b, phy_base + DMPHY_DCR); - writel(ddrphy_dtpr0[freq], phy_base + DMPHY_DTPR0); - writel(ddrphy_dtpr1[freq], phy_base + DMPHY_DTPR1); - writel(ddrphy_dtpr2[freq], phy_base + DMPHY_DTPR2); - writel(ddrphy_dtpr3[freq], phy_base + DMPHY_DTPR3); - writel(ddrphy_mr0[freq], phy_base + DMPHY_MR0); - writel(0x00000006, phy_base + DMPHY_MR1); - writel(ddrphy_mr2[freq], phy_base + DMPHY_MR2); - writel(0x00000000, phy_base + DMPHY_MR3); + writel(0x0024641e, phy_base + MPHY_DSGCR); + writel(0x0000040b, phy_base + MPHY_DCR); + writel(ddrphy_dtpr0[freq], phy_base + MPHY_DTPR0); + writel(ddrphy_dtpr1[freq], phy_base + MPHY_DTPR1); + writel(ddrphy_dtpr2[freq], phy_base + MPHY_DTPR2); + writel(ddrphy_dtpr3[freq], phy_base + MPHY_DTPR3); + writel(ddrphy_mr0[freq], phy_base + MPHY_MR0); + writel(0x00000006, phy_base + MPHY_MR1); + writel(ddrphy_mr2[freq], phy_base + MPHY_MR2); + writel(0x00000000, phy_base + MPHY_MR3); tmp = 0; for (dx = 0; dx < nr_dx; dx++) - tmp |= BIT(DMPHY_DTCR_RANKEN_SHIFT + ddrphy_get_rank(dx)); - writel(0x90003087 | tmp, phy_base + DMPHY_DTCR); + tmp |= BIT(MPHY_DTCR_RANKEN_SHIFT + ddrphy_get_rank(dx)); + writel(0x90003087 | tmp, phy_base + MPHY_DTCR); - writel(0x00000000, phy_base + DMPHY_DTAR0); - writel(0x00000008, phy_base + DMPHY_DTAR1); - writel(0x00000010, phy_base + DMPHY_DTAR2); - writel(0x00000018, phy_base + DMPHY_DTAR3); - writel(0xdd22ee11, phy_base + DMPHY_DTDR0); - writel(0x7788bb44, phy_base + DMPHY_DTDR1); + writel(0x00000000, phy_base + MPHY_DTAR0); + writel(0x00000008, phy_base + MPHY_DTAR1); + writel(0x00000010, phy_base + MPHY_DTAR2); + writel(0x00000018, phy_base + MPHY_DTAR3); + writel(0xdd22ee11, phy_base + MPHY_DTDR0); + writel(0x7788bb44, phy_base + MPHY_DTDR1); /* impedance control settings */ - writel(0x04048900, phy_base + DMPHY_ZQCR); + writel(0x04048900, phy_base + MPHY_ZQCR); - zq_base = phy_base + DMPHY_ZQ_BASE; + zq_base = phy_base + MPHY_ZQ_BASE; for (zq = 0; zq < 4; zq++) { /* * board-dependent * PXS2: CH0ZQ0=0x5B, CH1ZQ0=0x5B, CH2ZQ0=0x59, others=0x5D */ - writel(0x0007BB5D, zq_base + DMPHY_ZQ_PR); - zq_base += DMPHY_ZQ_STRIDE; + writel(0x0007BB5D, zq_base + MPHY_ZQ_PR); + zq_base += MPHY_ZQ_STRIDE; } /* DATX8 settings */ - dx_base = phy_base + DMPHY_DX_BASE; + dx_base = phy_base + MPHY_DX_BASE; for (dx = 0; dx < 4; dx++) { - tmp = readl(dx_base + DMPHY_DX_GCR0); - tmp &= ~DMPHY_DX_GCR0_WLRKEN_MASK; - tmp |= BIT(DMPHY_DX_GCR0_WLRKEN_SHIFT + ddrphy_get_rank(dx)) & - DMPHY_DX_GCR0_WLRKEN_MASK; - writel(tmp, dx_base + DMPHY_DX_GCR0); + tmp = readl(dx_base + MPHY_DX_GCR0); + tmp &= ~MPHY_DX_GCR0_WLRKEN_MASK; + tmp |= BIT(MPHY_DX_GCR0_WLRKEN_SHIFT + ddrphy_get_rank(dx)) & + MPHY_DX_GCR0_WLRKEN_MASK; + writel(tmp, dx_base + MPHY_DX_GCR0); - writel(0x00000000, dx_base + DMPHY_DX_GCR1); - writel(0x00000000, dx_base + DMPHY_DX_GCR2); - writel(0x00000000, dx_base + DMPHY_DX_GCR3); - dx_base += DMPHY_DX_STRIDE; + writel(0x00000000, dx_base + MPHY_DX_GCR1); + writel(0x00000000, dx_base + MPHY_DX_GCR2); + writel(0x00000000, dx_base + MPHY_DX_GCR3); + dx_base += MPHY_DX_STRIDE; } - while (!(readl(phy_base + DMPHY_PGSR0) & DMPHY_PGSR0_IDONE)) + while (!(readl(phy_base + MPHY_PGSR0) & MPHY_PGSR0_IDONE)) cpu_relax(); ddrphy_dqs_delay_fixup(phy_base, nr_dx, -4); @@ -260,9 +244,9 @@ struct ddrphy_init_sequence { static const struct ddrphy_init_sequence impedance_calibration_sequence[] = { { "Impedance Calibration", - DMPHY_PIR_ZCAL, - DMPHY_PGSR0_ZCDONE, - DMPHY_PGSR0_ZCERR, + MPHY_PIR_ZCAL, + MPHY_PGSR0_ZCDONE, + MPHY_PGSR0_ZCERR, }, { /* sentinel */ } }; @@ -270,8 +254,8 @@ static const struct ddrphy_init_sequence impedance_calibration_sequence[] = { static const struct ddrphy_init_sequence dram_init_sequence[] = { { "DRAM Initialization", - DMPHY_PIR_DRAMRST | DMPHY_PIR_DRAMINIT, - DMPHY_PGSR0_DIDONE, + MPHY_PIR_DRAMRST | MPHY_PIR_DRAMINIT, + MPHY_PGSR0_DIDONE, 0, }, { /* sentinel */ } @@ -280,45 +264,45 @@ static const struct ddrphy_init_sequence dram_init_sequence[] = { static const struct ddrphy_init_sequence training_sequence[] = { { "Write Leveling", - DMPHY_PIR_WL, - DMPHY_PGSR0_WLDONE, - DMPHY_PGSR0_WLERR, + MPHY_PIR_WL, + MPHY_PGSR0_WLDONE, + MPHY_PGSR0_WLERR, }, { "Read DQS Gate Training", - DMPHY_PIR_QSGATE, - DMPHY_PGSR0_QSGDONE, - DMPHY_PGSR0_QSGERR, + MPHY_PIR_QSGATE, + MPHY_PGSR0_QSGDONE, + MPHY_PGSR0_QSGERR, }, { "Write Leveling Adjustment", - DMPHY_PIR_WLADJ, - DMPHY_PGSR0_WLADONE, - DMPHY_PGSR0_WLAERR, + MPHY_PIR_WLADJ, + MPHY_PGSR0_WLADONE, + MPHY_PGSR0_WLAERR, }, { "Read Bit Deskew", - DMPHY_PIR_RDDSKW, - DMPHY_PGSR0_RDDONE, - DMPHY_PGSR0_RDERR, + MPHY_PIR_RDDSKW, + MPHY_PGSR0_RDDONE, + MPHY_PGSR0_RDERR, }, { "Write Bit Deskew", - DMPHY_PIR_WRDSKW, - DMPHY_PGSR0_WDDONE, - DMPHY_PGSR0_WDERR, + MPHY_PIR_WRDSKW, + MPHY_PGSR0_WDDONE, + MPHY_PGSR0_WDERR, }, { "Read Eye Training", - DMPHY_PIR_RDEYE, - DMPHY_PGSR0_REDONE, - DMPHY_PGSR0_REERR, + MPHY_PIR_RDEYE, + MPHY_PGSR0_REDONE, + MPHY_PGSR0_REERR, }, { "Write Eye Training", - DMPHY_PIR_WREYE, - DMPHY_PGSR0_WEDONE, - DMPHY_PGSR0_WEERR, + MPHY_PIR_WREYE, + MPHY_PGSR0_WEDONE, + MPHY_PGSR0_WEERR, }, { /* sentinel */ } }; @@ -328,8 +312,8 @@ static int __ddrphy_training(void __iomem *phy_base, { const struct ddrphy_init_sequence *s; u32 pgsr0; - u32 init_flag = DMPHY_PIR_INIT; - u32 done_flag = DMPHY_PGSR0_IDONE; + u32 init_flag = MPHY_PIR_INIT; + u32 done_flag = MPHY_PGSR0_IDONE; int timeout = 50000; /* 50 msec is long enough */ #ifdef DISPLAY_ELAPSED_TIME ulong start = get_timer(0); @@ -340,7 +324,7 @@ static int __ddrphy_training(void __iomem *phy_base, done_flag |= s->done_flag; } - writel(init_flag, phy_base + DMPHY_PIR); + writel(init_flag, phy_base + MPHY_PIR); do { if (--timeout < 0) { @@ -349,7 +333,7 @@ static int __ddrphy_training(void __iomem *phy_base, return -ETIMEDOUT; } udelay(1); - pgsr0 = readl(phy_base + DMPHY_PGSR0); + pgsr0 = readl(phy_base + MPHY_PGSR0); } while ((pgsr0 & done_flag) != done_flag); for (s = seq; s->description; s++) { @@ -384,12 +368,12 @@ static int ddrphy_impedance_calibration(void __iomem *phy_base) udelay(1); /* reflect ZQ settings and enable average algorithm*/ - tmp = readl(phy_base + DMPHY_ZQCR); - tmp |= DMPHY_ZQCR_FORCE_ZCAL_VT_UPDATE; - writel(tmp, phy_base + DMPHY_ZQCR); - tmp &= ~DMPHY_ZQCR_FORCE_ZCAL_VT_UPDATE; - tmp |= DMPHY_ZQCR_AVGEN; - writel(tmp, phy_base + DMPHY_ZQCR); + tmp = readl(phy_base + MPHY_ZQCR); + tmp |= MPHY_ZQCR_FORCE_ZCAL_VT_UPDATE; + writel(tmp, phy_base + MPHY_ZQCR); + tmp &= ~MPHY_ZQCR_FORCE_ZCAL_VT_UPDATE; + tmp |= MPHY_ZQCR_AVGEN; + writel(tmp, phy_base + MPHY_ZQCR); return 0; } @@ -405,6 +389,23 @@ static int ddrphy_training(void __iomem *phy_base) } /* UMC */ +static u32 umc_cmdctla[DRAM_FREQ_NR] = {0x66DD131D, 0x77EE1722}; +/* + * The ch2 is a different generation UMC core. + * The register spec is different, unfortunately. + */ +static u32 umc_cmdctlb_ch01[DRAM_FREQ_NR] = {0x13E87C44, 0x18F88C44}; +static u32 umc_cmdctlb_ch2[DRAM_FREQ_NR] = {0x19E8DC44, 0x1EF8EC44}; +static u32 umc_spcctla[DRAM_FREQ_NR][DRAM_SZ_NR] = { + {0x004A071D, 0x0078071D}, + {0x0055081E, 0x0089081E}, +}; + +static u32 umc_spcctlb[] = {0x00FF000A, 0x00FF000B}; +/* The ch2 is different for some reason only hardware guys know... */ +static u32 umc_flowctla_ch01[] = {0x0800001E, 0x08000022}; +static u32 umc_flowctla_ch2[] = {0x0800001E, 0x0800001E}; + static void umc_set_system_latency(void __iomem *dc_base, int phy_latency) { u32 val; From 513cfaccc8ee166ac2e29e380f86173483ae71c8 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:47 +0900 Subject: [PATCH 07/16] ARM: uniphier: refactor cmd_ddrmphy Make it look like cmd_ddrphy. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/dram/cmd_ddrmphy.c | 189 +++++++++++++--------- 1 file changed, 109 insertions(+), 80 deletions(-) diff --git a/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c b/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c index 4e6616208c..873dad229a 100644 --- a/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c +++ b/arch/arm/mach-uniphier/dram/cmd_ddrmphy.c @@ -1,13 +1,15 @@ /* - * Copyright (C) 2015 Masahiro Yamada + * Copyright (C) 2015-2017 Socionext Inc. + * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include -#include "../init.h" +#include "../soc-info.h" #include "ddrmphy-regs.h" /* Select either decimal or hexadecimal */ @@ -19,24 +21,41 @@ /* field separator */ #define FS " " -static void __iomem *get_phy_base(int ch) -{ - return (void __iomem *)(0x5b830000 + ch * 0x00200000); -} +#define ptr_to_uint(p) ((unsigned int)(unsigned long)(p)) -static int get_nr_ch(void) -{ - const struct uniphier_board_data *bd = uniphier_get_board_param(); +#define UNIPHIER_MAX_NR_DDRMPHY 3 - return bd->dram_ch[2].size ? 3 : 2; -} +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 int get_nr_datx8(int ch) -{ - const struct uniphier_board_data *bd = uniphier_get_board_param(); - - return bd->dram_ch[ch].width / 8; -} +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 +66,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; + void __iomem *phy_base, *dx_base; + int phy, dx; - nr_ch = get_nr_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 (ch = 0; ch < nr_ch; ch++) { - 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); + 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 +133,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 +154,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 +177,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 +199,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 +216,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 +236,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 +278,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" From 9c572684b4bbf776954420fd34f8ec707f631d67 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:48 +0900 Subject: [PATCH 08/16] ARM: uniphier: compile board data only for SPL Now U-Boot proper need not get the uniphier_boards array. Compile it only for SPL. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-uniphier/Makefile b/arch/arm/mach-uniphier/Makefile index abfdccc02a..166b41f217 100644 --- a/arch/arm/mach-uniphier/Makefile +++ b/arch/arm/mach-uniphier/Makefile @@ -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/ From 3e0cfaa05d38779a0118756b3cbf9bf7a5412eb5 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:49 +0900 Subject: [PATCH 09/16] ARM: uniphier: collect SPL CONFIG symbols to the bottom of header 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. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index a6deda8425..90876e3f10 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -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 @@ -240,6 +239,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) || \ @@ -257,9 +261,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 @@ -273,7 +274,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 @@ -283,6 +283,5 @@ #define CONFIG_SPL_BSS_START_ADDR 0x30016000 #endif #define CONFIG_SPL_BSS_MAX_SIZE 0x2000 -#endif #endif /* __CONFIG_UNIPHIER_COMMON_H__ */ From 99b8517037f212a3cf4bf75ed99fa877fe4e6d9d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:50 +0900 Subject: [PATCH 10/16] ARM: uniphier: use Image.gz instead Image for booting ARM64 Linux 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. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 90876e3f10..5507f84f71 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -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 *----------------------------------------------------------------------*/ @@ -166,46 +170,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" From c0df1fafd764aa41e1b5762af377c7dea296e600 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:51 +0900 Subject: [PATCH 11/16] ARM: uniphier: set initrd_high environment to skip initrd relocation 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. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 5507f84f71..d6dd5eca3a 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -202,8 +202,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 &&" \ @@ -222,6 +226,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 &&" \ From 0b93e3de1e5ec9c7db7ffcf33bc9dcaddff91109 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:52 +0900 Subject: [PATCH 12/16] ARM: uniphier: change the offset to environment storage area 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. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index d6dd5eca3a..817bf45f8f 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -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) */ From c0efc3140e75e3ffd6127a5aec97b75347ec7417 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:53 +0900 Subject: [PATCH 13/16] ARM: uniphier: change CONFIG_SPL_PAD_TO to 128KB 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. Signed-off-by: Masahiro Yamada --- common/spl/Kconfig | 3 +-- include/configs/uniphier.h | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index b1aa1483c9..b2ba492abd 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -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 || \ diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 817bf45f8f..49309c967b 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -230,19 +230,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 @@ -282,14 +282,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) @@ -297,4 +301,6 @@ #endif #define CONFIG_SPL_BSS_MAX_SIZE 0x2000 +#define CONFIG_SPL_PAD_TO 0x20000 + #endif /* __CONFIG_UNIPHIER_COMMON_H__ */ From b7b4303642af1cf3a2c58befaa8e8944b9fbb3c9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:54 +0900 Subject: [PATCH 14/16] ARM: uniphier: make update commands more flexible for ATF 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. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 49309c967b..62c3daff14 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -146,6 +146,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" @@ -229,20 +240,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 From 800acb850ebffd91c3a51f426897566ed0441262 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:55 +0900 Subject: [PATCH 15/16] i2c: uniphier(-f): remove unneeded #include This include is unnecessary for low-level drivers. Signed-off-by: Masahiro Yamada --- drivers/i2c/i2c-uniphier-f.c | 1 - drivers/i2c/i2c-uniphier.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c index 8bfa916294..e212c13e69 100644 --- a/drivers/i2c/i2c-uniphier-f.c +++ b/drivers/i2c/i2c-uniphier-f.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c index f391f11e93..73575e9895 100644 --- a/drivers/i2c/i2c-uniphier.c +++ b/drivers/i2c/i2c-uniphier.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include From 68578582ab956691ecce174057b52600f52d7d09 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 28 Jan 2017 06:53:56 +0900 Subject: [PATCH 16/16] i2c: uniphier-f: use readl_poll_timeout() to poll registers 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 --- drivers/i2c/i2c-uniphier-f.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c index e212c13e69..9f0df599a0 100644 --- a/drivers/i2c/i2c-uniphier-f.c +++ b/drivers/i2c/i2c-uniphier-f.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -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; + int ret; - do { - udelay(1); - irq = readl(&dev->regs->intr); - } while (!(irq & flags) && wait--); - - 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");