From d60a2099a20254b33a314895a4b5e6a21aebd135 Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:34 +0800 Subject: [PATCH 01/17] arm: ls102xa: Add Freescale LS102xA SoC support The QorIQ LS1 family is built on Layerscape architecture, the industry's first software-aware, core-agnostic networking architecture to offer unprecedented efficiency and scale. Freescale LS102xA is a set of SoCs combines two ARM Cortex-A7 cores that have been optimized for high reliability and pack the highest level of integration available for sub-3 W embedded communications processors with Layerscape architecture and with a comprehensive enablement model focused on ease of programmability. Signed-off-by: Alison Wang Signed-off-by: Jason Jin Signed-off-by: Jingchang Lu Signed-off-by: Prabhakar Kushwaha --- arch/arm/cpu/armv7/ls102xa/Makefile | 12 + arch/arm/cpu/armv7/ls102xa/clock.c | 130 +++++ arch/arm/cpu/armv7/ls102xa/cpu.c | 103 ++++ arch/arm/cpu/armv7/ls102xa/fdt.c | 136 +++++ arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c | 120 +++++ arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h | 12 + arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c | 41 ++ arch/arm/cpu/armv7/ls102xa/timer.c | 127 +++++ arch/arm/include/asm/arch-ls102xa/clock.h | 23 + arch/arm/include/asm/arch-ls102xa/config.h | 74 +++ .../arm/include/asm/arch-ls102xa/fsl_serdes.h | 33 ++ .../include/asm/arch-ls102xa/immap_ls102xa.h | 493 ++++++++++++++++++ arch/arm/include/asm/arch-ls102xa/imx-regs.h | 53 ++ arch/arm/include/asm/config.h | 4 + arch/arm/include/asm/io.h | 8 +- drivers/watchdog/Makefile | 2 +- 16 files changed, 1369 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7/ls102xa/Makefile create mode 100644 arch/arm/cpu/armv7/ls102xa/clock.c create mode 100644 arch/arm/cpu/armv7/ls102xa/cpu.c create mode 100644 arch/arm/cpu/armv7/ls102xa/fdt.c create mode 100644 arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c create mode 100644 arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h create mode 100644 arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c create mode 100644 arch/arm/cpu/armv7/ls102xa/timer.c create mode 100644 arch/arm/include/asm/arch-ls102xa/clock.h create mode 100644 arch/arm/include/asm/arch-ls102xa/config.h create mode 100644 arch/arm/include/asm/arch-ls102xa/fsl_serdes.h create mode 100644 arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h create mode 100644 arch/arm/include/asm/arch-ls102xa/imx-regs.h diff --git a/arch/arm/cpu/armv7/ls102xa/Makefile b/arch/arm/cpu/armv7/ls102xa/Makefile new file mode 100644 index 0000000000..d82ce8d014 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/Makefile @@ -0,0 +1,12 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += cpu.o +obj-y += clock.o +obj-y += timer.o + +obj-$(CONFIG_OF_LIBFDT) += fdt.o +obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o diff --git a/arch/arm/cpu/armv7/ls102xa/clock.c b/arch/arm/cpu/armv7/ls102xa/clock.c new file mode 100644 index 0000000000..8f80c6175f --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/clock.c @@ -0,0 +1,130 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS +#define CONFIG_SYS_FSL_NUM_CC_PLLS 2 +#endif + +void get_sys_info(struct sys_info *sys_info) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); +#ifdef CONFIG_FSL_IFC + struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR; + u32 ccr; +#endif + struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR); + unsigned int cpu; + const u8 core_cplx_pll[6] = { + [0] = 0, /* CC1 PPL / 1 */ + [1] = 0, /* CC1 PPL / 2 */ + [4] = 1, /* CC2 PPL / 1 */ + [5] = 1, /* CC2 PPL / 2 */ + }; + + const u8 core_cplx_pll_div[6] = { + [0] = 1, /* CC1 PPL / 1 */ + [1] = 2, /* CC1 PPL / 2 */ + [4] = 1, /* CC2 PPL / 1 */ + [5] = 2, /* CC2 PPL / 2 */ + }; + + uint i; + uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS]; + uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS]; + unsigned long sysclk = CONFIG_SYS_CLK_FREQ; + + sys_info->freq_systembus = sysclk; +#ifdef CONFIG_DDR_CLK_FREQ + sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; +#else + sys_info->freq_ddrbus = sysclk; +#endif + + sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> + RCWSR0_SYS_PLL_RAT_SHIFT) & RCWSR0_SYS_PLL_RAT_MASK; + sys_info->freq_ddrbus *= (in_be32(&gur->rcwsr[0]) >> + RCWSR0_MEM_PLL_RAT_SHIFT) & RCWSR0_MEM_PLL_RAT_MASK; + + for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { + ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f; + if (ratio[i] > 4) + freq_c_pll[i] = sysclk * ratio[i]; + else + freq_c_pll[i] = sys_info->freq_systembus * ratio[i]; + } + + for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) { + u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27) + & 0xf; + u32 cplx_pll = core_cplx_pll[c_pll_sel]; + + sys_info->freq_processor[cpu] = + freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel]; + } + +#if defined(CONFIG_FSL_IFC) + ccr = in_be32(&ifc_regs->ifc_ccr); + ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1; + + sys_info->freq_localbus = sys_info->freq_systembus / ccr; +#endif +} + +int get_clocks(void) +{ + struct sys_info sys_info; + + get_sys_info(&sys_info); + gd->cpu_clk = sys_info.freq_processor[0]; + gd->bus_clk = sys_info.freq_systembus; + gd->mem_clk = sys_info.freq_ddrbus * 2; + +#if defined(CONFIG_FSL_ESDHC) + gd->arch.sdhc_clk = gd->bus_clk; +#endif + + return 0; +} + +ulong get_bus_freq(ulong dummy) +{ + return gd->bus_clk; +} + +ulong get_ddr_freq(ulong dummy) +{ + return gd->mem_clk; +} + +int get_serial_clock(void) +{ + return gd->bus_clk / 2; +} + +unsigned int mxc_get_clock(enum mxc_clock clk) +{ + switch (clk) { + case MXC_I2C_CLK: + return get_bus_freq(0) / 2; + case MXC_ESDHC_CLK: + return get_bus_freq(0); + case MXC_DSPI_CLK: + return get_bus_freq(0) / 2; + case MXC_UART_CLK: + return get_bus_freq(0) / 2; + default: + printf("Unsupported clock\n"); + } + return 0; +} diff --git a/arch/arm/cpu/armv7/ls102xa/cpu.c b/arch/arm/cpu/armv7/ls102xa/cpu.c new file mode 100644 index 0000000000..b7dde45ed3 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/cpu.c @@ -0,0 +1,103 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + char buf1[32], buf2[32]; + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr, major, minor, ver, i; + + svr = in_be32(&gur->svr); + major = SVR_MAJ(svr); + minor = SVR_MIN(svr); + + puts("CPU: Freescale LayerScape "); + + ver = SVR_SOC_VER(svr); + switch (ver) { + case SOC_VER_SLS1020: + puts("SLS1020"); + break; + case SOC_VER_LS1020: + puts("LS1020"); + break; + case SOC_VER_LS1021: + puts("LS1021"); + break; + case SOC_VER_LS1022: + puts("LS1022"); + break; + default: + puts("Unknown"); + break; + } + + if (IS_E_PROCESSOR(svr) && (ver != SOC_VER_SLS1020)) + puts("E"); + + printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr); + + puts("Clock Configuration:"); + + printf("\n CPU0(ARMV7):%-4s MHz, ", strmhz(buf1, gd->cpu_clk)); + printf("\n Bus:%-4s MHz, ", strmhz(buf1, gd->bus_clk)); + printf("DDR:%-4s MHz (%s MT/s data rate), ", + strmhz(buf1, gd->mem_clk/2), strmhz(buf2, gd->mem_clk)); + puts("\n"); + + /* Display the RCW, so that no one gets confused as to what RCW + * we're actually using for this boot. + */ + puts("Reset Configuration Word (RCW):"); + for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) { + u32 rcw = in_be32(&gur->rcwsr[i]); + + if ((i % 4) == 0) + printf("\n %08x:", i * 4); + printf(" %08x", rcw); + } + puts("\n"); + + return 0; +} +#endif + +void enable_caches(void) +{ +#ifndef CONFIG_SYS_ICACHE_OFF + icache_enable(); +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + dcache_enable(); +#endif +} + +#ifdef CONFIG_FSL_ESDHC +int cpu_mmc_init(bd_t *bis) +{ + return fsl_esdhc_mmc_init(bis); +} +#endif + +int cpu_eth_init(bd_t *bis) +{ +#ifdef CONFIG_TSEC_ENET + tsec_standard_init(bis); +#endif + + return 0; +} diff --git a/arch/arm/cpu/armv7/ls102xa/fdt.c b/arch/arm/cpu/armv7/ls102xa/fdt.c new file mode 100644 index 0000000000..4ce38086f4 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/fdt.c @@ -0,0 +1,136 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_FSL_ESDHC +#include +#endif +#include + +DECLARE_GLOBAL_DATA_PTR; + +void ft_fixup_enet_phy_connect_type(void *fdt) +{ + struct eth_device *dev; + struct tsec_private *priv; + const char *enet_path, *phy_path; + char enet[16]; + char phy[16]; + int phy_node; + int i = 0; + int enet_id = 0; + uint32_t ph; + + while ((dev = eth_get_dev_by_index(i++)) != NULL) { + if (strstr(dev->name, "eTSEC1")) + enet_id = 0; + else if (strstr(dev->name, "eTSEC2")) + enet_id = 1; + else if (strstr(dev->name, "eTSEC3")) + enet_id = 2; + else + continue; + + priv = dev->priv; + if (priv->flags & TSEC_SGMII) + continue; + + sprintf(enet, "ethernet%d", enet_id); + enet_path = fdt_get_alias(fdt, enet); + if (!enet_path) + continue; + + sprintf(phy, "enet%d_rgmii_phy", enet_id); + phy_path = fdt_get_alias(fdt, phy); + if (!phy_path) + continue; + + phy_node = fdt_path_offset(fdt, phy_path); + if (phy_node < 0) + continue; + + ph = fdt_create_phandle(fdt, phy_node); + if (ph) + do_fixup_by_path_u32(fdt, enet_path, + "phy-handle", ph, 1); + + do_fixup_by_path(fdt, enet_path, "phy-connection-type", + phy_string_for_interface( + PHY_INTERFACE_MODE_RGMII_ID), + sizeof(phy_string_for_interface( + PHY_INTERFACE_MODE_RGMII_ID)), + 1); + } +} + +void ft_cpu_setup(void *blob, bd_t *bd) +{ + int off; + int val; + const char *sysclk_path; + + unsigned long busclk = get_bus_freq(0); + + fdt_fixup_ethernet(blob); + + off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4); + while (off != -FDT_ERR_NOTFOUND) { + val = gd->cpu_clk; + fdt_setprop(blob, off, "clock-frequency", &val, 4); + off = fdt_node_offset_by_prop_value(blob, off, + "device_type", "cpu", 4); + } + + do_fixup_by_prop_u32(blob, "device_type", "soc", + 4, "bus-frequency", busclk / 2, 1); + + ft_fixup_enet_phy_connect_type(blob); + +#ifdef CONFIG_SYS_NS16550 + do_fixup_by_compat_u32(blob, "fsl,16550-FIFO64", + "clock-frequency", CONFIG_SYS_NS16550_CLK, 1); +#endif + + sysclk_path = fdt_get_alias(blob, "sysclk"); + if (sysclk_path) + do_fixup_by_path_u32(blob, sysclk_path, "clock-frequency", + CONFIG_SYS_CLK_FREQ, 1); + do_fixup_by_compat_u32(blob, "fsl,qoriq-sysclk-2.0", + "clock-frequency", CONFIG_SYS_CLK_FREQ, 1); + +#if defined(CONFIG_FSL_ESDHC) + fdt_fixup_esdhc(blob, bd); +#endif + + /* + * platform bus clock = system bus clock/2 + * Here busclk = system bus clock + * We are using the platform bus clock as 1588 Timer reference + * clock source select + */ + do_fixup_by_compat_u32(blob, "fsl, gianfar-ptp-timer", + "timer-frequency", busclk / 2, 1); + + /* + * clock-freq should change to clock-frequency and + * flexcan-v1.0 should change to p1010-flexcan respectively + * in the future. + */ + do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0", + "clock_freq", busclk / 2, 1); + + do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0", + "clock-frequency", busclk / 2, 1); + + do_fixup_by_compat_u32(blob, "fsl, ls1021a-flexcan", + "clock-frequency", busclk / 2, 1); +} diff --git a/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c new file mode 100644 index 0000000000..9b78acb25a --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c @@ -0,0 +1,120 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include "fsl_ls1_serdes.h" + +#ifdef CONFIG_SYS_FSL_SRDS_1 +static u64 serdes1_prtcl_map; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 +static u64 serdes2_prtcl_map; +#endif + +int is_serdes_configured(enum srds_prtcl device) +{ + u64 ret = 0; + +#ifdef CONFIG_SYS_FSL_SRDS_1 + ret |= (1ULL << device) & serdes1_prtcl_map; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + ret |= (1ULL << device) & serdes2_prtcl_map; +#endif + + return !!ret; +} + +int serdes_get_first_lane(u32 sd, enum srds_prtcl device) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 cfg = in_be32(&gur->rcwsr[4]); + int i; + + switch (sd) { +#ifdef CONFIG_SYS_FSL_SRDS_1 + case FSL_SRDS_1: + cfg &= RCWSR4_SRDS1_PRTCL_MASK; + cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT; + break; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + case FSL_SRDS_2: + cfg &= RCWSR4_SRDS2_PRTCL_MASK; + cfg >>= RCWSR4_SRDS2_PRTCL_SHIFT; + break; +#endif + default: + printf("invalid SerDes%d\n", sd); + break; + } + /* Is serdes enabled at all? */ + if (unlikely(cfg == 0)) + return -ENODEV; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (serdes_get_prtcl(sd, cfg, i) == device) + return i; + } + + return -ENODEV; +} + +u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u64 serdes_prtcl_map = 0; + u32 cfg; + int lane; + + cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask; + cfg >>= sd_prctl_shift; + printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg); + + if (!is_serdes_prtcl_valid(sd, cfg)) + printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg); + + for (lane = 0; lane < SRDS_MAX_LANES; lane++) { + enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane); + + serdes_prtcl_map |= (1ULL << lane_prtcl); + } + + return serdes_prtcl_map; +} + +void fsl_serdes_init(void) +{ +#ifdef CONFIG_SYS_FSL_SRDS_1 + serdes1_prtcl_map = serdes_init(FSL_SRDS_1, + CONFIG_SYS_FSL_SERDES_ADDR, + RCWSR4_SRDS1_PRTCL_MASK, + RCWSR4_SRDS1_PRTCL_SHIFT); +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + serdes2_prtcl_map = serdes_init(FSL_SRDS_2, + CONFIG_SYS_FSL_SERDES_ADDR + + FSL_SRDS_2 * 0x1000, + RCWSR4_SRDS2_PRTCL_MASK, + RCWSR4_SRDS2_PRTCL_SHIFT); +#endif +} + +const char *serdes_clock_to_string(u32 clock) +{ + switch (clock) { + case SRDS_PLLCR0_RFCK_SEL_100: + return "100"; + case SRDS_PLLCR0_RFCK_SEL_125: + return "125"; + default: + return "100"; + } +} diff --git a/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h new file mode 100644 index 0000000000..834aa532bf --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h @@ -0,0 +1,12 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_LS1_SERDES_H +#define __FSL_LS1_SERDES_H + +int is_serdes_prtcl_valid(int serdes, u32 prtcl); +int serdes_lane_enabled(int lane); +#endif /* __FSL_LS1_SERDES_H */ diff --git a/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c b/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c new file mode 100644 index 0000000000..cc53910bbb --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c @@ -0,0 +1,41 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +static u8 serdes_cfg_tbl[][SRDS_MAX_LANES] = { + [0x00] = {PCIE1, PCIE1, PCIE1, PCIE1}, + [0x10] = {PCIE1, SATA1, PCIE2, PCIE2}, + [0x20] = {PCIE1, SGMII_TSEC1, PCIE2, SGMII_TSEC2}, + [0x30] = {PCIE1, SATA1, SGMII_TSEC1, SGMII_TSEC2}, + [0x40] = {PCIE1, PCIE1, SATA1, SGMII_TSEC2}, + [0x50] = {PCIE1, PCIE1, PCIE2, SGMII_TSEC2}, + [0x60] = {PCIE1, PCIE1, SGMII_TSEC1, SGMII_TSEC2}, + [0x70] = {PCIE1, SATA1, PCIE2, SGMII_TSEC2}, + [0x80] = {PCIE2, PCIE2, PCIE2, PCIE2}, +}; + +enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane) +{ + return serdes_cfg_tbl[cfg][lane]; +} + +int is_serdes_prtcl_valid(int serdes, u32 prtcl) +{ + int i; + + if (prtcl >= ARRAY_SIZE(serdes_cfg_tbl)) + return 0; + + for (i = 0; i < SRDS_MAX_LANES; i++) { + if (serdes_cfg_tbl[prtcl][i] != NONE) + return 1; + } + + return 0; +} diff --git a/arch/arm/cpu/armv7/ls102xa/timer.c b/arch/arm/cpu/armv7/ls102xa/timer.c new file mode 100644 index 0000000000..11b17b2c74 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/timer.c @@ -0,0 +1,127 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/* + * This function is intended for SHORT delays only. + * It will overflow at around 10 seconds @ 400MHz, + * or 20 seconds @ 200MHz. + */ +unsigned long usec2ticks(unsigned long usec) +{ + ulong ticks; + + if (usec < 1000) + ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000; + else + ticks = ((usec / 10) * (get_tbclk() / 100000)); + + return ticks; +} + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + unsigned long freq; + + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq)); + + tick *= CONFIG_SYS_HZ; + do_div(tick, freq); + + return tick; +} + +static inline unsigned long long us_to_tick(unsigned long long usec) +{ + unsigned long freq; + + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq)); + + usec = usec * freq + 999999; + do_div(usec, 1000000); + + return usec; +} + +int timer_init(void) +{ + struct sctr_regs *sctr = (struct sctr_regs *)SCTR_BASE_ADDR; + unsigned long ctrl, val, freq; + + /* Enable System Counter */ + writel(SYS_COUNTER_CTRL_ENABLE, &sctr->cntcr); + + freq = GENERIC_TIMER_CLK; + asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); + + /* Set PL1 Physical Timer Ctrl */ + ctrl = ARCH_TIMER_CTRL_ENABLE; + asm("mcr p15, 0, %0, c14, c2, 1" : : "r" (ctrl)); + + /* Set PL1 Physical Comp Value */ + val = TIMER_COMP_VAL; + asm("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val)); + + gd->arch.tbl = 0; + gd->arch.tbu = 0; + + return 0; +} + +unsigned long long get_ticks(void) +{ + unsigned long long now; + + asm("mrrc p15, 0, %Q0, %R0, c14" : "=r" (now)); + + gd->arch.tbl = (unsigned long)(now & 0xffffffff); + gd->arch.tbu = (unsigned long)(now >> 32); + + return now; +} + +unsigned long get_timer_masked(void) +{ + return tick_to_time(get_ticks()); +} + +unsigned long get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* delay x useconds and preserve advance timstamp value */ +void __udelay(unsigned long usec) +{ + unsigned long long start; + unsigned long tmo; + + start = get_ticks(); /* get current timestamp */ + tmo = us_to_tick(usec); /* convert usecs to ticks */ + + while ((get_ticks() - start) < tmo) + ; /* loop till time has passed */ +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +unsigned long get_tbclk(void) +{ + unsigned long freq; + + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq)); + + return freq; +} diff --git a/arch/arm/include/asm/arch-ls102xa/clock.h b/arch/arm/include/asm/arch-ls102xa/clock.h new file mode 100644 index 0000000000..fd36bb0a50 --- /dev/null +++ b/arch/arm/include/asm/arch-ls102xa/clock.h @@ -0,0 +1,23 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ + +#ifndef __ASM_ARCH_LS102XA_CLOCK_H_ +#define __ASM_ARCH_LS102XA_CLOCK_H_ + +#include + +enum mxc_clock { + MXC_ARM_CLK = 0, + MXC_UART_CLK, + MXC_ESDHC_CLK, + MXC_I2C_CLK, + MXC_DSPI_CLK, +}; + +unsigned int mxc_get_clock(enum mxc_clock clk); + +#endif /* __ASM_ARCH_LS102XA_CLOCK_H_ */ diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h new file mode 100644 index 0000000000..08c21afd1e --- /dev/null +++ b/arch/arm/include/asm/arch-ls102xa/config.h @@ -0,0 +1,74 @@ +/* + * Copyright 2014, Freescale Semiconductor + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_ARMV7_LS102XA_CONFIG_ +#define _ASM_ARMV7_LS102XA_CONFIG_ + +#define CONFIG_SYS_CACHELINE_SIZE 64 + +#define OCRAM_BASE_ADDR 0x10000000 +#define OCRAM_SIZE 0x00020000 + +#define CONFIG_SYS_IMMR 0x01000000 + +#define CONFIG_SYS_FSL_DDR_ADDR (CONFIG_SYS_IMMR + 0x00080000) +#define CONFIG_SYS_CCI400_ADDR (CONFIG_SYS_IMMR + 0x00180000) +#define CONFIG_SYS_IFC_ADDR (CONFIG_SYS_IMMR + 0x00530000) +#define CONFIG_SYS_FSL_ESDHC_ADDR (CONFIG_SYS_IMMR + 0x00560000) +#define CONFIG_SYS_FSL_SCFG_ADDR (CONFIG_SYS_IMMR + 0x00570000) +#define CONFIG_SYS_FSL_SERDES_ADDR (CONFIG_SYS_IMMR + 0x00ea0000) +#define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00ee0000) +#define CONFIG_SYS_FSL_LS1_CLK_ADDR (CONFIG_SYS_IMMR + 0x00ee1000) +#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011c0500) +#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011d0500) + +#define CONFIG_SYS_TSEC1_OFFSET 0x01d10000 +#define CONFIG_SYS_TSEC2_OFFSET 0x01d50000 +#define CONFIG_SYS_TSEC3_OFFSET 0x01d90000 +#define CONFIG_SYS_MDIO1_OFFSET 0x01d24000 + +#define TSEC_BASE_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_TSEC1_OFFSET) +#define MDIO_BASE_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MDIO1_OFFSET) + +#define SCTR_BASE_ADDR (CONFIG_SYS_IMMR + 0x01b00000) + +#define I2C1_BASE_ADDR (CONFIG_SYS_IMMR + 0x01180000) +#define I2C2_BASE_ADDR (CONFIG_SYS_IMMR + 0x01190000) +#define I2C3_BASE_ADDR (CONFIG_SYS_IMMR + 0x011a0000) + +#define WDOG1_BASE_ADDR (CONFIG_SYS_IMMR + 0x01ad0000) + +#define QSPI0_BASE_ADDR (CONFIG_SYS_IMMR + 0x00550000) +#define DSPI1_BASE_ADDR (CONFIG_SYS_IMMR + 0x01100000) + +#define LPUART_BASE (CONFIG_SYS_IMMR + 0x01950000) + +#ifdef CONFIG_DDR_SPD +#define CONFIG_SYS_FSL_DDR_BE +#define CONFIG_VERY_BIG_RAM +#define CONFIG_SYS_FSL_DDRC_ARM_GEN3 +#define CONFIG_SYS_FSL_DDR +#define CONFIG_SYS_LS1_DDR_BLOCK1_SIZE ((phys_size_t)2 << 30) +#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_LS1_DDR_BLOCK1_SIZE +#endif + +#define CONFIG_SYS_FSL_IFC_BE +#define CONFIG_SYS_FSL_ESDHC_BE +#define CONFIG_SYS_FSL_WDOG_BE +#define CONFIG_SYS_FSL_DSPI_BE +#define CONFIG_SYS_FSL_QSPI_BE + +#define CONFIG_SYS_FSL_SRDS_1 + +#ifdef CONFIG_LS102XA +#define CONFIG_MAX_CPUS 2 +#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8 +#define CONFIG_NUM_DDR_CONTROLLERS 1 +#else +#error SoC not defined +#endif + +#endif /* _ASM_ARMV7_LS102XA_CONFIG_ */ diff --git a/arch/arm/include/asm/arch-ls102xa/fsl_serdes.h b/arch/arm/include/asm/arch-ls102xa/fsl_serdes.h new file mode 100644 index 0000000000..3a92f5a7b4 --- /dev/null +++ b/arch/arm/include/asm/arch-ls102xa/fsl_serdes.h @@ -0,0 +1,33 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_SERDES_H +#define __FSL_SERDES_H + +#include + +enum srds_prtcl { + NONE = 0, + PCIE1, + PCIE2, + SATA1, + SGMII_TSEC1, + SGMII_TSEC2, +}; + +enum srds { + FSL_SRDS_1 = 0, + FSL_SRDS_2 = 1, +}; + +int is_serdes_configured(enum srds_prtcl device); +void fsl_serdes_init(void); +const char *serdes_clock_to_string(u32 clock); + +int serdes_get_first_lane(u32 sd, enum srds_prtcl device); +enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane); + +#endif /* __FSL_SERDES_H */ diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h new file mode 100644 index 0000000000..7995fe262b --- /dev/null +++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h @@ -0,0 +1,493 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_LS102XA_IMMAP_H_ +#define __ASM_ARCH_LS102XA_IMMAP_H_ + +#define SVR_MAJ(svr) (((svr) >> 4) & 0xf) +#define SVR_MIN(svr) (((svr) >> 0) & 0xf) +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0x7ff) +#define IS_E_PROCESSOR(svr) (svr & 0x80000) + +#define SOC_VER_SLS1020 0x00 +#define SOC_VER_LS1020 0x10 +#define SOC_VER_LS1021 0x11 +#define SOC_VER_LS1022 0x12 + +#define RCWSR0_SYS_PLL_RAT_SHIFT 25 +#define RCWSR0_SYS_PLL_RAT_MASK 0x1f +#define RCWSR0_MEM_PLL_RAT_SHIFT 16 +#define RCWSR0_MEM_PLL_RAT_MASK 0x3f + +#define RCWSR4_SRDS1_PRTCL_SHIFT 24 +#define RCWSR4_SRDS1_PRTCL_MASK 0xff000000 + +#define TIMER_COMP_VAL 0xffffffff +#define ARCH_TIMER_CTRL_ENABLE (1 << 0) +#define SYS_COUNTER_CTRL_ENABLE (1 << 24) + +struct sys_info { + unsigned long freq_processor[CONFIG_MAX_CPUS]; + unsigned long freq_systembus; + unsigned long freq_ddrbus; + unsigned long freq_localbus; +}; + +/* Device Configuration and Pin Control */ +struct ccsr_gur { + u32 porsr1; /* POR status 1 */ + u32 porsr2; /* POR status 2 */ + u8 res_008[0x20-0x8]; + u32 gpporcr1; /* General-purpose POR configuration */ + u32 gpporcr2; + u32 dcfg_fusesr; /* Fuse status register */ + u8 res_02c[0x70-0x2c]; + u32 devdisr; /* Device disable control */ + u32 devdisr2; /* Device disable control 2 */ + u32 devdisr3; /* Device disable control 3 */ + u32 devdisr4; /* Device disable control 4 */ + u32 devdisr5; /* Device disable control 5 */ + u8 res_084[0x94-0x84]; + u32 coredisru; /* uppper portion for support of 64 cores */ + u32 coredisrl; /* lower portion for support of 64 cores */ + u8 res_09c[0xa4-0x9c]; + u32 svr; /* System version */ + u8 res_0a8[0xb0-0xa8]; + u32 rstcr; /* Reset control */ + u32 rstrqpblsr; /* Reset request preboot loader status */ + u8 res_0b8[0xc0-0xb8]; + u32 rstrqmr1; /* Reset request mask */ + u8 res_0c4[0xc8-0xc4]; + u32 rstrqsr1; /* Reset request status */ + u8 res_0cc[0xd4-0xcc]; + u32 rstrqwdtmrl; /* Reset request WDT mask */ + u8 res_0d8[0xdc-0xd8]; + u32 rstrqwdtsrl; /* Reset request WDT status */ + u8 res_0e0[0xe4-0xe0]; + u32 brrl; /* Boot release */ + u8 res_0e8[0x100-0xe8]; + u32 rcwsr[16]; /* Reset control word status */ + u8 res_140[0x200-0x140]; + u32 scratchrw[4]; /* Scratch Read/Write */ + u8 res_210[0x300-0x210]; + u32 scratchw1r[4]; /* Scratch Read (Write once) */ + u8 res_310[0x400-0x310]; + u32 crstsr; + u8 res_404[0x550-0x404]; + u32 sataliodnr; + u8 res_554[0x604-0x554]; + u32 pamubypenr; + u32 dmacr1; + u8 res_60c[0x740-0x60c]; /* add more registers when needed */ + u32 tp_ityp[64]; /* Topology Initiator Type Register */ + struct { + u32 upper; + u32 lower; + } tp_cluster[1]; /* Core Cluster n Topology Register */ + u8 res_848[0xe60-0x848]; + u32 ddrclkdr; + u8 res_e60[0xe68-0xe64]; + u32 ifcclkdr; + u8 res_e68[0xe80-0xe6c]; + u32 sdhcpcr; +}; + +#define SCFG_SCFGREVCR_REV 0xffffffff +#define SCFG_SCFGREVCR_NOREV 0 +#define SCFG_ETSECDMAMCR_LE_BD_FR 0xf8001a0f +#define SCFG_ETSECCMCR_GE2_CLK125 0x04000000 +#define SCFG_PIXCLKCR_PXCKEN 0x80000000 + +/* Supplemental Configuration Unit */ +struct ccsr_scfg { + u32 dpslpcr; + u32 resv0[2]; + u32 etsecclkdpslpcr; + u32 resv1[5]; + u32 fuseovrdcr; + u32 pixclkcr; + u32 resv2[5]; + u32 spimsicr; + u32 resv3[6]; + u32 pex1pmwrcr; + u32 pex1pmrdsr; + u32 resv4[3]; + u32 usb3prm1cr; + u32 usb4prm2cr; + u32 pex1rdmsgpldlsbsr; + u32 pex1rdmsgpldmsbsr; + u32 pex2rdmsgpldlsbsr; + u32 pex2rdmsgpldmsbsr; + u32 pex1rdmmsgrqsr; + u32 pex2rdmmsgrqsr; + u32 spimsiclrcr; + u32 pex1mscportsr; + u32 pex2mscportsr; + u32 pex2pmwrcr; + u32 resv5[24]; + u32 mac1_streamid; + u32 mac2_streamid; + u32 mac3_streamid; + u32 pex1_streamid; + u32 pex2_streamid; + u32 dma_streamid; + u32 sata_streamid; + u32 usb3_streamid; + u32 qe_streamid; + u32 sdhc_streamid; + u32 adma_streamid; + u32 letechsftrstcr; + u32 core0_sft_rst; + u32 core1_sft_rst; + u32 resv6[1]; + u32 usb_hi_addr; + u32 etsecclkadjcr; + u32 sai_clk; + u32 resv7[1]; + u32 dcu_streamid; + u32 usb2_streamid; + u32 ftm_reset; + u32 altcbar; + u32 qspi_cfg; + u32 pmcintecr; + u32 pmcintlecr; + u32 pmcintsr; + u32 qos1; + u32 qos2; + u32 qos3; + u32 cci_cfg; + u32 resv8[1]; + u32 etsecdmamcr; + u32 usb3prm3cr; + u32 resv9[1]; + u32 debug_streamid; + u32 resv10[5]; + u32 snpcnfgcr; + u32 resv11[1]; + u32 intpcr; + u32 resv12[20]; + u32 scfgrevcr; + u32 coresrencr; + u32 pex2pmrdsr; + u32 ddrc1cr; + u32 ddrc2cr; + u32 ddrc3cr; + u32 ddrc4cr; + u32 ddrgcr; + u32 resv13[120]; + u32 qeioclkcr; + u32 etsecmcr; + u32 sdhciovserlcr; + u32 resv14[61]; + u32 sparecr; +}; + +/* Clocking */ +struct ccsr_clk { + struct { + u32 clkcncsr; /* core cluster n clock control status */ + u8 res_004[0x1c]; + } clkcsr[2]; + u8 res_040[0x7c0]; /* 0x100 */ + struct { + u32 pllcngsr; + u8 res_804[0x1c]; + } pllcgsr[2]; + u8 res_840[0x1c0]; + u32 clkpcsr; /* 0xa00 Platform clock domain control/status */ + u8 res_a04[0x1fc]; + u32 pllpgsr; /* 0xc00 Platform PLL General Status */ + u8 res_c04[0x1c]; + u32 plldgsr; /* 0xc20 DDR PLL General Status */ + u8 res_c24[0x3dc]; +}; + +/* System Counter */ +struct sctr_regs { + u32 cntcr; + u32 cntsr; + u32 cntcv1; + u32 cntcv2; + u32 resv1[4]; + u32 cntfid0; + u32 cntfid1; + u32 resv2[1002]; + u32 counterid[12]; +}; + +#define MAX_SERDES 1 +#define SRDS_MAX_LANES 4 +#define SRDS_MAX_BANK 2 + +#define SRDS_RSTCTL_RST 0x80000000 +#define SRDS_RSTCTL_RSTDONE 0x40000000 +#define SRDS_RSTCTL_RSTERR 0x20000000 +#define SRDS_RSTCTL_SWRST 0x10000000 +#define SRDS_RSTCTL_SDEN 0x00000020 +#define SRDS_RSTCTL_SDRST_B 0x00000040 +#define SRDS_RSTCTL_PLLRST_B 0x00000080 +#define SRDS_PLLCR0_POFF 0x80000000 +#define SRDS_PLLCR0_RFCK_SEL_MASK 0x70000000 +#define SRDS_PLLCR0_RFCK_SEL_100 0x00000000 +#define SRDS_PLLCR0_RFCK_SEL_125 0x10000000 +#define SRDS_PLLCR0_RFCK_SEL_156_25 0x20000000 +#define SRDS_PLLCR0_RFCK_SEL_150 0x30000000 +#define SRDS_PLLCR0_RFCK_SEL_161_13 0x40000000 +#define SRDS_PLLCR0_RFCK_SEL_122_88 0x50000000 +#define SRDS_PLLCR0_PLL_LCK 0x00800000 +#define SRDS_PLLCR0_FRATE_SEL_MASK 0x000f0000 +#define SRDS_PLLCR0_FRATE_SEL_5 0x00000000 +#define SRDS_PLLCR0_FRATE_SEL_3_75 0x00050000 +#define SRDS_PLLCR0_FRATE_SEL_5_15 0x00060000 +#define SRDS_PLLCR0_FRATE_SEL_4 0x00070000 +#define SRDS_PLLCR0_FRATE_SEL_3_12 0x00090000 +#define SRDS_PLLCR0_FRATE_SEL_3 0x000a0000 +#define SRDS_PLLCR1_PLL_BWSEL 0x08000000 + +struct ccsr_serdes { + struct { + u32 rstctl; /* Reset Control Register */ + + u32 pllcr0; /* PLL Control Register 0 */ + + u32 pllcr1; /* PLL Control Register 1 */ + u32 res_0c; /* 0x00c */ + u32 pllcr3; + u32 pllcr4; + u8 res_18[0x20-0x18]; + } bank[2]; + u8 res_40[0x90-0x40]; + u32 srdstcalcr; /* 0x90 TX Calibration Control */ + u8 res_94[0xa0-0x94]; + u32 srdsrcalcr; /* 0xa0 RX Calibration Control */ + u8 res_a4[0xb0-0xa4]; + u32 srdsgr0; /* 0xb0 General Register 0 */ + u8 res_b4[0xe0-0xb4]; + u32 srdspccr0; /* 0xe0 Protocol Converter Config 0 */ + u32 srdspccr1; /* 0xe4 Protocol Converter Config 1 */ + u32 srdspccr2; /* 0xe8 Protocol Converter Config 2 */ + u32 srdspccr3; /* 0xec Protocol Converter Config 3 */ + u32 srdspccr4; /* 0xf0 Protocol Converter Config 4 */ + u8 res_f4[0x100-0xf4]; + struct { + u32 lnpssr; /* 0x100, 0x120, ..., 0x1e0 */ + u8 res_104[0x120-0x104]; + } srdslnpssr[4]; + u8 res_180[0x300-0x180]; + u32 srdspexeqcr; + u32 srdspexeqpcr[11]; + u8 res_330[0x400-0x330]; + u32 srdspexapcr; + u8 res_404[0x440-0x404]; + u32 srdspexbpcr; + u8 res_444[0x800-0x444]; + struct { + u32 gcr0; /* 0x800 General Control Register 0 */ + u32 gcr1; /* 0x804 General Control Register 1 */ + u32 gcr2; /* 0x808 General Control Register 2 */ + u32 sscr0; + u32 recr0; /* 0x810 Receive Equalization Control */ + u32 recr1; + u32 tecr0; /* 0x818 Transmit Equalization Control */ + u32 sscr1; + u32 ttlcr0; /* 0x820 Transition Tracking Loop Ctrl 0 */ + u8 res_824[0x83c-0x824]; + u32 tcsr3; + } lane[4]; /* Lane A, B, C, D, E, F, G, H */ + u8 res_a00[0x1000-0xa00]; /* from 0xa00 to 0xfff */ +}; + +#define DDR_SDRAM_CFG 0x470c0008 +#define DDR_CS0_BNDS 0x008000bf +#define DDR_CS0_CONFIG 0x80014302 +#define DDR_TIMING_CFG_0 0x50550004 +#define DDR_TIMING_CFG_1 0xbcb38c56 +#define DDR_TIMING_CFG_2 0x0040d120 +#define DDR_TIMING_CFG_3 0x010e1000 +#define DDR_TIMING_CFG_4 0x00000001 +#define DDR_TIMING_CFG_5 0x03401400 +#define DDR_SDRAM_CFG_2 0x00401010 +#define DDR_SDRAM_MODE 0x00061c60 +#define DDR_SDRAM_MODE_2 0x00180000 +#define DDR_SDRAM_INTERVAL 0x18600618 +#define DDR_DDR_WRLVL_CNTL 0x8655f605 +#define DDR_DDR_WRLVL_CNTL_2 0x05060607 +#define DDR_DDR_WRLVL_CNTL_3 0x05050505 +#define DDR_DDR_CDR1 0x80040000 +#define DDR_DDR_CDR2 0x00000001 +#define DDR_SDRAM_CLK_CNTL 0x02000000 +#define DDR_DDR_ZQ_CNTL 0x89080600 +#define DDR_CS0_CONFIG_2 0 +#define DDR_SDRAM_CFG_MEM_EN 0x80000000 + +/* DDR memory controller registers */ +struct ccsr_ddr { + u32 cs0_bnds; /* Chip Select 0 Memory Bounds */ + u32 resv1[1]; + u32 cs1_bnds; /* Chip Select 1 Memory Bounds */ + u32 resv2[1]; + u32 cs2_bnds; /* Chip Select 2 Memory Bounds */ + u32 resv3[1]; + u32 cs3_bnds; /* Chip Select 3 Memory Bounds */ + u32 resv4[25]; + u32 cs0_config; /* Chip Select Configuration */ + u32 cs1_config; /* Chip Select Configuration */ + u32 cs2_config; /* Chip Select Configuration */ + u32 cs3_config; /* Chip Select Configuration */ + u32 resv5[12]; + u32 cs0_config_2; /* Chip Select Configuration 2 */ + u32 cs1_config_2; /* Chip Select Configuration 2 */ + u32 cs2_config_2; /* Chip Select Configuration 2 */ + u32 cs3_config_2; /* Chip Select Configuration 2 */ + u32 resv6[12]; + u32 timing_cfg_3; /* SDRAM Timing Configuration 3 */ + u32 timing_cfg_0; /* SDRAM Timing Configuration 0 */ + u32 timing_cfg_1; /* SDRAM Timing Configuration 1 */ + u32 timing_cfg_2; /* SDRAM Timing Configuration 2 */ + u32 sdram_cfg; /* SDRAM Control Configuration */ + u32 sdram_cfg_2; /* SDRAM Control Configuration 2 */ + u32 sdram_mode; /* SDRAM Mode Configuration */ + u32 sdram_mode_2; /* SDRAM Mode Configuration 2 */ + u32 sdram_md_cntl; /* SDRAM Mode Control */ + u32 sdram_interval; /* SDRAM Interval Configuration */ + u32 sdram_data_init; /* SDRAM Data initialization */ + u32 resv7[1]; + u32 sdram_clk_cntl; /* SDRAM Clock Control */ + u32 resv8[5]; + u32 init_addr; /* training init addr */ + u32 init_ext_addr; /* training init extended addr */ + u32 resv9[4]; + u32 timing_cfg_4; /* SDRAM Timing Configuration 4 */ + u32 timing_cfg_5; /* SDRAM Timing Configuration 5 */ + u32 timing_cfg_6; /* SDRAM Timing Configuration 6 */ + u32 timing_cfg_7; /* SDRAM Timing Configuration 7 */ + u32 ddr_zq_cntl; /* ZQ calibration control*/ + u32 ddr_wrlvl_cntl; /* write leveling control*/ + u32 resv10[1]; + u32 ddr_sr_cntr; /* self refresvh counter */ + u32 ddr_sdram_rcw_1; /* Control Words 1 */ + u32 ddr_sdram_rcw_2; /* Control Words 2 */ + u32 resv11[2]; + u32 ddr_wrlvl_cntl_2; /* write leveling control 2 */ + u32 ddr_wrlvl_cntl_3; /* write leveling control 3 */ + u32 resv12[2]; + u32 ddr_sdram_rcw_3; /* Control Words 3 */ + u32 ddr_sdram_rcw_4; /* Control Words 4 */ + u32 ddr_sdram_rcw_5; /* Control Words 5 */ + u32 ddr_sdram_rcw_6; /* Control Words 6 */ + u32 resv13[20]; + u32 sdram_mode_3; /* SDRAM Mode Configuration 3 */ + u32 sdram_mode_4; /* SDRAM Mode Configuration 4 */ + u32 sdram_mode_5; /* SDRAM Mode Configuration 5 */ + u32 sdram_mode_6; /* SDRAM Mode Configuration 6 */ + u32 sdram_mode_7; /* SDRAM Mode Configuration 7 */ + u32 sdram_mode_8; /* SDRAM Mode Configuration 8 */ + u32 sdram_mode_9; /* SDRAM Mode Configuration 9 */ + u32 sdram_mode_10; /* SDRAM Mode Configuration 10 */ + u32 sdram_mode_11; /* SDRAM Mode Configuration 11 */ + u32 sdram_mode_12; /* SDRAM Mode Configuration 12 */ + u32 sdram_mode_13; /* SDRAM Mode Configuration 13 */ + u32 sdram_mode_14; /* SDRAM Mode Configuration 14 */ + u32 sdram_mode_15; /* SDRAM Mode Configuration 15 */ + u32 sdram_mode_16; /* SDRAM Mode Configuration 16 */ + u32 resv14[4]; + u32 timing_cfg_8; /* SDRAM Timing Configuration 8 */ + u32 timing_cfg_9; /* SDRAM Timing Configuration 9 */ + u32 resv15[2]; + u32 sdram_cfg_3; /* SDRAM Control Configuration 3 */ + u32 resv16[15]; + u32 deskew_cntl; /* SDRAM Deskew Control */ + u32 resv17[545]; + u32 ddr_dsr1; /* Debug Status 1 */ + u32 ddr_dsr2; /* Debug Status 2 */ + u32 ddr_cdr1; /* Control Driver 1 */ + u32 ddr_cdr2; /* Control Driver 2 */ + u32 resv18[50]; + u32 ip_rev1; /* IP Block Revision 1 */ + u32 ip_rev2; /* IP Block Revision 2 */ + u32 eor; /* Enhanced Optimization Register */ + u32 resv19[63]; + u32 mtcr; /* Memory Test Control Register */ + u32 resv20[7]; + u32 mtp1; /* Memory Test Pattern 1 */ + u32 mtp2; /* Memory Test Pattern 2 */ + u32 mtp3; /* Memory Test Pattern 3 */ + u32 mtp4; /* Memory Test Pattern 4 */ + u32 mtp5; /* Memory Test Pattern 5 */ + u32 mtp6; /* Memory Test Pattern 6 */ + u32 mtp7; /* Memory Test Pattern 7 */ + u32 mtp8; /* Memory Test Pattern 8 */ + u32 mtp9; /* Memory Test Pattern 9 */ + u32 mtp10; /* Memory Test Pattern 10 */ + u32 resv21[6]; + u32 ddr_mt_st_ext_addr; /* Memory Test Start Extended Address */ + u32 ddr_mt_st_addr; /* Memory Test Start Address */ + u32 ddr_mt_end_ext_addr; /* Memory Test End Extended Address */ + u32 ddr_mt_end_addr; /* Memory Test End Address */ + u32 resv22[36]; + u32 data_err_inject_hi; /* Data Path Err Injection Mask High */ + u32 data_err_inject_lo; /* Data Path Err Injection Mask Low */ + u32 ecc_err_inject; /* Data Path Err Injection Mask ECC */ + u32 resv23[5]; + u32 capture_data_hi; /* Data Path Read Capture High */ + u32 capture_data_lo; /* Data Path Read Capture Low */ + u32 capture_ecc; /* Data Path Read Capture ECC */ + u32 resv24[5]; + u32 err_detect; /* Error Detect */ + u32 err_disable; /* Error Disable */ + u32 err_int_en; + u32 capture_attributes; /* Error Attrs Capture */ + u32 capture_address; /* Error Addr Capture */ + u32 capture_ext_address; /* Error Extended Addr Capture */ + u32 err_sbe; /* Single-Bit ECC Error Management */ + u32 resv25[105]; +}; + +#define CCI400_CTRLORD_TERM_BARRIER 0x00000008 +#define CCI400_CTRLORD_EN_BARRIER 0 + +/* CCI-400 registers */ +struct ccsr_cci400 { + u32 ctrl_ord; /* Control Override */ + u32 spec_ctrl; /* Speculation Control */ + u32 secure_access; /* Secure Access */ + u32 status; /* Status */ + u32 impr_err; /* Imprecise Error */ + u8 res_14[0x100 - 0x14]; + u32 pmcr; /* Performance Monitor Control */ + u8 res_104[0xfd0 - 0x104]; + u32 pid[8]; /* Peripheral ID */ + u32 cid[4]; /* Component ID */ + struct { + u32 snoop_ctrl; /* Snoop Control */ + u32 sha_ord; /* Shareable Override */ + u8 res_1008[0x1100 - 0x1008]; + u32 rc_qos_ord; /* read channel QoS Value Override */ + u32 wc_qos_ord; /* read channel QoS Value Override */ + u8 res_1108[0x110c - 0x1108]; + u32 qos_ctrl; /* QoS Control */ + u32 max_ot; /* Max OT */ + u8 res_1114[0x1130 - 0x1114]; + u32 target_lat; /* Target Latency */ + u32 latency_regu; /* Latency Regulation */ + u32 qos_range; /* QoS Range */ + u8 res_113c[0x2000 - 0x113c]; + } slave[5]; /* Slave Interface */ + u8 res_6000[0x9004 - 0x6000]; + u32 cycle_counter; /* Cycle counter */ + u32 count_ctrl; /* Count Control */ + u32 overflow_status; /* Overflow Flag Status */ + u8 res_9010[0xa000 - 0x9010]; + struct { + u32 event_select; /* Event Select */ + u32 event_count; /* Event Count */ + u32 counter_ctrl; /* Counter Control */ + u32 overflow_status; /* Overflow Flag Status */ + u8 res_a010[0xb000 - 0xa010]; + } pcounter[4]; /* Performance Counter */ + u8 res_e004[0x10000 - 0xe004]; +}; +#endif /* __ASM_ARCH_LS102XA_IMMAP_H_ */ diff --git a/arch/arm/include/asm/arch-ls102xa/imx-regs.h b/arch/arm/include/asm/arch-ls102xa/imx-regs.h new file mode 100644 index 0000000000..f9cd75b021 --- /dev/null +++ b/arch/arm/include/asm/arch-ls102xa/imx-regs.h @@ -0,0 +1,53 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + */ + +#ifndef __ASM_ARCH_IMX_REGS_H__ +#define __ASM_ARCH_IMX_REGS_H__ + +#define I2C_QUIRK_REG /* enable 8-bit driver */ + +#ifdef CONFIG_LPUART_32B_REG +struct lpuart_fsl { + u32 baud; + u32 stat; + u32 ctrl; + u32 data; + u32 match; + u32 modir; + u32 fifo; + u32 water; +}; +#else +struct lpuart_fsl { + u8 ubdh; + u8 ubdl; + u8 uc1; + u8 uc2; + u8 us1; + u8 us2; + u8 uc3; + u8 ud; + u8 uma1; + u8 uma2; + u8 uc4; + u8 uc5; + u8 ued; + u8 umodem; + u8 uir; + u8 reserved; + u8 upfifo; + u8 ucfifo; + u8 usfifo; + u8 utwfifo; + u8 utcfifo; + u8 urwfifo; + u8 urcfifo; + u8 rsvd[28]; +}; +#endif + +#endif /* __ASM_ARCH_IMX_REGS_H__ */ diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h index 5f2a5f4ea9..be80434dee 100644 --- a/arch/arm/include/asm/config.h +++ b/arch/arm/include/asm/config.h @@ -23,4 +23,8 @@ #include #endif +#ifdef CONFIG_LS102XA +#include +#endif + #endif diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 88ecddbc41..bfbe0a0988 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -376,7 +376,12 @@ out: return retval; } -#elif !defined(readb) +#else +#define memset_io(a, b, c) memset((void *)(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) +#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) + +#if !defined(readb) #define readb(addr) (__readwrite_bug("readb"),0) #define readw(addr) (__readwrite_bug("readw"),0) @@ -389,6 +394,7 @@ out: #define check_signature(io,sig,len) (0) +#endif #endif /* __mem_pci */ /* diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 0276a10564..1dc0f5aa10 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -7,7 +7,7 @@ obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o -ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610)) +ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610 ls102xa)) obj-y += imx_watchdog.o endif obj-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o From df0a5b880d6e53b62ea05b483243dd8675cf4648 Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:35 +0800 Subject: [PATCH 02/17] ls102xa: i2c: Add i2c support for LS102xA The existing i.MX's I2C driver mxc_i2c.c is compatible with the controller of LS102xA. As I2C's registers are 8-bit on LS102xA, I2C_QUIRK_REG is enabled to use 8-bit driver. This patch is to add I2C 1,2,3 support for LS102xA. Signed-off-by: Alison Wang --- drivers/i2c/mxc_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index c14797ce0e..021b2fe511 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -423,7 +423,7 @@ static void * const i2c_bases[] = { (void *)IMX_I2C2_BASE #elif defined(CONFIG_MX31) || defined(CONFIG_MX35) || \ defined(CONFIG_MX51) || defined(CONFIG_MX53) || \ - defined(CONFIG_MX6) + defined(CONFIG_MX6) || defined(CONFIG_LS102XA) (void *)I2C1_BASE_ADDR, (void *)I2C2_BASE_ADDR, (void *)I2C3_BASE_ADDR @@ -545,7 +545,7 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe, CONFIG_SYS_MXC_I2C2_SLAVE, 1) #if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\ defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\ - defined(CONFIG_MX6) + defined(CONFIG_MX6) || defined(CONFIG_LS102XA) U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe, mxc_i2c_read, mxc_i2c_write, mxc_i2c_set_bus_speed, From 93f26f130eede8db0cb47afcaf66016987b91731 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Fri, 5 Sep 2014 13:52:36 +0800 Subject: [PATCH 03/17] net: Merge asm/fsl_enet.h into fsl_mdio.h fsl_enet.h defines the mapping of the usual MII management registers, which are included in the MDIO register block common to Freescale ethernet controllers. So it shouldn't depend on the CPU architecture but it should be actually part of the arch independent fsl_mdio.h. To remove the arch dependency, merge the content of asm/fsl_enet.h into fsl_mdio.h. Some files (like fm_eth.h) were simply including fsl_enet.h only for phy.h. These were updated to include phy.h instead. Signed-off-by: Claudiu Manoil --- arch/powerpc/include/asm/fsl_enet.h | 24 ----------------------- board/freescale/mpc8360emds/mpc8360emds.c | 2 +- board/freescale/mpc837xemds/mpc837xemds.c | 1 - drivers/net/fm/dtsec.c | 1 - drivers/net/fm/fm.h | 2 +- drivers/net/fm/init.c | 1 + drivers/net/fm/memac.c | 1 - drivers/net/fm/tgec.c | 1 - drivers/net/fsl_mdio.c | 1 - drivers/qe/uec.h | 1 - include/fm_eth.h | 2 +- include/fsl_mdio.h | 13 +++++++++++- include/tsec.h | 2 +- 13 files changed, 17 insertions(+), 35 deletions(-) delete mode 100644 arch/powerpc/include/asm/fsl_enet.h diff --git a/arch/powerpc/include/asm/fsl_enet.h b/arch/powerpc/include/asm/fsl_enet.h deleted file mode 100644 index 96146b6e32..0000000000 --- a/arch/powerpc/include/asm/fsl_enet.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ASM_PPC_FSL_ENET_H -#define __ASM_PPC_FSL_ENET_H - -#include - -struct tsec_mii_mng { - u32 miimcfg; /* MII management configuration reg */ - u32 miimcom; /* MII management command reg */ - u32 miimadd; /* MII management address reg */ - u32 miimcon; /* MII management control reg */ - u32 miimstat; /* MII management status reg */ - u32 miimind; /* MII management indication reg */ - u32 ifstat; /* Interface Status Register */ -} __attribute__ ((packed)); - -int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc); - -#endif /* __ASM_PPC_FSL_ENET_H */ diff --git a/board/freescale/mpc8360emds/mpc8360emds.c b/board/freescale/mpc8360emds/mpc8360emds.c index ac96163aa4..5ff9dff587 100644 --- a/board/freescale/mpc8360emds/mpc8360emds.c +++ b/board/freescale/mpc8360emds/mpc8360emds.c @@ -11,13 +11,13 @@ #include #include #include +#include #if defined(CONFIG_PCI) #include #endif #include #include #include -#include #include #if defined(CONFIG_OF_LIBFDT) #include diff --git a/board/freescale/mpc837xemds/mpc837xemds.c b/board/freescale/mpc837xemds/mpc837xemds.c index 0a3c9720d6..c749e5553a 100644 --- a/board/freescale/mpc837xemds/mpc837xemds.c +++ b/board/freescale/mpc837xemds/mpc837xemds.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fm/dtsec.c b/drivers/net/fm/dtsec.c index 78bbd439f1..8d3dc0e308 100644 --- a/drivers/net/fm/dtsec.c +++ b/drivers/net/fm/dtsec.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index 316e06e17e..a9691c635a 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -8,8 +8,8 @@ #define __FM_H__ #include +#include #include -#include #include /* Port ID */ diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index ff04695c32..6cf21c6f65 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "fm.h" diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c index 592a67f2a5..9499290bba 100644 --- a/drivers/net/fm/memac.c +++ b/drivers/net/fm/memac.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "fm.h" diff --git a/drivers/net/fm/tgec.c b/drivers/net/fm/tgec.c index f450f800e2..50171230ea 100644 --- a/drivers/net/fm/tgec.c +++ b/drivers/net/fm/tgec.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "fm.h" diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c index 1d88e6504b..8d09f5d1fe 100644 --- a/drivers/net/fsl_mdio.c +++ b/drivers/net/fsl_mdio.c @@ -11,7 +11,6 @@ #include #include #include -#include void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr, int dev_addr, int regnum, int value) diff --git a/drivers/qe/uec.h b/drivers/qe/uec.h index 48a163411c..6b559f7974 100644 --- a/drivers/qe/uec.h +++ b/drivers/qe/uec.h @@ -13,7 +13,6 @@ #include "qe.h" #include "uccf.h" #include -#include #define MAX_TX_THREADS 8 #define MAX_RX_THREADS 8 diff --git a/include/fm_eth.h b/include/fm_eth.h index 98edfcf4ad..e46a684129 100644 --- a/include/fm_eth.h +++ b/include/fm_eth.h @@ -8,8 +8,8 @@ #define __FM_ETH_H__ #include +#include #include -#include enum fm_port { FM1_DTSEC1, diff --git a/include/fsl_mdio.h b/include/fsl_mdio.h index b58713d896..2137282df3 100644 --- a/include/fsl_mdio.h +++ b/include/fsl_mdio.h @@ -10,7 +10,18 @@ #include #include -#include + +struct tsec_mii_mng { + u32 miimcfg; /* MII management configuration reg */ + u32 miimcom; /* MII management command reg */ + u32 miimadd; /* MII management address reg */ + u32 miimcon; /* MII management control reg */ + u32 miimstat; /* MII management status reg */ + u32 miimind; /* MII management indication reg */ + u32 ifstat; /* Interface Status Register */ +}; + +int fdt_fixup_phy_connection(void *blob, int offset, phy_interface_t phyc); /* PHY register offsets */ #define PHY_EXT_PAGE_ACCESS 0x1f diff --git a/include/tsec.h b/include/tsec.h index 1046426c5c..20547153a1 100644 --- a/include/tsec.h +++ b/include/tsec.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #define TSEC_SIZE 0x01000 #define TSEC_MDIO_OFFSET 0x01000 From d2614ea0ffda9d7c0d049f0fa5b23ce390bcb7a8 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Fri, 5 Sep 2014 13:52:37 +0800 Subject: [PATCH 04/17] net: mdio: Use mb() to be compatible for both ARM and PowerPC Use mb() instead of sync assembly instruction to be compatible for both ARM and PowerPC. Signed-off-by: Alison Wang --- drivers/net/fsl_mdio.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c index 8d09f5d1fe..d6b181b386 100644 --- a/drivers/net/fsl_mdio.c +++ b/drivers/net/fsl_mdio.c @@ -19,7 +19,8 @@ void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr, out_be32(&phyregs->miimadd, (port_addr << 8) | (regnum & 0x1f)); out_be32(&phyregs->miimcon, value); - asm("sync"); + /* Memory barrier */ + mb(); while ((in_be32(&phyregs->miimind) & MIIMIND_BUSY) && timeout--) ; @@ -37,11 +38,13 @@ int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr, /* Clear the command register, and wait */ out_be32(&phyregs->miimcom, 0); - asm("sync"); + /* Memory barrier */ + mb(); /* Initiate a read command, and wait */ out_be32(&phyregs->miimcom, MIIMCOM_READ_CYCLE); - asm("sync"); + /* Memory barrier */ + mb(); /* Wait for the the indication that the read is done */ while ((in_be32(&phyregs->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)) From 52d00a812a29974e660f64a8839ddb550dca5290 Mon Sep 17 00:00:00 2001 From: Alison Wang Date: Fri, 5 Sep 2014 13:52:38 +0800 Subject: [PATCH 05/17] ls102xa: etsec: Add etsec support for LS102xA This patch is to add etsec support for LS102xA. First, Little-endian descriptor mode should be enabled. So RxBDs and TxBDs are interpreted with little-endian byte ordering. Second, TSEC_SIZE and TSEC_MDIO_OFFSET are different from PowerPC, redefine them for LS1021xA. Signed-off-by: Alison Wang --- drivers/net/tsec.c | 7 +++++++ include/tsec.h | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index e9138f0338..79d656133a 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -20,6 +20,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -270,6 +271,9 @@ void redundant_init(struct eth_device *dev) out_be32(®s->tstat, TSTAT_CLEAR_THALT); out_be32(®s->rstat, RSTAT_CLEAR_RHALT); clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); +#ifdef CONFIG_LS102XA + setbits_be32(®s->dmactrl, DMACTRL_LE); +#endif do { uint16_t status; @@ -366,6 +370,9 @@ static void startup_tsec(struct eth_device *dev) out_be32(®s->tstat, TSTAT_CLEAR_THALT); out_be32(®s->rstat, RSTAT_CLEAR_RHALT); clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); +#ifdef CONFIG_LS102XA + setbits_be32(®s->dmactrl, DMACTRL_LE); +#endif } /* This returns the status bits of the device. The return value diff --git a/include/tsec.h b/include/tsec.h index 20547153a1..1119d2cb60 100644 --- a/include/tsec.h +++ b/include/tsec.h @@ -20,10 +20,14 @@ #include #include #include -#include +#ifdef CONFIG_LS102XA +#define TSEC_SIZE 0x40000 +#define TSEC_MDIO_OFFSET 0x40000 +#else #define TSEC_SIZE 0x01000 #define TSEC_MDIO_OFFSET 0x01000 +#endif #define CONFIG_SYS_MDIO_BASE_ADDR (MDIO_BASE_ADDR + 0x520) @@ -128,6 +132,7 @@ #define DMACTRL_INIT_SETTINGS 0x000000c3 #define DMACTRL_GRS 0x00000010 #define DMACTRL_GTS 0x00000008 +#define DMACTRL_LE 0x00008000 #define TSTAT_CLEAR_THALT 0x80000000 #define RSTAT_CLEAR_RHALT 0x00800000 From c82e9de400ee36038c76be67c5a6fb39c165ac1c Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:39 +0800 Subject: [PATCH 06/17] esdhc: Add CONFIG_SYS_FSL_ESDHC_LE and CONFIG_SYS_FSL_ESDHC_BE macros For LS102xA, the processor is in little-endian mode, while esdhc IP is in big-endian mode. CONFIG_SYS_FSL_ESDHC_LE and CONFIG_SYS_FSL_ESDHC_BE are added. So accessing ESDHC registers can be determined by ESDHC IP's endian mode. Signed-off-by: Alison Wang --- doc/README.fsl-esdhc | 5 +++++ include/fsl_esdhc.h | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 doc/README.fsl-esdhc diff --git a/doc/README.fsl-esdhc b/doc/README.fsl-esdhc new file mode 100644 index 0000000000..b70f271d1a --- /dev/null +++ b/doc/README.fsl-esdhc @@ -0,0 +1,5 @@ +CONFIG_SYS_FSL_ESDHC_LE means ESDHC IP is in little-endian mode. +CONFIG_SYS_FSL_ESDHC_BE means ESDHC IP is in big-endian mode. + +Accessing ESDHC registers can be determined by ESDHC IP's endian +mode or processor's endian mode. diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index 9814964937..c1b6648591 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -162,7 +162,19 @@ struct fsl_esdhc_cfg { }; /* Select the correct accessors depending on endianess */ -#if __BYTE_ORDER == __LITTLE_ENDIAN +#if defined CONFIG_SYS_FSL_ESDHC_LE +#define esdhc_read32 in_le32 +#define esdhc_write32 out_le32 +#define esdhc_clrsetbits32 clrsetbits_le32 +#define esdhc_clrbits32 clrbits_le32 +#define esdhc_setbits32 setbits_le32 +#elif defined(CONFIG_SYS_FSL_ESDHC_BE) +#define esdhc_read32 in_be32 +#define esdhc_write32 out_be32 +#define esdhc_clrsetbits32 clrsetbits_be32 +#define esdhc_clrbits32 clrbits_be32 +#define esdhc_setbits32 setbits_be32 +#elif __BYTE_ORDER == __LITTLE_ENDIAN #define esdhc_read32 in_le32 #define esdhc_write32 out_le32 #define esdhc_clrsetbits32 clrsetbits_le32 From 19060bd886381a58cfe335c2f13b6111ed936dd5 Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:40 +0800 Subject: [PATCH 07/17] ls102xa: esdhc: Add esdhc support for LS102xA For LS1, esdhc is big-endian IP. Accessing the registers should be in big-endian mode. So we use esdhc_read32() to read Host controller capabilities register for LS1. For LS1, when using CMD12, cmdtype need to be set to ABORT, otherwise, next read command will hang. Signed-off-by: Alison Wang --- drivers/mmc/fsl_esdhc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 55416136ab..97d0389d9d 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -96,7 +96,7 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data) else if (cmd->resp_type & MMC_RSP_PRESENT) xfertyp |= XFERTYP_RSPTYP_48; -#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) +#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) || defined(CONFIG_LS102XA) if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) xfertyp |= XFERTYP_CMDTYP_ABORT; #endif @@ -561,7 +561,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) memset(&cfg->cfg, 0, sizeof(cfg->cfg)); voltage_caps = 0; - caps = regs->hostcapblt; + caps = esdhc_read32(®s->hostcapblt); #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135 caps = caps & ~(ESDHC_HOSTCAPBLT_SRS | From d28cb6714216cc9e6bfdc1fa333d5dcd174207bd Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 5 Sep 2014 13:52:41 +0800 Subject: [PATCH 08/17] driver/ddr/freescale: Add support of accumulate ECC If less than 8 ECC pins are used for DDR data bus width smaller than 64 bits, the 8-bit ECC code will be transmitted/received across several beats, and it will be used to check 64-bits of data once 8-bits of ECC are accumulated. Signed-off-by: York Sun --- drivers/ddr/fsl/ctrl_regs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 04e4178b15..5e0ee77e46 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -693,6 +693,7 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, unsigned int x32_en = 0; /* x32 enable */ unsigned int pchb8 = 0; /* precharge bit 8 enable */ unsigned int hse; /* Global half strength override */ + unsigned int acc_ecc_en = 0; /* Accumulated ECC enable */ unsigned int mem_halt = 0; /* memory controller halt */ unsigned int bi = 0; /* Bypass initialization */ @@ -736,6 +737,9 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, ba_intlv_ctl = popts->ba_intlv_ctl; hse = popts->half_strength_driver_enable; + /* set when ddr bus width < 64 */ + acc_ecc_en = (dbw != 0 && ecc_en == 1) ? 1 : 0; + ddr->ddr_sdram_cfg = (0 | ((mem_en & 0x1) << 31) | ((sren & 0x1) << 30) @@ -752,6 +756,7 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr, | ((x32_en & 0x1) << 5) | ((pchb8 & 0x1) << 4) | ((hse & 0x1) << 3) + | ((acc_ecc_en & 0x1) << 2) | ((mem_halt & 0x1) << 1) | ((bi & 0x1) << 0) ); From 5cb27c5d44ac789f0f0583b57c15dc708ca55c69 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 5 Sep 2014 13:52:42 +0800 Subject: [PATCH 09/17] driver/ddr/freescale: Fix DDR3 driver for ARM Reading DDR register should use ddr_in32() for proper endianess. This patch fixes incorrect waiting time for ARM platforms. Signed-off-by: York Sun --- drivers/ddr/fsl/arm_ddr_gen3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c index d4ed9aec2a..59f2fd6610 100644 --- a/drivers/ddr/fsl/arm_ddr_gen3.c +++ b/drivers/ddr/fsl/arm_ddr_gen3.c @@ -194,7 +194,7 @@ step2: * For example, 2GB on 666MT/s 64-bit bus takes about 402ms * Let's wait for 800ms */ - bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK) + bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK) >> SDRAM_CFG_DBW_SHIFT); timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 / (get_ddr_freq(0) >> 20)) << 1; From ef87cab66492fe530bb6ec2e499b030c5ae60286 Mon Sep 17 00:00:00 2001 From: York Sun Date: Fri, 5 Sep 2014 13:52:43 +0800 Subject: [PATCH 10/17] driver/ddr/fsl: Add support of overriding chip select write leveling JEDEC spec allows DRAM vendors to use prime DQ for write leveling. This is not an issue unless some DQ pins are not connected. If a platform uses regular DIMMs but with reduced DDR ECC pins, the prime DQ may end up on those floating pins for the second rank. The workaround is to use a known good chip select for this purpose. Signed-off-by: York Sun --- drivers/ddr/fsl/ctrl_regs.c | 3 +++ drivers/ddr/fsl/interactive.c | 2 ++ include/fsl_ddr_sdram.h | 2 ++ 3 files changed, 7 insertions(+) diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index 5e0ee77e46..d9cac2296a 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -2276,6 +2276,9 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts, if (ip_rev > 0x40400) unq_mrs_en = 1; + if (ip_rev > 0x40700) + ddr->debug[18] = popts->cswl_override; + set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en); set_ddr_sdram_mode(ddr, popts, common_dimm, cas_latency, additive_latency, unq_mrs_en); diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index 7fb418744e..6aa16b23dd 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -511,6 +511,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo, CTRL_OPTIONS(wrlvl_override), CTRL_OPTIONS(wrlvl_sample), CTRL_OPTIONS(wrlvl_start), + CTRL_OPTIONS(cswl_override), CTRL_OPTIONS(rcw_override), CTRL_OPTIONS(rcw_1), CTRL_OPTIONS(rcw_2), @@ -801,6 +802,7 @@ static void print_memctl_options(const memctl_options_t *popts) CTRL_OPTIONS(wrlvl_override), CTRL_OPTIONS(wrlvl_sample), CTRL_OPTIONS(wrlvl_start), + CTRL_OPTIONS_HEX(cswl_override), CTRL_OPTIONS(rcw_override), CTRL_OPTIONS(rcw_1), CTRL_OPTIONS(rcw_2), diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index e8a2db91cb..987119b014 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -281,6 +281,7 @@ typedef struct memctl_options_partial_s { #define DDR_DATA_BUS_WIDTH_64 0 #define DDR_DATA_BUS_WIDTH_32 1 #define DDR_DATA_BUS_WIDTH_16 2 +#define DDR_CSWL_CS0 0x04000001 /* * Generalized parameters for memory controller configuration, * might be a little specific to the FSL memory controller @@ -340,6 +341,7 @@ typedef struct memctl_options_s { unsigned int cpo_override; unsigned int write_data_delay; /* DQS adjust */ + unsigned int cswl_override; unsigned int wrlvl_override; unsigned int wrlvl_sample; /* Write leveling */ unsigned int wrlvl_start; From 550e3dc090888fbc9c0fc4066541a2b4eb88c47b Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:44 +0800 Subject: [PATCH 11/17] arm: ls102xa: Add basic support for LS1021AQDS board LS102xA is an ARMv7 implementation. This patch is to add basic support for LS1021AQDS board. One DDR controller DUART1 is used as the console For the detail board information, please refer to README. Signed-off-by: Alison Wang Signed-off-by: Jason Jin Signed-off-by: York Sun Signed-off-by: Yuan Yao Signed-off-by: Prabhakar Kushwaha --- arch/arm/Kconfig | 4 + board/freescale/ls1021aqds/Kconfig | 23 ++ board/freescale/ls1021aqds/MAINTAINERS | 6 + board/freescale/ls1021aqds/Makefile | 9 + board/freescale/ls1021aqds/README | 112 +++++ board/freescale/ls1021aqds/ddr.c | 159 +++++++ board/freescale/ls1021aqds/ddr.h | 49 +++ board/freescale/ls1021aqds/eth.c | 186 +++++++++ board/freescale/ls1021aqds/ls1021aqds.c | 255 ++++++++++++ board/freescale/ls1021aqds/ls1021aqds_qixis.h | 35 ++ configs/ls1021aqds_nor_defconfig | 2 + include/configs/ls1021aqds.h | 389 ++++++++++++++++++ 12 files changed, 1229 insertions(+) create mode 100644 board/freescale/ls1021aqds/Kconfig create mode 100644 board/freescale/ls1021aqds/MAINTAINERS create mode 100644 board/freescale/ls1021aqds/Makefile create mode 100644 board/freescale/ls1021aqds/README create mode 100644 board/freescale/ls1021aqds/ddr.c create mode 100644 board/freescale/ls1021aqds/ddr.h create mode 100644 board/freescale/ls1021aqds/eth.c create mode 100644 board/freescale/ls1021aqds/ls1021aqds.c create mode 100644 board/freescale/ls1021aqds/ls1021aqds_qixis.h create mode 100644 configs/ls1021aqds_nor_defconfig create mode 100644 include/configs/ls1021aqds.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 22f0f09af6..d7ed3e207d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -470,6 +470,9 @@ config TARGET_LS2085A_EMU config TARGET_LS2085A_SIMU bool "Support ls2085a_simu" +config TARGET_LS1021AQDS + bool "Support ls1021aqds_nor" + config TARGET_BALLOON3 bool "Support balloon3" @@ -594,6 +597,7 @@ source "board/eukrea/cpu9260/Kconfig" source "board/eukrea/cpuat91/Kconfig" source "board/faraday/a320evb/Kconfig" source "board/freescale/ls2085a/Kconfig" +source "board/freescale/ls1021aqds/Kconfig" source "board/freescale/mx23evk/Kconfig" source "board/freescale/mx25pdk/Kconfig" source "board/freescale/mx28evk/Kconfig" diff --git a/board/freescale/ls1021aqds/Kconfig b/board/freescale/ls1021aqds/Kconfig new file mode 100644 index 0000000000..c28bd2b835 --- /dev/null +++ b/board/freescale/ls1021aqds/Kconfig @@ -0,0 +1,23 @@ +if TARGET_LS1021AQDS + +config SYS_CPU + string + default "armv7" + +config SYS_BOARD + string + default "ls1021aqds" + +config SYS_VENDOR + string + default "freescale" + +config SYS_SOC + string + default "ls102xa" + +config SYS_CONFIG_NAME + string + default "ls1021aqds" + +endif diff --git a/board/freescale/ls1021aqds/MAINTAINERS b/board/freescale/ls1021aqds/MAINTAINERS new file mode 100644 index 0000000000..021d82b74d --- /dev/null +++ b/board/freescale/ls1021aqds/MAINTAINERS @@ -0,0 +1,6 @@ +LS1021AQDS BOARD +M: Alison Wang +S: Maintained +F: board/freescale/ls1021aqds/ +F: include/configs/ls1021aqds.h +F: configs/ls1021aqds_nor_defconfig diff --git a/board/freescale/ls1021aqds/Makefile b/board/freescale/ls1021aqds/Makefile new file mode 100644 index 0000000000..3b6903c83b --- /dev/null +++ b/board/freescale/ls1021aqds/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ls1021aqds.o +obj-y += ddr.o +obj-y += eth.o diff --git a/board/freescale/ls1021aqds/README b/board/freescale/ls1021aqds/README new file mode 100644 index 0000000000..c561776621 --- /dev/null +++ b/board/freescale/ls1021aqds/README @@ -0,0 +1,112 @@ +Overview +-------- +The LS1021AQDS is a Freescale reference board that hosts the LS1021A SoC. + +LS1021A SoC Overview +------------------ +The QorIQ LS1 family, which includes the LS1021A communications processor, +is built on Layerscape architecture, the industry's first software-aware, +core-agnostic networking architecture to offer unprecedented efficiency +and scale. + +A member of the value-performance tier, the QorIQ LS1021A processor provides +extensive integration and power efficiency for fanless, small form factor +enterprise networking applications. Incorporating dual ARM Cortex-A7 cores +running up to 1.0 GHz, the LS1021A processor delivers pre-silicon CoreMark +performance of over 6,000, as well as virtualization support, advanced +security features and the broadest array of high-speed interconnects and +optimized peripheral features ever offered in a sub-3 W processor. + +The QorIQ LS1021A processor features an integrated LCD controller, +CAN controller for implementing industrial protocols, DDR3L/4 running +up to 1600 MHz, integrated security engine and QUICC Engine, and ECC +protection on both L1 and L2 caches. The LS1021A processor is pin- and +software-compatible with the QorIQ LS1020A and LS1022A processors. + +The LS1021A SoC includes the following function and features: + + - ARM Cortex-A7 MPCore compliant with ARMv7-A architecture + - Dual high-preformance ARM Cortex-A7 cores, each core includes: + - 32 Kbyte L1 Instruction Cache and Data Cache for each core (ECC protection) + - 512 Kbyte shared coherent L2 Cache (with ECC protection) + - NEON Co-processor (per core) + - 40-bit physical addressing + - Vector floating-point support + - ARM Core-Link CCI-400 Cache Coherent Interconnect + - One DDR3L/DDR4 SDRAM memory controller with x8/x16/x32-bit configuration + supporting speeds up to 1600Mtps + - ECC and interleaving support + - VeTSEC Ethernet complex + - Up to 3x virtualized 10/100/1000 Ethernet controllers + - MII, RMII, RGMII, and SGMII support + - QoS, lossless flow control, and IEEE 1588 support + - 4-lane 6GHz SerDes + - High speed interconnect (4 SerDes lanes with are muxed for these protocol) + - Two PCI Express Gen2 controllers running at up to 5 GHz + - One Serial ATA 3.0 supporting 6 GT/s operation + - Two SGMII interfaces supporting 1000 Mbps + - Additional peripheral interfaces + - One high-speed USB 3.0 controller with integrated PHY and one high-speed + USB 2.00 controller with ULPI + - Integrated flash controller (IFC) with 16-bit interface + - Quad SPI NOR Flash + - One enhanced Secure digital host controller + - Display controller unit (DCU) 24-bit RGB (12-bit DDR pin interface) + - Ten UARTs comprised of two 16550 compliant DUARTs, and six low power + UARTs + - Three I2C controllers + - Eight FlexTimers four supporting PWM and four FlexCAN ports + - Four GPIO controllers supporting up to 109 general purpose I/O signals + - Integrated advanced audio block: + - Four synchronous audio interfaces (SAI) + - Sony/Philips Digital Interconnect Format (SPDIF) + - Asynchronous Sample Rate Converter (ASRC) + - Hardware based crypto offload engine + - IPSec forwarding at up to 1Gbps + - QorIQ Trust Architecture, Secure Boot, and ARM TrustZone supported + - Public key hardware accelerator + - True Random Number Generator (NIST Certified) + - Advanced Encryption Standard Accelerators (AESA) + - Data Encryption Standard Accelerators + - QUICC Engine ULite block + - Two universal communication controllers (TDM and HDLC) supporting 64 + multichannels, each running at 64 Kbps + - Support for 256 channels of HDLC + - QorIQ TrustArchitecture with Secure Boot, as well as ARM TrustZone supported + +LS1021AQDS board Overview +------------------------- + - DDR Controller + - Supports rates of up to 1600 MHz data-rate + - Supports one DDR3LP UDIMM, of single-, dual- types. + - IFC/Local Bus + - NAND flash: 512M 8-bit NAND flash + - NOR: 128MB 16-bit NOR Flash + - Ethernet + - Three on-board RGMII 10/100/1G ethernet ports. + - FPGA + - Clocks + - System and DDR clock (SYSCLK, DDRCLK) + - SERDES clocks + - Power Supplies + - SDHC + - SDHC/SDXC connector + - Other IO + - Two Serial ports + - Three I2C ports + +Memory map +----------- +The addresses in brackets are physical addresses. + +Start Address End Address Description Size +0x00_0000_0000 0x00_000F_FFFF Secure Boot ROM 1MB +0x00_0100_0000 0x00_0FFF_FFFF CCSRBAR 240MB +0x00_1000_0000 0x00_1000_FFFF OCRAM0 64KB +0x00_1001_0000 0x00_1001_FFFF OCRAM1 64KB +0x00_2000_0000 0x00_20FF_FFFF DCSR 16MB +0x00_4000_0000 0x00_5FFF_FFFF QSPI 512MB +0x00_6000_0000 0x00_67FF_FFFF IFC - NOR Flash 128MB +0x00_7E80_0000 0x00_7E80_FFFF IFC - NAND Flash 64KB +0x00_7FB0_0000 0x00_7FB0_0FFF IFC - FPGA 4KB +0x00_8000_0000 0x00_FFFF_FFFF DRAM1 2GB diff --git a/board/freescale/ls1021aqds/ddr.c b/board/freescale/ls1021aqds/ddr.c new file mode 100644 index 0000000000..679c654fb5 --- /dev/null +++ b/board/freescale/ls1021aqds/ddr.c @@ -0,0 +1,159 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include "ddr.h" + +DECLARE_GLOBAL_DATA_PTR; + +void fsl_ddr_board_options(memctl_options_t *popts, + dimm_params_t *pdimm, + unsigned int ctrl_num) +{ + const struct board_specific_parameters *pbsp, *pbsp_highest = NULL; + ulong ddr_freq; + + if (ctrl_num > 3) { + printf("Not supported controller number %d\n", ctrl_num); + return; + } + if (!pdimm->n_ranks) + return; + + pbsp = udimms[0]; + + /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr + * freqency and n_banks specified in board_specific_parameters table. + */ + ddr_freq = get_ddr_freq(0) / 1000000; + while (pbsp->datarate_mhz_high) { + if (pbsp->n_ranks == pdimm->n_ranks) { + if (ddr_freq <= pbsp->datarate_mhz_high) { + popts->clk_adjust = pbsp->clk_adjust; + popts->wrlvl_start = pbsp->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + popts->cpo_override = pbsp->cpo_override; + popts->write_data_delay = + pbsp->write_data_delay; + goto found; + } + pbsp_highest = pbsp; + } + pbsp++; + } + + if (pbsp_highest) { + printf("Error: board specific timing not found for %lu MT/s\n", + ddr_freq); + printf("Trying to use the highest speed (%u) parameters\n", + pbsp_highest->datarate_mhz_high); + popts->clk_adjust = pbsp_highest->clk_adjust; + popts->wrlvl_start = pbsp_highest->wrlvl_start; + popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2; + popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3; + } else { + panic("DIMM is not supported by this board"); + } +found: + debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n", + pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb); + + /* force DDR bus width to 32 bits */ + popts->data_bus_width = 1; + popts->otf_burst_chop_en = 0; + popts->burst_length = DDR_BL8; + + /* + * Factors to consider for half-strength driver enable: + * - number of DIMMs installed + */ + popts->half_strength_driver_enable = 1; + /* + * Write leveling override + */ + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + popts->cswl_override = DDR_CSWL_CS0; + + /* + * Rtt and Rtt_WR override + */ + popts->rtt_override = 0; + + /* Enable ZQ calibration */ + popts->zq_en = 1; + + /* DHC_EN =1, ODT = 75 Ohm */ + popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm); + popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm); +} + +#ifdef CONFIG_SYS_DDR_RAW_TIMING +dimm_params_t ddr_raw_timing = { + .n_ranks = 1, + .rank_density = 1073741824u, + .capacity = 1073741824u, + .primary_sdram_width = 32, + .ec_sdram_width = 0, + .registered_dimm = 0, + .mirrored_dimm = 0, + .n_row_addr = 15, + .n_col_addr = 10, + .n_banks_per_sdram_device = 8, + .edc_config = 0, + .burst_lengths_bitmask = 0x0c, + + .tckmin_x_ps = 1071, + .caslat_x = 0xfe << 4, /* 5,6,7,8 */ + .taa_ps = 13125, + .twr_ps = 15000, + .trcd_ps = 13125, + .trrd_ps = 7500, + .trp_ps = 13125, + .tras_ps = 37500, + .trc_ps = 50625, + .trfc_ps = 160000, + .twtr_ps = 7500, + .trtp_ps = 7500, + .refresh_rate_ps = 7800000, + .tfaw_ps = 37500, +}; + +int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, + unsigned int controller_number, + unsigned int dimm_number) +{ + static const char dimm_model[] = "Fixed DDR on board"; + + if (((controller_number == 0) && (dimm_number == 0)) || + ((controller_number == 1) && (dimm_number == 0))) { + memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t)); + memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); + memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); + } + + return 0; +} +#endif + +phys_size_t initdram(int board_type) +{ + phys_size_t dram_size; + + puts("Initializing DDR....using SPD\n"); + dram_size = fsl_ddr_sdram(); + + return dram_size; +} + +void dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = gd->ram_size; +} diff --git a/board/freescale/ls1021aqds/ddr.h b/board/freescale/ls1021aqds/ddr.h new file mode 100644 index 0000000000..16d87cbe82 --- /dev/null +++ b/board/freescale/ls1021aqds/ddr.h @@ -0,0 +1,49 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DDR_H__ +#define __DDR_H__ +struct board_specific_parameters { + u32 n_ranks; + u32 datarate_mhz_high; + u32 rank_gb; + u32 clk_adjust; + u32 wrlvl_start; + u32 wrlvl_ctl_2; + u32 wrlvl_ctl_3; + u32 cpo_override; + u32 write_data_delay; + u32 force_2t; +}; + +/* + * These tables contain all valid speeds we want to override with board + * specific parameters. datarate_mhz_high values need to be in ascending order + * for each n_ranks group. + */ +static const struct board_specific_parameters udimm0[] = { + /* + * memory controller 0 + * num| hi| rank| clk| wrlvl | wrlvl | wrlvl | cpo |wrdata|2T + * ranks| mhz| GB |adjst| start | ctl2 | ctl3 | |delay | + */ + {1, 833, 1, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0}, + {1, 1350, 1, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {1, 833, 2, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0}, + {1, 1350, 2, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {2, 833, 4, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0}, + {2, 1350, 4, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {2, 1350, 0, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0}, + {2, 1666, 4, 4, 0xa, 0x0B08090C, 0x0B0E0D0A, 0x1f, 2, 0}, + {2, 1666, 0, 4, 0xa, 0x0B08090C, 0x0B0E0D0A, 0x1f, 2, 0}, + {} +}; + +static const struct board_specific_parameters *udimms[] = { + udimm0, +}; + +#endif diff --git a/board/freescale/ls1021aqds/eth.c b/board/freescale/ls1021aqds/eth.c new file mode 100644 index 0000000000..be351befec --- /dev/null +++ b/board/freescale/ls1021aqds/eth.c @@ -0,0 +1,186 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * This file handles the board muxing between the RGMII/SGMII PHYs on + * Freescale LS1021AQDS board. The RGMII PHYs are the three on-board 1Gb + * ports. The SGMII PHYs are provided by the standard Freescale four-port + * SGMII riser card. + * + * Muxing is handled via the PIXIS BRDCFG4 register. The EMI1 bits control + * muxing among the RGMII PHYs and the SGMII PHYs. The value for RGMII depends + * on which port is used. The value for SGMII depends on which slot the riser + * is inserted in. + */ + +#include +#include +#include +#include +#include +#include + +#include "../common/sgmii_riser.h" +#include "../common/qixis.h" + +#define EMI1_MASK 0x1f +#define EMI1_RGMII0 1 +#define EMI1_RGMII1 2 +#define EMI1_RGMII2 3 +#define EMI1_SGMII1 0x1c +#define EMI1_SGMII2 0x1d + +struct ls1021a_mdio { + struct mii_dev *realbus; +}; + +static void ls1021a_mux_mdio(int addr) +{ + u8 brdcfg4; + + brdcfg4 = QIXIS_READ(brdcfg[4]); + brdcfg4 &= EMI1_MASK; + + switch (addr) { + case EMI1_RGMII0: + brdcfg4 |= 0; + break; + case EMI1_RGMII1: + brdcfg4 |= 0x20; + break; + case EMI1_RGMII2: + brdcfg4 |= 0x40; + break; + case EMI1_SGMII1: + brdcfg4 |= 0x60; + break; + case EMI1_SGMII2: + brdcfg4 |= 0x80; + break; + default: + brdcfg4 |= 0xa0; + break; + } + + QIXIS_WRITE(brdcfg[4], brdcfg4); +} + +static int ls1021a_mdio_read(struct mii_dev *bus, int addr, int devad, + int regnum) +{ + struct ls1021a_mdio *priv = bus->priv; + + ls1021a_mux_mdio(addr); + + return priv->realbus->read(priv->realbus, addr, devad, regnum); +} + +static int ls1021a_mdio_write(struct mii_dev *bus, int addr, int devad, + int regnum, u16 value) +{ + struct ls1021a_mdio *priv = bus->priv; + + ls1021a_mux_mdio(addr); + + return priv->realbus->write(priv->realbus, addr, devad, regnum, value); +} + +static int ls1021a_mdio_reset(struct mii_dev *bus) +{ + struct ls1021a_mdio *priv = bus->priv; + + return priv->realbus->reset(priv->realbus); +} + +static int ls1021a_mdio_init(char *realbusname, char *fakebusname) +{ + struct ls1021a_mdio *lsmdio; + struct mii_dev *bus = mdio_alloc(); + + if (!bus) { + printf("Failed to allocate LS102xA MDIO bus\n"); + return -1; + } + + lsmdio = malloc(sizeof(*lsmdio)); + if (!lsmdio) { + printf("Failed to allocate LS102xA private data\n"); + free(bus); + return -1; + } + + bus->read = ls1021a_mdio_read; + bus->write = ls1021a_mdio_write; + bus->reset = ls1021a_mdio_reset; + sprintf(bus->name, fakebusname); + + lsmdio->realbus = miiphy_get_dev_by_name(realbusname); + + if (!lsmdio->realbus) { + printf("No bus with name %s\n", realbusname); + free(bus); + free(lsmdio); + return -1; + } + + bus->priv = lsmdio; + + return mdio_register(bus); +} + +int board_eth_init(bd_t *bis) +{ + struct fsl_pq_mdio_info mdio_info; + struct tsec_info_struct tsec_info[3]; + int num = 0; + +#ifdef CONFIG_TSEC1 + SET_STD_TSEC_INFO(tsec_info[num], 1); + if (is_serdes_configured(SGMII_TSEC1)) { + puts("eTSEC1 is in sgmii mode\n"); + tsec_info[num].flags |= TSEC_SGMII; + tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO"; + } else { + tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; + } + num++; +#endif +#ifdef CONFIG_TSEC2 + SET_STD_TSEC_INFO(tsec_info[num], 2); + if (is_serdes_configured(SGMII_TSEC2)) { + puts("eTSEC2 is in sgmii mode\n"); + tsec_info[num].flags |= TSEC_SGMII; + tsec_info[num].mii_devname = "LS1021A_SGMII_MDIO"; + } else { + tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; + } + num++; +#endif +#ifdef CONFIG_TSEC3 + SET_STD_TSEC_INFO(tsec_info[num], 3); + tsec_info[num].mii_devname = "LS1021A_RGMII_MDIO"; + num++; +#endif + if (!num) { + printf("No TSECs initialized\n"); + return 0; + } + +#ifdef CONFIG_FSL_SGMII_RISER + fsl_sgmii_riser_init(tsec_info, num); +#endif + + mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.name = DEFAULT_MII_NAME; + + fsl_pq_mdio_init(bis, &mdio_info); + + /* Register the virtual MDIO front-ends */ + ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_RGMII_MDIO"); + ls1021a_mdio_init(DEFAULT_MII_NAME, "LS1021A_SGMII_MDIO"); + + tsec_eth_init(bis, tsec_info, num); + + return pci_eth_init(bis); +} diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c new file mode 100644 index 0000000000..12e83f7645 --- /dev/null +++ b/board/freescale/ls1021aqds/ls1021aqds.c @@ -0,0 +1,255 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../common/qixis.h" +#include "ls1021aqds_qixis.h" + +DECLARE_GLOBAL_DATA_PTR; + +enum { + MUX_TYPE_SD_PCI4, + MUX_TYPE_SD_PC_SA_SG_SG, + MUX_TYPE_SD_PC_SA_PC_SG, + MUX_TYPE_SD_PC_SG_SG, +}; + +int checkboard(void) +{ + char buf[64]; + u8 sw; + + puts("Board: LS1021AQDS\n"); + + sw = QIXIS_READ(brdcfg[0]); + sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; + + if (sw < 0x8) + printf("vBank: %d\n", sw); + else if (sw == 0x8) + puts("PromJet\n"); + else if (sw == 0x9) + puts("NAND\n"); + else if (sw == 0x15) + printf("IFCCard\n"); + else + printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH); + + printf("Sys ID:0x%02x, Sys Ver: 0x%02x\n", + QIXIS_READ(id), QIXIS_READ(arch)); + + printf("FPGA: v%d (%s), build %d\n", + (int)QIXIS_READ(scver), qixis_read_tag(buf), + (int)qixis_read_minor()); + + return 0; +} + +unsigned long get_board_sys_clk(void) +{ + u8 sysclk_conf = QIXIS_READ(brdcfg[1]); + + switch (sysclk_conf & 0x0f) { + case QIXIS_SYSCLK_64: + return 64000000; + case QIXIS_SYSCLK_83: + return 83333333; + case QIXIS_SYSCLK_100: + return 100000000; + case QIXIS_SYSCLK_125: + return 125000000; + case QIXIS_SYSCLK_133: + return 133333333; + case QIXIS_SYSCLK_150: + return 150000000; + case QIXIS_SYSCLK_160: + return 160000000; + case QIXIS_SYSCLK_166: + return 166666666; + } + return 66666666; +} + +unsigned long get_board_ddr_clk(void) +{ + u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); + + switch ((ddrclk_conf & 0x30) >> 4) { + case QIXIS_DDRCLK_100: + return 100000000; + case QIXIS_DDRCLK_125: + return 125000000; + case QIXIS_DDRCLK_133: + return 133333333; + } + return 66666666; +} + +int dram_init(void) +{ + gd->ram_size = initdram(0); + + return 0; +} + +#ifdef CONFIG_FSL_ESDHC +struct fsl_esdhc_cfg esdhc_cfg[1] = { + {CONFIG_SYS_FSL_ESDHC_ADDR}, +}; + +int board_mmc_init(bd_t *bis) +{ + esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + + return fsl_esdhc_initialize(bis, &esdhc_cfg[0]); +} +#endif + +int select_i2c_ch_pca9547(u8 ch) +{ + int ret; + + ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); + if (ret) { + puts("PCA: failed to select proper channel\n"); + return ret; + } + + return 0; +} + +int board_early_init_f(void) +{ + struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + +#ifdef CONFIG_TSEC_ENET + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_REV); + out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_NOREV); +#endif + +#ifdef CONFIG_FSL_IFC + init_early_memctl_regs(); +#endif + + /* Workaround for the issue that DDR could not respond to + * barrier transaction which is generated by executing DSB/ISB + * instruction. Set CCI-400 control override register to + * terminate the barrier transaction. After DDR is initialized, + * allow barrier transaction to DDR again */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + + return 0; +} + +int config_board_mux(int ctrl_type) +{ + u8 reg12; + + reg12 = QIXIS_READ(brdcfg[12]); + + switch (ctrl_type) { + case MUX_TYPE_SD_PCI4: + reg12 = 0x38; + break; + case MUX_TYPE_SD_PC_SA_SG_SG: + reg12 = 0x01; + break; + case MUX_TYPE_SD_PC_SA_PC_SG: + reg12 = 0x01; + break; + case MUX_TYPE_SD_PC_SG_SG: + reg12 = 0x21; + break; + default: + printf("Wrong mux interface type\n"); + return -1; + } + + QIXIS_WRITE(brdcfg[12], reg12); + + return 0; +} + +int config_serdes_mux(void) +{ + struct ccsr_gur *gur = (struct ccsr_gur *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 cfg; + + cfg = in_be32(&gur->rcwsr[4]) & RCWSR4_SRDS1_PRTCL_MASK; + cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT; + + switch (cfg) { + case 0x0: + config_board_mux(MUX_TYPE_SD_PCI4); + break; + case 0x30: + config_board_mux(MUX_TYPE_SD_PC_SA_SG_SG); + break; + case 0x60: + config_board_mux(MUX_TYPE_SD_PC_SG_SG); + break; + case 0x70: + config_board_mux(MUX_TYPE_SD_PC_SA_PC_SG); + break; + default: + printf("SRDS1 prtcl:0x%x\n", cfg); + break; + } + + return 0; +} + +int board_init(void) +{ + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR; + + /* Set CCI-400 control override register to + * enable barrier transaction */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); + + select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); + +#ifndef CONFIG_SYS_FSL_NO_SERDES + fsl_serdes_init(); + config_serdes_mux(); +#endif + return 0; +} + +void ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); +} + +u8 flash_read8(void *addr) +{ + return __raw_readb(addr + 1); +} + +void flash_write16(u16 val, void *addr) +{ + u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00)); + + __raw_writew(shftval, addr); +} + +u16 flash_read16(void *addr) +{ + u16 val = __raw_readw(addr); + + return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00); +} diff --git a/board/freescale/ls1021aqds/ls1021aqds_qixis.h b/board/freescale/ls1021aqds/ls1021aqds_qixis.h new file mode 100644 index 0000000000..09b3be2f9c --- /dev/null +++ b/board/freescale/ls1021aqds/ls1021aqds_qixis.h @@ -0,0 +1,35 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __LS1021AQDS_QIXIS_H__ +#define __LS1021AQDS_QIXIS_H__ + +/* Definitions of QIXIS Registers for LS1021AQDS */ + +/* BRDCFG4[4:7]] select EC1 and EC2 as a pair */ +#define BRDCFG4_EMISEL_MASK 0xe0 +#define BRDCFG4_EMISEL_SHIFT 5 + +/* SYSCLK */ +#define QIXIS_SYSCLK_66 0x0 +#define QIXIS_SYSCLK_83 0x1 +#define QIXIS_SYSCLK_100 0x2 +#define QIXIS_SYSCLK_125 0x3 +#define QIXIS_SYSCLK_133 0x4 +#define QIXIS_SYSCLK_150 0x5 +#define QIXIS_SYSCLK_160 0x6 +#define QIXIS_SYSCLK_166 0x7 +#define QIXIS_SYSCLK_64 0x8 + +/* DDRCLK */ +#define QIXIS_DDRCLK_66 0x0 +#define QIXIS_DDRCLK_100 0x1 +#define QIXIS_DDRCLK_125 0x2 +#define QIXIS_DDRCLK_133 0x3 + +#define QIXIS_SRDS1CLK_100 0x0 + +#endif diff --git a/configs/ls1021aqds_nor_defconfig b/configs/ls1021aqds_nor_defconfig new file mode 100644 index 0000000000..9e42d61095 --- /dev/null +++ b/configs/ls1021aqds_nor_defconfig @@ -0,0 +1,2 @@ +CONFIG_ARM=y +CONFIG_TARGET_LS1021AQDS=y diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h new file mode 100644 index 0000000000..657e3b6d48 --- /dev/null +++ b/include/configs/ls1021aqds.h @@ -0,0 +1,389 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#define CONFIG_LS102XA + +#define CONFIG_SYS_GENERIC_BOARD + +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_BOARD_EARLY_INIT_F + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 16 * 1024 * 1024) + +#define CONFIG_SYS_INIT_RAM_ADDR OCRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE OCRAM_SIZE + +/* + * Generic Timer Definitions + */ +#define GENERIC_TIMER_CLK 12500000 + +#ifndef __ASSEMBLY__ +unsigned long get_board_sys_clk(void); +unsigned long get_board_ddr_clk(void); +#endif + +#define CONFIG_SYS_CLK_FREQ get_board_sys_clk() +#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk() + +#ifndef CONFIG_SYS_TEXT_BASE +#define CONFIG_SYS_TEXT_BASE 0x67f80000 +#endif + +#define CONFIG_NR_DRAM_BANKS 1 + +#define CONFIG_DDR_SPD +#define SPD_EEPROM_ADDRESS 0x51 +#define CONFIG_SYS_SPD_BUS_NUM 0 +#define CONFIG_SYS_DDR_RAW_TIMING + +#define CONFIG_FSL_DDR_INTERACTIVE /* Interactive debugging */ +#define CONFIG_SYS_FSL_DDR3 /* Use DDR3 memory */ +#define CONFIG_DIMM_SLOTS_PER_CTLR 1 +#define CONFIG_CHIP_SELECTS_PER_CTRL 4 + +#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000UL +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE + +#define CONFIG_DDR_ECC +#ifdef CONFIG_DDR_ECC +#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER +#define CONFIG_MEM_INIT_VALUE 0xdeadbeef +#endif + +#define CONFIG_SYS_HAS_SERDES + +/* + * IFC Definitions + */ +#define CONFIG_FSL_IFC +#define CONFIG_SYS_FLASH_BASE 0x60000000 +#define CONFIG_SYS_FLASH_BASE_PHYS CONFIG_SYS_FLASH_BASE + +#define CONFIG_SYS_NOR0_CSPR_EXT (0x0) +#define CONFIG_SYS_NOR0_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR1_CSPR_EXT (0x0) +#define CONFIG_SYS_NOR1_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS \ + + 0x8000000) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128 * 1024 * 1024) + +#define CONFIG_SYS_NOR_CSOR (CSOR_NOR_ADM_SHIFT(4) | \ + CSOR_NOR_TRHZ_80) +#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x4) | \ + FTIM0_NOR_TEADC(0x5) | \ + FTIM0_NOR_TEAHC(0x5)) +#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x35) | \ + FTIM1_NOR_TRAD_NOR(0x1a) | \ + FTIM1_NOR_TSEQRAD_NOR(0x13)) +#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x4) | \ + FTIM2_NOR_TCH(0x4) | \ + FTIM2_NOR_TWPH(0xe) | \ + FTIM2_NOR_TWP(0x1c)) +#define CONFIG_SYS_NOR_FTIM3 0 + +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_FLASH_SHOW_PROGRESS 45 +#define CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS + +#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define CONFIG_SYS_FLASH_BANKS_LIST {CONFIG_SYS_FLASH_BASE_PHYS, \ + CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000} + +/* + * NAND Flash Definitions + */ +#define CONFIG_NAND_FSL_IFC + +#define CONFIG_SYS_NAND_BASE 0x7e800000 +#define CONFIG_SYS_NAND_BASE_PHYS CONFIG_SYS_NAND_BASE + +#define CONFIG_SYS_NAND_CSPR_EXT (0x0) + +#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ + | CSPR_PORT_SIZE_8 \ + | CSPR_MSEL_NAND \ + | CSPR_V) +#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64*1024) +#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \ + | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \ + | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \ + | CSOR_NAND_RAL_3 /* RAL = 3 Bytes */ \ + | CSOR_NAND_PGS_2K /* Page Size = 2K */ \ + | CSOR_NAND_SPRZ_64 /* Spare size = 64 */ \ + | CSOR_NAND_PB(64)) /* 64 Pages Per Block */ + +#define CONFIG_SYS_NAND_ONFI_DETECTION + +#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x7) | \ + FTIM0_NAND_TWP(0x18) | \ + FTIM0_NAND_TWCHT(0x7) | \ + FTIM0_NAND_TWH(0xa)) +#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \ + FTIM1_NAND_TWBE(0x39) | \ + FTIM1_NAND_TRR(0xe) | \ + FTIM1_NAND_TRP(0x18)) +#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0xf) | \ + FTIM2_NAND_TREH(0xa) | \ + FTIM2_NAND_TWHRE(0x1e)) +#define CONFIG_SYS_NAND_FTIM3 0x0 + +#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE } +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_CMD_NAND + +#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) + +/* + * QIXIS Definitions + */ +#define CONFIG_FSL_QIXIS + +#ifdef CONFIG_FSL_QIXIS +#define QIXIS_BASE 0x7fb00000 +#define QIXIS_BASE_PHYS QIXIS_BASE +#define CONFIG_SYS_I2C_FPGA_ADDR 0x66 +#define QIXIS_LBMAP_SWITCH 6 +#define QIXIS_LBMAP_MASK 0x0f +#define QIXIS_LBMAP_SHIFT 0 +#define QIXIS_LBMAP_DFLTBANK 0x00 +#define QIXIS_LBMAP_ALTBANK 0x04 +#define QIXIS_RST_CTL_RESET 0x44 +#define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20 +#define QIXIS_RCFG_CTL_RECONFIG_START 0x21 +#define QIXIS_RCFG_CTL_WATCHDOG_ENBLE 0x08 + +#define CONFIG_SYS_FPGA_CSPR_EXT (0x0) +#define CONFIG_SYS_FPGA_CSPR (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS) | \ + CSPR_PORT_SIZE_8 | \ + CSPR_MSEL_GPCM | \ + CSPR_V) +#define CONFIG_SYS_FPGA_AMASK IFC_AMASK(64 * 1024) +#define CONFIG_SYS_FPGA_CSOR (CSOR_NOR_ADM_SHIFT(4) | \ + CSOR_NOR_NOR_MODE_AVD_NOR | \ + CSOR_NOR_TRHZ_80) + +/* + * QIXIS Timing parameters for IFC GPCM + */ +#define CONFIG_SYS_FPGA_FTIM0 (FTIM0_GPCM_TACSE(0xe) | \ + FTIM0_GPCM_TEADC(0xe) | \ + FTIM0_GPCM_TEAHC(0xe)) +#define CONFIG_SYS_FPGA_FTIM1 (FTIM1_GPCM_TACO(0xe) | \ + FTIM1_GPCM_TRAD(0x1f)) +#define CONFIG_SYS_FPGA_FTIM2 (FTIM2_GPCM_TCS(0xe) | \ + FTIM2_GPCM_TCH(0xe) | \ + FTIM2_GPCM_TWP(0xf0)) +#define CONFIG_SYS_FPGA_FTIM3 0x0 +#endif + +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NOR1_CSPR_EXT +#define CONFIG_SYS_CSPR1 CONFIG_SYS_NOR1_CSPR +#define CONFIG_SYS_AMASK1 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR1 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NAND_CSPR_EXT +#define CONFIG_SYS_CSPR2 CONFIG_SYS_NAND_CSPR +#define CONFIG_SYS_AMASK2 CONFIG_SYS_NAND_AMASK +#define CONFIG_SYS_CSOR2 CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NAND_FTIM0 +#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NAND_FTIM1 +#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NAND_FTIM2 +#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NAND_FTIM3 +#define CONFIG_SYS_CSPR3_EXT CONFIG_SYS_FPGA_CSPR_EXT +#define CONFIG_SYS_CSPR3 CONFIG_SYS_FPGA_CSPR +#define CONFIG_SYS_AMASK3 CONFIG_SYS_FPGA_AMASK +#define CONFIG_SYS_CSOR3 CONFIG_SYS_FPGA_CSOR +#define CONFIG_SYS_CS3_FTIM0 CONFIG_SYS_FPGA_FTIM0 +#define CONFIG_SYS_CS3_FTIM1 CONFIG_SYS_FPGA_FTIM1 +#define CONFIG_SYS_CS3_FTIM2 CONFIG_SYS_FPGA_FTIM2 +#define CONFIG_SYS_CS3_FTIM3 CONFIG_SYS_FPGA_FTIM3 + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_SYS_NS16550_CLK get_serial_clock() + +#define CONFIG_BAUDRATE 115200 + +/* + * I2C + */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC + +/* + * I2C bus multiplexer + */ +#define I2C_MUX_PCA_ADDR_PRI 0x77 +#define I2C_MUX_CH_DEFAULT 0x8 + +/* + * MMC + */ +#define CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_GENERIC_MMC + +/* + * eTSEC + */ +#define CONFIG_TSEC_ENET + +#ifdef CONFIG_TSEC_ENET +#define CONFIG_MII +#define CONFIG_MII_DEFAULT_TSEC 3 +#define CONFIG_TSEC1 1 +#define CONFIG_TSEC1_NAME "eTSEC1" +#define CONFIG_TSEC2 1 +#define CONFIG_TSEC2_NAME "eTSEC2" +#define CONFIG_TSEC3 1 +#define CONFIG_TSEC3_NAME "eTSEC3" + +#define TSEC1_PHY_ADDR 1 +#define TSEC2_PHY_ADDR 2 +#define TSEC3_PHY_ADDR 3 + +#define TSEC1_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC2_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC3_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) + +#define TSEC1_PHYIDX 0 +#define TSEC2_PHYIDX 0 +#define TSEC3_PHYIDX 0 + +#define CONFIG_ETHPRIME "eTSEC1" + +#define CONFIG_PHY_GIGE +#define CONFIG_PHYLIB +#define CONFIG_PHY_REALTEK + +#define CONFIG_HAS_ETH0 +#define CONFIG_HAS_ETH1 +#define CONFIG_HAS_ETH2 + +#define CONFIG_FSL_SGMII_RISER 1 +#define SGMII_RISER_PHY_OFFSET 0x1b + +#ifdef CONFIG_FSL_SGMII_RISER +#define CONFIG_SYS_TBIPA_VALUE 8 +#endif + +#endif +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MII +#define CONFIG_CMD_NET + +#define CONFIG_CMDLINE_TAG +#define CONFIG_CMDLINE_EDITING +#define CONFIG_CMD_IMLS + +#define CONFIG_HWCONFIG +#define HWCONFIG_BUFFER_SIZE 128 + +#define CONFIG_BOOTDELAY 3 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootargs=root=/dev/ram0 rw console=ttyS0,115200\0" \ + "fdt_high=0xcfffffff\0" \ + "initrd_high=0xcfffffff\0" \ + "hwconfig=fsl_ddr:ctlr_intlv=null,bank_intlv=null\0" + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "=> " +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE \ + (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_CMD_ENV_EXISTS +#define CONFIG_CMD_GREPENV +#define CONFIG_CMD_MEMINFO +#define CONFIG_CMD_MEMTEST +#define CONFIG_SYS_MEMTEST_START 0x80000000 +#define CONFIG_SYS_MEMTEST_END 0x9fffffff + +#define CONFIG_SYS_LOAD_ADDR 0x82000000 +#define CONFIG_SYS_HZ 1000 + +/* + * Stack sizes + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (30 * 1024) + +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* start of monitor */ + +/* + * Environment + */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K (one sector) */ + +#define CONFIG_OF_LIBFDT +#define CONFIG_OF_BOARD_SETUP +#define CONFIG_CMD_BOOTZ + +#endif From c8a7d9dab01c00c9efb5431284e9f16f8f2e92bb Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:45 +0800 Subject: [PATCH 12/17] arm: ls102xa: Add basic support for LS1021ATWR board LS102xA is an ARMv7 implementation. This patch is to add basic support for LS1021ATWR board. One DDR controller DUART1 is used as the console For the detail board information, please refer to README. Signed-off-by: Chen Lu Signed-off-by: Yuan Yao Signed-off-by: Alison Wang --- arch/arm/Kconfig | 4 + board/freescale/ls1021atwr/Kconfig | 23 ++ board/freescale/ls1021atwr/MAINTAINERS | 6 + board/freescale/ls1021atwr/Makefile | 7 + board/freescale/ls1021atwr/README | 109 ++++++ board/freescale/ls1021atwr/ls1021atwr.c | 482 ++++++++++++++++++++++++ configs/ls1021atwr_nor_defconfig | 2 + include/configs/ls1021atwr.h | 273 ++++++++++++++ 8 files changed, 906 insertions(+) create mode 100644 board/freescale/ls1021atwr/Kconfig create mode 100644 board/freescale/ls1021atwr/MAINTAINERS create mode 100644 board/freescale/ls1021atwr/Makefile create mode 100644 board/freescale/ls1021atwr/README create mode 100644 board/freescale/ls1021atwr/ls1021atwr.c create mode 100644 configs/ls1021atwr_nor_defconfig create mode 100644 include/configs/ls1021atwr.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d7ed3e207d..11143a8c38 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -473,6 +473,9 @@ config TARGET_LS2085A_SIMU config TARGET_LS1021AQDS bool "Support ls1021aqds_nor" +config TARGET_LS1021ATWR + bool "Support ls1021atwr_nor" + config TARGET_BALLOON3 bool "Support balloon3" @@ -598,6 +601,7 @@ source "board/eukrea/cpuat91/Kconfig" source "board/faraday/a320evb/Kconfig" source "board/freescale/ls2085a/Kconfig" source "board/freescale/ls1021aqds/Kconfig" +source "board/freescale/ls1021atwr/Kconfig" source "board/freescale/mx23evk/Kconfig" source "board/freescale/mx25pdk/Kconfig" source "board/freescale/mx28evk/Kconfig" diff --git a/board/freescale/ls1021atwr/Kconfig b/board/freescale/ls1021atwr/Kconfig new file mode 100644 index 0000000000..057808df99 --- /dev/null +++ b/board/freescale/ls1021atwr/Kconfig @@ -0,0 +1,23 @@ +if TARGET_LS1021ATWR + +config SYS_CPU + string + default "armv7" + +config SYS_BOARD + string + default "ls1021atwr" + +config SYS_VENDOR + string + default "freescale" + +config SYS_SOC + string + default "ls102xa" + +config SYS_CONFIG_NAME + string + default "ls1021atwr" + +endif diff --git a/board/freescale/ls1021atwr/MAINTAINERS b/board/freescale/ls1021atwr/MAINTAINERS new file mode 100644 index 0000000000..4e5bc15a0d --- /dev/null +++ b/board/freescale/ls1021atwr/MAINTAINERS @@ -0,0 +1,6 @@ +LS1021ATWR BOARD +M: Alison Wang +S: Maintained +F: board/freescale/ls1021atwr/ +F: include/configs/ls1021atwr.h +F: configs/ls1021atwr_nor_defconfig diff --git a/board/freescale/ls1021atwr/Makefile b/board/freescale/ls1021atwr/Makefile new file mode 100644 index 0000000000..b5df668713 --- /dev/null +++ b/board/freescale/ls1021atwr/Makefile @@ -0,0 +1,7 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ls1021atwr.o diff --git a/board/freescale/ls1021atwr/README b/board/freescale/ls1021atwr/README new file mode 100644 index 0000000000..d2821cbb6b --- /dev/null +++ b/board/freescale/ls1021atwr/README @@ -0,0 +1,109 @@ +Overview +-------- +The LS1021ATWR is a Freescale reference board that hosts the LS1021A SoC. + +LS1021A SoC Overview +------------------ +The QorIQ LS1 family, which includes the LS1021A communications processor, +is built on Layerscape architecture, the industry's first software-aware, +core-agnostic networking architecture to offer unprecedented efficiency +and scale. + +A member of the value-performance tier, the QorIQ LS1021A processor provides +extensive integration and power efficiency for fanless, small form factor +enterprise networking applications. Incorporating dual ARM Cortex-A7 cores +running up to 1.0 GHz, the LS1021A processor delivers pre-silicon CoreMark +performance of over 6,000, as well as virtualization support, advanced +security features and the broadest array of high-speed interconnects and +optimized peripheral features ever offered in a sub-3 W processor. + +The QorIQ LS1021A processor features an integrated LCD controller, +CAN controller for implementing industrial protocols, DDR3L/4 running +up to 1600 MHz, integrated security engine and QUICC Engine, and ECC +protection on both L1 and L2 caches. The LS1021A processor is pin- and +software-compatible with the QorIQ LS1020A and LS1022A processors. + +The LS1021A SoC includes the following function and features: + + - ARM Cortex-A7 MPCore compliant with ARMv7-A architecture + - Dual high-preformance ARM Cortex-A7 cores, each core includes: + - 32 Kbyte L1 Instruction Cache and Data Cache for each core (ECC protection) + - 512 Kbyte shared coherent L2 Cache (with ECC protection) + - NEON Co-processor (per core) + - 40-bit physical addressing + - Vector floating-point support + - ARM Core-Link CCI-400 Cache Coherent Interconnect + - One DDR3L/DDR4 SDRAM memory controller with x8/x16/x32-bit configuration + supporting speeds up to 1600Mtps + - ECC and interleaving support + - VeTSEC Ethernet complex + - Up to 3x virtualized 10/100/1000 Ethernet controllers + - MII, RMII, RGMII, and SGMII support + - QoS, lossless flow control, and IEEE 1588 support + - 4-lane 6GHz SerDes + - High speed interconnect (4 SerDes lanes with are muxed for these protocol) + - Two PCI Express Gen2 controllers running at up to 5 GHz + - One Serial ATA 3.0 supporting 6 GT/s operation + - Two SGMII interfaces supporting 1000 Mbps + - Additional peripheral interfaces + - One high-speed USB 3.0 controller with integrated PHY and one high-speed + USB 2.00 controller with ULPI + - Integrated flash controller (IFC) with 16-bit interface + - Quad SPI NOR Flash + - One enhanced Secure digital host controller + - Display controller unit (DCU) 24-bit RGB (12-bit DDR pin interface) + - Ten UARTs comprised of two 16550 compliant DUARTs, and six low power + UARTs + - Three I2C controllers + - Eight FlexTimers four supporting PWM and four FlexCAN ports + - Four GPIO controllers supporting up to 109 general purpose I/O signals + - Integrated advanced audio block: + - Four synchronous audio interfaces (SAI) + - Sony/Philips Digital Interconnect Format (SPDIF) + - Asynchronous Sample Rate Converter (ASRC) + - Hardware based crypto offload engine + - IPSec forwarding at up to 1Gbps + - QorIQ Trust Architecture, Secure Boot, and ARM TrustZone supported + - Public key hardware accelerator + - True Random Number Generator (NIST Certified) + - Advanced Encryption Standard Accelerators (AESA) + - Data Encryption Standard Accelerators + - QUICC Engine ULite block + - Two universal communication controllers (TDM and HDLC) supporting 64 + multichannels, each running at 64 Kbps + - Support for 256 channels of HDLC + - QorIQ TrustArchitecture with Secure Boot, as well as ARM TrustZone supported + +LS1021ATWR board Overview +------------------------- + - DDR Controller + - Supports rates of up to 1600 MHz data-rate + - Supports one DDR3LP SDRAM. + - IFC/Local Bus + - NOR: 128MB 16-bit NOR Flash + - Ethernet + - Three on-board RGMII 10/100/1G ethernet ports. + - CPLD + - Clocks + - System and DDR clock (SYSCLK, DDRCLK) + - SERDES clocks + - Power Supplies + - SDHC + - SDHC/SDXC connector + - Other IO + - One Serial port + - Three I2C ports + +Memory map +----------- +The addresses in brackets are physical addresses. + +Start Address End Address Description Size +0x00_0000_0000 0x00_000F_FFFF Secure Boot ROM 1MB +0x00_0100_0000 0x00_0FFF_FFFF CCSRBAR 240MB +0x00_1000_0000 0x00_1000_FFFF OCRAM0 64KB +0x00_1001_0000 0x00_1001_FFFF OCRAM1 64KB +0x00_2000_0000 0x00_20FF_FFFF DCSR 16MB +0x00_4000_0000 0x00_5FFF_FFFF QSPI 512MB +0x00_6000_0000 0x00_67FF_FFFF IFC - NOR Flash 128MB +0x00_8000_0000 0x00_FFFF_FFFF DRAM1 2GB diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c new file mode 100644 index 0000000000..92ad8cd9bd --- /dev/null +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -0,0 +1,482 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define VERSION_MASK 0x00FF +#define BANK_MASK 0x0001 +#define CONFIG_RESET 0x1 +#define INIT_RESET 0x1 + +#define CPLD_SET_MUX_SERDES 0x20 +#define CPLD_SET_BOOT_BANK 0x40 + +#define BOOT_FROM_UPPER_BANK 0x0 +#define BOOT_FROM_LOWER_BANK 0x1 + +#define LANEB_SATA (0x01) +#define LANEB_SGMII1 (0x02) +#define LANEC_SGMII1 (0x04) +#define LANEC_PCIEX1 (0x08) +#define LANED_PCIEX2 (0x10) +#define LANED_SGMII2 (0x20) + +#define MASK_LANE_B 0x1 +#define MASK_LANE_C 0x2 +#define MASK_LANE_D 0x4 +#define MASK_SGMII 0x8 + +#define KEEP_STATUS 0x0 +#define NEED_RESET 0x1 + +struct cpld_data { + u8 cpld_ver; /* cpld revision */ + u8 cpld_ver_sub; /* cpld sub revision */ + u8 pcba_ver; /* pcb revision number */ + u8 system_rst; /* reset system by cpld */ + u8 soft_mux_on; /* CPLD override physical switches Enable */ + u8 cfg_rcw_src1; /* Reset config word 1 */ + u8 cfg_rcw_src2; /* Reset config word 2 */ + u8 vbank; /* Flash bank selection Control */ + u8 gpio; /* GPIO for TWR-ELEV */ + u8 i2c3_ifc_mux; + u8 mux_spi2; + u8 can3_usb2_mux; /* CAN3 and USB2 Selection */ + u8 qe_lcd_mux; /* QE and LCD Selection */ + u8 serdes_mux; /* Multiplexed pins for SerDes Lanes */ + u8 global_rst; /* reset with init CPLD reg to default */ + u8 rev1; /* Reserved */ + u8 rev2; /* Reserved */ +}; + +static void convert_serdes_mux(int type, int need_reset); + +void cpld_show(void) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + printf("CPLD: V%x.%x\nPCBA: V%x.0\nVBank: %d\n", + in_8(&cpld_data->cpld_ver) & VERSION_MASK, + in_8(&cpld_data->cpld_ver_sub) & VERSION_MASK, + in_8(&cpld_data->pcba_ver) & VERSION_MASK, + in_8(&cpld_data->vbank) & BANK_MASK); + +#ifdef CONFIG_DEBUG + printf("soft_mux_on =%x\n", + in_8(&cpld_data->soft_mux_on)); + printf("cfg_rcw_src1 =%x\n", + in_8(&cpld_data->cfg_rcw_src1)); + printf("cfg_rcw_src2 =%x\n", + in_8(&cpld_data->cfg_rcw_src2)); + printf("vbank =%x\n", + in_8(&cpld_data->vbank)); + printf("gpio =%x\n", + in_8(&cpld_data->gpio)); + printf("i2c3_ifc_mux =%x\n", + in_8(&cpld_data->i2c3_ifc_mux)); + printf("mux_spi2 =%x\n", + in_8(&cpld_data->mux_spi2)); + printf("can3_usb2_mux =%x\n", + in_8(&cpld_data->can3_usb2_mux)); + printf("qe_lcd_mux =%x\n", + in_8(&cpld_data->qe_lcd_mux)); + printf("serdes_mux =%x\n", + in_8(&cpld_data->serdes_mux)); +#endif +} + +int checkboard(void) +{ + puts("Board: LS1021ATWR\n"); + cpld_show(); + + return 0; +} + +void ddrmc_init(void) +{ + struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR; + + out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG); + + out_be32(&ddr->cs0_bnds, DDR_CS0_BNDS); + out_be32(&ddr->cs0_config, DDR_CS0_CONFIG); + + out_be32(&ddr->timing_cfg_0, DDR_TIMING_CFG_0); + out_be32(&ddr->timing_cfg_1, DDR_TIMING_CFG_1); + out_be32(&ddr->timing_cfg_2, DDR_TIMING_CFG_2); + out_be32(&ddr->timing_cfg_3, DDR_TIMING_CFG_3); + out_be32(&ddr->timing_cfg_4, DDR_TIMING_CFG_4); + out_be32(&ddr->timing_cfg_5, DDR_TIMING_CFG_5); + + out_be32(&ddr->sdram_cfg_2, DDR_SDRAM_CFG_2); + + out_be32(&ddr->sdram_mode, DDR_SDRAM_MODE); + out_be32(&ddr->sdram_mode_2, DDR_SDRAM_MODE_2); + + out_be32(&ddr->sdram_interval, DDR_SDRAM_INTERVAL); + + out_be32(&ddr->ddr_wrlvl_cntl, DDR_DDR_WRLVL_CNTL); + + out_be32(&ddr->ddr_wrlvl_cntl_2, DDR_DDR_WRLVL_CNTL_2); + out_be32(&ddr->ddr_wrlvl_cntl_3, DDR_DDR_WRLVL_CNTL_3); + + out_be32(&ddr->ddr_cdr1, DDR_DDR_CDR1); + out_be32(&ddr->ddr_cdr2, DDR_DDR_CDR2); + + out_be32(&ddr->sdram_clk_cntl, DDR_SDRAM_CLK_CNTL); + out_be32(&ddr->ddr_zq_cntl, DDR_DDR_ZQ_CNTL); + + out_be32(&ddr->cs0_config_2, DDR_CS0_CONFIG_2); + udelay(1); + out_be32(&ddr->sdram_cfg, DDR_SDRAM_CFG | DDR_SDRAM_CFG_MEM_EN); +} + +int dram_init(void) +{ +#if (!defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)) + ddrmc_init(); +#endif + + gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE); + return 0; +} + +#ifdef CONFIG_FSL_ESDHC +struct fsl_esdhc_cfg esdhc_cfg[1] = { + {CONFIG_SYS_FSL_ESDHC_ADDR}, +}; + +int board_mmc_init(bd_t *bis) +{ + esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + + return fsl_esdhc_initialize(bis, &esdhc_cfg[0]); +} +#endif + +#ifdef CONFIG_TSEC_ENET +int board_eth_init(bd_t *bis) +{ + struct fsl_pq_mdio_info mdio_info; + struct tsec_info_struct tsec_info[4]; + int num = 0; + +#ifdef CONFIG_TSEC1 + SET_STD_TSEC_INFO(tsec_info[num], 1); + if (is_serdes_configured(SGMII_TSEC1)) { + puts("eTSEC1 is in sgmii mode.\n"); + tsec_info[num].flags |= TSEC_SGMII; + } + num++; +#endif +#ifdef CONFIG_TSEC2 + SET_STD_TSEC_INFO(tsec_info[num], 2); + if (is_serdes_configured(SGMII_TSEC2)) { + puts("eTSEC2 is in sgmii mode.\n"); + tsec_info[num].flags |= TSEC_SGMII; + } + num++; +#endif +#ifdef CONFIG_TSEC3 + SET_STD_TSEC_INFO(tsec_info[num], 3); + num++; +#endif + if (!num) { + printf("No TSECs initialized\n"); + return 0; + } + + mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + mdio_info.name = DEFAULT_MII_NAME; + fsl_pq_mdio_init(bis, &mdio_info); + + tsec_eth_init(bis, tsec_info, num); + + return pci_eth_init(bis); +} +#endif + +int config_serdes_mux(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + u32 protocol = in_be32(&gur->rcwsr[4]) & RCWSR4_SRDS1_PRTCL_MASK; + + protocol >>= RCWSR4_SRDS1_PRTCL_SHIFT; + switch (protocol) { + case 0x10: + convert_serdes_mux(LANEB_SATA, KEEP_STATUS); + convert_serdes_mux(LANED_PCIEX2 | + LANEC_PCIEX1, KEEP_STATUS); + break; + case 0x20: + convert_serdes_mux(LANEB_SGMII1, KEEP_STATUS); + convert_serdes_mux(LANEC_PCIEX1, KEEP_STATUS); + convert_serdes_mux(LANED_SGMII2, KEEP_STATUS); + break; + case 0x30: + convert_serdes_mux(LANEB_SATA, KEEP_STATUS); + convert_serdes_mux(LANEC_SGMII1, KEEP_STATUS); + convert_serdes_mux(LANED_SGMII2, KEEP_STATUS); + break; + case 0x70: + convert_serdes_mux(LANEB_SATA, KEEP_STATUS); + convert_serdes_mux(LANEC_PCIEX1, KEEP_STATUS); + convert_serdes_mux(LANED_SGMII2, KEEP_STATUS); + break; + } + + return 0; +} + +int board_early_init_f(void) +{ + struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; + +#ifdef CONFIG_TSEC_ENET + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_REV); + out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR); + out_be32(&scfg->etsecmcr, SCFG_ETSECCMCR_GE2_CLK125); + udelay(10); + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_NOREV); +#endif + +#ifdef CONFIG_FSL_IFC + init_early_memctl_regs(); +#endif + + return 0; +} + +int board_init(void) +{ +#ifndef CONFIG_SYS_FSL_NO_SERDES + fsl_serdes_init(); + config_serdes_mux(); +#endif + + return 0; +} + +void ft_board_setup(void *blob, bd_t *bd) +{ + ft_cpu_setup(blob, bd); +} + +u8 flash_read8(void *addr) +{ + return __raw_readb(addr + 1); +} + +void flash_write16(u16 val, void *addr) +{ + u16 shftval = (((val >> 8) & 0xff) | ((val << 8) & 0xff00)); + + __raw_writew(shftval, addr); +} + +u16 flash_read16(void *addr) +{ + u16 val = __raw_readw(addr); + + return (((val) >> 8) & 0x00ff) | (((val) << 8) & 0xff00); +} + +static void convert_flash_bank(char bank) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + printf("Now switch to boot from flash bank %d.\n", bank); + cpld_data->soft_mux_on = CPLD_SET_BOOT_BANK; + cpld_data->vbank = bank; + + printf("Reset board to enable configuration.\n"); + cpld_data->system_rst = CONFIG_RESET; +} + +static int flash_bank_cmd(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc != 2) + return CMD_RET_USAGE; + if (strcmp(argv[1], "0") == 0) + convert_flash_bank(BOOT_FROM_UPPER_BANK); + else if (strcmp(argv[1], "1") == 0) + convert_flash_bank(BOOT_FROM_LOWER_BANK); + else + return CMD_RET_USAGE; + + return 0; +} + +U_BOOT_CMD( + boot_bank, 2, 0, flash_bank_cmd, + "Flash bank Selection Control", + "bank[0-upper bank/1-lower bank] (e.g. boot_bank 0)" +); + +static int cpld_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + if (argc > 2) + return CMD_RET_USAGE; + if ((argc == 1) || (strcmp(argv[1], "conf") == 0)) + cpld_data->system_rst = CONFIG_RESET; + else if (strcmp(argv[1], "init") == 0) + cpld_data->global_rst = INIT_RESET; + else + return CMD_RET_USAGE; + + return 0; +} + +U_BOOT_CMD( + cpld_reset, 2, 0, cpld_reset_cmd, + "Reset via CPLD", + "conf\n" + " -reset with current CPLD configuration\n" + "init\n" + " -reset and initial CPLD configuration with default value" + +); + +static void convert_serdes_mux(int type, int need_reset) +{ + char current_serdes; + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + current_serdes = cpld_data->serdes_mux; + + switch (type) { + case LANEB_SATA: + current_serdes &= ~MASK_LANE_B; + break; + case LANEB_SGMII1: + current_serdes |= (MASK_LANE_B | MASK_SGMII | MASK_LANE_C); + break; + case LANEC_SGMII1: + current_serdes &= ~(MASK_LANE_B | MASK_SGMII | MASK_LANE_C); + break; + case LANED_SGMII2: + current_serdes |= MASK_LANE_D; + break; + case LANEC_PCIEX1: + current_serdes |= MASK_LANE_C; + break; + case (LANED_PCIEX2 | LANEC_PCIEX1): + current_serdes |= MASK_LANE_C; + current_serdes &= ~MASK_LANE_D; + break; + default: + printf("CPLD serdes MUX: unsupported MUX type 0x%x\n", type); + return; + } + + cpld_data->soft_mux_on |= CPLD_SET_MUX_SERDES; + cpld_data->serdes_mux = current_serdes; + + if (need_reset == 1) { + printf("Reset board to enable configuration\n"); + cpld_data->system_rst = CONFIG_RESET; + } +} + +void print_serdes_mux(void) +{ + char current_serdes; + struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE); + + current_serdes = cpld_data->serdes_mux; + + printf("Serdes Lane B: "); + if ((current_serdes & MASK_LANE_B) == 0) + printf("SATA,\n"); + else + printf("SGMII 1,\n"); + + printf("Serdes Lane C: "); + if ((current_serdes & MASK_LANE_C) == 0) + printf("SGMII 1,\n"); + else + printf("PCIe,\n"); + + printf("Serdes Lane D: "); + if ((current_serdes & MASK_LANE_D) == 0) + printf("PCIe,\n"); + else + printf("SGMII 2,\n"); + + printf("SGMII 1 is on lane "); + if ((current_serdes & MASK_SGMII) == 0) + printf("C.\n"); + else + printf("B.\n"); +} + +static int serdes_mux_cmd(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + if (argc != 2) + return CMD_RET_USAGE; + if (strcmp(argv[1], "sata") == 0) { + printf("Set serdes lane B to SATA.\n"); + convert_serdes_mux(LANEB_SATA, NEED_RESET); + } else if (strcmp(argv[1], "sgmii1b") == 0) { + printf("Set serdes lane B to SGMII 1.\n"); + convert_serdes_mux(LANEB_SGMII1, NEED_RESET); + } else if (strcmp(argv[1], "sgmii1c") == 0) { + printf("Set serdes lane C to SGMII 1.\n"); + convert_serdes_mux(LANEC_SGMII1, NEED_RESET); + } else if (strcmp(argv[1], "sgmii2") == 0) { + printf("Set serdes lane D to SGMII 2.\n"); + convert_serdes_mux(LANED_SGMII2, NEED_RESET); + } else if (strcmp(argv[1], "pciex1") == 0) { + printf("Set serdes lane C to PCIe X1.\n"); + convert_serdes_mux(LANEC_PCIEX1, NEED_RESET); + } else if (strcmp(argv[1], "pciex2") == 0) { + printf("Set serdes lane C & lane D to PCIe X2.\n"); + convert_serdes_mux((LANED_PCIEX2 | LANEC_PCIEX1), NEED_RESET); + } else if (strcmp(argv[1], "show") == 0) { + print_serdes_mux(); + } else { + return CMD_RET_USAGE; + } + + return 0; +} + +U_BOOT_CMD( + lane_bank, 2, 0, serdes_mux_cmd, + "Multiplexed function setting for SerDes Lanes", + "sata\n" + " -change lane B to sata\n" + "lane_bank sgmii1b\n" + " -change lane B to SGMII1\n" + "lane_bank sgmii1c\n" + " -change lane C to SGMII1\n" + "lane_bank sgmii2\n" + " -change lane D to SGMII2\n" + "lane_bank pciex1\n" + " -change lane C to PCIeX1\n" + "lane_bank pciex2\n" + " -change lane C & lane D to PCIeX2\n" + "\nWARNING: If you aren't familiar with the setting of serdes, don't try to change anything!\n" +); diff --git a/configs/ls1021atwr_nor_defconfig b/configs/ls1021atwr_nor_defconfig new file mode 100644 index 0000000000..5f465d3100 --- /dev/null +++ b/configs/ls1021atwr_nor_defconfig @@ -0,0 +1,2 @@ +CONFIG_ARM=y +CONFIG_TARGET_LS1021ATWR=y diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h new file mode 100644 index 0000000000..cb6b400425 --- /dev/null +++ b/include/configs/ls1021atwr.h @@ -0,0 +1,273 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#define CONFIG_LS102XA + +#define CONFIG_SYS_GENERIC_BOARD + +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DISPLAY_BOARDINFO + +#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_BOARD_EARLY_INIT_F + +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 16 * 1024 * 1024) + +#define CONFIG_SYS_INIT_RAM_ADDR OCRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE OCRAM_SIZE + +/* + * Generic Timer Definitions + */ +#define GENERIC_TIMER_CLK 12500000 + +#define CONFIG_SYS_CLK_FREQ 100000000 +#define CONFIG_DDR_CLK_FREQ 100000000 + +#ifndef CONFIG_SYS_TEXT_BASE +#define CONFIG_SYS_TEXT_BASE 0x67f80000 +#endif + +#define CONFIG_NR_DRAM_BANKS 1 +#define PHYS_SDRAM 0x80000000 +#define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024) + +#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000UL +#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE + +#define CONFIG_SYS_HAS_SERDES + +/* + * IFC Definitions + */ +#define CONFIG_FSL_IFC +#define CONFIG_SYS_FLASH_BASE 0x60000000 +#define CONFIG_SYS_FLASH_BASE_PHYS CONFIG_SYS_FLASH_BASE + +#define CONFIG_SYS_NOR0_CSPR_EXT (0x0) +#define CONFIG_SYS_NOR0_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | \ + CSPR_MSEL_NOR | \ + CSPR_V) +#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128 * 1024 * 1024) + +/* NOR Flash Timing Params */ +#define CONFIG_SYS_NOR_CSOR (CSOR_NOR_ADM_SHIFT(4) | \ + CSOR_NOR_TRHZ_80) +#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x4) | \ + FTIM0_NOR_TEADC(0x5) | \ + FTIM0_NOR_TAVDS(0x0) | \ + FTIM0_NOR_TEAHC(0x5)) +#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x35) | \ + FTIM1_NOR_TRAD_NOR(0x1A) | \ + FTIM1_NOR_TSEQRAD_NOR(0x13)) +#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x4) | \ + FTIM2_NOR_TCH(0x4) | \ + FTIM2_NOR_TWP(0x1c) | \ + FTIM2_NOR_TWPH(0x0e)) +#define CONFIG_SYS_NOR_FTIM3 0 + +#define CONFIG_FLASH_CFI_DRIVER +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_SYS_FLASH_QUIET_TEST +#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */ + +#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */ +#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */ +#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +#define CONFIG_SYS_FLASH_EMPTY_INFO +#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE_PHYS } + +#define CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS + +/* CPLD */ + +#define CONFIG_SYS_CPLD_BASE 0x7fb00000 +#define CPLD_BASE_PHYS CONFIG_SYS_CPLD_BASE + +#define CONFIG_SYS_FPGA_CSPR_EXT (0x0) +#define CONFIG_SYS_FPGA_CSPR (CSPR_PHYS_ADDR(CPLD_BASE_PHYS) | \ + CSPR_PORT_SIZE_8 | \ + CSPR_MSEL_GPCM | \ + CSPR_V) +#define CONFIG_SYS_FPGA_AMASK IFC_AMASK(64 * 1024) +#define CONFIG_SYS_FPGA_CSOR (CSOR_NOR_ADM_SHIFT(4) | \ + CSOR_NOR_NOR_MODE_AVD_NOR | \ + CSOR_NOR_TRHZ_80) + +/* CPLD Timing parameters for IFC GPCM */ +#define CONFIG_SYS_FPGA_FTIM0 (FTIM0_GPCM_TACSE(0xf) | \ + FTIM0_GPCM_TEADC(0xf) | \ + FTIM0_GPCM_TEAHC(0xf)) +#define CONFIG_SYS_FPGA_FTIM1 (FTIM1_GPCM_TACO(0xff) | \ + FTIM1_GPCM_TRAD(0x3f)) +#define CONFIG_SYS_FPGA_FTIM2 (FTIM2_GPCM_TCS(0xf) | \ + FTIM2_GPCM_TCH(0xf) | \ + FTIM2_GPCM_TWP(0xff)) +#define CONFIG_SYS_FPGA_FTIM3 0x0 +#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT +#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR +#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK +#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR +#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0 +#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1 +#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2 +#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3 +#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_FPGA_CSPR_EXT +#define CONFIG_SYS_CSPR1 CONFIG_SYS_FPGA_CSPR +#define CONFIG_SYS_AMASK1 CONFIG_SYS_FPGA_AMASK +#define CONFIG_SYS_CSOR1 CONFIG_SYS_FPGA_CSOR +#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_FPGA_FTIM0 +#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_FPGA_FTIM1 +#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_FPGA_FTIM2 +#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_FPGA_FTIM3 + +/* + * Serial Port + */ +#define CONFIG_CONS_INDEX 1 +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE 1 +#define CONFIG_SYS_NS16550_CLK get_serial_clock() + +#define CONFIG_BAUDRATE 115200 + +/* + * I2C + */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C +#define CONFIG_SYS_I2C_MXC + +/* + * MMC + */ +#define CONFIG_MMC +#define CONFIG_CMD_MMC +#define CONFIG_FSL_ESDHC +#define CONFIG_GENERIC_MMC + +/* + * eTSEC + */ +#define CONFIG_TSEC_ENET + +#ifdef CONFIG_TSEC_ENET +#define CONFIG_MII +#define CONFIG_MII_DEFAULT_TSEC 1 +#define CONFIG_TSEC1 1 +#define CONFIG_TSEC1_NAME "eTSEC1" +#define CONFIG_TSEC2 1 +#define CONFIG_TSEC2_NAME "eTSEC2" +#define CONFIG_TSEC3 1 +#define CONFIG_TSEC3_NAME "eTSEC3" + +#define TSEC1_PHY_ADDR 2 +#define TSEC2_PHY_ADDR 0 +#define TSEC3_PHY_ADDR 1 + +#define TSEC1_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC2_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) +#define TSEC3_FLAGS (TSEC_GIGABIT | TSEC_REDUCED) + +#define TSEC1_PHYIDX 0 +#define TSEC2_PHYIDX 0 +#define TSEC3_PHYIDX 0 + +#define CONFIG_ETHPRIME "eTSEC1" + +#define CONFIG_PHY_GIGE +#define CONFIG_PHYLIB +#define CONFIG_PHY_ATHEROS + +#define CONFIG_HAS_ETH0 +#define CONFIG_HAS_ETH1 +#define CONFIG_HAS_ETH2 +#endif + +#define CONFIG_CMD_PING +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_MII +#define CONFIG_CMD_NET + +#define CONFIG_CMDLINE_TAG +#define CONFIG_CMDLINE_EDITING +#define CONFIG_CMD_IMLS + +#define CONFIG_HWCONFIG +#define HWCONFIG_BUFFER_SIZE 128 + +#define CONFIG_BOOTDELAY 3 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "bootargs=root=/dev/ram0 rw console=ttyS0,115200\0" \ + "initrd_high=0xcfffffff\0" \ + "fdt_high=0xcfffffff\0" + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_PROMPT "=> " +#define CONFIG_AUTO_COMPLETE +#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_PBSIZE \ + (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + +#define CONFIG_CMD_ENV_EXISTS +#define CONFIG_CMD_GREPENV +#define CONFIG_CMD_MEMINFO +#define CONFIG_CMD_MEMTEST +#define CONFIG_SYS_MEMTEST_START 0x80000000 +#define CONFIG_SYS_MEMTEST_END 0x9fffffff + +#define CONFIG_SYS_LOAD_ADDR 0x82000000 +#define CONFIG_SYS_HZ 1000 + +/* + * Stack sizes + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE (30 * 1024) + +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE /* start of monitor */ + +/* + * Environment + */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_SIZE 0x20000 +#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K (one sector) */ + +#define CONFIG_OF_LIBFDT +#define CONFIG_OF_BOARD_SETUP +#define CONFIG_CMD_BOOTZ + +#endif From 5ea060a9f96740969d1d1c392e446da823bb01d3 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Fri, 5 Sep 2014 13:52:46 +0800 Subject: [PATCH 13/17] net: tsec: Remove tx snooping support from LS1 Remove the DMCTRL Tx snooping bits (TDSEN and TBDSEN) as a workaround for LS1. It has been observed that currently the Tx stops functioning after a fair amount of Tx traffic with these settings on. These bits are sticky and once set they cannot be reset from Linux, for instance. Signed-off-by: Claudiu Manoil --- include/tsec.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/tsec.h b/include/tsec.h index 1119d2cb60..58cdc19df3 100644 --- a/include/tsec.h +++ b/include/tsec.h @@ -129,7 +129,11 @@ #define MINFLR_INIT_SETTINGS 0x00000040 +#ifdef CONFIG_LS102XA +#define DMACTRL_INIT_SETTINGS 0x00000003 +#else #define DMACTRL_INIT_SETTINGS 0x000000c3 +#endif #define DMACTRL_GRS 0x00000010 #define DMACTRL_GTS 0x00000008 #define DMACTRL_LE 0x00008000 From 6209e14cb026c20614c388020eb74b8972a16747 Mon Sep 17 00:00:00 2001 From: Jingchang Lu Date: Fri, 5 Sep 2014 13:52:47 +0800 Subject: [PATCH 14/17] serial: lpuart: add 32-bit registers lpuart support On vybrid, lpuart's registers are 8-bit. On LS102xA, lpuart's registers are 32-bit. This patch adds the support for 32-bit registers on LS102xA. Signed-off-by: Jingchang Lu Signed-off-by: Yuan Yao --- drivers/serial/serial_lpuart.c | 118 +++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index da5f9a21f4..b0c6f6f4ab 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -17,10 +17,34 @@ #define UC2_TE (1 << 3) #define UC2_RE (1 << 2) +#define STAT_LBKDIF (1 << 31) +#define STAT_RXEDGIF (1 << 30) +#define STAT_TDRE (1 << 23) +#define STAT_RDRF (1 << 21) +#define STAT_IDLE (1 << 20) +#define STAT_OR (1 << 19) +#define STAT_NF (1 << 18) +#define STAT_FE (1 << 17) +#define STAT_PF (1 << 16) +#define STAT_MA1F (1 << 15) +#define STAT_MA2F (1 << 14) +#define STAT_FLAGS (STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \ + STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F) + +#define CTRL_TE (1 << 19) +#define CTRL_RE (1 << 18) + +#define FIFO_TXFE 0x80 +#define FIFO_RXFE 0x40 + +#define WATER_TXWATER_OFF 1 +#define WATER_RXWATER_OFF 16 + DECLARE_GLOBAL_DATA_PTR; struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE; +#ifndef CONFIG_LPUART_32B_REG static void lpuart_serial_setbrg(void) { u32 clk = mxc_get_clock(MXC_UART_CLK); @@ -107,13 +131,107 @@ static struct serial_device lpuart_serial_drv = { .getc = lpuart_serial_getc, .tstc = lpuart_serial_tstc, }; +#else +static void lpuart32_serial_setbrg(void) +{ + u32 clk = CONFIG_SYS_CLK_FREQ; + u32 sbr; + + if (!gd->baudrate) + gd->baudrate = CONFIG_BAUDRATE; + + sbr = (clk / (16 * gd->baudrate)); + /* place adjustment later - n/32 BRFA */ + + out_be32(&base->baud, sbr); +} + +static int lpuart32_serial_getc(void) +{ + u32 stat; + + while (((stat = in_be32(&base->stat)) & STAT_RDRF) == 0) { + out_be32(&base->stat, STAT_FLAGS); + WATCHDOG_RESET(); + } + + return in_be32(&base->data) & 0x3ff; +} + +static void lpuart32_serial_putc(const char c) +{ + if (c == '\n') + serial_putc('\r'); + + while (!(in_be32(&base->stat) & STAT_TDRE)) + WATCHDOG_RESET(); + + out_be32(&base->data, c); +} + +/* + * Test whether a character is in the RX buffer + */ +static int lpuart32_serial_tstc(void) +{ + if ((in_be32(&base->water) >> 24) == 0) + return 0; + + return 1; +} + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + */ +static int lpuart32_serial_init(void) +{ + u8 ctrl; + + ctrl = in_be32(&base->ctrl); + ctrl &= ~CTRL_RE; + ctrl &= ~CTRL_TE; + out_be32(&base->ctrl, ctrl); + + out_be32(&base->modir, 0); + out_be32(&base->fifo, ~(FIFO_TXFE | FIFO_RXFE)); + + out_be32(&base->match, 0); + /* provide data bits, parity, stop bit, etc */ + + serial_setbrg(); + + out_be32(&base->ctrl, CTRL_RE | CTRL_TE); + + return 0; +} + +static struct serial_device lpuart32_serial_drv = { + .name = "lpuart32_serial", + .start = lpuart32_serial_init, + .stop = NULL, + .setbrg = lpuart32_serial_setbrg, + .putc = lpuart32_serial_putc, + .puts = default_serial_puts, + .getc = lpuart32_serial_getc, + .tstc = lpuart32_serial_tstc, +}; +#endif void lpuart_serial_initialize(void) { +#ifdef CONFIG_LPUART_32B_REG + serial_register(&lpuart32_serial_drv); +#else serial_register(&lpuart_serial_drv); +#endif } __weak struct serial_device *default_serial_console(void) { +#ifdef CONFIG_LPUART_32B_REG + return &lpuart32_serial_drv; +#else return &lpuart_serial_drv; +#endif } From 327def5060d03648801b8c92b3235b0c9426af47 Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:48 +0800 Subject: [PATCH 15/17] video: dcu: Add DCU driver support This patch is to add DCU driver support. DCU also named 2D-ACE(Two Dimensional Animation and Compositing Engine) is a system master that fetches graphics stored in internal or external memory and displays them on a TFT LCD panel. Signed-off-by: Alison Wang --- arch/arm/include/asm/arch-ls102xa/config.h | 4 + drivers/video/Makefile | 1 + drivers/video/fsl_dcu_fb.c | 365 +++++++++++++++++++++ include/fsl_dcu_fb.h | 16 + 4 files changed, 386 insertions(+) create mode 100644 drivers/video/fsl_dcu_fb.c create mode 100644 include/fsl_dcu_fb.h diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h index 08c21afd1e..ed78c33e0a 100644 --- a/arch/arm/include/asm/arch-ls102xa/config.h +++ b/arch/arm/include/asm/arch-ls102xa/config.h @@ -24,6 +24,7 @@ #define CONFIG_SYS_FSL_LS1_CLK_ADDR (CONFIG_SYS_IMMR + 0x00ee1000) #define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011c0500) #define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011d0500) +#define CONFIG_SYS_DCU_ADDR (CONFIG_SYS_IMMR + 0x01ce0000) #define CONFIG_SYS_TSEC1_OFFSET 0x01d10000 #define CONFIG_SYS_TSEC2_OFFSET 0x01d50000 @@ -60,6 +61,9 @@ #define CONFIG_SYS_FSL_WDOG_BE #define CONFIG_SYS_FSL_DSPI_BE #define CONFIG_SYS_FSL_QSPI_BE +#define CONFIG_SYS_FSL_DCU_BE + +#define DCU_LAYER_MAX_NUM 16 #define CONFIG_SYS_FSL_SRDS_1 diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 93a91c3fa6..0914ea173d 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \ exynos_mipi_dsi_lowlevel.o obj-$(CONFIG_EXYNOS_PWM_BL) += exynos_pwm_bl.o obj-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o +obj-$(CONFIG_FSL_DCU_FB) += fsl_dcu_fb.o videomodes.o obj-$(CONFIG_L5F31188) += l5f31188.o obj-$(CONFIG_MPC8XX_LCD) += mpc8xx_lcd.o obj-$(CONFIG_PXA_LCD) += pxa_lcd.o diff --git a/drivers/video/fsl_dcu_fb.c b/drivers/video/fsl_dcu_fb.c new file mode 100644 index 0000000000..d4cd382776 --- /dev/null +++ b/drivers/video/fsl_dcu_fb.c @@ -0,0 +1,365 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * FSL DCU Framebuffer driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include "videomodes.h" + +/* Convert the X,Y resolution pair into a single number */ +#define RESOLUTION(x, y) (((u32)(x) << 16) | (y)) + +#ifdef CONFIG_SYS_FSL_DCU_LE +#define dcu_read32 in_le32 +#define dcu_write32 out_le32 +#elif defined(CONFIG_SYS_FSL_DCU_BE) +#define dcu_read32 in_be32 +#define dcu_write32 out_be32 +#endif + +#define DCU_MODE_BLEND_ITER(x) ((x) << 20) +#define DCU_MODE_RASTER_EN (1 << 14) +#define DCU_MODE_NORMAL 1 +#define DCU_MODE_COLORBAR 3 +#define DCU_BGND_R(x) ((x) << 16) +#define DCU_BGND_G(x) ((x) << 8) +#define DCU_BGND_B(x) (x) +#define DCU_DISP_SIZE_DELTA_Y(x) ((x) << 16) +#define DCU_DISP_SIZE_DELTA_X(x) (x) +#define DCU_HSYN_PARA_BP(x) ((x) << 22) +#define DCU_HSYN_PARA_PW(x) ((x) << 11) +#define DCU_HSYN_PARA_FP(x) (x) +#define DCU_VSYN_PARA_BP(x) ((x) << 22) +#define DCU_VSYN_PARA_PW(x) ((x) << 11) +#define DCU_VSYN_PARA_FP(x) (x) +#define DCU_SYN_POL_INV_PXCK_FALL (0 << 6) +#define DCU_SYN_POL_NEG_REMAIN (0 << 5) +#define DCU_SYN_POL_INV_VS_LOW (1 << 1) +#define DCU_SYN_POL_INV_HS_LOW (1) +#define DCU_THRESHOLD_LS_BF_VS(x) ((x) << 16) +#define DCU_THRESHOLD_OUT_BUF_HIGH(x) ((x) << 8) +#define DCU_THRESHOLD_OUT_BUF_LOW(x) (x) +#define DCU_UPDATE_MODE_MODE (1 << 31) +#define DCU_UPDATE_MODE_READREG (1 << 30) + +#define DCU_CTRLDESCLN_1_HEIGHT(x) ((x) << 16) +#define DCU_CTRLDESCLN_1_WIDTH(x) (x) +#define DCU_CTRLDESCLN_2_POSY(x) ((x) << 16) +#define DCU_CTRLDESCLN_2_POSX(x) (x) +#define DCU_CTRLDESCLN_4_EN (1 << 31) +#define DCU_CTRLDESCLN_4_TILE_EN (1 << 30) +#define DCU_CTRLDESCLN_4_DATA_SEL_CLUT (1 << 29) +#define DCU_CTRLDESCLN_4_SAFETY_EN (1 << 28) +#define DCU_CTRLDESCLN_4_TRANS(x) ((x) << 20) +#define DCU_CTRLDESCLN_4_BPP(x) ((x) << 16) +#define DCU_CTRLDESCLN_4_RLE_EN (1 << 15) +#define DCU_CTRLDESCLN_4_LUOFFS(x) ((x) << 4) +#define DCU_CTRLDESCLN_4_BB_ON (1 << 2) +#define DCU_CTRLDESCLN_4_AB(x) (x) +#define DCU_CTRLDESCLN_5_CKMAX_R(x) ((x) << 16) +#define DCU_CTRLDESCLN_5_CKMAX_G(x) ((x) << 8) +#define DCU_CTRLDESCLN_5_CKMAX_B(x) (x) +#define DCU_CTRLDESCLN_6_CKMIN_R(x) ((x) << 16) +#define DCU_CTRLDESCLN_6_CKMIN_G(x) ((x) << 8) +#define DCU_CTRLDESCLN_6_CKMIN_B(x) (x) +#define DCU_CTRLDESCLN_7_TILE_VER(x) ((x) << 16) +#define DCU_CTRLDESCLN_7_TILE_HOR(x) (x) +#define DCU_CTRLDESCLN_8_FG_FCOLOR(x) (x) +#define DCU_CTRLDESCLN_9_BG_BCOLOR(x) (x) + +#define BPP_16_RGB565 4 +#define BPP_24_RGB888 5 +#define BPP_32_ARGB8888 6 + +/* + * This setting is used for the TWR_LCD_RGB card + */ +static struct fb_videomode fsl_dcu_mode_480_272 = { + .name = "480x272-60", + .refresh = 60, + .xres = 480, + .yres = 272, + .pixclock = 91996, + .left_margin = 2, + .right_margin = 2, + .upper_margin = 1, + .lower_margin = 1, + .hsync_len = 41, + .vsync_len = 2, + .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED +}; + +/* + * This setting is used for Siliconimage SiI9022A HDMI + */ +static struct fb_videomode fsl_dcu_mode_640_480 = { + .name = "640x480-60", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 39722, + .left_margin = 48, + .right_margin = 16, + .upper_margin = 33, + .lower_margin = 10, + .hsync_len = 96, + .vsync_len = 2, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, +}; + +/* + * DCU register map + */ +struct dcu_reg { + u32 desc_cursor[4]; + u32 mode; + u32 bgnd; + u32 disp_size; + u32 hsyn_para; + u32 vsyn_para; + u32 synpol; + u32 threshold; + u32 int_status; + u32 int_mask; + u32 colbar[8]; + u32 div_ratio; + u32 sign_calc[2]; + u32 crc_val; + u8 res_064[0x6c-0x64]; + u32 parr_err_status1; + u8 res_070[0x7c-0x70]; + u32 parr_err_status3; + u32 mparr_err_status1; + u8 res_084[0x90-0x84]; + u32 mparr_err_status3; + u32 threshold_inp_buf[2]; + u8 res_09c[0xa0-0x9c]; + u32 luma_comp; + u32 chroma_red; + u32 chroma_green; + u32 chroma_blue; + u32 crc_pos; + u32 lyr_intpol_en; + u32 lyr_luma_comp; + u32 lyr_chrm_red; + u32 lyr_chrm_grn; + u32 lyr_chrm_blue; + u8 res_0c4[0xcc-0xc8]; + u32 update_mode; + u32 underrun; + u8 res_0d4[0x100-0xd4]; + u32 gpr; + u32 slr_l[2]; + u32 slr_disp_size; + u32 slr_hvsync_para; + u32 slr_pol; + u32 slr_l_transp[2]; + u8 res_120[0x200-0x120]; + u32 ctrldescl[DCU_LAYER_MAX_NUM][16]; +}; + +static struct fb_info info; + +static void reset_total_layers(void) +{ + struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR; + int i; + + for (i = 0; i < DCU_LAYER_MAX_NUM; i++) { + dcu_write32(®s->ctrldescl[i][0], 0); + dcu_write32(®s->ctrldescl[i][1], 0); + dcu_write32(®s->ctrldescl[i][2], 0); + dcu_write32(®s->ctrldescl[i][3], 0); + dcu_write32(®s->ctrldescl[i][4], 0); + dcu_write32(®s->ctrldescl[i][5], 0); + dcu_write32(®s->ctrldescl[i][6], 0); + dcu_write32(®s->ctrldescl[i][7], 0); + dcu_write32(®s->ctrldescl[i][8], 0); + dcu_write32(®s->ctrldescl[i][9], 0); + dcu_write32(®s->ctrldescl[i][10], 0); + } + + dcu_write32(®s->update_mode, DCU_UPDATE_MODE_READREG); +} + +static int layer_ctrldesc_init(int index, u32 pixel_format) +{ + struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR; + unsigned int bpp = BPP_24_RGB888; + + dcu_write32(®s->ctrldescl[index][0], + DCU_CTRLDESCLN_1_HEIGHT(info.var.yres) | + DCU_CTRLDESCLN_1_WIDTH(info.var.xres)); + + dcu_write32(®s->ctrldescl[index][1], + DCU_CTRLDESCLN_2_POSY(0) | + DCU_CTRLDESCLN_2_POSX(0)); + + dcu_write32(®s->ctrldescl[index][2], (unsigned int)info.screen_base); + + switch (pixel_format) { + case 16: + bpp = BPP_16_RGB565; + break; + case 24: + bpp = BPP_24_RGB888; + break; + case 32: + bpp = BPP_32_ARGB8888; + break; + default: + printf("unsupported color depth: %u\n", pixel_format); + } + + dcu_write32(®s->ctrldescl[index][3], + DCU_CTRLDESCLN_4_EN | + DCU_CTRLDESCLN_4_TRANS(0xff) | + DCU_CTRLDESCLN_4_BPP(bpp) | + DCU_CTRLDESCLN_4_AB(0)); + + dcu_write32(®s->ctrldescl[index][4], + DCU_CTRLDESCLN_5_CKMAX_R(0xff) | + DCU_CTRLDESCLN_5_CKMAX_G(0xff) | + DCU_CTRLDESCLN_5_CKMAX_B(0xff)); + dcu_write32(®s->ctrldescl[index][5], + DCU_CTRLDESCLN_6_CKMIN_R(0) | + DCU_CTRLDESCLN_6_CKMIN_G(0) | + DCU_CTRLDESCLN_6_CKMIN_B(0)); + + dcu_write32(®s->ctrldescl[index][6], + DCU_CTRLDESCLN_7_TILE_VER(0) | + DCU_CTRLDESCLN_7_TILE_HOR(0)); + + dcu_write32(®s->ctrldescl[index][7], DCU_CTRLDESCLN_8_FG_FCOLOR(0)); + dcu_write32(®s->ctrldescl[index][8], DCU_CTRLDESCLN_9_BG_BCOLOR(0)); + + dcu_write32(®s->update_mode, DCU_UPDATE_MODE_READREG); + + return 0; +} + +int fsl_dcu_init(unsigned int xres, unsigned int yres, + unsigned int pixel_format) +{ + struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR; + unsigned int div, mode; + + /* Memory allocation for framebuffer */ + info.screen_size = + info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8); + info.screen_base = (char *)memalign(ARCH_DMA_MINALIGN, + roundup(info.screen_size, ARCH_DMA_MINALIGN)); + memset(info.screen_base, 0, info.screen_size); + + reset_total_layers(); + div = dcu_set_pixel_clock(info.var.pixclock); + dcu_write32(®s->div_ratio, (div - 1)); + + dcu_write32(®s->disp_size, + DCU_DISP_SIZE_DELTA_Y(info.var.yres) | + DCU_DISP_SIZE_DELTA_X(info.var.xres / 16)); + + dcu_write32(®s->hsyn_para, + DCU_HSYN_PARA_BP(info.var.left_margin) | + DCU_HSYN_PARA_PW(info.var.hsync_len) | + DCU_HSYN_PARA_FP(info.var.right_margin)); + + dcu_write32(®s->vsyn_para, + DCU_VSYN_PARA_BP(info.var.upper_margin) | + DCU_VSYN_PARA_PW(info.var.vsync_len) | + DCU_VSYN_PARA_FP(info.var.lower_margin)); + + dcu_write32(®s->synpol, + DCU_SYN_POL_INV_PXCK_FALL | + DCU_SYN_POL_NEG_REMAIN | + DCU_SYN_POL_INV_VS_LOW | + DCU_SYN_POL_INV_HS_LOW); + + dcu_write32(®s->bgnd, + DCU_BGND_R(0) | DCU_BGND_G(0) | DCU_BGND_B(0)); + + dcu_write32(®s->mode, + DCU_MODE_BLEND_ITER(DCU_LAYER_MAX_NUM) | + DCU_MODE_RASTER_EN); + + dcu_write32(®s->threshold, + DCU_THRESHOLD_LS_BF_VS(0x3) | + DCU_THRESHOLD_OUT_BUF_HIGH(0x78) | + DCU_THRESHOLD_OUT_BUF_LOW(0)); + + mode = dcu_read32(®s->mode); + dcu_write32(®s->mode, mode | DCU_MODE_NORMAL); + + layer_ctrldesc_init(0, pixel_format); + + return 0; +} + +void *video_hw_init(void) +{ + static GraphicDevice ctfb; + const char *options; + unsigned int depth = 0, freq = 0; + struct fb_videomode *fsl_dcu_mode_db = &fsl_dcu_mode_480_272; + + if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq, + &options)) + return NULL; + + /* Find the monitor port, which is a required option */ + if (!options) + return NULL; + if (strncmp(options, "monitor=", 8) != 0) + return NULL; + + switch (RESOLUTION(ctfb.winSizeX, ctfb.winSizeY)) { + case RESOLUTION(480, 272): + fsl_dcu_mode_db = &fsl_dcu_mode_480_272; + break; + case RESOLUTION(640, 480): + fsl_dcu_mode_db = &fsl_dcu_mode_640_480; + break; + default: + printf("unsupported resolution %ux%u\n", + ctfb.winSizeX, ctfb.winSizeY); + } + + info.var.xres = fsl_dcu_mode_db->xres; + info.var.yres = fsl_dcu_mode_db->yres; + info.var.bits_per_pixel = 32; + info.var.pixclock = fsl_dcu_mode_db->pixclock; + info.var.left_margin = fsl_dcu_mode_db->left_margin; + info.var.right_margin = fsl_dcu_mode_db->right_margin; + info.var.upper_margin = fsl_dcu_mode_db->upper_margin; + info.var.lower_margin = fsl_dcu_mode_db->lower_margin; + info.var.hsync_len = fsl_dcu_mode_db->hsync_len; + info.var.vsync_len = fsl_dcu_mode_db->vsync_len; + info.var.sync = fsl_dcu_mode_db->sync; + info.var.vmode = fsl_dcu_mode_db->vmode; + info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8; + + if (platform_dcu_init(ctfb.winSizeX, ctfb.winSizeY, + options + 8, fsl_dcu_mode_db) < 0) + return NULL; + + ctfb.frameAdrs = (unsigned int)info.screen_base; + ctfb.plnSizeX = ctfb.winSizeX; + ctfb.plnSizeY = ctfb.winSizeY; + + ctfb.gdfBytesPP = 4; + ctfb.gdfIndex = GDF_32BIT_X888RGB; + + ctfb.memSize = info.screen_size; + + return &ctfb; +} diff --git a/include/fsl_dcu_fb.h b/include/fsl_dcu_fb.h new file mode 100644 index 0000000000..42632984d3 --- /dev/null +++ b/include/fsl_dcu_fb.h @@ -0,0 +1,16 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * FSL DCU Framebuffer driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include + +int fsl_dcu_init(unsigned int xres, unsigned int yres, + unsigned int pixel_format); + +/* Prototypes for external board-specific functions */ +int platform_dcu_init(unsigned int xres, unsigned int yres, + const char *port, struct fb_videomode *dcu_fb_videomode); +unsigned int dcu_set_pixel_clock(unsigned int pixclock); From 4081bf4f903cf3709a48a0d67cba7b043dd7a50e Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:49 +0800 Subject: [PATCH 16/17] video: dcu: Add Sii9022A HDMI Transmitter support On LS1021ATWR, Silicon's Sii9022A HDMI Transmitter is used. This patch adds the common setting for this chip. Signed-off-by: Alison Wang --- board/freescale/common/Makefile | 2 + board/freescale/common/dcu_sii9022a.c | 153 ++++++++++++++++++++++++++ board/freescale/common/dcu_sii9022a.h | 13 +++ 3 files changed, 168 insertions(+) create mode 100644 board/freescale/common/dcu_sii9022a.c create mode 100644 board/freescale/common/dcu_sii9022a.h diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 50d77317df..32b5a3b70c 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -36,6 +36,8 @@ endif obj-$(CONFIG_FSL_DIU_CH7301) += diu_ch7301.o +obj-$(CONFIG_FSL_DCU_SII9022A) += dcu_sii9022a.o + obj-$(CONFIG_MPC8541CDS) += cds_pci_ft.o obj-$(CONFIG_MPC8548CDS) += cds_pci_ft.o obj-$(CONFIG_MPC8555CDS) += cds_pci_ft.o diff --git a/board/freescale/common/dcu_sii9022a.c b/board/freescale/common/dcu_sii9022a.c new file mode 100644 index 0000000000..2da627e1f9 --- /dev/null +++ b/board/freescale/common/dcu_sii9022a.c @@ -0,0 +1,153 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +#define PIXEL_CLK_LSB_REG 0x00 +#define PIXEL_CLK_MSB_REG 0x01 +#define VERT_FREQ_LSB_REG 0x02 +#define VERT_FREQ_MSB_REG 0x03 +#define TOTAL_PIXELS_LSB_REG 0x04 +#define TOTAL_PIXELS_MSB_REG 0x05 +#define TOTAL_LINES_LSB_REG 0x06 +#define TOTAL_LINES_MSB_REG 0x07 +#define TPI_INBUS_FMT_REG 0x08 +#define TPI_INPUT_FMT_REG 0x09 +#define TPI_OUTPUT_FMT_REG 0x0A +#define TPI_SYS_CTRL_REG 0x1A +#define TPI_PWR_STAT_REG 0x1E +#define TPI_AUDIO_HANDING_REG 0x25 +#define TPI_AUDIO_INTF_REG 0x26 +#define TPI_AUDIO_FREQ_REG 0x27 +#define TPI_SET_PAGE_REG 0xBC +#define TPI_SET_OFFSET_REG 0xBD +#define TPI_RW_ACCESS_REG 0xBE +#define TPI_TRANS_MODE_REG 0xC7 + +#define TPI_INBUS_CLOCK_RATIO_1 (1 << 6) +#define TPI_INBUS_FULL_PIXEL_WIDE (1 << 5) +#define TPI_INBUS_RISING_EDGE (1 << 4) +#define TPI_INPUT_CLR_DEPTH_8BIT (0 << 6) +#define TPI_INPUT_VRANGE_EXPAN_AUTO (0 << 2) +#define TPI_INPUT_CLR_RGB (0 << 0) +#define TPI_OUTPUT_CLR_DEPTH_8BIT (0 << 6) +#define TPI_OUTPUT_VRANGE_COMPRE_AUTO (0 << 2) +#define TPI_OUTPUT_CLR_HDMI_RGB (0 << 0) +#define TPI_SYS_TMDS_OUTPUT (0 << 4) +#define TPI_SYS_AV_NORAML (0 << 3) +#define TPI_SYS_AV_MUTE (1 << 3) +#define TPI_SYS_DVI_MODE (0 << 0) +#define TPI_SYS_HDMI_MODE (1 << 0) +#define TPI_PWR_STAT_MASK (3 << 0) +#define TPI_PWR_STAT_D0 (0 << 0) +#define TPI_AUDIO_PASS_BASIC (0 << 0) +#define TPI_AUDIO_INTF_I2S (2 << 6) +#define TPI_AUDIO_INTF_NORMAL (0 << 4) +#define TPI_AUDIO_TYPE_PCM (1 << 0) +#define TPI_AUDIO_SAMP_SIZE_16BIT (1 << 6) +#define TPI_AUDIO_SAMP_FREQ_44K (2 << 3) +#define TPI_SET_PAGE_SII9022A 0x01 +#define TPI_SET_OFFSET_SII9022A 0x82 +#define TPI_RW_EN_SRC_TERMIN (1 << 0) +#define TPI_TRANS_MODE_ENABLE (0 << 7) + +/* Programming of Silicon SIi9022a HDMI Transmitter */ +int dcu_set_dvi_encoder(struct fb_videomode *videomode) +{ + u8 temp; + u16 temp1, temp2; + u32 temp3; + + i2c_set_bus_num(CONFIG_SYS_I2C_DVI_BUS_NUM); + + /* Enable TPI transmitter mode */ + temp = TPI_TRANS_MODE_ENABLE; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_TRANS_MODE_REG, 1, &temp, 1); + + /* Enter into D0 state, full operation */ + i2c_read(CONFIG_SYS_I2C_DVI_ADDR, TPI_PWR_STAT_REG, 1, &temp, 1); + temp &= ~TPI_PWR_STAT_MASK; + temp |= TPI_PWR_STAT_D0; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_PWR_STAT_REG, 1, &temp, 1); + + /* Enable source termination */ + temp = TPI_SET_PAGE_SII9022A; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SET_PAGE_REG, 1, &temp, 1); + temp = TPI_SET_OFFSET_SII9022A; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SET_OFFSET_REG, 1, &temp, 1); + + i2c_read(CONFIG_SYS_I2C_DVI_ADDR, TPI_RW_ACCESS_REG, 1, &temp, 1); + temp |= TPI_RW_EN_SRC_TERMIN; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_RW_ACCESS_REG, 1, &temp, 1); + + /* Set TPI system control */ + temp = TPI_SYS_TMDS_OUTPUT | TPI_SYS_AV_NORAML | TPI_SYS_DVI_MODE; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_SYS_CTRL_REG, 1, &temp, 1); + + /* Set pixel clock */ + temp1 = PICOS2KHZ(videomode->pixclock) / 10; + temp = (u8)(temp1 & 0xFF); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, PIXEL_CLK_LSB_REG, 1, &temp, 1); + temp = (u8)(temp1 >> 8); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, PIXEL_CLK_MSB_REG, 1, &temp, 1); + + /* Set total pixels per line */ + temp1 = videomode->hsync_len + videomode->left_margin + + videomode->xres + videomode->right_margin; + temp = (u8)(temp1 & 0xFF); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_PIXELS_LSB_REG, 1, &temp, 1); + temp = (u8)(temp1 >> 8); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_PIXELS_MSB_REG, 1, &temp, 1); + + /* Set total lines */ + temp2 = videomode->vsync_len + videomode->upper_margin + + videomode->yres + videomode->lower_margin; + temp = (u8)(temp2 & 0xFF); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_LINES_LSB_REG, 1, &temp, 1); + temp = (u8)(temp2 >> 8); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TOTAL_LINES_MSB_REG, 1, &temp, 1); + + /* Set vertical frequency in Hz */ + temp3 = temp1 * temp2; + temp3 = (PICOS2KHZ(videomode->pixclock) * 1000) / temp3; + temp1 = (u16)temp3 * 100; + temp = (u8)(temp1 & 0xFF); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, VERT_FREQ_LSB_REG, 1, &temp, 1); + temp = (u8)(temp1 >> 8); + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, VERT_FREQ_MSB_REG, 1, &temp, 1); + + /* Set TPI input bus and pixel repetition data */ + temp = TPI_INBUS_CLOCK_RATIO_1 | TPI_INBUS_FULL_PIXEL_WIDE | + TPI_INBUS_RISING_EDGE; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_INBUS_FMT_REG, 1, &temp, 1); + + /* Set TPI AVI Input format data */ + temp = TPI_INPUT_CLR_DEPTH_8BIT | TPI_INPUT_VRANGE_EXPAN_AUTO | + TPI_INPUT_CLR_RGB; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_INPUT_FMT_REG, 1, &temp, 1); + + /* Set TPI AVI Output format data */ + temp = TPI_OUTPUT_CLR_DEPTH_8BIT | TPI_OUTPUT_VRANGE_COMPRE_AUTO | + TPI_OUTPUT_CLR_HDMI_RGB; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_OUTPUT_FMT_REG, 1, &temp, 1); + + /* Set TPI audio configuration write data */ + temp = TPI_AUDIO_PASS_BASIC; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_HANDING_REG, 1, &temp, 1); + + temp = TPI_AUDIO_INTF_I2S | TPI_AUDIO_INTF_NORMAL | + TPI_AUDIO_TYPE_PCM; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_INTF_REG, 1, &temp, 1); + + temp = TPI_AUDIO_SAMP_SIZE_16BIT | TPI_AUDIO_SAMP_FREQ_44K; + i2c_write(CONFIG_SYS_I2C_DVI_ADDR, TPI_AUDIO_FREQ_REG, 1, &temp, 1); + + return 0; +} diff --git a/board/freescale/common/dcu_sii9022a.h b/board/freescale/common/dcu_sii9022a.h new file mode 100644 index 0000000000..de76733b36 --- /dev/null +++ b/board/freescale/common/dcu_sii9022a.h @@ -0,0 +1,13 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DCU_HDMI_SII9022A__ +#define __DCU_HDMI_SII9022A__ + +/* Programming of Silicon SII9022A connector HDMI Transmitter*/ +int dcu_set_dvi_encoder(struct fb_videomode *videomode); + +#endif From b4ecc8c6f8c85d25f72933af23531728069a5b0f Mon Sep 17 00:00:00 2001 From: Wang Huan Date: Fri, 5 Sep 2014 13:52:50 +0800 Subject: [PATCH 17/17] ls102xa: dcu: Add platform support for DCU on LS1021ATWR board This patch adds the TWR_LCD_RGB card/HDMI options and the common configuration for DCU on LS1021ATWR board. Signed-off-by: Alison Wang --- board/freescale/ls1021atwr/Makefile | 1 + board/freescale/ls1021atwr/dcu.c | 47 +++++++++++++++++++++++++ board/freescale/ls1021atwr/ls1021atwr.c | 6 ++++ include/configs/ls1021atwr.h | 18 ++++++++++ 4 files changed, 72 insertions(+) create mode 100644 board/freescale/ls1021atwr/dcu.c diff --git a/board/freescale/ls1021atwr/Makefile b/board/freescale/ls1021atwr/Makefile index b5df668713..01296c04b2 100644 --- a/board/freescale/ls1021atwr/Makefile +++ b/board/freescale/ls1021atwr/Makefile @@ -5,3 +5,4 @@ # obj-y += ls1021atwr.o +obj-$(CONFIG_FSL_DCU_FB) += dcu.o diff --git a/board/freescale/ls1021atwr/dcu.c b/board/freescale/ls1021atwr/dcu.c new file mode 100644 index 0000000000..8fe4ccbeb4 --- /dev/null +++ b/board/freescale/ls1021atwr/dcu.c @@ -0,0 +1,47 @@ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * + * FSL DCU Framebuffer driver + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include "div64.h" +#include "../common/dcu_sii9022a.h" + +DECLARE_GLOBAL_DATA_PTR; + +unsigned int dcu_set_pixel_clock(unsigned int pixclock) +{ + unsigned long long div; + + div = (unsigned long long)(gd->bus_clk / 1000); + div *= (unsigned long long)pixclock; + do_div(div, 1000000000); + + return div; +} + +int platform_dcu_init(unsigned int xres, unsigned int yres, + const char *port, + struct fb_videomode *dcu_fb_videomode) +{ + const char *name; + unsigned int pixel_format; + + if (strncmp(port, "twr_lcd", 4) == 0) { + name = "TWR_LCD_RGB card"; + } else { + name = "HDMI"; + dcu_set_dvi_encoder(dcu_fb_videomode); + } + + printf("DCU: Switching to %s monitor @ %ux%u\n", name, xres, yres); + + pixel_format = 32; + fsl_dcu_init(xres, yres, pixel_format); + + return 0; +} diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c index 92ad8cd9bd..b522ff28e5 100644 --- a/board/freescale/ls1021atwr/ls1021atwr.c +++ b/board/freescale/ls1021atwr/ls1021atwr.c @@ -261,6 +261,12 @@ int board_early_init_f(void) init_early_memctl_regs(); #endif +#ifdef CONFIG_FSL_DCU_FB + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_REV); + out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN); + out_be32(&scfg->scfgrevcr, SCFG_SCFGREVCR_NOREV); +#endif + return 0; } diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index cb6b400425..45b2272ff5 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -162,6 +162,24 @@ #define CONFIG_FSL_ESDHC #define CONFIG_GENERIC_MMC +/* + * Video + */ +#define CONFIG_FSL_DCU_FB + +#ifdef CONFIG_FSL_DCU_FB +#define CONFIG_VIDEO +#define CONFIG_CMD_BMP +#define CONFIG_CFB_CONSOLE +#define CONFIG_VGA_AS_SINGLE_DEVICE +#define CONFIG_VIDEO_LOGO +#define CONFIG_VIDEO_BMP_LOGO + +#define CONFIG_FSL_DCU_SII9022A +#define CONFIG_SYS_I2C_DVI_BUS_NUM 1 +#define CONFIG_SYS_I2C_DVI_ADDR 0x39 +#endif + /* * eTSEC */