diff options
Diffstat (limited to 'arch/arm')
40 files changed, 1091 insertions, 166 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2b0d2c9..5eb1d03 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -800,6 +800,7 @@ config ARCH_UNIPHIER bool "Panasonic UniPhier platform" select CPU_V7 select SUPPORT_SPL + select SPL select OF_CONTROL if !SPL_BUILD endchoice diff --git a/arch/arm/cpu/armv7/bcm281xx/Makefile b/arch/arm/cpu/armv7/bcm281xx/Makefile index bd867a2..f24aeb3 100644 --- a/arch/arm/cpu/armv7/bcm281xx/Makefile +++ b/arch/arm/cpu/armv7/bcm281xx/Makefile @@ -10,3 +10,4 @@ obj-y += clk-bcm281xx.o obj-y += clk-sdio.o obj-y += clk-bsc.o obj-$(CONFIG_BCM_SF2_ETH) += clk-eth.o +obj-y += clk-usb-otg.o diff --git a/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c b/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c index d16b99f..7e25255 100644 --- a/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c +++ b/arch/arm/cpu/armv7/bcm281xx/clk-bcm281xx.c @@ -209,6 +209,10 @@ static struct peri_clk_data sdio4_sleep_data = { .gate = SW_ONLY_GATE(0x0360, 20, 4), }; +static struct bus_clk_data usb_otg_ahb_data = { + .gate = HW_SW_GATE_AUTO(0x0348, 16, 0, 1), +}; + static struct bus_clk_data sdio1_ahb_data = { .gate = HW_SW_GATE_AUTO(0x0358, 16, 0, 1), }; @@ -331,6 +335,17 @@ static struct ccu_clock esub_ccu_clk = { */ /* KPM bus clocks */ +static struct bus_clock usb_otg_ahb_clk = { + .clk = { + .name = "usb_otg_ahb_clk", + .parent = &kpm_ccu_clk.clk, + .ops = &bus_clk_ops, + .ccu_clk_mgr_base = KONA_MST_CLK_BASE_ADDR, + }, + .freq_tbl = master_ahb_freq_tbl, + .data = &usb_otg_ahb_data, +}; + static struct bus_clock sdio1_ahb_clk = { .clk = { .name = "sdio1_ahb_clk", @@ -541,6 +556,7 @@ struct clk_lookup arch_clk_tbl[] = { CLK_LK(bsc2), CLK_LK(bsc3), /* Bus clocks */ + CLK_LK(usb_otg_ahb), CLK_LK(sdio1_ahb), CLK_LK(sdio2_ahb), CLK_LK(sdio3_ahb), diff --git a/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c b/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c new file mode 100644 index 0000000..1d7c5af --- /dev/null +++ b/arch/arm/cpu/armv7/bcm281xx/clk-usb-otg.c @@ -0,0 +1,27 @@ +/* + * Copyright 2014 Broadcom Corporation. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/errno.h> +#include <asm/arch/sysmap.h> +#include "clk-core.h" + +/* Enable appropriate clocks for the USB OTG port */ +int clk_usb_otg_enable(void *base) +{ + char *ahbstr; + + switch ((u32) base) { + case HSOTG_BASE_ADDR: + ahbstr = "usb_otg_ahb_clk"; + break; + default: + printf("%s: base 0x%p not found\n", __func__, base); + return -EINVAL; + } + + return clk_get_and_enable(ahbstr); +} diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig index f3eadb4..7fcb5d2 100644 --- a/arch/arm/cpu/armv7/exynos/Kconfig +++ b/arch/arm/cpu/armv7/exynos/Kconfig @@ -24,6 +24,10 @@ config TARGET_TRATS2 config TARGET_ODROID bool "Exynos4412 Odroid board" +config TARGET_ODROID_XU3 + bool "Exynos5422 Odroid board" + select OF_CONTROL + config TARGET_ARNDALE bool "Exynos5250 Arndale board" select CPU_V7_HAS_NONSEC diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 8fab135..b31c13b 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -848,6 +848,8 @@ static unsigned long exynos5420_get_mmc_clk(int dev_index) if (sel == 0x3) sclk = get_pll_clk(MPLL); + else if (sel == 0x4) + sclk = get_pll_clk(SPLL); else if (sel == 0x6) sclk = get_pll_clk(EPLL); else diff --git a/arch/arm/cpu/armv7/kona-common/clk-stubs.c b/arch/arm/cpu/armv7/kona-common/clk-stubs.c index 338e0e4..fa10802 100644 --- a/arch/arm/cpu/armv7/kona-common/clk-stubs.c +++ b/arch/arm/cpu/armv7/kona-common/clk-stubs.c @@ -19,3 +19,8 @@ int __weak clk_bsc_enable(void *base, u32 rate, u32 *actual_ratep) { return 0; } + +int __weak clk_usb_otg_enable(void *base) +{ + return 0; +} diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index 93a02ad..b6983e6 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -746,10 +746,11 @@ unsigned int mxc_get_clock(enum mxc_clock clk) case MXC_SATA_CLK: return get_ahb_clk(); default: + printf("Unsupported MXC CLK: %d\n", clk); break; } - return -1; + return 0; } /* diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c index 73cffd3..7873c38 100644 --- a/arch/arm/cpu/armv7/socfpga/misc.c +++ b/arch/arm/cpu/armv7/socfpga/misc.c @@ -9,6 +9,7 @@ #include <altera.h> #include <miiphy.h> #include <netdev.h> +#include <watchdog.h> #include <asm/arch/reset_manager.h> #include <asm/arch/system_manager.h> #include <asm/arch/dwmmc.h> @@ -150,14 +151,23 @@ static inline void socfpga_fpga_add(void) {} int arch_cpu_init(void) { +#ifdef CONFIG_HW_WATCHDOG + /* + * In case the watchdog is enabled, make sure to (re-)configure it + * so that the defined timeout is valid. Otherwise the SPL (Perloader) + * timeout value is still active which might too short for Linux + * booting. + */ + hw_watchdog_init(); +#else /* * If the HW watchdog is NOT enabled, make sure it is not running, * for example because it was enabled in the preloader. This might * trigger a watchdog-triggered reboot of Linux kernel later. */ -#ifndef CONFIG_HW_WATCHDOG socfpga_watchdog_reset(); #endif + return 0; } diff --git a/arch/arm/cpu/armv7/uniphier/Kconfig b/arch/arm/cpu/armv7/uniphier/Kconfig index 9760299..0556e4b 100644 --- a/arch/arm/cpu/armv7/uniphier/Kconfig +++ b/arch/arm/cpu/armv7/uniphier/Kconfig @@ -65,6 +65,13 @@ config DRAM_INIT bool default SPL_BUILD +config CMD_DDRPHY_DUMP + bool "Enable dump command of DDR PHY parameters" + depends on !SPL_BUILD + help + The command "ddrphy" shows the resulting parameters of DDR PHY + training; it is useful for the evaluation of DDR PHY training. + choice prompt "DDR3 Frequency select" depends on DRAM_INIT diff --git a/arch/arm/cpu/armv7/uniphier/Makefile b/arch/arm/cpu/armv7/uniphier/Makefile index 4a7b8a9..0546232 100644 --- a/arch/arm/cpu/armv7/uniphier/Makefile +++ b/arch/arm/cpu/armv7/uniphier/Makefile @@ -10,11 +10,13 @@ obj-y += reset.o obj-y += cache_uniphier.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += board_postclk_init.o obj-y += dram_init.o +obj-$(CONFIG_DRAM_INIT) += ddrphy_training.o obj-$(CONFIG_DISPLAY_CPUINFO) += cpu_info.o obj-$(CONFIG_BOARD_EARLY_INIT_R) += board_early_init_r.o obj-$(CONFIG_BOARD_LATE_INIT) += board_late_init.o obj-$(CONFIG_UNIPHIER_SMP) += smp.o obj-$(CONFIG_CMD_PINMON) += cmd_pinmon.o +obj-$(CONFIG_CMD_DDRPHY_DUMP) += cmd_ddrphy.o obj-y += board_common.o obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += support_card.o diff --git a/arch/arm/cpu/armv7/uniphier/cmd_ddrphy.c b/arch/arm/cpu/armv7/uniphier/cmd_ddrphy.c new file mode 100644 index 0000000..431d901 --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/cmd_ddrphy.c @@ -0,0 +1,229 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/ddrphy-regs.h> + +/* Select either decimal or hexadecimal */ +#if 1 +#define PRINTF_FORMAT "%2d" +#else +#define PRINTF_FORMAT "%02x" +#endif +/* field separator */ +#define FS " " + +static u32 read_bdl(struct ddrphy_datx8 __iomem *dx, int index) +{ + return (readl(&dx->bdlr[index / 5]) >> (index % 5 * 6)) & 0x3f; +} + +static void dump_loop(void (*callback)(struct ddrphy_datx8 __iomem *)) +{ + int ch, p, dx; + struct ddrphy __iomem *phy; + + for (ch = 0; ch < NR_DDRCH; ch++) { + for (p = 0; p < NR_DDRPHY_PER_CH; p++) { + phy = (struct ddrphy __iomem *)DDRPHY_BASE(ch, p); + + for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) { + printf("CH%dP%dDX%d:", ch, p, dx); + (*callback)(&phy->dx[dx]); + printf("\n"); + } + } + } +} + +static void __wbdl_dump(struct ddrphy_datx8 __iomem *dx) +{ + int i; + + for (i = 0; i < 10; i++) + printf(FS PRINTF_FORMAT, read_bdl(dx, i)); + + printf(FS "(+" PRINTF_FORMAT ")", readl(&dx->lcdlr[1]) & 0xff); +} + +void wbdl_dump(void) +{ + printf("\n--- Write Bit Delay Line ---\n"); + printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM DQS (WDQD)\n"); + + dump_loop(&__wbdl_dump); +} + +static void __rbdl_dump(struct ddrphy_datx8 __iomem *dx) +{ + int i; + + for (i = 15; i < 24; i++) + printf(FS PRINTF_FORMAT, read_bdl(dx, i)); + + printf(FS "(+" PRINTF_FORMAT ")", (readl(&dx->lcdlr[1]) >> 8) & 0xff); +} + +void rbdl_dump(void) +{ + printf("\n--- Read Bit Delay Line ---\n"); + printf(" DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM (RDQSD)\n"); + + dump_loop(&__rbdl_dump); +} + +static void __wld_dump(struct ddrphy_datx8 __iomem *dx) +{ + int rank; + u32 lcdlr0 = readl(&dx->lcdlr[0]); + u32 gtr = readl(&dx->gtr); + + for (rank = 0; rank < 4; rank++) { + u32 wld = (lcdlr0 >> (8 * rank)) & 0xff; /* Delay */ + u32 wlsl = (gtr >> (12 + 2 * rank)) & 0x3; /* System Latency */ + + printf(FS PRINTF_FORMAT "%sT", wld, + wlsl == 0 ? "-1" : wlsl == 1 ? "+0" : "+1"); + } +} + +void wld_dump(void) +{ + printf("\n--- Write Leveling Delay ---\n"); + printf(" Rank0 Rank1 Rank2 Rank3\n"); + + dump_loop(&__wld_dump); +} + +static void __dqsgd_dump(struct ddrphy_datx8 __iomem *dx) +{ + int rank; + u32 lcdlr2 = readl(&dx->lcdlr[2]); + u32 gtr = readl(&dx->gtr); + + for (rank = 0; rank < 4; rank++) { + u32 dqsgd = (lcdlr2 >> (8 * rank)) & 0xff; /* Delay */ + u32 dgsl = (gtr >> (3 * rank)) & 0x7; /* System Latency */ + + printf(FS PRINTF_FORMAT "+%dT", dqsgd, dgsl); + } +} + +void dqsgd_dump(void) +{ + printf("\n--- DQS Gating Delay ---\n"); + printf(" Rank0 Rank1 Rank2 Rank3\n"); + + dump_loop(&__dqsgd_dump); +} + +static void __mdl_dump(struct ddrphy_datx8 __iomem *dx) +{ + int i; + u32 mdl = readl(&dx->mdlr); + for (i = 0; i < 3; i++) + printf(FS PRINTF_FORMAT, (mdl >> (8 * i)) & 0xff); +} + +void mdl_dump(void) +{ + printf("\n--- Master Delay Line ---\n"); + printf(" IPRD TPRD MDLD\n"); + + dump_loop(&__mdl_dump); +} + +#define REG_DUMP(x) \ + { u32 __iomem *p = &phy->x; printf("%3d: %-10s: %p : %08x\n", \ + p - (u32 *)phy, #x, p, readl(p)); } + +void reg_dump(void) +{ + int ch, p; + struct ddrphy __iomem *phy; + + printf("\n--- DDR PHY registers ---\n"); + + for (ch = 0; ch < NR_DDRCH; ch++) { + for (p = 0; p < NR_DDRPHY_PER_CH; p++) { + printf("== Ch%d, PHY%d ==\n", ch, p); + printf(" No: Name : Address : Data\n"); + + phy = (struct ddrphy __iomem *)DDRPHY_BASE(ch, p); + + REG_DUMP(ridr); + REG_DUMP(pir); + REG_DUMP(pgcr[0]); + REG_DUMP(pgcr[1]); + REG_DUMP(pgsr[0]); + REG_DUMP(pgsr[1]); + REG_DUMP(pllcr); + REG_DUMP(ptr[0]); + REG_DUMP(ptr[1]); + REG_DUMP(ptr[2]); + REG_DUMP(ptr[3]); + REG_DUMP(ptr[4]); + REG_DUMP(acmdlr); + REG_DUMP(acbdlr); + REG_DUMP(dxccr); + REG_DUMP(dsgcr); + REG_DUMP(dcr); + REG_DUMP(dtpr[0]); + REG_DUMP(dtpr[1]); + REG_DUMP(dtpr[2]); + REG_DUMP(mr0); + REG_DUMP(mr1); + REG_DUMP(mr2); + REG_DUMP(mr3); + REG_DUMP(dx[0].gcr); + REG_DUMP(dx[0].gtr); + REG_DUMP(dx[1].gcr); + REG_DUMP(dx[1].gtr); + } + } +} + +static int do_ddr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *cmd = argv[1]; + + if (argc == 1) + cmd = "all"; + + if (!strcmp(cmd, "wbdl") || !strcmp(cmd, "all")) + wbdl_dump(); + + if (!strcmp(cmd, "rbdl") || !strcmp(cmd, "all")) + rbdl_dump(); + + if (!strcmp(cmd, "wld") || !strcmp(cmd, "all")) + wld_dump(); + + if (!strcmp(cmd, "dqsgd") || !strcmp(cmd, "all")) + dqsgd_dump(); + + if (!strcmp(cmd, "mdl") || !strcmp(cmd, "all")) + mdl_dump(); + + if (!strcmp(cmd, "reg") || !strcmp(cmd, "all")) + reg_dump(); + + return 0; +} + +U_BOOT_CMD( + ddr, 2, 1, do_ddr, + "UniPhier DDR PHY parameters dumper", + "- dump all of the followings\n" + "ddr wbdl - dump Write Bit Delay\n" + "ddr rbdl - dump Read Bit Delay\n" + "ddr wld - dump Write Leveling\n" + "ddr dqsgd - dump DQS Gating Delay\n" + "ddr mdl - dump Master Delay Line\n" + "ddr reg - dump registers\n" +); diff --git a/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c b/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c index eef9f39..3561b40 100644 --- a/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c +++ b/arch/arm/cpu/armv7/uniphier/cmd_pinmon.c @@ -7,6 +7,7 @@ #include <common.h> #include <asm/arch/boot-device.h> +#include <asm/arch/sbc-regs.h> static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { @@ -15,6 +16,8 @@ static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) mode_sel = get_boot_mode_sel(); + printf("Boot Swap: %s\n\n", boot_is_swapped() ? "ON" : "OFF"); + puts("Boot Mode Pin:\n"); for (table = boot_device_table; strlen(table->info); table++) { diff --git a/arch/arm/cpu/armv7/uniphier/ddrphy_training.c b/arch/arm/cpu/armv7/uniphier/ddrphy_training.c new file mode 100644 index 0000000..cc8b8ad --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ddrphy_training.c @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2011-2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/ddrphy-regs.h> + +void ddrphy_prepare_training(struct ddrphy __iomem *phy, int rank) +{ + int dx; + u32 __iomem tmp, *p; + + for (dx = 0; dx < NR_DATX8_PER_DDRPHY; dx++) { + p = &phy->dx[dx].gcr; + + tmp = readl(p); + /* Specify the rank that should be write leveled */ + tmp &= ~DXGCR_WLRKEN_MASK; + tmp |= (1 << (DXGCR_WLRKEN_SHIFT + rank)) & DXGCR_WLRKEN_MASK; + writel(tmp, p); + } + + p = &phy->dtcr; + + tmp = readl(p); + /* Specify the rank used during data bit deskew and eye centering */ + tmp &= ~DTCR_DTRANK_MASK; + tmp |= (rank << DTCR_DTRANK_SHIFT) & DTCR_DTRANK_MASK; + /* Use Multi-Purpose Register for DQS gate training */ + tmp |= DTCR_DTMPR; + /* Specify the rank enabled for data-training */ + tmp &= ~DTCR_RNKEN_MASK; + tmp |= (1 << (DTCR_RNKEN_SHIFT + rank)) & DTCR_RNKEN_MASK; + writel(tmp, p); +} + +struct ddrphy_init_sequence { + char *description; + u32 init_flag; + u32 done_flag; + u32 err_flag; +}; + +static struct ddrphy_init_sequence init_sequence[] = { + { + "DRAM Initialization", + PIR_DRAMRST | PIR_DRAMINIT, + PGSR0_DIDONE, + PGSR0_DIERR + }, + { + "Write Leveling", + PIR_WL, + PGSR0_WLDONE, + PGSR0_WLERR + }, + { + "Read DQS Gate Training", + PIR_QSGATE, + PGSR0_QSGDONE, + PGSR0_QSGERR + }, + { + "Write Leveling Adjustment", + PIR_WLADJ, + PGSR0_WLADONE, + PGSR0_WLAERR + }, + { + "Read Bit Deskew", + PIR_RDDSKW, + PGSR0_RDDONE, + PGSR0_RDERR + }, + { + "Write Bit Deskew", + PIR_WRDSKW, + PGSR0_WDDONE, + PGSR0_WDERR + }, + { + "Read Eye Training", + PIR_RDEYE, + PGSR0_REDONE, + PGSR0_REERR + }, + { + "Write Eye Training", + PIR_WREYE, + PGSR0_WEDONE, + PGSR0_WEERR + } +}; + +int ddrphy_training(struct ddrphy __iomem *phy) +{ + int i; + u32 pgsr0; + u32 init_flag = PIR_INIT; + u32 done_flag = PGSR0_IDONE; + int timeout = 50000; /* 50 msec is long enough */ +#ifdef DISPLAY_ELAPSED_TIME + ulong start = get_timer(0); +#endif + + for (i = 0; i < ARRAY_SIZE(init_sequence); i++) { + init_flag |= init_sequence[i].init_flag; + done_flag |= init_sequence[i].done_flag; + } + + writel(init_flag, &phy->pir); + + do { + if (--timeout < 0) { +#ifndef CONFIG_SPL_BUILD + printf("%s: error: timeout during DDR training\n", + __func__); +#endif + return -1; + } + udelay(1); + pgsr0 = readl(&phy->pgsr[0]); + } while ((pgsr0 & done_flag) != done_flag); + + for (i = 0; i < ARRAY_SIZE(init_sequence); i++) { + if (pgsr0 & init_sequence[i].err_flag) { +#ifndef CONFIG_SPL_BUILD + printf("%s: error: %s failed\n", __func__, + init_sequence[i].description); +#endif + return -1; + } + } + +#ifdef DISPLAY_ELAPSED_TIME + printf("%s: info: elapsed time %ld msec\n", get_timer(start)); +#endif + + return 0; +} diff --git a/arch/arm/cpu/armv7/uniphier/init_page_table.c b/arch/arm/cpu/armv7/uniphier/init_page_table.c index a0d10a9..febb3c8 100644 --- a/arch/arm/cpu/armv7/uniphier/init_page_table.c +++ b/arch/arm/cpu/armv7/uniphier/init_page_table.c @@ -17,11 +17,7 @@ #define REG DEVICE /* IO Register: Device */ #define DDR DEVICE /* DDR SDRAM: Device */ -#ifdef CONFIG_SPL_BUILD #define IS_SPL_TEXT_AREA(x) ((x) == ((CONFIG_SPL_TEXT_BASE) >> 20)) -#else -#define IS_SPL_TEXT_AREA(x) ((x) == ((CONFIG_SYS_TEXT_BASE) >> 20)) -#endif #define IS_INIT_STACK_AREA(x) ((x) == ((CONFIG_SYS_INIT_SP_ADDR) >> 20)) diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile index 5d682d3..8794629 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/Makefile @@ -8,4 +8,4 @@ obj-y += boot-mode.o obj-$(CONFIG_SOC_INIT) += bcu_init.o sbc_init.o sg_init.o pll_init.o \ clkrst_init.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += pinctrl.o -obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o +obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/ddrphy_init.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/ddrphy_init.c new file mode 100644 index 0000000..60fc5ad --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/ddrphy_init.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/types.h> +#include <asm/io.h> +#include <asm/arch/ddrphy-regs.h> + +void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) +{ + u32 tmp; + + writel(0x0300c473, &phy->pgcr[1]); + if (freq == 1333) { + writel(0x0a806844, &phy->ptr[0]); + writel(0x208e0124, &phy->ptr[1]); + } else { + writel(0x0c807d04, &phy->ptr[0]); + writel(0x2710015E, &phy->ptr[1]); + } + writel(0x00083DEF, &phy->ptr[2]); + if (freq == 1333) { + writel(0x0f051616, &phy->ptr[3]); + writel(0x06ae08d6, &phy->ptr[4]); + } else { + writel(0x12061A80, &phy->ptr[3]); + writel(0x08027100, &phy->ptr[4]); + } + writel(0xF004001A, &phy->dsgcr); + + /* change the value of the on-die pull-up/pull-down registors */ + tmp = readl(&phy->dxccr); + tmp &= ~0x0ee0; + tmp |= DXCCR_DQSNRES_688_OHM | DXCCR_DQSRES_688_OHM; + writel(tmp, &phy->dxccr); + + writel(0x0000040B, &phy->dcr); + if (freq == 1333) { + writel(0x85589955, &phy->dtpr[0]); + if (size == 1) + writel(0x1a8253c0, &phy->dtpr[1]); + else + writel(0x1a8363c0, &phy->dtpr[1]); + writel(0x5002c200, &phy->dtpr[2]); + writel(0x00000b51, &phy->mr0); + } else { + writel(0x999cbb66, &phy->dtpr[0]); + if (size == 1) + writel(0x1a82dbc0, &phy->dtpr[1]); + else + writel(0x1a878400, &phy->dtpr[1]); + writel(0xa00214f8, &phy->dtpr[2]); + writel(0x00000d71, &phy->mr0); + } + writel(0x00000006, &phy->mr1); + if (freq == 1333) + writel(0x00000290, &phy->mr2); + else + writel(0x00000298, &phy->mr2); + + writel(0x00000800, &phy->mr3); + + while (!(readl(&phy->pgsr[0]) & PGSR0_IDONE)) + ; + + writel(0x0300C473, &phy->pgcr[1]); + writel(0x0000005D, &phy->zq[0].cr[1]); +} diff --git a/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c b/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c index ebcbaab..8788916 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-ld4/umc_init.c @@ -7,6 +7,7 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/umc-regs.h> +#include <asm/arch/ddrphy-regs.h> static inline void umc_start_ssif(void __iomem *ssif_base) { @@ -125,6 +126,8 @@ static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) void __iomem *ca_base1 = (void __iomem *)UMC_CA_BASE(1); void __iomem *dramcont0 = (void __iomem *)UMC_DRAMCONT_BASE(0); void __iomem *dramcont1 = (void __iomem *)UMC_DRAMCONT_BASE(1); + void __iomem *phy0_0 = (void __iomem *)DDRPHY_BASE(0, 0); + void __iomem *phy1_0 = (void __iomem *)DDRPHY_BASE(1, 0); umc_dram_init_start(dramcont0); umc_dram_init_start(dramcont1); @@ -133,8 +136,18 @@ static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) writel(0x00000101, dramcont0 + UMC_DIOCTLA); + ddrphy_init(phy0_0, freq, size_ch0); + + ddrphy_prepare_training(phy0_0, 0); + ddrphy_training(phy0_0); + writel(0x00000101, dramcont1 + UMC_DIOCTLA); + ddrphy_init(phy1_0, freq, size_ch1); + + ddrphy_prepare_training(phy1_0, 1); + ddrphy_training(phy1_0); + umc_dramcont_init(dramcont0, ca_base0, size_ch0, freq); umc_dramcont_init(dramcont1, ca_base1, size_ch1, freq); diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile index fd1c432..cee7878 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/Makefile @@ -7,4 +7,4 @@ obj-$(if $(CONFIG_OF_CONTROL),,y) += platdevice.o obj-y += boot-mode.o obj-$(CONFIG_SOC_INIT) += sbc_init.o sg_init.o pll_init.o clkrst_init.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += pinctrl.o -obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o +obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/ddrphy_init.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/ddrphy_init.c new file mode 100644 index 0000000..c5d1f60 --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/ddrphy_init.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/types.h> +#include <asm/io.h> +#include <asm/arch/ddrphy-regs.h> + +void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) +{ + u32 tmp; + + writel(0x0300c473, &phy->pgcr[1]); + if (freq == 1333) { + writel(0x0a806844, &phy->ptr[0]); + writel(0x208e0124, &phy->ptr[1]); + } else { + writel(0x0c807d04, &phy->ptr[0]); + writel(0x2710015E, &phy->ptr[1]); + } + writel(0x00083DEF, &phy->ptr[2]); + if (freq == 1333) { + writel(0x0f051616, &phy->ptr[3]); + writel(0x06ae08d6, &phy->ptr[4]); + } else { + writel(0x12061A80, &phy->ptr[3]); + writel(0x08027100, &phy->ptr[4]); + } + writel(0xF004001A, &phy->dsgcr); + + /* change the value of the on-die pull-up/pull-down registors */ + tmp = readl(&phy->dxccr); + tmp &= ~0x0ee0; + tmp |= DXCCR_DQSNRES_688_OHM | DXCCR_DQSRES_688_OHM; + writel(tmp, &phy->dxccr); + + writel(0x0000040B, &phy->dcr); + if (freq == 1333) { + writel(0x85589955, &phy->dtpr[0]); + if (size == 1) + writel(0x1a8363c0, &phy->dtpr[1]); + else + writel(0x1a8363c0, &phy->dtpr[1]); + writel(0x5002c200, &phy->dtpr[2]); + writel(0x00000b51, &phy->mr0); + } else { + writel(0x999cbb66, &phy->dtpr[0]); + if (size == 1) + writel(0x1a878400, &phy->dtpr[1]); + else + writel(0x1a878400, &phy->dtpr[1]); + writel(0xa00214f8, &phy->dtpr[2]); + writel(0x00000d71, &phy->mr0); + } + writel(0x00000006, &phy->mr1); + if (freq == 1333) + writel(0x00000290, &phy->mr2); + else + writel(0x00000298, &phy->mr2); + + writel(0x00000000, &phy->mr3); + + while (!(readl(&phy->pgsr[0]) & PGSR0_IDONE)) + ; + + writel(0x0300C473, &phy->pgcr[1]); + writel(0x0000005D, &phy->zq[0].cr[1]); +} diff --git a/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c b/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c index 328b2f4..1973ab0 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-pro4/umc_init.c @@ -7,6 +7,7 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/umc-regs.h> +#include <asm/arch/ddrphy-regs.h> static inline void umc_start_ssif(void __iomem *ssif_base) { @@ -94,6 +95,10 @@ static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) void __iomem *ca_base1 = (void __iomem *)UMC_CA_BASE(1); void __iomem *dramcont0 = (void __iomem *)UMC_DRAMCONT_BASE(0); void __iomem *dramcont1 = (void __iomem *)UMC_DRAMCONT_BASE(1); + void __iomem *phy0_0 = (void __iomem *)DDRPHY_BASE(0, 0); + void __iomem *phy0_1 = (void __iomem *)DDRPHY_BASE(0, 1); + void __iomem *phy1_0 = (void __iomem *)DDRPHY_BASE(1, 0); + void __iomem *phy1_1 = (void __iomem *)DDRPHY_BASE(1, 1); umc_dram_init_start(dramcont0); umc_dram_init_start(dramcont1); @@ -102,12 +107,32 @@ static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) writel(0x00000101, dramcont0 + UMC_DIOCTLA); + ddrphy_init(phy0_0, freq, size_ch0); + + ddrphy_prepare_training(phy0_0, 0); + ddrphy_training(phy0_0); + writel(0x00000103, dramcont0 + UMC_DIOCTLA); + ddrphy_init(phy0_1, freq, size_ch0); + + ddrphy_prepare_training(phy0_1, 1); + ddrphy_training(phy0_1); + writel(0x00000101, dramcont1 + UMC_DIOCTLA); + ddrphy_init(phy1_0, freq, size_ch1); + + ddrphy_prepare_training(phy1_0, 0); + ddrphy_training(phy1_0); + writel(0x00000103, dramcont1 + UMC_DIOCTLA); + ddrphy_init(phy1_1, freq, size_ch1); + + ddrphy_prepare_training(phy1_1, 1); + ddrphy_training(phy1_1); + umc_dramcont_init(dramcont0, ca_base0, size_ch0, freq); umc_dramcont_init(dramcont1, ca_base1, size_ch1, freq); diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile index 5d682d3..8794629 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/Makefile @@ -8,4 +8,4 @@ obj-y += boot-mode.o obj-$(CONFIG_SOC_INIT) += bcu_init.o sbc_init.o sg_init.o pll_init.o \ clkrst_init.o obj-$(CONFIG_BOARD_POSTCLK_INIT) += pinctrl.o -obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o +obj-$(CONFIG_DRAM_INIT) += pll_spectrum.o umc_init.o ddrphy_init.o diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/ddrphy_init.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/ddrphy_init.c new file mode 100644 index 0000000..a5eafef --- /dev/null +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/ddrphy_init.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2014 Panasonic Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <linux/types.h> +#include <asm/io.h> +#include <asm/arch/ddrphy-regs.h> + +void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size) +{ + u32 tmp; + + writel(0x0300c473, &phy->pgcr[1]); + if (freq == 1333) { + writel(0x0a806844, &phy->ptr[0]); + writel(0x208e0124, &phy->ptr[1]); + } else { + writel(0x0c807d04, &phy->ptr[0]); + writel(0x2710015E, &phy->ptr[1]); + } + writel(0x00083DEF, &phy->ptr[2]); + if (freq == 1333) { + writel(0x0f051616, &phy->ptr[3]); + writel(0x06ae08d6, &phy->ptr[4]); + } else { + writel(0x12061A80, &phy->ptr[3]); + writel(0x08027100, &phy->ptr[4]); + } + writel(0xF004001A, &phy->dsgcr); + + /* change the value of the on-die pull-up/pull-down registors */ + tmp = readl(&phy->dxccr); + tmp &= ~0x0ee0; + tmp |= DXCCR_DQSNRES_688_OHM | DXCCR_DQSRES_688_OHM; + writel(tmp, &phy->dxccr); + + writel(0x0000040B, &phy->dcr); + if (freq == 1333) { + writel(0x85589955, &phy->dtpr[0]); + if (size == 1) + writel(0x1a8363c0, &phy->dtpr[1]); + else + writel(0x1a8363c0, &phy->dtpr[1]); + writel(0x5002c200, &phy->dtpr[2]); + writel(0x00000b51, &phy->mr0); + } else { + writel(0x999cbb66, &phy->dtpr[0]); + if (size == 1) + writel(0x1a878400, &phy->dtpr[1]); + else + writel(0x1a878400, &phy->dtpr[1]); + writel(0xa00214f8, &phy->dtpr[2]); + writel(0x00000d71, &phy->mr0); + } + writel(0x00000006, &phy->mr1); + if (freq == 1333) + writel(0x00000290, &phy->mr2); + else + writel(0x00000298, &phy->mr2); + +#ifdef CONFIG_DDR_STANDARD + writel(0x00000000, &phy->mr3); +#else + writel(0x00000800, &phy->mr3); +#endif + + while (!(readl(&phy->pgsr[0]) & PGSR0_IDONE)) + ; + + writel(0x0300C473, &phy->pgcr[1]); + writel(0x0000005D, &phy->zq[0].cr[1]); +} diff --git a/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c b/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c index a44f999..2e0f9ae 100644 --- a/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c +++ b/arch/arm/cpu/armv7/uniphier/ph1-sld8/umc_init.c @@ -7,6 +7,7 @@ #include <common.h> #include <asm/io.h> #include <asm/arch/umc-regs.h> +#include <asm/arch/ddrphy-regs.h> static inline void umc_start_ssif(void __iomem *ssif_base) { @@ -105,6 +106,8 @@ static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) void __iomem *ca_base1 = (void __iomem *)UMC_CA_BASE(1); void __iomem *dramcont0 = (void __iomem *)UMC_DRAMCONT_BASE(0); void __iomem *dramcont1 = (void __iomem *)UMC_DRAMCONT_BASE(1); + void __iomem *phy0_0 = (void __iomem *)DDRPHY_BASE(0, 0); + void __iomem *phy1_0 = (void __iomem *)DDRPHY_BASE(1, 0); umc_dram_init_start(dramcont0); umc_dram_init_start(dramcont1); @@ -113,8 +116,18 @@ static inline int umc_init_sub(int freq, int size_ch0, int size_ch1) writel(0x00000101, dramcont0 + UMC_DIOCTLA); + ddrphy_init(phy0_0, freq, size_ch0); + + ddrphy_prepare_training(phy0_0, 0); + ddrphy_training(phy0_0); + writel(0x00000101, dramcont1 + UMC_DIOCTLA); + ddrphy_init(phy1_0, freq, size_ch1); + + ddrphy_prepare_training(phy1_0, 1); + ddrphy_training(phy1_0); + umc_dramcont_init(dramcont0, ca_base0, size_ch0, freq); umc_dramcont_init(dramcont1, ca_base1, size_ch1, freq); diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index e6a495c..fac16cc 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -13,7 +13,8 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5250-smdk5250.dtb \ exynos5420-smdk5420.dtb \ exynos5420-peach-pit.dtb \ - exynos5800-peach-pi.dtb + exynos5800-peach-pi.dtb \ + exynos5422-odroidxu3.dtb dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \ diff --git a/arch/arm/dts/exynos5422-odroidxu3.dts b/arch/arm/dts/exynos5422-odroidxu3.dts new file mode 100644 index 0000000..79a7acd --- /dev/null +++ b/arch/arm/dts/exynos5422-odroidxu3.dts @@ -0,0 +1,49 @@ +/* + * Odroid XU3 device tree source + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/dts-v1/; +#include "exynos54xx.dtsi" + +/ { + model = "Odroid XU3 based on EXYNOS5422"; + compatible = "samsung,odroidxu3", "samsung,exynos5"; + + aliases { + serial0 = "/serial@12C00000"; + console = "/serial@12C20000"; + }; + + memory { + device_type = "memory"; + reg = <0x40000000 0x10000000 + 0x50000000 0x10000000 + 0x60000000 0x10000000 + 0x70000000 0x10000000 + 0x80000000 0x10000000 + 0x90000000 0x10000000 + 0xa0000000 0x10000000 + 0xb0000000 0xea00000>; + }; + + ehci@12110000 { + samsung,vbus-gpio = <&gpio 0x66 0>; /* X26 */ + }; + + serial@12C20000 { + status="okay"; + }; + + mmc@12200000 { + fifoth_val = <0x201f0020>; + }; + + mmc@12220000 { + fifoth_val = <0x201f0020>; + }; +}; diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts index 8aedf8e..2f9d2db 100644 --- a/arch/arm/dts/exynos5800-peach-pi.dts +++ b/arch/arm/dts/exynos5800-peach-pi.dts @@ -63,11 +63,6 @@ reg = <0x20>; compatible = "maxim,max98090-codec"; }; - - edp-lvds-bridge@48 { - compatible = "parade,ps8625"; - reg = <0x48>; - }; }; sound@3830000 { diff --git a/arch/arm/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/dts/uniphier-ph1-ld4-ref.dts index 08bbd03..6855878 100644 --- a/arch/arm/dts/uniphier-ph1-ld4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-ld4-ref.dts @@ -25,10 +25,10 @@ }; aliases { - uart0 = &uart0; - uart1 = &uart1; - uart2 = &uart2; - uart3 = &uart3; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; diff --git a/arch/arm/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/dts/uniphier-ph1-pro4-ref.dts index 23add7c..1227b62 100644 --- a/arch/arm/dts/uniphier-ph1-pro4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-pro4-ref.dts @@ -25,10 +25,10 @@ }; aliases { - uart0 = &uart0; - uart1 = &uart1; - uart2 = &uart2; - uart3 = &uart3; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; diff --git a/arch/arm/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/dts/uniphier-ph1-sld3-ref.dts index 91b4dbe..fefc592 100644 --- a/arch/arm/dts/uniphier-ph1-sld3-ref.dts +++ b/arch/arm/dts/uniphier-ph1-sld3-ref.dts @@ -25,9 +25,9 @@ }; aliases { - uart0 = &uart0; - uart1 = &uart1; - uart2 = &uart2; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; diff --git a/arch/arm/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/dts/uniphier-ph1-sld8-ref.dts index a8ce049..9b6d95c 100644 --- a/arch/arm/dts/uniphier-ph1-sld8-ref.dts +++ b/arch/arm/dts/uniphier-ph1-sld8-ref.dts @@ -25,10 +25,10 @@ }; aliases { - uart0 = &uart0; - uart1 = &uart1; - uart2 = &uart2; - uart3 = &uart3; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; diff --git a/arch/arm/imx-common/i2c-mxv7.c b/arch/arm/imx-common/i2c-mxv7.c index 34f5387..1a632e7 100644 --- a/arch/arm/imx-common/i2c-mxv7.c +++ b/arch/arm/imx-common/i2c-mxv7.c @@ -73,26 +73,21 @@ static void * const i2c_bases[] = { int setup_i2c(unsigned i2c_index, int speed, int slave_addr, struct i2c_pads_info *p) { - char *name1, *name2; + char name[9]; int ret; if (i2c_index >= ARRAY_SIZE(i2c_bases)) return -EINVAL; - name1 = malloc(9); - name2 = malloc(9); - if (!name1 || !name2) - return -ENOMEM; - - sprintf(name1, "i2c_sda%d", i2c_index); - sprintf(name2, "i2c_scl%d", i2c_index); - ret = gpio_request(p->sda.gp, name1); + snprintf(name, sizeof(name), "i2c_sda%01d", i2c_index); + ret = gpio_request(p->sda.gp, name); if (ret) - goto err_req1; + return ret; - ret = gpio_request(p->scl.gp, name2); + snprintf(name, sizeof(name), "i2c_scl%01d", i2c_index); + ret = gpio_request(p->scl.gp, name); if (ret) - goto err_req2; + goto err_req; /* Enable i2c clock */ ret = enable_i2c_clk(1, i2c_index); @@ -112,11 +107,8 @@ int setup_i2c(unsigned i2c_index, int speed, int slave_addr, err_idle: err_clk: gpio_free(p->scl.gp); -err_req2: +err_req: gpio_free(p->sda.gp); -err_req1: - free(name1); - free(name2); return ret; } diff --git a/arch/arm/imx-common/spl.c b/arch/arm/imx-common/spl.c index 477c38c..ac6e40e 100644 --- a/arch/arm/imx-common/spl.c +++ b/arch/arm/imx-common/spl.c @@ -68,8 +68,10 @@ u32 spl_boot_mode(void) /* for MMC return either RAW or FAT mode */ case BOOT_DEVICE_MMC1: case BOOT_DEVICE_MMC2: -#ifdef CONFIG_SPL_FAT_SUPPORT +#if defined(CONFIG_SPL_FAT_SUPPORT) return MMCSD_MODE_FS; +#elif defined(CONFIG_SUPPORT_EMMC_BOOT) + return MMCSD_MODE_EMMCBOOT; #else return MMCSD_MODE_RAW; #endif diff --git a/arch/arm/include/asm/arch-bcm281xx/sysmap.h b/arch/arm/include/asm/arch-bcm281xx/sysmap.h index 350e7f6..93ebf34 100644 --- a/arch/arm/include/asm/arch-bcm281xx/sysmap.h +++ b/arch/arm/include/asm/arch-bcm281xx/sysmap.h @@ -13,6 +13,8 @@ #define ESUB_CLK_BASE_ADDR 0x38000000 #define ESW_CONTRL_BASE_ADDR 0x38200000 #define GPIO2_BASE_ADDR 0x35003000 +#define HSOTG_BASE_ADDR 0x3f120000 +#define HSOTG_CTRL_BASE_ADDR 0x3f130000 #define KONA_MST_CLK_BASE_ADDR 0x3f001000 #define KONA_SLV_CLK_BASE_ADDR 0x3e011000 #define PMU_BSC_BASE_ADDR 0x3500d000 diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h index 0289ba6..88d2ec1 100644 --- a/arch/arm/include/asm/arch-bcm2835/mbox.h +++ b/arch/arm/include/asm/arch-bcm2835/mbox.h @@ -140,6 +140,7 @@ struct bcm2835_mbox_tag_hdr { #define BCM2835_BOARD_REV_B_REV2_f 0xf #define BCM2835_BOARD_REV_B_PLUS 0x10 #define BCM2835_BOARD_REV_CM 0x11 +#define BCM2835_BOARD_REV_A_PLUS 0x12 struct bcm2835_mbox_tag_get_board_rev { struct bcm2835_mbox_tag_hdr tag_hdr; diff --git a/arch/arm/include/asm/arch-exynos/system.h b/arch/arm/include/asm/arch-exynos/system.h index 320763f..4968d3d 100644 --- a/arch/arm/include/asm/arch-exynos/system.h +++ b/arch/arm/include/asm/arch-exynos/system.h @@ -41,7 +41,4 @@ void set_usbhost_mode(unsigned int mode); void set_system_display_ctrl(void); int exynos_lcd_early_init(const void *blob); -/* Initialize the Parade dP<->LVDS bridge if present */ -int parade_init(const void *blob); - #endif /* _EXYNOS4_SYSTEM_H */ diff --git a/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h b/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h new file mode 100644 index 0000000..484559c --- /dev/null +++ b/arch/arm/include/asm/arch-uniphier/ddrphy-regs.h @@ -0,0 +1,172 @@ +/* + * UniPhier DDR PHY registers + * + * Copyright (C) 2014 Panasonic Corporation + * Author: Masahiro Yamada <yamada.m@jp.panasonic.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef ARCH_DDRPHY_REGS_H +#define ARCH_DDRPHY_REGS_H + +#include <linux/compiler.h> + +#ifndef __ASSEMBLY__ + +struct ddrphy { + u32 ridr; /* Revision Identification Register */ + u32 pir; /* PHY Initialixation Register */ + u32 pgcr[2]; /* PHY General Configuration Register */ + u32 pgsr[2]; /* PHY General Status Register */ + u32 pllcr; /* PLL Control Register */ + u32 ptr[5]; /* PHY Timing Register */ + u32 acmdlr; /* AC Master Delay Line Register */ + u32 acbdlr; /* AC Bit Delay Line Register */ + u32 aciocr; /* AC I/O Configuration Register */ + u32 dxccr; /* DATX8 Common Configuration Register */ + u32 dsgcr; /* DDR System General Configuration Register */ + u32 dcr; /* DRAM Configuration Register */ + u32 dtpr[3]; /* DRAM Timing Parameters Register */ + u32 mr0; /* Mode Register 0 */ + u32 mr1; /* Mode Register 1 */ + u32 mr2; /* Mode Register 2 */ + u32 mr3; /* Mode Register 3 */ + u32 odtcr; /* ODT Configuration Register */ + u32 dtcr; /* Data Training Configuration Register */ + u32 dtar[4]; /* Data Training Address Register */ + u32 dtdr[2]; /* Data Training Data Register */ + u32 dtedr[2]; /* Data Training Eye Data Register */ + u32 rsv0[13]; /* Reserved */ + u32 dcuar; /* DCU Address Register */ + u32 dcudr; /* DCU Data Register */ + u32 dcurr; /* DCU Run Register */ + u32 dculr; /* DCU Loop Register */ + u32 dcugcr; /* DCU General Configuration Register */ + u32 dcutpr; /* DCU Timing Parameters Register */ + u32 dcusr[2]; /* DCU Status Register */ + u32 rsv1[8]; /* Reserved */ + u32 bistrr; /* BIST Run Register */ + u32 bistwcr; /* BIST Word Count Register */ + u32 bistmskr[3]; /* BIST Mask Register */ + u32 bistlsr; /* BIST LFSR Sed Register */ + u32 bistar[3]; /* BIST Address Register */ + u32 bistudpr; /* BIST User Data Pattern Register */ + u32 bistgsr; /* BIST General Status Register */ + u32 bistwer; /* BIST Word Error Register */ + u32 bistber[4]; /* BIST Bit Error Register */ + u32 bistwcsr; /* BIST Word Count Status Register */ + u32 bistfwr[3]; /* BIST Fail Word Register */ + u32 rsv2[10]; /* Reserved */ + u32 gpr[2]; /* General Purpose Register */ + struct ddrphy_zq { /* ZQ */ + u32 cr[2]; /* Impedance Control Register */ + u32 sr[2]; /* Impedance Status Register */ + } zq[4]; + struct ddrphy_datx8 { /* DATX8 */ + u32 gcr; /* General Configuration Register */ + u32 gsr[2]; /* General Status Register */ + u32 bdlr[5]; /* Bit Delay Line Register */ + u32 lcdlr[3]; /* Local Calibrated Delay Line Register */ + u32 mdlr; /* Master Delay Line Register */ + u32 gtr; /* General Timing Register */ + u32 rsv[3]; /* Reserved */ + } dx[9]; +} __packed; + +#endif /* __ASSEMBLY__ */ + +#define PIR_INIT (1 << 0) /* Initialization Trigger */ +#define PIR_ZCAL (1 << 1) /* Impedance Calibration */ +#define PIR_PLLINIT (1 << 4) /* PLL Initialization */ +#define PIR_DCAL (1 << 5) /* DDL Calibration */ +#define PIR_PHYRST (1 << 6) /* PHY Reset */ +#define PIR_DRAMRST (1 << 7) /* DRAM Reset */ +#define PIR_DRAMINIT (1 << 8) /* DRAM Initialization */ +#define PIR_WL (1 << 9) /* Write Leveling */ +#define PIR_QSGATE (1 << 10) /* Read DQS Gate Training */ +#define PIR_WLADJ (1 << 11) /* Write Leveling Adjust */ +#define PIR_RDDSKW (1 << 12) /* Read Data Bit Deskew */ +#define PIR_WRDSKW (1 << 13) /* Write Data Bit Deskew */ +#define PIR_RDEYE (1 << 14) /* Read Data Eye Training */ +#define PIR_WREYE (1 << 15) /* Write Data Eye Training */ +#define PIR_LOCKBYP (1 << 28) /* PLL Lock Bypass */ +#define PIR_DCALBYP (1 << 29) /* DDL Calibration Bypass */ +#define PIR_ZCALBYP (1 << 30) /* Impedance Calib Bypass */ +#define PIR_INITBYP (1 << 31) /* Initialization Bypass */ + +#define PGSR0_IDONE (1 << 0) /* Initialization Done */ +#define PGSR0_PLDONE (1 << 1) /* PLL Lock Done */ +#define PGSR0_DCDONE (1 << 2) /* DDL Calibration Done */ +#define PGSR0_ZCDONE (1 << 3) /* Impedance Calibration Done */ +#define PGSR0_DIDONE (1 << 4) /* DRAM Initialization Done */ +#define PGSR0_WLDONE (1 << 5) /* Write Leveling Done */ +#define PGSR0_QSGDONE (1 << 6) /* DQS Gate Training Done */ +#define PGSR0_WLADONE (1 << 7) /* Write Leveling Adjust Done */ +#define PGSR0_RDDONE (1 << 8) /* Read Bit Deskew Done */ +#define PGSR0_WDDONE (1 << 9) /* Write Bit Deskew Done */ +#define PGSR0_REDONE (1 << 10) /* Read Eye Training Done */ +#define PGSR0_WEDONE (1 << 11) /* Write Eye Training Done */ +#define PGSR0_IERR (1 << 16) /* Initialization Error */ +#define PGSR0_PLERR (1 << 17) /* PLL Lock Error */ +#define PGSR0_DCERR (1 << 18) /* DDL Calibration Error */ +#define PGSR0_ZCERR (1 << 19) /* Impedance Calib Error */ +#define PGSR0_DIERR (1 << 20) /* DRAM Initialization Error */ +#define PGSR0_WLERR (1 << 21) /* Write Leveling Error */ +#define PGSR0_QSGERR (1 << 22) /* DQS Gate Training Error */ +#define PGSR0_WLAERR (1 << 23) /* Write Leveling Adj Error */ +#define PGSR0_RDERR (1 << 24) /* Read Bit Deskew Error */ +#define PGSR0_WDERR (1 << 25) /* Write Bit Deskew Error */ +#define PGSR0_REERR (1 << 26) /* Read Eye Training Error */ +#define PGSR0_WEERR (1 << 27) /* Write Eye Training Error */ +#define PGSR0_DTERR_SHIFT 28 /* Data Training Error Status*/ +#define PGSR0_DTERR (7 << (PGSR0_DTERR_SHIFT)) +#define PGSR0_APLOCK (1 << 31) /* AC PLL Lock */ + +#define DXCCR_DQSRES_OPEN (0 << 5) +#define DXCCR_DQSRES_688_OHM (1 << 5) +#define DXCCR_DQSRES_611_OHM (2 << 5) +#define DXCCR_DQSRES_550_OHM (3 << 5) +#define DXCCR_DQSRES_500_OHM (4 << 5) +#define DXCCR_DQSRES_458_OHM (5 << 5) +#define DXCCR_DQSRES_393_OHM (6 << 5) +#define DXCCR_DQSRES_344_OHM (7 << 5) + +#define DXCCR_DQSNRES_OPEN (0 << 9) +#define DXCCR_DQSNRES_688_OHM (1 << 9) +#define DXCCR_DQSNRES_611_OHM (2 << 9) +#define DXCCR_DQSNRES_550_OHM (3 << 9) +#define DXCCR_DQSNRES_500_OHM (4 << 9) +#define DXCCR_DQSNRES_458_OHM (5 << 9) +#define DXCCR_DQSNRES_393_OHM (6 << 9) +#define DXCCR_DQSNRES_344_OHM (7 << 9) + +#define DTCR_DTRANK_SHIFT 4 /* Data Training Rank */ +#define DTCR_DTRANK_MASK (0x3 << (DTCR_DTRANK_SHIFT)) +#define DTCR_DTMPR (1 << 6) /* Data Training using MPR */ +#define DTCR_RNKEN_SHIFT 24 /* Rank Enable */ +#define DTCR_RNKEN_MASK (0xf << (DTCR_RNKEN_SHIFT)) + +#define DXGCR_WLRKEN_SHIFT 26 /* Write Level Rank Enable */ +#define DXGCR_WLRKEN_MASK (0xf << (DXGCR_WLRKEN_SHIFT)) + +/* SoC-specific parameters */ +#define NR_DATX8_PER_DDRPHY 2 + +#if defined(CONFIG_MACH_PH1_LD4) || defined(CONFIG_MACH_PH1_SLD8) +#define NR_DDRPHY_PER_CH 1 +#else +#define NR_DDRPHY_PER_CH 2 +#endif + +#define NR_DDRCH 2 + +#define DDRPHY_BASE(ch, phy) (0x5bc01000 + 0x200000 * (ch) + 0x1000 * (phy)) + +#ifndef __ASSEMBLY__ +void ddrphy_init(struct ddrphy __iomem *phy, int freq, int size); +void ddrphy_prepare_training(struct ddrphy __iomem *phy, int rank); +int ddrphy_training(struct ddrphy __iomem *phy); +#endif + +#endif /* ARCH_DDRPHY_REGS_H */ diff --git a/arch/arm/include/asm/kona-common/clk.h b/arch/arm/include/asm/kona-common/clk.h index 2c7e829..a5e2fd9 100644 --- a/arch/arm/include/asm/kona-common/clk.h +++ b/arch/arm/include/asm/kona-common/clk.h @@ -25,5 +25,6 @@ int clk_set_parent(struct clk *clk, struct clk *parent); struct clk *clk_get_parent(struct clk *clk); int clk_sdio_enable(void *base, u32 rate, u32 *actual_ratep); int clk_bsc_enable(void *base); +int clk_usb_otg_enable(void *base); #endif diff --git a/arch/arm/include/asm/semihosting.h b/arch/arm/include/asm/semihosting.h index 74111dc..835ca7e 100644 --- a/arch/arm/include/asm/semihosting.h +++ b/arch/arm/include/asm/semihosting.h @@ -12,10 +12,6 @@ * code for more information. */ int smh_load(const char *fname, void *memp, int avail, int verbose); -int smh_read(int fd, void *memp, int len); -int smh_open(const char *fname, char *modestr); -int smh_close(int fd); -int smh_len_fd(int fd); -int smh_len(const char *fname); +long smh_len(const char *fname); #endif /* __SEMIHOSTING_H__ */ diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c index cb5dc26..fd6d857 100644 --- a/arch/arm/lib/semihosting.c +++ b/arch/arm/lib/semihosting.c @@ -26,9 +26,9 @@ /* * Call the handler */ -static int smh_trap(unsigned int sysnum, void *addr) +static long smh_trap(unsigned int sysnum, void *addr) { - register int result asm("r0"); + register long result asm("r0"); #if defined(CONFIG_ARM64) asm volatile ("hlt #0xf000" : "=r" (result) : "0"(sysnum), "r"(addr)); #else @@ -39,167 +39,164 @@ static int smh_trap(unsigned int sysnum, void *addr) } /* - * Open, load a file into memory, and close it. Check that the available space - * is sufficient to store the entire file. Return the bytes actually read from - * the file as seen by the read function. The verbose flag enables some extra - * printing of successful read status. + * Open a file on the host. Mode is "r" or "rb" currently. Returns a file + * descriptor or -1 on error. */ -int smh_load(const char *fname, void *memp, int avail, int verbose) +static long smh_open(const char *fname, char *modestr) { - int ret, fd, len; - - ret = -1; - - debug("%s: fname \'%s\', avail %u, memp %p\n", __func__, fname, - avail, memp); - - /* Open the file */ - fd = smh_open(fname, "rb"); - if (fd == -1) - return ret; + long fd; + unsigned long mode; + struct smh_open_s { + const char *fname; + unsigned long mode; + size_t len; + } open; - /* Get the file length */ - ret = smh_len_fd(fd); - if (ret == -1) { - smh_close(fd); - return ret; - } + debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); - /* Check that the file will fit in the supplied buffer */ - if (ret > avail) { - printf("%s: ERROR ret %d, avail %u\n", __func__, ret, - avail); - smh_close(fd); - return ret; + /* Check the file mode */ + if (!(strcmp(modestr, "r"))) { + mode = MODE_READ; + } else if (!(strcmp(modestr, "rb"))) { + mode = MODE_READBIN; + } else { + printf("%s: ERROR mode \'%s\' not supported\n", __func__, + modestr); + return -1; } - len = ret; - - /* Read the file into the buffer */ - ret = smh_read(fd, memp, len); - if (ret == 0) { - /* Print successful load information if requested */ - if (verbose) { - printf("\n%s\n", fname); - printf(" 0x%8p dest\n", memp); - printf(" 0x%08x size\n", len); - printf(" 0x%08x avail\n", avail); - } - } + open.fname = fname; + open.len = strlen(fname); + open.mode = mode; - /* Close the file */ - smh_close(fd); + /* Open the file on the host */ + fd = smh_trap(SYSOPEN, &open); + if (fd == -1) + printf("%s: ERROR fd %ld for file \'%s\'\n", __func__, fd, + fname); - return ret; + return fd; } /* * Read 'len' bytes of file into 'memp'. Returns 0 on success, else failure */ -int smh_read(int fd, void *memp, int len) +static long smh_read(long fd, void *memp, size_t len) { - int ret; + long ret; struct smh_read_s { - int fd; + long fd; void *memp; - int len; + size_t len; } read; - debug("%s: fd %d, memp %p, len %d\n", __func__, fd, memp, len); + debug("%s: fd %ld, memp %p, len %lu\n", __func__, fd, memp, len); read.fd = fd; read.memp = memp; read.len = len; ret = smh_trap(SYSREAD, &read); - if (ret == 0) { - return 0; - } else { + if (ret < 0) { /* * The ARM handler allows for returning partial lengths, * but in practice this never happens so rather than create * hard to maintain partial read loops and such, just fail * with an error message. */ - printf("%s: ERROR ret %d, fd %d, len %u memp %p\n", + printf("%s: ERROR ret %ld, fd %ld, len %lu memp %p\n", __func__, ret, fd, len, memp); + return -1; } - return ret; + + return 0; } /* - * Open a file on the host. Mode is "r" or "rb" currently. Returns a file - * descriptor or -1 on error. + * Close the file using the file descriptor */ -int smh_open(const char *fname, char *modestr) +static long smh_close(long fd) { - int ret, fd, mode; - struct smh_open_s { - const char *fname; - unsigned int mode; - unsigned int len; - } open; + long ret; - debug("%s: file \'%s\', mode \'%s\'\n", __func__, fname, modestr); - - ret = -1; + debug("%s: fd %ld\n", __func__, fd); - /* Check the file mode */ - if (!(strcmp(modestr, "r"))) { - mode = MODE_READ; - } else if (!(strcmp(modestr, "rb"))) { - mode = MODE_READBIN; - } else { - printf("%s: ERROR mode \'%s\' not supported\n", __func__, - modestr); - return ret; - } - - open.fname = fname; - open.len = strlen(fname); - open.mode = mode; - - /* Open the file on the host */ - fd = smh_trap(SYSOPEN, &open); - if (fd == -1) - printf("%s: ERROR fd %d for file \'%s\'\n", __func__, fd, - fname); + ret = smh_trap(SYSCLOSE, &fd); + if (ret == -1) + printf("%s: ERROR fd %ld\n", __func__, fd); - return fd; + return ret; } /* - * Close the file using the file descriptor + * Get the file length from the file descriptor */ -int smh_close(int fd) +static long smh_len_fd(long fd) { - int ret; - long fdlong; + long ret; - debug("%s: fd %d\n", __func__, fd); + debug("%s: fd %ld\n", __func__, fd); - fdlong = (long)fd; - ret = smh_trap(SYSCLOSE, &fdlong); + ret = smh_trap(SYSFLEN, &fd); if (ret == -1) - printf("%s: ERROR fd %d\n", __func__, fd); + printf("%s: ERROR ret %ld, fd %ld\n", __func__, ret, fd); return ret; } /* - * Get the file length from the file descriptor + * Open, load a file into memory, and close it. Check that the available space + * is sufficient to store the entire file. Return the bytes actually read from + * the file as seen by the read function. The verbose flag enables some extra + * printing of successful read status. */ -int smh_len_fd(int fd) +int smh_load(const char *fname, void *memp, int avail, int verbose) { - int ret; - long fdlong; + long ret; + long fd; + size_t len; - debug("%s: fd %d\n", __func__, fd); + ret = -1; - fdlong = (long)fd; - ret = smh_trap(SYSFLEN, &fdlong); - if (ret == -1) - printf("%s: ERROR ret %d\n", __func__, ret); + debug("%s: fname \'%s\', avail %u, memp %p\n", __func__, fname, + avail, memp); + + /* Open the file */ + fd = smh_open(fname, "rb"); + if (fd == -1) + return -1; + + /* Get the file length */ + ret = smh_len_fd(fd); + if (ret == -1) { + smh_close(fd); + return -1; + } + + /* Check that the file will fit in the supplied buffer */ + if (ret > avail) { + printf("%s: ERROR ret %ld, avail %u\n", __func__, ret, + avail); + smh_close(fd); + return -1; + } + + len = ret; + + /* Read the file into the buffer */ + ret = smh_read(fd, memp, len); + if (ret == 0) { + /* Print successful load information if requested */ + if (verbose) { + printf("\n%s\n", fname); + printf(" 0x%8p dest\n", memp); + printf(" 0x%08lx size\n", len); + printf(" 0x%08x avail\n", avail); + } + } + + /* Close the file */ + smh_close(fd); return ret; } @@ -207,26 +204,32 @@ int smh_len_fd(int fd) /* * Get the file length from the filename */ -int smh_len(const char *fname) +long smh_len(const char *fname) { - int ret, fd, len; + long ret; + long fd; + long len; debug("%s: file \'%s\'\n", __func__, fname); /* Open the file */ fd = smh_open(fname, "rb"); - if (fd == -1) + if (fd < 0) return fd; /* Get the file length */ len = smh_len_fd(fd); + if (len < 0) { + smh_close(fd); + return len; + } /* Close the file */ ret = smh_close(fd); - if (ret == -1) + if (ret < 0) return ret; - debug("%s: returning len %d\n", __func__, len); + debug("%s: returning len %ld\n", __func__, len); /* Return the file length (or -1 error indication) */ return len; |