diff options
author | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
---|---|---|
committer | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/u-boot/arch/arm/cpu/armv7/ls102xa | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/u-boot/arch/arm/cpu/armv7/ls102xa')
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig | 104 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile | 19 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c | 122 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c | 399 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c | 196 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c | 213 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h | 75 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c | 130 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h | 11 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c | 246 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c | 40 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S | 257 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c | 242 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c | 15 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c | 126 |
15 files changed, 2195 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig new file mode 100644 index 000000000..747059b56 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Kconfig @@ -0,0 +1,104 @@ +config ARCH_LS1021A + bool + select SYS_FSL_DDR_BE if SYS_FSL_DDR + select SYS_FSL_DDR_VER_50 if SYS_FSL_DDR + select SYS_FSL_ERRATUM_A008378 + select SYS_FSL_ERRATUM_A008407 + select SYS_FSL_ERRATUM_A008850 + select SYS_FSL_ERRATUM_A008997 if USB + select SYS_FSL_ERRATUM_A009007 if USB + select SYS_FSL_ERRATUM_A009008 if USB + select SYS_FSL_ERRATUM_A009663 + select SYS_FSL_ERRATUM_A009798 if USB + select SYS_FSL_ERRATUM_A009942 + select SYS_FSL_ERRATUM_A010315 + select SYS_FSL_HAS_CCI400 + select SYS_FSL_HAS_DDR3 if SYS_FSL_DDR + select SYS_FSL_HAS_DDR4 if SYS_FSL_DDR + select SYS_FSL_HAS_SEC + select SYS_FSL_SEC_COMPAT_5 + select SYS_FSL_SEC_LE + select SYS_FSL_SRDS_1 + select SYS_HAS_SERDES + imply CMD_PCI + imply SCSI + imply SCSI_AHCI + +menu "LS102xA architecture" + depends on ARCH_LS1021A + +config LS1_DEEP_SLEEP + bool "Deep sleep" + +config MAX_CPUS + int "Maximum number of CPUs permitted for LS102xA" + default 2 + help + Set this number to the maximum number of possible CPUs in the SoC. + SoCs may have multiple clusters with each cluster may have multiple + ports. If some ports are reserved but higher ports are used for + cores, count the reserved ports. This will allocate enough memory + in spin table to properly handle all cores. + +config NXP_ESBC + bool "NXP_ESBC" + help + Enable Freescale Secure Boot feature. Normally selected + by defconfig. If unsure, do not change. + +config SYS_CCI400_OFFSET + hex "Offset for CCI400 base" + depends on SYS_FSL_HAS_CCI400 + default 0x180000 + help + Offset for CCI400 base. + CCI400 base addr = CCSRBAR + CCI400_OFFSET + +config SYS_FSL_ERRATUM_A008850 + bool + help + Workaround for DDR erratum A008850 + +config SYS_FSL_ERRATUM_A008997 + bool + help + Workaround for USB PHY erratum A008997 + +config SYS_FSL_ERRATUM_A009007 + bool + help + Workaround for USB PHY erratum A009007 + +config SYS_FSL_ERRATUM_A009008 + bool + help + Workaround for USB PHY erratum A009008 + +config SYS_FSL_ERRATUM_A009798 + bool + help + Workaround for USB PHY erratum A009798 + +config SYS_FSL_ERRATUM_A010315 + bool "Workaround for PCIe erratum A010315" + +config SYS_FSL_HAS_CCI400 + bool + +config SYS_FSL_SRDS_1 + bool + +config SYS_FSL_SRDS_2 + bool + +config SYS_HAS_SERDES + bool + +config SYS_FSL_IFC_BANK_COUNT + int "Maximum banks of Integrated flash controller" + default 8 + +config SYS_FSL_ERRATUM_A008407 + bool + +endmenu diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile new file mode 100644 index 000000000..0c1596f33 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/Makefile @@ -0,0 +1,19 @@ +# +# Copyright 2014 Freescale Semiconductor, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += cpu.o +obj-y += clock.o +obj-y += timer.o +obj-y += fsl_epu.o +obj-y += soc.o + +obj-$(CONFIG_OF_LIBFDT) += fdt.o +obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o +obj-$(CONFIG_SPL) += spl.o + +ifdef CONFIG_ARMV7_PSCI +obj-y += psci.o ls102xa_psci.o +endif diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c new file mode 100644 index 000000000..940995ef5 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/clock.c @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <clock_legacy.h> +#include <asm/global_data.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); + 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) + sys_info->freq_localbus = sys_info->freq_systembus; +#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_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/roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c new file mode 100644 index 000000000..d863c9625 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c @@ -0,0 +1,399 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <cpu_func.h> +#include <init.h> +#include <net.h> +#include <vsprintf.h> +#include <asm/arch/clock.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/cache.h> +#include <asm/system.h> +#include <tsec.h> +#include <netdev.h> +#include <fsl_esdhc.h> +#include <config.h> +#include <fsl_wdog.h> +#include <linux/delay.h> + +#include "fsl_epu.h" + +#define DCSR_RCPM2_BLOCK_OFFSET 0x223000 +#define DCSR_RCPM2_CPMFSMCR0 0x400 +#define DCSR_RCPM2_CPMFSMSR0 0x404 +#define DCSR_RCPM2_CPMFSMCR1 0x414 +#define DCSR_RCPM2_CPMFSMSR1 0x418 +#define CPMFSMSR_FSM_STATE_MASK 0x7f + +DECLARE_GLOBAL_DATA_PTR; + +#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) + +/* + * Bit[1] of the descriptor indicates the descriptor type, + * and bit[0] indicates whether the descriptor is valid. + */ +#define PMD_TYPE_TABLE 0x3 +#define PMD_TYPE_SECT 0x1 + +/* AttrIndx[2:0] */ +#define PMD_ATTRINDX(t) ((t) << 2) + +/* Section */ +#define PMD_SECT_AF (1 << 10) + +#define BLOCK_SIZE_L1 (1UL << 30) +#define BLOCK_SIZE_L2 (1UL << 21) + +/* TTBCR flags */ +#define TTBCR_EAE (1 << 31) +#define TTBCR_T0SZ(x) ((x) << 0) +#define TTBCR_T1SZ(x) ((x) << 16) +#define TTBCR_USING_TTBR0 (TTBCR_T0SZ(0) | TTBCR_T1SZ(0)) +#define TTBCR_IRGN0_NC (0 << 8) +#define TTBCR_IRGN0_WBWA (1 << 8) +#define TTBCR_IRGN0_WT (2 << 8) +#define TTBCR_IRGN0_WBNWA (3 << 8) +#define TTBCR_IRGN0_MASK (3 << 8) +#define TTBCR_ORGN0_NC (0 << 10) +#define TTBCR_ORGN0_WBWA (1 << 10) +#define TTBCR_ORGN0_WT (2 << 10) +#define TTBCR_ORGN0_WBNWA (3 << 10) +#define TTBCR_ORGN0_MASK (3 << 10) +#define TTBCR_SHARED_NON (0 << 12) +#define TTBCR_SHARED_OUTER (2 << 12) +#define TTBCR_SHARED_INNER (3 << 12) +#define TTBCR_EPD0 (0 << 7) +#define TTBCR (TTBCR_SHARED_NON | \ + TTBCR_ORGN0_NC | \ + TTBCR_IRGN0_NC | \ + TTBCR_USING_TTBR0 | \ + TTBCR_EAE) + +/* + * Memory region attributes for LPAE (defined in pgtable): + * + * n = AttrIndx[2:0] + * + * n MAIR + * UNCACHED 000 00000000 + * BUFFERABLE 001 01000100 + * DEV_WC 001 01000100 + * WRITETHROUGH 010 10101010 + * WRITEBACK 011 11101110 + * DEV_CACHED 011 11101110 + * DEV_SHARED 100 00000100 + * DEV_NONSHARED 100 00000100 + * unused 101 + * unused 110 + * WRITEALLOC 111 11111111 + */ +#define MT_MAIR0 0xeeaa4400 +#define MT_MAIR1 0xff000004 +#define MT_STRONLY_ORDER 0 +#define MT_NORMAL_NC 1 +#define MT_DEVICE_MEM 4 +#define MT_NORMAL 7 + +/* The phy_addr must be aligned to 4KB */ +static inline void set_pgtable(u32 *page_table, u32 index, u32 phy_addr) +{ + u32 value = phy_addr | PMD_TYPE_TABLE; + + page_table[2 * index] = value; + page_table[2 * index + 1] = 0; +} + +/* The phy_addr must be aligned to 4KB */ +static inline void set_pgsection(u32 *page_table, u32 index, u64 phy_addr, + u32 memory_type) +{ + u64 value; + + value = phy_addr | PMD_TYPE_SECT | PMD_SECT_AF; + value |= PMD_ATTRINDX(memory_type); + page_table[2 * index] = value & 0xFFFFFFFF; + page_table[2 * index + 1] = (value >> 32) & 0xFFFFFFFF; +} + +/* + * Start MMU after DDR is available, we create MMU table in DRAM. + * The base address of TTLB is gd->arch.tlb_addr. We use two + * levels of translation tables here to cover 40-bit address space. + * + * The TTLBs are located at PHY 2G~4G. + * + * VA mapping: + * + * ------- <---- 0GB + * | | + * | | + * |-------| <---- 0x24000000 + * |///////| ===> 192MB VA map for PCIe1 with offset 0x40_0000_0000 + * |-------| <---- 0x300000000 + * | | + * |-------| <---- 0x34000000 + * |///////| ===> 192MB VA map for PCIe2 with offset 0x48_0000_0000 + * |-------| <---- 0x40000000 + * | | + * |-------| <---- 0x80000000 DDR0 space start + * |\\\\\\\| + *.|\\\\\\\| ===> 2GB VA map for 2GB DDR0 Memory space + * |\\\\\\\| + * ------- <---- 4GB DDR0 space end + */ +static void mmu_setup(void) +{ + u32 *level0_table = (u32 *)gd->arch.tlb_addr; + u32 *level1_table = (u32 *)(gd->arch.tlb_addr + 0x1000); + u64 va_start = 0; + u32 reg; + int i; + + /* Level 0 Table 2-3 are used to map DDR */ + set_pgsection(level0_table, 3, 3 * BLOCK_SIZE_L1, MT_NORMAL); + set_pgsection(level0_table, 2, 2 * BLOCK_SIZE_L1, MT_NORMAL); + /* Level 0 Table 1 is used to map device */ + set_pgsection(level0_table, 1, 1 * BLOCK_SIZE_L1, MT_DEVICE_MEM); + /* Level 0 Table 0 is used to map device including PCIe MEM */ + set_pgtable(level0_table, 0, (u32)level1_table); + + /* Level 1 has 512 entries */ + for (i = 0; i < 512; i++) { + /* Mapping for PCIe 1 */ + if (va_start >= CONFIG_SYS_PCIE1_VIRT_ADDR && + va_start < (CONFIG_SYS_PCIE1_VIRT_ADDR + + CONFIG_SYS_PCIE_MMAP_SIZE)) + set_pgsection(level1_table, i, + CONFIG_SYS_PCIE1_PHYS_BASE + va_start, + MT_DEVICE_MEM); + /* Mapping for PCIe 2 */ + else if (va_start >= CONFIG_SYS_PCIE2_VIRT_ADDR && + va_start < (CONFIG_SYS_PCIE2_VIRT_ADDR + + CONFIG_SYS_PCIE_MMAP_SIZE)) + set_pgsection(level1_table, i, + CONFIG_SYS_PCIE2_PHYS_BASE + va_start, + MT_DEVICE_MEM); + else + set_pgsection(level1_table, i, + va_start, + MT_DEVICE_MEM); + va_start += BLOCK_SIZE_L2; + } + + asm volatile("dsb sy;isb"); + asm volatile("mcr p15, 0, %0, c2, c0, 2" /* Write RT to TTBCR */ + : : "r" (TTBCR) : "memory"); + asm volatile("mcrr p15, 0, %0, %1, c2" /* TTBR 0 */ + : : "r" ((u32)level0_table), "r" (0) : "memory"); + asm volatile("mcr p15, 0, %0, c10, c2, 0" /* write MAIR 0 */ + : : "r" (MT_MAIR0) : "memory"); + asm volatile("mcr p15, 0, %0, c10, c2, 1" /* write MAIR 1 */ + : : "r" (MT_MAIR1) : "memory"); + + /* Set the access control to all-supervisor */ + asm volatile("mcr p15, 0, %0, c3, c0, 0" + : : "r" (~0)); + + /* Enable the mmu */ + reg = get_cr(); + set_cr(reg | CR_M); +} + +/* + * This function is called from lib/board.c. It recreates MMU + * table in main memory. MMU and i/d-cache are enabled here. + */ +void enable_caches(void) +{ + /* Invalidate all TLB */ + mmu_page_table_flush(gd->arch.tlb_addr, + gd->arch.tlb_addr + gd->arch.tlb_size); + /* Set up and enable mmu */ + mmu_setup(); + + /* Invalidate & Enable d-cache */ + invalidate_dcache_all(); + set_cr(get_cr() | CR_C); +} +#endif /* #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) */ + + +uint get_svr(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + + return in_be32(&gur->svr); +} + +#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 + +#ifdef CONFIG_FSL_ESDHC +int cpu_mmc_init(struct bd_info *bis) +{ + return fsl_esdhc_mmc_init(bis); +} +#endif + +int cpu_eth_init(struct bd_info *bis) +{ +#if defined(CONFIG_TSEC_ENET) && !defined(CONFIG_DM_ETH) + tsec_standard_init(bis); +#endif + + return 0; +} + +int arch_cpu_init(void) +{ + void *epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET); + void *rcpm2_base = + (void *)(CONFIG_SYS_DCSRBAR + DCSR_RCPM2_BLOCK_OFFSET); + struct ccsr_scfg *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + u32 state; + + icache_enable(); + + /* + * The RCPM FSM state may not be reset after power-on. + * So, reset them. + */ + state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR0) & + CPMFSMSR_FSM_STATE_MASK; + if (state != 0) { + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x80); + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x0); + } + + state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR1) & + CPMFSMSR_FSM_STATE_MASK; + if (state != 0) { + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x80); + out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x0); + } + + /* + * After wakeup from deep sleep, Clear EPU registers + * as early as possible to prevent from possible issue. + * It's also safe to clear at normal boot. + */ + fsl_epu_clean(epu_base); + + setbits_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SEC_RD_WR); + + return 0; +} + +#ifdef CONFIG_ARMV7_NONSEC +/* Set the address at which the secondary core starts from.*/ +void smp_set_core_boot_addr(unsigned long addr, int corenr) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + + out_be32(&gur->scratchrw[0], addr); +} + +/* Release the secondary core from holdoff state and kick it */ +void smp_kick_all_cpus(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + + out_be32(&gur->brrl, 0x2); + + /* + * LS1 STANDBYWFE is not captured outside the ARM module in the soc. + * So add a delay to wait bootrom execute WFE. + */ + udelay(1); + + asm volatile("sev"); +} +#endif + +void reset_cpu(void) +{ + struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; + + clrbits_be16(&wdog->wcr, WCR_SRS); + + while (1) { + /* + * Let the watchdog trigger + */ + } +} + +void arch_preboot_os(void) +{ + unsigned long ctrl; + + /* Disable PL1 Physical Timer */ + asm("mrc p15, 0, %0, c14, c2, 1" : "=r" (ctrl)); + ctrl &= ~ARCH_TIMER_CTRL_ENABLE; + asm("mcr p15, 0, %0, c14, c2, 1" : : "r" (ctrl)); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c new file mode 100644 index 000000000..0daf8234f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <clock_legacy.h> +#include <net.h> +#include <asm/global_data.h> +#include <linux/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 +#include <tsec.h> +#include <asm/arch/immap_ls102xa.h> +#include <fsl_sec.h> +#include <dm.h> + +DECLARE_GLOBAL_DATA_PTR; + +void ft_fixup_enet_phy_connect_type(void *fdt) +{ +#ifdef CONFIG_DM_ETH + struct udevice *dev; +#else + struct eth_device *dev; +#endif + struct tsec_private *priv; + const char *enet_path, *phy_path; + char enet[16]; + char phy[16]; + int phy_node; + int i = 0; + uint32_t ph; +#ifdef CONFIG_DM_ETH + char *name[3] = { "ethernet@2d10000", "ethernet@2d50000", + "ethernet@2d90000" }; +#else + char *name[3] = { "eTSEC1", "eTSEC2", "eTSEC3" }; +#endif + + for (; i < ARRAY_SIZE(name); i++) { + dev = eth_get_dev_by_name(name[i]); + if (dev) { + sprintf(enet, "ethernet%d", i); + sprintf(phy, "enet%d_rgmii_phy", i); + } else { + continue; + } + +#ifdef CONFIG_DM_ETH + priv = dev_get_priv(dev); +#else + priv = dev->priv; +#endif + if (priv->flags & TSEC_SGMII) + continue; + + enet_path = fdt_get_alias(fdt, enet); + if (!enet_path) + continue; + + 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), + strlen(phy_string_for_interface( + PHY_INTERFACE_MODE_RGMII_ID)) + 1, + 1); + } +} + +void ft_cpu_setup(void *blob, struct bd_info *bd) +{ + int off; + int val; + const char *sysclk_path; + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr; + svr = in_be32(&gur->svr); + + unsigned long busclk = get_bus_freq(0); + + /* delete crypto node if not on an E-processor */ + if (!IS_E_PROCESSOR(svr)) + fdt_fixup_crypto_node(blob, 0); +#if CONFIG_SYS_FSL_SEC_COMPAT >= 4 + else { + ccsr_sec_t __iomem *sec; + + sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR; + fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms)); + } +#endif + + 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, 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_DEEP_SLEEP) && defined(CONFIG_SD_BOOT) +#define UBOOT_HEAD_LEN 0x1000 + /* + * Reserved memory in SD boot deep sleep case. + * Second stage uboot binary and malloc space should be reserved. + * If the memory they occupied has not been reserved, then this + * space would be used by kernel and overwritten in uboot when + * deep sleep resume, which cause deep sleep failed. + * Since second uboot binary has a head, that space need to be + * reserved either(assuming its size is less than 0x1000). + */ + off = fdt_add_mem_rsv(blob, CONFIG_SYS_TEXT_BASE - UBOOT_HEAD_LEN, + CONFIG_SYS_MONITOR_LEN + CONFIG_SYS_SPL_MALLOC_SIZE + + UBOOT_HEAD_LEN); + if (off < 0) + printf("Failed to reserve memory for SD boot deep sleep: %s\n", + fdt_strerror(off)); +#endif + +#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); + +#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI) + off = fdt_node_offset_by_compat_reg(blob, FSL_IFC_COMPAT, + CONFIG_SYS_IFC_ADDR); + fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); +#else + off = fdt_node_offset_by_compat_reg(blob, FSL_QSPI_COMPAT, + QSPI0_BASE_ADDR); + fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); + off = fdt_node_offset_by_compat_reg(blob, FSL_DSPI_COMPAT, + DSPI1_BASE_ADDR); + fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); +#endif +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c new file mode 100644 index 000000000..e31a4fb6c --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <asm/io.h> + +#include "fsl_epu.h" + +struct fsm_reg_vals epu_default_val[] = { + /* EPGCR (Event Processor Global Control Register) */ + {EPGCR, 0}, + /* EPECR (Event Processor Event Control Registers) */ + {EPECR0 + EPECR_STRIDE * 0, 0}, + {EPECR0 + EPECR_STRIDE * 1, 0}, + {EPECR0 + EPECR_STRIDE * 2, 0xF0004004}, + {EPECR0 + EPECR_STRIDE * 3, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 4, 0x20000084}, + {EPECR0 + EPECR_STRIDE * 5, 0x08000004}, + {EPECR0 + EPECR_STRIDE * 6, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 7, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 8, 0x60000084}, + {EPECR0 + EPECR_STRIDE * 9, 0x08000084}, + {EPECR0 + EPECR_STRIDE * 10, 0x42000084}, + {EPECR0 + EPECR_STRIDE * 11, 0x90000084}, + {EPECR0 + EPECR_STRIDE * 12, 0x80000084}, + {EPECR0 + EPECR_STRIDE * 13, 0x08000084}, + {EPECR0 + EPECR_STRIDE * 14, 0x02000084}, + {EPECR0 + EPECR_STRIDE * 15, 0x00000004}, + /* + * EPEVTCR (Event Processor EVT Pin Control Registers) + * SCU8 triger EVT2, and SCU11 triger EVT9 + */ + {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x80000001}, + {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0}, + {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB0000001}, + /* EPCMPR (Event Processor Counter Compare Registers) */ + {EPCMPR0 + EPCMPR_STRIDE * 0, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 1, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 2, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 3, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 4, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 5, 0x00000020}, + {EPCMPR0 + EPCMPR_STRIDE * 6, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 7, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 8, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 9, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 10, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 11, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 12, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 13, 0}, + {EPCMPR0 + EPCMPR_STRIDE * 14, 0x000000FF}, + {EPCMPR0 + EPCMPR_STRIDE * 15, 0x000000FF}, + /* EPCCR (Event Processor Counter Control Registers) */ + {EPCCR0 + EPCCR_STRIDE * 0, 0}, + {EPCCR0 + EPCCR_STRIDE * 1, 0}, + {EPCCR0 + EPCCR_STRIDE * 2, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 3, 0}, + {EPCCR0 + EPCCR_STRIDE * 4, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 5, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 6, 0}, + {EPCCR0 + EPCCR_STRIDE * 7, 0}, + {EPCCR0 + EPCCR_STRIDE * 8, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 9, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 10, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 11, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 12, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 13, 0}, + {EPCCR0 + EPCCR_STRIDE * 14, 0x92840000}, + {EPCCR0 + EPCCR_STRIDE * 15, 0x92840000}, + /* EPSMCR (Event Processor SCU Mux Control Registers) */ + {EPSMCR0 + EPSMCR_STRIDE * 0, 0}, + {EPSMCR0 + EPSMCR_STRIDE * 1, 0}, + {EPSMCR0 + EPSMCR_STRIDE * 2, 0x6C700000}, + {EPSMCR0 + EPSMCR_STRIDE * 3, 0x2F000000}, + {EPSMCR0 + EPSMCR_STRIDE * 4, 0x002F0000}, + {EPSMCR0 + EPSMCR_STRIDE * 5, 0x00002E00}, + {EPSMCR0 + EPSMCR_STRIDE * 6, 0x7C000000}, + {EPSMCR0 + EPSMCR_STRIDE * 7, 0x30000000}, + {EPSMCR0 + EPSMCR_STRIDE * 8, 0x64300000}, + {EPSMCR0 + EPSMCR_STRIDE * 9, 0x00003000}, + {EPSMCR0 + EPSMCR_STRIDE * 10, 0x65000030}, + {EPSMCR0 + EPSMCR_STRIDE * 11, 0x31740000}, + {EPSMCR0 + EPSMCR_STRIDE * 12, 0x7F000000}, + {EPSMCR0 + EPSMCR_STRIDE * 13, 0x00003100}, + {EPSMCR0 + EPSMCR_STRIDE * 14, 0x00000031}, + {EPSMCR0 + EPSMCR_STRIDE * 15, 0x76000000}, + /* EPACR (Event Processor Action Control Registers) */ + {EPACR0 + EPACR_STRIDE * 0, 0}, + {EPACR0 + EPACR_STRIDE * 1, 0}, + {EPACR0 + EPACR_STRIDE * 2, 0}, + {EPACR0 + EPACR_STRIDE * 3, 0x00000080}, + {EPACR0 + EPACR_STRIDE * 4, 0}, + {EPACR0 + EPACR_STRIDE * 5, 0x00000040}, + {EPACR0 + EPACR_STRIDE * 6, 0}, + {EPACR0 + EPACR_STRIDE * 7, 0}, + {EPACR0 + EPACR_STRIDE * 8, 0}, + {EPACR0 + EPACR_STRIDE * 9, 0x0000001C}, + {EPACR0 + EPACR_STRIDE * 10, 0x00000020}, + {EPACR0 + EPACR_STRIDE * 11, 0}, + {EPACR0 + EPACR_STRIDE * 12, 0x00000003}, + {EPACR0 + EPACR_STRIDE * 13, 0x06000000}, + {EPACR0 + EPACR_STRIDE * 14, 0x04000000}, + {EPACR0 + EPACR_STRIDE * 15, 0x02000000}, + /* EPIMCR (Event Processor Input Mux Control Registers) */ + {EPIMCR0 + EPIMCR_STRIDE * 0, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 1, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 2, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 3, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 4, 0x44000000}, + {EPIMCR0 + EPIMCR_STRIDE * 5, 0x40000000}, + {EPIMCR0 + EPIMCR_STRIDE * 6, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 7, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 8, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 9, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 10, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 11, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 12, 0x44000000}, + {EPIMCR0 + EPIMCR_STRIDE * 13, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 14, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 15, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 16, 0x6A000000}, + {EPIMCR0 + EPIMCR_STRIDE * 17, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 18, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 19, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 20, 0x48000000}, + {EPIMCR0 + EPIMCR_STRIDE * 21, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 22, 0x6C000000}, + {EPIMCR0 + EPIMCR_STRIDE * 23, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 24, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 25, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 26, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 27, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 28, 0x76000000}, + {EPIMCR0 + EPIMCR_STRIDE * 29, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 30, 0}, + {EPIMCR0 + EPIMCR_STRIDE * 31, 0x76000000}, + /* EPXTRIGCR (Event Processor Crosstrigger Control Register) */ + {EPXTRIGCR, 0x0000FFDF}, + /* end */ + {FSM_END_FLAG, 0}, +}; + +/** + * fsl_epu_setup - Setup EPU registers to default values + */ +void fsl_epu_setup(void *epu_base) +{ + struct fsm_reg_vals *data = epu_default_val; + + if (!epu_base || !data) + return; + + while (data->offset != FSM_END_FLAG) { + out_be32(epu_base + data->offset, data->value); + data++; + } +} + +/** + * fsl_epu_clean - Clear EPU registers + */ +void fsl_epu_clean(void *epu_base) +{ + u32 offset; + + /* follow the exact sequence to clear the registers */ + /* Clear EPACRn */ + for (offset = EPACR0; offset <= EPACR15; offset += EPACR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPEVTCRn */ + for (offset = EPEVTCR0; offset <= EPEVTCR9; offset += EPEVTCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPGCR */ + out_be32(epu_base + EPGCR, 0); + + /* Clear EPSMCRn */ + for (offset = EPSMCR0; offset <= EPSMCR15; offset += EPSMCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPCCRn */ + for (offset = EPCCR0; offset <= EPCCR31; offset += EPCCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPCMPRn */ + for (offset = EPCMPR0; offset <= EPCMPR31; offset += EPCMPR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPCTRn */ + for (offset = EPCTR0; offset <= EPCTR31; offset += EPCTR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPIMCRn */ + for (offset = EPIMCR0; offset <= EPIMCR31; offset += EPIMCR_STRIDE) + out_be32(epu_base + offset, 0); + + /* Clear EPXTRIGCRn */ + out_be32(epu_base + EPXTRIGCR, 0); + + /* Clear EPECRn */ + for (offset = EPECR0; offset <= EPECR15; offset += EPECR_STRIDE) + out_be32(epu_base + offset, 0); +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h new file mode 100644 index 000000000..711eea565 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#ifndef __FSL_EPU_H +#define __FSL_EPU_H + +#include <asm/types.h> + +#define FSL_STRIDE_4B 4 +#define FSL_STRIDE_8B 8 + +/* Block offsets */ +#define EPU_BLOCK_OFFSET 0x00000000 + +/* EPGCR (Event Processor Global Control Register) */ +#define EPGCR 0x000 + +/* EPEVTCR0-9 (Event Processor EVT Pin Control Registers) */ +#define EPEVTCR0 0x050 +#define EPEVTCR9 0x074 +#define EPEVTCR_STRIDE FSL_STRIDE_4B + +/* EPXTRIGCR (Event Processor Crosstrigger Control Register) */ +#define EPXTRIGCR 0x090 + +/* EPIMCR0-31 (Event Processor Input Mux Control Registers) */ +#define EPIMCR0 0x100 +#define EPIMCR31 0x17C +#define EPIMCR_STRIDE FSL_STRIDE_4B + +/* EPSMCR0-15 (Event Processor SCU Mux Control Registers) */ +#define EPSMCR0 0x200 +#define EPSMCR15 0x278 +#define EPSMCR_STRIDE FSL_STRIDE_8B + +/* EPECR0-15 (Event Processor Event Control Registers) */ +#define EPECR0 0x300 +#define EPECR15 0x33C +#define EPECR_STRIDE FSL_STRIDE_4B + +/* EPACR0-15 (Event Processor Action Control Registers) */ +#define EPACR0 0x400 +#define EPACR15 0x43C +#define EPACR_STRIDE FSL_STRIDE_4B + +/* EPCCRi0-15 (Event Processor Counter Control Registers) */ +#define EPCCR0 0x800 +#define EPCCR15 0x83C +#define EPCCR31 0x87C +#define EPCCR_STRIDE FSL_STRIDE_4B + +/* EPCMPR0-15 (Event Processor Counter Compare Registers) */ +#define EPCMPR0 0x900 +#define EPCMPR15 0x93C +#define EPCMPR31 0x97C +#define EPCMPR_STRIDE FSL_STRIDE_4B + +/* EPCTR0-31 (Event Processor Counter Register) */ +#define EPCTR0 0xA00 +#define EPCTR31 0xA7C +#define EPCTR_STRIDE FSL_STRIDE_4B + +#define FSM_END_FLAG 0xFFFFFFFFUL + +struct fsm_reg_vals { + u32 offset; + u32 value; +}; + +void fsl_epu_setup(void *epu_base); +void fsl_epu_clean(void *epu_base); + +#endif diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c new file mode 100644 index 000000000..caf51e17b --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch/immap_ls102xa.h> +#include <linux/errno.h> +#include <asm/io.h> +#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 + if (!(serdes1_prtcl_map & (1ULL << NONE))) + fsl_serdes_init(); + + ret |= (1ULL << device) & serdes1_prtcl_map; +#endif +#ifdef CONFIG_SYS_FSL_SRDS_2 + if (!(serdes2_prtcl_map & (1ULL << NONE))) + fsl_serdes_init(); + + 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); + } + + /* Set the first bit to indicate serdes has been initialized */ + serdes_prtcl_map |= (1ULL << NONE); + + return serdes_prtcl_map; +} + +void fsl_serdes_init(void) +{ +#ifdef CONFIG_SYS_FSL_SRDS_1 + if (!(serdes1_prtcl_map & (1ULL << NONE))) + 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 + if (!(serdes2_prtcl_map & (1ULL << NONE))) + 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/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h new file mode 100644 index 000000000..7382aef8e --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#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/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c new file mode 100644 index 000000000..28a794520 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Author: Hongbo Zhang <hongbo.zhang@nxp.com> + * This file implements LS102X platform PSCI SYSTEM-SUSPEND function + */ + +#include <config.h> +#include <cpu_func.h> +#include <asm/io.h> +#include <asm/psci.h> +#include <asm/arch/immap_ls102xa.h> +#include <fsl_immap.h> +#include "fsl_epu.h" + +#define __secure __section("._secure.text") + +#define CCSR_GICD_CTLR 0x1000 +#define CCSR_GICC_CTLR 0x2000 +#define DCSR_RCPM_CG1CR0 0x31c +#define DCSR_RCPM_CSTTACR0 0xb00 +#define DCFG_CRSTSR_WDRFR 0x8 +#define DDR_RESV_LEN 128 + +#ifdef CONFIG_LS1_DEEP_SLEEP +/* + * DDR controller initialization training breaks the first 128 bytes of DDR, + * save them so that the bootloader can restore them while resuming. + */ +static void __secure ls1_save_ddr_head(void) +{ + const char *src = (const char *)CONFIG_SYS_SDRAM_BASE; + char *dest = (char *)(OCRAM_BASE_S_ADDR + OCRAM_S_SIZE - DDR_RESV_LEN); + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + int i; + + out_le32(&scfg->sparecr[2], dest); + + for (i = 0; i < DDR_RESV_LEN; i++) + *dest++ = *src++; +} + +static void __secure ls1_fsm_setup(void) +{ + void *dcsr_epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET); + void *dcsr_rcpm_base = (void *)SYS_FSL_DCSR_RCPM_ADDR; + + out_be32(dcsr_rcpm_base + DCSR_RCPM_CSTTACR0, 0x00001001); + out_be32(dcsr_rcpm_base + DCSR_RCPM_CG1CR0, 0x00000001); + + fsl_epu_setup((void *)dcsr_epu_base); + + /* Pull MCKE signal low before enabling deep sleep signal in FPGA */ + out_be32(dcsr_epu_base + EPECR0, 0x5); + out_be32(dcsr_epu_base + EPSMCR15, 0x76300000); +} + +static void __secure ls1_deepsleep_irq_cfg(void) +{ + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR; + u32 ippdexpcr0, ippdexpcr1, pmcintecr = 0; + + /* Mask interrupts from GIC */ + out_be32(&rcpm->nfiqoutr, 0x0ffffffff); + out_be32(&rcpm->nirqoutr, 0x0ffffffff); + /* Mask deep sleep wake-up interrupts while entering deep sleep */ + out_be32(&rcpm->dsimskr, 0x0ffffffff); + + ippdexpcr0 = in_be32(&rcpm->ippdexpcr0); + /* + * Workaround of errata A-008646 + * Errata states that read to register ippdexpcr1 always returns + * zero irrespective of what value is written into it. So its value + * is first saved to a spare register and then read from it + */ + ippdexpcr1 = in_be32(&scfg->sparecr[7]); + + /* + * To allow OCRAM to be used as wakeup source in deep sleep, + * do not power it down. + */ + out_be32(&rcpm->ippdexpcr1, ippdexpcr1 | RCPM_IPPDEXPCR1_OCRAM1); + + if (ippdexpcr0 & RCPM_IPPDEXPCR0_ETSEC) + pmcintecr |= SCFG_PMCINTECR_ETSECRXG0 | + SCFG_PMCINTECR_ETSECRXG1 | + SCFG_PMCINTECR_ETSECERRG0 | + SCFG_PMCINTECR_ETSECERRG1; + + if (ippdexpcr0 & RCPM_IPPDEXPCR0_GPIO) + pmcintecr |= SCFG_PMCINTECR_GPIO; + + if (ippdexpcr1 & RCPM_IPPDEXPCR1_LPUART) + pmcintecr |= SCFG_PMCINTECR_LPUART; + + if (ippdexpcr1 & RCPM_IPPDEXPCR1_FLEXTIMER) + pmcintecr |= SCFG_PMCINTECR_FTM; + + /* Always set external IRQ pins as wakeup source */ + pmcintecr |= SCFG_PMCINTECR_IRQ0 | SCFG_PMCINTECR_IRQ1; + + out_be32(&scfg->pmcintlecr, 0); + /* Clear PMC interrupt status */ + out_be32(&scfg->pmcintsr, 0xffffffff); + /* Enable wakeup interrupt during deep sleep */ + out_be32(&scfg->pmcintecr, pmcintecr); +} + +static void __secure ls1_delay(unsigned int loop) +{ + while (loop--) { + int i = 1000; + while (i--) + ; + } +} + +static void __secure ls1_start_fsm(void) +{ + void *dcsr_epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET); + void *ccsr_gic_base = (void *)SYS_FSL_GIC_ADDR; + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + + /* Set HRSTCR */ + setbits_be32(&scfg->hrstcr, 0x80000000); + + /* Place DDR controller in self refresh mode */ + setbits_be32(&ddr->sdram_cfg_2, 0x80000000); + + ls1_delay(2000); + + /* Set EVT4_B to lock the signal MCKE down */ + out_be32(dcsr_epu_base + EPECR0, 0x0); + + ls1_delay(2000); + + out_be32(ccsr_gic_base + CCSR_GICD_CTLR, 0x0); + out_be32(ccsr_gic_base + CCSR_GICC_CTLR, 0x0); + + /* Enable all EPU Counters */ + setbits_be32(dcsr_epu_base + EPGCR, 0x80000000); + + /* Enable SCU15 */ + setbits_be32(dcsr_epu_base + EPECR15, 0x90000004); + + /* Enter WFI mode, and EPU FSM will start */ + __asm__ __volatile__ ("wfi" : : : "memory"); + + /* NEVER ENTER HERE */ + while (1) + ; +} + +static void __secure ls1_deep_sleep(u32 entry_point) +{ + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR; +#ifdef QIXIS_BASE + u32 tmp; + void *qixis_base = (void *)QIXIS_BASE; +#endif + + /* Enable cluster to enter the PCL10 state */ + out_be32(&scfg->clusterpmcr, SCFG_CLUSTERPMCR_WFIL2EN); + + /* Save the first 128 bytes of DDR data */ + ls1_save_ddr_head(); + + /* Save the kernel resume entry */ + out_le32(&scfg->sparecr[3], entry_point); + + /* Request to put cluster 0 in PCL10 state */ + setbits_be32(&rcpm->clpcl10setr, RCPM_CLPCL10SETR_C0); + + /* Setup the registers of the EPU FSM for deep sleep */ + ls1_fsm_setup(); + +#ifdef QIXIS_BASE + /* Connect the EVENT button to IRQ in FPGA */ + tmp = in_8(qixis_base + QIXIS_CTL_SYS); + tmp &= ~QIXIS_CTL_SYS_EVTSW_MASK; + tmp |= QIXIS_CTL_SYS_EVTSW_IRQ; + out_8(qixis_base + QIXIS_CTL_SYS, tmp); + + /* Enable deep sleep signals in FPGA */ + tmp = in_8(qixis_base + QIXIS_PWR_CTL2); + tmp |= QIXIS_PWR_CTL2_PCTL; + out_8(qixis_base + QIXIS_PWR_CTL2, tmp); + + /* Pull down PCIe RST# */ + tmp = in_8(qixis_base + QIXIS_RST_FORCE_3); + tmp |= QIXIS_RST_FORCE_3_PCIESLOT1; + out_8(qixis_base + QIXIS_RST_FORCE_3, tmp); +#endif + + /* Enable Warm Device Reset */ + setbits_be32(&scfg->dpslpcr, SCFG_DPSLPCR_WDRR_EN); + setbits_be32(&gur->crstsr, DCFG_CRSTSR_WDRFR); + + /* Disable QE */ + setbits_be32(&gur->devdisr, CCSR_DEVDISR1_QE); + + ls1_deepsleep_irq_cfg(); + + psci_v7_flush_dcache_all(); + + ls1_start_fsm(); +} + +#else +static void __secure ls1_sleep(void) +{ + struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_rcpm __iomem *rcpm = (void *)CONFIG_SYS_FSL_RCPM_ADDR; + +#ifdef QIXIS_BASE + u32 tmp; + void *qixis_base = (void *)QIXIS_BASE; + + /* Connect the EVENT button to IRQ in FPGA */ + tmp = in_8(qixis_base + QIXIS_CTL_SYS); + tmp &= ~QIXIS_CTL_SYS_EVTSW_MASK; + tmp |= QIXIS_CTL_SYS_EVTSW_IRQ; + out_8(qixis_base + QIXIS_CTL_SYS, tmp); +#endif + + /* Enable cluster to enter the PCL10 state */ + out_be32(&scfg->clusterpmcr, SCFG_CLUSTERPMCR_WFIL2EN); + + setbits_be32(&rcpm->powmgtcsr, RCPM_POWMGTCSR_LPM20_REQ); + + __asm__ __volatile__ ("wfi" : : : "memory"); +} +#endif + +void __secure ls1_system_suspend(u32 fn, u32 entry_point, u32 context_id) +{ +#ifdef CONFIG_LS1_DEEP_SLEEP + ls1_deep_sleep(entry_point); +#else + ls1_sleep(); +#endif +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c new file mode 100644 index 000000000..8c030be8b --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch/immap_ls102xa.h> + +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/roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S new file mode 100644 index 000000000..531cfb033 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/psci.S @@ -0,0 +1,257 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + * Author: Wang Dongsheng <dongsheng.wang@freescale.com> + */ + +#include <config.h> +#include <linux/linkage.h> + +#include <asm/armv7.h> +#include <asm/arch-armv7/generictimer.h> +#include <asm/psci.h> + +#define RCPM_TWAITSR 0x04C + +#define SCFG_CORE0_SFT_RST 0x130 +#define SCFG_CORESRENCR 0x204 + +#define DCFG_CCSR_RSTCR 0x0B0 +#define DCFG_CCSR_RSTCR_RESET_REQ 0x2 +#define DCFG_CCSR_BRR 0x0E4 +#define DCFG_CCSR_SCRATCHRW1 0x200 + +#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0 +#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0 +#define PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK 0x0 + + .pushsection ._secure.text, "ax" + + .arch_extension sec + + .align 5 + +#define ONE_MS (COUNTER_FREQUENCY / 1000) +#define RESET_WAIT (30 * ONE_MS) + +.globl psci_version +psci_version: + movw r0, #0 + movt r0, #1 + + bx lr + +_ls102x_psci_supported_table: + .word ARM_PSCI_0_2_FN_PSCI_VERSION + .word PSCI_FN_PSCI_VERSION_FEATURE_MASK + .word ARM_PSCI_0_2_FN_CPU_SUSPEND + .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK + .word ARM_PSCI_0_2_FN_CPU_OFF + .word PSCI_FN_CPU_OFF_FEATURE_MASK + .word ARM_PSCI_0_2_FN_CPU_ON + .word PSCI_FN_CPU_ON_FEATURE_MASK + .word ARM_PSCI_0_2_FN_AFFINITY_INFO + .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK + .word ARM_PSCI_0_2_FN_SYSTEM_OFF + .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK + .word ARM_PSCI_0_2_FN_SYSTEM_RESET + .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK + .word ARM_PSCI_1_0_FN_SYSTEM_SUSPEND + .word PSCI_FN_SYSTEM_SUSPEND_FEATURE_MASK + .word 0 + .word ARM_PSCI_RET_NI + +.globl psci_features +psci_features: + adr r2, _ls102x_psci_supported_table +1: ldr r3, [r2] + cmp r3, #0 + beq out_psci_features + cmp r1, r3 + addne r2, r2, #8 + bne 1b + +out_psci_features: + ldr r0, [r2, #4] + bx lr + +@ r0: return value ARM_PSCI_RET_SUCCESS or ARM_PSCI_RET_INVAL +@ r1: input target CPU ID in MPIDR format, original value in r1 may be dropped +@ r4: output validated CPU ID if ARM_PSCI_RET_SUCCESS returns, meaningless for +@ ARM_PSCI_RET_INVAL,suppose caller saves r4 before calling +LENTRY(psci_check_target_cpu_id) + @ Get the real CPU number + and r4, r1, #0xff + mov r0, #ARM_PSCI_RET_INVAL + + @ Bit[31:24], bits must be zero. + tst r1, #0xff000000 + bxne lr + + @ Affinity level 2 - Cluster: only one cluster in LS1021xa. + tst r1, #0xff0000 + bxne lr + + @ Affinity level 1 - Processors: should be in 0xf00 format. + lsr r1, r1, #8 + teq r1, #0xf + bxne lr + + @ Affinity level 0 - CPU: only 0, 1 are valid in LS1021xa. + cmp r4, #2 + bxge lr + + mov r0, #ARM_PSCI_RET_SUCCESS + bx lr +ENDPROC(psci_check_target_cpu_id) + + @ r1 = target CPU + @ r2 = target PC +.globl psci_cpu_on +psci_cpu_on: + push {r4, r5, r6, lr} + + @ Clear and Get the correct CPU number + @ r1 = 0xf01 + bl psci_check_target_cpu_id + cmp r0, #ARM_PSCI_RET_INVAL + beq out_psci_cpu_on + + mov r0, r4 + mov r1, r2 + mov r2, r3 + bl psci_save + mov r1, r4 + + @ Get DCFG base address + movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) + movt r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16) + + @ Detect target CPU state + ldr r2, [r4, #DCFG_CCSR_BRR] + rev r2, r2 + lsr r2, r2, r1 + ands r2, r2, #1 + beq holdoff_release + + @ Reset target CPU + @ Get SCFG base address + movw r0, #(CONFIG_SYS_FSL_SCFG_ADDR & 0xffff) + movt r0, #(CONFIG_SYS_FSL_SCFG_ADDR >> 16) + + @ Enable CORE Soft Reset + movw r5, #0 + movt r5, #(1 << 15) + rev r5, r5 + str r5, [r0, #SCFG_CORESRENCR] + + @ Get CPUx offset register + mov r6, #0x4 + mul r6, r6, r1 + add r2, r0, r6 + + @ Do reset on target CPU + movw r5, #0 + movt r5, #(1 << 15) + rev r5, r5 + str r5, [r2, #SCFG_CORE0_SFT_RST] + + @ Wait target CPU up + timer_wait r2, RESET_WAIT + + @ Disable CORE soft reset + mov r5, #0 + str r5, [r0, #SCFG_CORESRENCR] + +holdoff_release: + @ Release on target CPU + ldr r2, [r4, #DCFG_CCSR_BRR] + mov r6, #1 + lsl r6, r6, r1 @ 32 bytes per CPU + + rev r6, r6 + orr r2, r2, r6 + str r2, [r4, #DCFG_CCSR_BRR] + + @ Set secondary boot entry + ldr r6, =psci_cpu_entry + rev r6, r6 + str r6, [r4, #DCFG_CCSR_SCRATCHRW1] + + isb + dsb + + @ Return + mov r0, #ARM_PSCI_RET_SUCCESS + +out_psci_cpu_on: + pop {r4, r5, r6, lr} + bx lr + +.globl psci_cpu_off +psci_cpu_off: + bl psci_cpu_off_common + +1: wfi + b 1b + +.globl psci_affinity_info +psci_affinity_info: + push {lr} + + mov r0, #ARM_PSCI_RET_INVAL + + @ Verify Affinity level + cmp r2, #0 + bne out_affinity_info + + bl psci_check_target_cpu_id + cmp r0, #ARM_PSCI_RET_INVAL + beq out_affinity_info + mov r1, r4 + + @ Get RCPM base address + movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff) + movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16) + + mov r0, #PSCI_AFFINITY_LEVEL_ON + + @ Detect target CPU state + ldr r2, [r4, #RCPM_TWAITSR] + rev r2, r2 + lsr r2, r2, r1 + ands r2, r2, #1 + beq out_affinity_info + + mov r0, #PSCI_AFFINITY_LEVEL_OFF + +out_affinity_info: + pop {pc} + +.globl psci_system_reset +psci_system_reset: + @ Get DCFG base address + movw r1, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) + movt r1, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16) + + mov r2, #DCFG_CCSR_RSTCR_RESET_REQ + rev r2, r2 + str r2, [r1, #DCFG_CCSR_RSTCR] + +1: wfi + b 1b + +.globl psci_system_suspend +psci_system_suspend: + push {lr} + + bl ls1_system_suspend + + pop {pc} + + .popsection diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c new file mode 100644 index 000000000..8a95ee86a --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/soc.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2015 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <log.h> +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <asm/arch/fsl_serdes.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/arch/ls102xa_soc.h> +#include <asm/arch/ls102xa_stream_id.h> +#include <fsl_csu.h> +#include <fsl_ddr_sdram.h> + +struct liodn_id_table sec_liodn_tbl[] = { + SET_SEC_JR_LIODN_ENTRY(0, 0x10, 0x10), + SET_SEC_JR_LIODN_ENTRY(1, 0x10, 0x10), + SET_SEC_JR_LIODN_ENTRY(2, 0x10, 0x10), + SET_SEC_JR_LIODN_ENTRY(3, 0x10, 0x10), + SET_SEC_RTIC_LIODN_ENTRY(a, 0x10), + SET_SEC_RTIC_LIODN_ENTRY(b, 0x10), + SET_SEC_RTIC_LIODN_ENTRY(c, 0x10), + SET_SEC_RTIC_LIODN_ENTRY(d, 0x10), + SET_SEC_DECO_LIODN_ENTRY(0, 0x10, 0x10), + SET_SEC_DECO_LIODN_ENTRY(1, 0x10, 0x10), + SET_SEC_DECO_LIODN_ENTRY(2, 0x10, 0x10), + SET_SEC_DECO_LIODN_ENTRY(3, 0x10, 0x10), + SET_SEC_DECO_LIODN_ENTRY(4, 0x10, 0x10), + SET_SEC_DECO_LIODN_ENTRY(5, 0x10, 0x10), + SET_SEC_DECO_LIODN_ENTRY(6, 0x10, 0x10), + SET_SEC_DECO_LIODN_ENTRY(7, 0x10, 0x10), +}; + +struct smmu_stream_id dev_stream_id[] = { + { 0x100, 0x01, "ETSEC MAC1" }, + { 0x104, 0x02, "ETSEC MAC2" }, + { 0x108, 0x03, "ETSEC MAC3" }, + { 0x10c, 0x04, "PEX1" }, + { 0x110, 0x05, "PEX2" }, + { 0x114, 0x06, "qDMA" }, + { 0x118, 0x07, "SATA" }, + { 0x11c, 0x08, "USB3" }, + { 0x120, 0x09, "QE" }, + { 0x124, 0x0a, "eSDHC" }, + { 0x128, 0x0b, "eMA" }, + { 0x14c, 0x0c, "2D-ACE" }, + { 0x150, 0x0d, "USB2" }, + { 0x18c, 0x0e, "DEBUG" }, +}; + +unsigned int get_soc_major_rev(void) +{ + struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR); + unsigned int svr, major; + + svr = in_be32(&gur->svr); + major = SVR_MAJ(svr); + + return major; +} + +static void erratum_a009008(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A009008 + u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE; + + clrsetbits_be32(scfg + SCFG_USB3PRM1CR / 4, + 0xF << 6, + SCFG_USB_TXVREFTUNE << 6); +#endif /* CONFIG_SYS_FSL_ERRATUM_A009008 */ +} + +static void erratum_a009798(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A009798 + u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE; + + clrbits_be32(scfg + SCFG_USB3PRM1CR / 4, + SCFG_USB_SQRXTUNE_MASK << 23); +#endif /* CONFIG_SYS_FSL_ERRATUM_A009798 */ +} + +static void erratum_a008997(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A008997 + u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE; + + clrsetbits_be32(scfg + SCFG_USB3PRM2CR / 4, + SCFG_USB_PCSTXSWINGFULL_MASK, + SCFG_USB_PCSTXSWINGFULL_VAL); +#endif /* CONFIG_SYS_FSL_ERRATUM_A008997 */ +} + +static void erratum_a009007(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A009007 + void __iomem *usb_phy = (void __iomem *)USB_PHY_BASE; + + out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_1); + out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_2); + out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_3); + out_le16(usb_phy + USB_PHY_RX_OVRD_IN_HI, USB_PHY_RX_EQ_VAL_4); +#endif /* CONFIG_SYS_FSL_ERRATUM_A009007 */ +} + +static void erratum_a008850_early(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A008850 + /* part 1 of 2 */ + struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); + struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + + /* disables propagation of barrier transactions to DDRC from CCI400 */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER); + + /* disable the re-ordering in DDRC */ + out_be32(&ddr->eor, DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS); +#endif +} + +void erratum_a008850_post(void) +{ +#ifdef CONFIG_SYS_FSL_ERRATUM_A008850 + /* part 2 of 2 */ + struct ccsr_cci400 __iomem *cci = (void *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); + struct ccsr_ddr __iomem *ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; + u32 tmp; + + /* enable propagation of barrier transactions to DDRC from CCI400 */ + out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER); + + /* enable the re-ordering in DDRC */ + tmp = in_be32(&ddr->eor); + tmp &= ~(DDR_EOR_RD_REOD_DIS | DDR_EOR_WD_REOD_DIS); + out_be32(&ddr->eor, tmp); +#endif +} + +void s_init(void) +{ +} + +#ifdef CONFIG_SYS_FSL_ERRATUM_A010315 +void erratum_a010315(void) +{ + int i; + + for (i = PCIE1; i <= PCIE2; i++) + if (!is_serdes_configured(i)) { + debug("PCIe%d: disabled all R/W permission!\n", i); + set_pcie_ns_access(i, 0); + } +} +#endif + +int arch_soc_init(void) +{ + struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR; + struct ccsr_cci400 *cci = (struct ccsr_cci400 *)(CONFIG_SYS_IMMR + + CONFIG_SYS_CCI400_OFFSET); + unsigned int major; + +#ifdef CONFIG_LAYERSCAPE_NS_ACCESS + enable_layerscape_ns_access(); +#endif + +#ifdef CONFIG_FSL_QSPI + out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL); +#endif + +#ifdef CONFIG_VIDEO_FSL_DCU_FB + out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN); +#endif + + /* Configure Little endian for SAI, ASRC and SPDIF */ + out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE); + + /* + * Enable snoop requests and DVM message requests for + * All the slave insterfaces. + */ + out_le32(&cci->slave[0].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + out_le32(&cci->slave[1].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + out_le32(&cci->slave[2].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + out_le32(&cci->slave[4].snoop_ctrl, + CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN); + + major = get_soc_major_rev(); + if (major == SOC_MAJOR_VER_1_0) { + /* + * Set CCI-400 Slave interface S1, S2 Shareable Override + * Register All transactions are treated as non-shareable + */ + out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE); + } + + /* Enable all the snoop signal for various masters */ + out_be32(&scfg->snpcnfgcr, SCFG_SNPCNFGCR_SEC_RD_WR | + SCFG_SNPCNFGCR_DCU_RD_WR | + SCFG_SNPCNFGCR_SATA_RD_WR | + SCFG_SNPCNFGCR_USB3_RD_WR | + SCFG_SNPCNFGCR_DBG_RD_WR | + SCFG_SNPCNFGCR_EDMA_SNP); + + /* + * Memory controller require a register write before being enabled. + * Affects: DDR + * Register: EDDRTQCFG + * Description: Memory controller performance is not optimal with + * default internal target queue register values. + * Workaround: Write a value of 63b2_0042h to address: 157_020Ch. + */ + out_be32(&scfg->eddrtqcfg, 0x63b20042); + + /* Erratum */ + erratum_a008850_early(); + erratum_a009008(); + erratum_a009798(); + erratum_a008997(); + erratum_a009007(); + + return 0; +} + +int ls102xa_smmu_stream_id_init(void) +{ + ls1021x_config_caam_stream_id(sec_liodn_tbl, + ARRAY_SIZE(sec_liodn_tbl)); + + ls102xa_config_smmu_stream_id(dev_stream_id, + ARRAY_SIZE(dev_stream_id)); + + return 0; +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c new file mode 100644 index 000000000..308536c33 --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/spl.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <spl.h> + +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SPL_MMC_SUPPORT + return BOOT_DEVICE_MMC1; +#endif + return BOOT_DEVICE_NAND; +} diff --git a/roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c new file mode 100644 index 000000000..d79bf105f --- /dev/null +++ b/roms/u-boot/arch/arm/cpu/armv7/ls102xa/timer.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + */ + +#include <common.h> +#include <init.h> +#include <time.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <div64.h> +#include <asm/arch/immap_ls102xa.h> +#include <asm/arch/clock.h> +#include <linux/delay.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, freq; + unsigned long long val; + + /* Enable System Counter */ + writel(SYS_COUNTER_CTRL_ENABLE, &sctr->cntcr); + + freq = COUNTER_FREQUENCY; + 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(ulong base) +{ + return tick_to_time(get_ticks()) - 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; +} |