
On 05/30/2014 10:22 AM, Alison Wang wrote:
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 alison.wang@freescale.com Signed-off-by: Jason Jin jason.jin@freescale.com Signed-off-by: Jingchang Lu jingchang.lu@freescale.com Signed-off-by: Prabhakar Kushwaha prabhakar@freescale.com
arch/arm/cpu/armv7/ls102xa/Makefile | 11 + arch/arm/cpu/armv7/ls102xa/clock.c | 131 +++++++ arch/arm/cpu/armv7/ls102xa/cpu.c | 102 ++++++ arch/arm/cpu/armv7/ls102xa/fdt.c | 82 +++++ arch/arm/cpu/armv7/ls102xa/timer.c | 129 +++++++ arch/arm/include/asm/arch-ls102xa/clock.h | 23 ++ arch/arm/include/asm/arch-ls102xa/config.h | 70 ++++ arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h | 420 ++++++++++++++++++++++ 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 +- 12 files changed, 1033 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/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/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 0000000..7ef793a --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/Makefile @@ -0,0 +1,11 @@ +# +# 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 diff --git a/arch/arm/cpu/armv7/ls102xa/clock.c b/arch/arm/cpu/armv7/ls102xa/clock.c new file mode 100644 index 0000000..75bb0e9 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/clock.c @@ -0,0 +1,131 @@ +/*
- Copyright 2014 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/arch/clock.h> +#include <fsl_ifc.h>
+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 0000000..72d198f --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/cpu.c @@ -0,0 +1,102 @@ +/*
- Copyright 2014 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <asm/arch/immap_ls102xa.h> +#include <tsec.h> +#include <netdev.h> +#include <fsl_esdhc.h>
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{
- char buf[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(buf, gd->cpu_clk));
- printf("\n Bus:%-4s MHz, ", strmhz(buf, gd->bus_clk));
- printf("DDR:%-4s MHz, ", strmhz(buf, 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 0000000..042d457 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/fdt.c @@ -0,0 +1,82 @@ +/*
- Copyright 2014 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <libfdt.h> +#include <fdt_support.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/arch/clock.h> +#include <linux/ctype.h> +#ifdef CONFIG_FSL_ESDHC +#include <fsl_esdhc.h> +#endif
+DECLARE_GLOBAL_DATA_PTR;
+void fdt_add_enet_stashing(void *fdt) +{
- do_fixup_by_compat(fdt, "fsl,etsec2", "bd-stash", NULL, 0, 1);
- do_fixup_by_compat_u32(fdt, "fsl,etsec2", "rx-stash-len", 96, 1);
- do_fixup_by_compat_u32(fdt, "fsl,etsec2", "rx-stash-idx", 0, 1);
+}
+void ft_cpu_setup(void *blob, bd_t *bd) +{
- int off;
- int val;
- unsigned long busclk = get_bus_freq(0);
- fdt_fixup_ethernet(blob);
- fdt_add_enet_stashing(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);
+#ifdef CONFIG_SYS_NS16550
- do_fixup_by_compat_u32(blob, "ns16550",
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
+#endif
- do_fixup_by_compat_u32(blob, "fsl,sys-clock",
"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,p1010-flexcan",
"clock-frequency", busclk / 2, 1);
+} diff --git a/arch/arm/cpu/armv7/ls102xa/timer.c b/arch/arm/cpu/armv7/ls102xa/timer.c new file mode 100644 index 0000000..db5eb65 --- /dev/null +++ b/arch/arm/cpu/armv7/ls102xa/timer.c @@ -0,0 +1,129 @@ +/*
- Copyright 2014 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <asm/io.h> +#include <div64.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/arch/clock.h>
+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));
- /* increment tbu if tbl has rolled over */
- if (now < gd->arch.tbl)
gd->arch.tbu++;
- gd->arch.tbl = now;
- return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+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 0000000..fd36bb0 --- /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 <common.h>
+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 0000000..2e90c94 --- /dev/null +++ b/arch/arm/include/asm/arch-ls102xa/config.h @@ -0,0 +1,70 @@ +/*
- Copyright 2014, Freescale Semiconductor
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _ASM_ARMV7_LS102xA_CONFIG_ +#define _ASM_ARMV7_LS102xA_CONFIG_
+#define CONFIG_SYS_IMMR 0x01000000
+#define CONFIG_SYS_FSL_DDR_ADDR (CONFIG_SYS_IMMR + 0x00080000) +#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_CCI400_ADDR 0x01180000
+#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 CONFIG_SYS_FSL_ESDHC_ADDR (CONFIG_SYS_IMMR + 0x00560000)
+#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)
+#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
+#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
What about CONFIG_ARMV7_VIRT? This config allows the kernel to be entered in the HYP mode which is a prerequisite for running KVM which we need to support.
Diana