diff options
author | Tom Rini <trini@konsulko.com> | 2015-11-30 15:18:30 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2015-11-30 15:18:30 -0500 |
commit | 1670c8c219f6e47de624b4ed557b5a995265cd40 (patch) | |
tree | 9b9daf857ab9b16642d79e28f7094c26eb162e67 /arch/arm/cpu | |
parent | 2a8696dfc2c6547c41836ceda573ad4548cba357 (diff) | |
parent | 3785f57015dbd7582f85fd1c34dcaa26638bf976 (diff) |
Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/cpu.c | 10 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/ls102xa/timer.c | 3 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/cache_v8.c | 4 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/Makefile | 10 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/README.lsch3 | 85 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/cpu.c | 10 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fdt.c | 2 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c | 25 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c | 11 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c (renamed from arch/arm/cpu/armv8/fsl-layerscape/ls2085a_serdes.c) | 5 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/mp.c | 6 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/soc.c | 45 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/fsl-layerscape/spl.c | 6 |
13 files changed, 204 insertions, 18 deletions
diff --git a/arch/arm/cpu/armv7/ls102xa/cpu.c b/arch/arm/cpu/armv7/ls102xa/cpu.c index df2e1b76f1..2215fe93cf 100644 --- a/arch/arm/cpu/armv7/ls102xa/cpu.c +++ b/arch/arm/cpu/armv7/ls102xa/cpu.c @@ -372,3 +372,13 @@ void reset_cpu(ulong addr) */ } } + +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/arch/arm/cpu/armv7/ls102xa/timer.c b/arch/arm/cpu/armv7/ls102xa/timer.c index 11b17b2c74..e6a32caafc 100644 --- a/arch/arm/cpu/armv7/ls102xa/timer.c +++ b/arch/arm/cpu/armv7/ls102xa/timer.c @@ -56,7 +56,8 @@ static inline unsigned long long us_to_tick(unsigned long long usec) int timer_init(void) { struct sctr_regs *sctr = (struct sctr_regs *)SCTR_BASE_ADDR; - unsigned long ctrl, val, freq; + unsigned long ctrl, freq; + unsigned long long val; /* Enable System Counter */ writel(SYS_COUNTER_CTRL_ENABLE, &sctr->cntcr); diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c index 1ece6a2c12..53bac3b449 100644 --- a/arch/arm/cpu/armv8/cache_v8.c +++ b/arch/arm/cpu/armv8/cache_v8.c @@ -13,13 +13,13 @@ DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_SYS_DCACHE_OFF inline void set_pgtable_section(u64 *page_table, u64 index, u64 section, - u64 memory_type, u64 share) + u64 memory_type, u64 attribute) { u64 value; value = section | PMD_TYPE_SECT | PMD_SECT_AF; value |= PMD_ATTRINDX(memory_type); - value |= share; + value |= attribute; page_table[index] = value; } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/Makefile b/arch/arm/cpu/armv8/fsl-layerscape/Makefile index 6fa08c8f3c..cce74052f7 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/Makefile +++ b/arch/arm/cpu/armv8/fsl-layerscape/Makefile @@ -21,10 +21,14 @@ obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch2_serdes.o endif endif +ifneq ($(CONFIG_LS2080A),) +obj-$(CONFIG_SYS_HAS_SERDES) += ls2080a_serdes.o +endif + ifneq ($(CONFIG_LS2085A),) -obj-$(CONFIG_SYS_HAS_SERDES) += ls2085a_serdes.o -else +obj-$(CONFIG_SYS_HAS_SERDES) += ls2080a_serdes.o +endif + ifneq ($(CONFIG_LS1043A),) obj-$(CONFIG_SYS_HAS_SERDES) += ls1043a_serdes.o endif -endif diff --git a/arch/arm/cpu/armv8/fsl-layerscape/README.lsch3 b/arch/arm/cpu/armv8/fsl-layerscape/README.lsch3 index 03e18f6573..f9323c1d28 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/README.lsch3 +++ b/arch/arm/cpu/armv8/fsl-layerscape/README.lsch3 @@ -7,7 +7,7 @@ Freescale LayerScape with Chassis Generation 3 This architecture supports Freescale ARMv8 SoCs with Chassis generation 3, -for example LS2085A. +for example LS2080A. DDR Layout ============ @@ -152,7 +152,7 @@ u-boot command nand write <rcw image in memory> 0 <size of rcw image> To form the NAND image, build u-boot with NAND config, for example, -ls2085aqds_nand_defconfig. The image needed is u-boot-with-spl.bin. +ls2080aqds_nand_defconfig. The image needed is u-boot-with-spl.bin. The u-boot image should be written to match SRC_ADDR, in above example 0x20000. nand write <u-boot image in memory> 200000 <size of u-boot image> @@ -242,3 +242,84 @@ MMU Translation Tables | 0x81_0000_0000 | | 0x08_0080_0000 | ------------------ ------------------ ... ... + + +DPAA2 commands to manage Management Complex (MC) +------------------------------------------------ +DPAA2 commands has been introduced to manage Management Complex +(MC). These commands are used to start mc, aiop and apply DPL +from u-boot command prompt. + +Please note Management complex Firmware(MC), DPL and DPC are no +more deployed during u-boot boot-sequence. + +Commands: +a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex +b) fsl_mc apply DPL <DPL_addr> - Apply DPL file +c) fsl_mc start aiop <FW_addr> - Start AIOP + +How to use commands :- +1. Command sequence for u-boot ethernet: + a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex + b) DPMAC net-devices are now available for use + + Example- + Assumption: MC firmware, DPL and DPC dtb is already programmed + on NOR flash. + + => fsl_mc start mc 580300000 580800000 + => setenv ethact DPMAC1@xgmii + => ping $serverip + +2. Command sequence for Linux boot: + a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex + b) fsl_mc apply DPL <DPL_addr> - Apply DPL file + c) No DPMAC net-devices are available for use in u-boot + d) boot Linux + + Example- + Assumption: MC firmware, DPL and DPC dtb is already programmed + on NOR flash. + + => fsl_mc start mc 580300000 580800000 + => setenv ethact DPMAC1@xgmii + => tftp a0000000 kernel.itb + => fsl_mc apply dpl 580700000 + => bootm a0000000 + +3. Command sequence for AIOP boot: + a) fsl_mc start mc <FW_addr> <DPC_addr> - Start Management Complex + b) fsl_mc start aiop <FW_addr> - Start AIOP + c) fsl_mc apply DPL <DPL_addr> - Apply DPL file + d) No DPMAC net-devices are availabe for use in u-boot + Please note actual AIOP start will happen during DPL parsing of + Management complex + + Example- + Assumption: MC firmware, DPL, DPC dtb and AIOP firmware is already + programmed on NOR flash. + + => fsl_mc start mc 580300000 580800000 + => fsl_mc start aiop 0x580900000 + => setenv ethact DPMAC1@xgmii + => fsl_mc apply dpl 580700000 + +Errata A009635 +--------------- +If the core runs at higher than x3 speed of the platform, there is +possiblity about sev instruction to getting missed by other cores. +This is because of SoC Run Control block may not able to sample +the EVENTI(Sev) signals. + +Workaround: Configure Run Control and EPU to periodically send out EVENTI signals to +wake up A57 cores + +Errata workaround uses Env variable "a009635_interval_val". It uses decimal +value. +- Default value of env variable is platform clock (MHz) + +- User can modify default value by updating the env variable + setenv a009635_interval_val 600; saveenv; + It configure platform clock as 600 MHz + +- Env variable as 0 signifies no workaround diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c index 0cb0afa0b3..8847fc0287 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c @@ -76,7 +76,7 @@ static int set_block_entry(const struct sys_mmu_table *list, index, block_addr, list->memory_type, - list->share); + list->attribute); block_addr += block_size; index++; } @@ -438,7 +438,7 @@ int print_cpuinfo(void) #ifdef CONFIG_SYS_DPAA_FMAN printf(" FMAN: %-4s MHz", strmhz(buf, sysinfo.freq_fman[0])); #endif -#ifdef CONFIG_FSL_LSCH3 +#ifdef CONFIG_SYS_FSL_HAS_DP_DDR printf(" DP-DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus2)); #endif puts("\n"); @@ -484,7 +484,13 @@ int arch_early_init_r(void) { #ifdef CONFIG_MP int rv = 1; +#endif +#ifdef CONFIG_SYS_FSL_ERRATUM_A009635 + erratum_a009635(); +#endif + +#ifdef CONFIG_MP rv = fsl_layerscape_wake_seconday_cores(); if (rv) printf("Did not wake secondary cores\n"); diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c index 47599c1217..eafdd71a84 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fdt.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fdt.c @@ -141,7 +141,7 @@ void append_mmu_masters(void *blob, const char *smmu_path, /* * The info below summarizes how streamID partitioning works - * for ls2085a and how it is conveyed to the OS via the device tree. + * for ls2080a and how it is conveyed to the OS via the device tree. * * -non-PCI legacy, platform devices (USB, SD/MMC, SATA, DMA) * -all legacy devices get a unique ICID assigned and programmed in diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c index 2ab8da6403..918e889052 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c @@ -18,6 +18,11 @@ static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT]; static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT]; #endif +#ifdef CONFIG_FSL_MC_ENET +int xfi_dpmac[XFI8 + 1]; +int sgmii_dpmac[SGMII16 + 1]; +#endif + int is_serdes_configured(enum srds_prtcl device) { int ret = 0; @@ -116,9 +121,15 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, wriop_init_dpmac(sd, 12, (int)lane_prtcl); break; default: + if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8) + wriop_init_dpmac(sd, + xfi_dpmac[lane_prtcl], + (int)lane_prtcl); + if (lane_prtcl >= SGMII1 && - lane_prtcl <= SGMII16) - wriop_init_dpmac(sd, lane + 1, + lane_prtcl <= SGMII16) + wriop_init_dpmac(sd, sgmii_dpmac[ + lane_prtcl], (int)lane_prtcl); break; } @@ -129,6 +140,16 @@ void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift, void fsl_serdes_init(void) { +#ifdef CONFIG_FSL_MC_ENET + int i , j; + + for (i = XFI1, j = 1; i <= XFI8; i++, j++) + xfi_dpmac[i] = j; + + for (i = SGMII1, j = 1; i <= SGMII16; i++, j++) + sgmii_dpmac[i] = j; +#endif + #ifdef CONFIG_SYS_FSL_SRDS_1 serdes_init(FSL_SRDS_1, CONFIG_SYS_FSL_LSCH3_SERDES_ADDR, diff --git a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c index 4054c3c7d2..81cf47049f 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c @@ -11,6 +11,7 @@ #include <fsl_ifc.h> #include <asm/processor.h> #include <asm/io.h> +#include <asm/arch-fsl-layerscape/immap_lsch3.h> #include <asm/arch/clock.h> #include <asm/arch/soc.h> #include "cpu.h" @@ -77,11 +78,15 @@ void get_sys_info(struct sys_info *sys_info) sys_info->freq_systembus = sysclk; #ifdef CONFIG_DDR_CLK_FREQ sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ; +#ifdef CONFIG_SYS_FSL_HAS_DP_DDR sys_info->freq_ddrbus2 = CONFIG_DDR_CLK_FREQ; +#endif #else sys_info->freq_ddrbus = sysclk; +#ifdef CONFIG_SYS_FSL_HAS_DP_DDR sys_info->freq_ddrbus2 = sysclk; #endif +#endif sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >> FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_SHIFT) & @@ -91,9 +96,11 @@ void get_sys_info(struct sys_info *sys_info) sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >> FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) & FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK; +#ifdef CONFIG_SYS_FSL_HAS_DP_DDR sys_info->freq_ddrbus2 *= (gur_in32(&gur->rcwsr[0]) >> FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT) & FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK; +#endif for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) { /* @@ -133,7 +140,9 @@ int get_clocks(void) gd->cpu_clk = sys_info.freq_processor[0]; gd->bus_clk = sys_info.freq_systembus; gd->mem_clk = sys_info.freq_ddrbus; +#ifdef CONFIG_SYS_FSL_HAS_DP_DDR gd->arch.mem2_clk = sys_info.freq_ddrbus2; +#endif #if defined(CONFIG_FSL_ESDHC) gd->arch.sdhc_clk = gd->bus_clk / 2; #endif /* defined(CONFIG_FSL_ESDHC) */ @@ -169,8 +178,10 @@ ulong get_ddr_freq(ulong ctrl_num) * DDR controller 0 & 1 are on memory complex 0 * DDR controler 2 is on memory complext 1 */ +#ifdef CONFIG_SYS_FSL_HAS_DP_DDR if (ctrl_num >= 2) return gd->arch.mem2_clk; +#endif return gd->mem_clk; } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/ls2085a_serdes.c b/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c index ea3114cca4..8ef4f1c38f 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/ls2085a_serdes.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/ls2080a_serdes.c @@ -28,7 +28,12 @@ static struct serdes_config serdes1_cfg_tbl[] = { SGMII1 } }, {0x26, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, XFI2, XFI1 } }, {0x28, {SGMII8, SGMII7, SGMII6, SGMII5, XFI4, XFI3, XFI2, XFI1 } }, +#ifdef CONFIG_LS2080A + {0x2A, {NONE, NONE, NONE, XFI5, XFI4, XFI3, XFI2, XFI1 } }, +#endif +#ifdef CONFIG_LS2085A {0x2A, {XFI8, XFI7, XFI6, XFI5, XFI4, XFI3, XFI2, XFI1 } }, +#endif {0x2B, {SGMII8, SGMII7, SGMII6, SGMII5, XAUI1, XAUI1, XAUI1, XAUI1 } }, {0x32, {XAUI2, XAUI2, XAUI2, XAUI2, XAUI1, XAUI1, XAUI1, XAUI1 } }, {0x33, {PCIE2, PCIE2, PCIE2, PCIE2, QSGMII_C, QSGMII_D, QSGMII_A, diff --git a/arch/arm/cpu/armv8/fsl-layerscape/mp.c b/arch/arm/cpu/armv8/fsl-layerscape/mp.c index 0d600db090..df7ffb88f6 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/mp.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/mp.c @@ -192,6 +192,12 @@ int cpu_release(int nr, int argc, char * const argv[]) (unsigned long)table + SPIN_TABLE_ELEM_SIZE); asm volatile("dsb st"); smp_kick_all_cpus(); /* only those with entry addr set will run */ + /* + * When the first release command runs, all cores are set to go. Those + * without a valid entry address will be trapped by "wfe". "sev" kicks + * them off to check the address again. When set, they continue to run. + */ + asm volatile("sev"); return 0; } diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c index 637853d51f..8896b70e78 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c @@ -9,10 +9,53 @@ #include <asm/arch/soc.h> #include <asm/io.h> #include <asm/global_data.h> +#include <asm/arch-fsl-layerscape/config.h> DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_LS2085A +#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) +#ifdef CONFIG_SYS_FSL_ERRATUM_A009635 +#define PLATFORM_CYCLE_ENV_VAR "a009635_interval_val" + +static unsigned long get_internval_val_mhz(void) +{ + char *interval = getenv(PLATFORM_CYCLE_ENV_VAR); + /* + * interval is the number of platform cycles(MHz) between + * wake up events generated by EPU. + */ + ulong interval_mhz = get_bus_freq(0) / (1000 * 1000); + + if (interval) + interval_mhz = simple_strtoul(interval, NULL, 10); + + return interval_mhz; +} + +void erratum_a009635(void) +{ + u32 val; + unsigned long interval_mhz = get_internval_val_mhz(); + + if (!interval_mhz) + return; + + val = in_le32(DCSR_CGACRE5); + writel(val | 0x00000200, DCSR_CGACRE5); + + val = in_le32(EPU_EPCMPR5); + writel(interval_mhz, EPU_EPCMPR5); + val = in_le32(EPU_EPCCR5); + writel(val | 0x82820000, EPU_EPCCR5); + val = in_le32(EPU_EPSMCR5); + writel(val | 0x002f0000, EPU_EPSMCR5); + val = in_le32(EPU_EPECR5); + writel(val | 0x20000000, EPU_EPECR5); + val = in_le32(EPU_EPGCR); + writel(val | 0x80000000, EPU_EPGCR); +} +#endif /* CONFIG_SYS_FSL_ERRATUM_A009635 */ + static void erratum_a008751(void) { #ifdef CONFIG_SYS_FSL_ERRATUM_A008751 diff --git a/arch/arm/cpu/armv8/fsl-layerscape/spl.c b/arch/arm/cpu/armv8/fsl-layerscape/spl.c index ba551aaa6e..f434c443ed 100644 --- a/arch/arm/cpu/armv8/fsl-layerscape/spl.c +++ b/arch/arm/cpu/armv8/fsl-layerscape/spl.c @@ -44,11 +44,9 @@ u32 spl_boot_mode(void) #ifdef CONFIG_SPL_BUILD void board_init_f(ulong dummy) { - /* Set global data pointer */ - gd = &gdata; /* Clear global data */ memset((void *)gd, 0, sizeof(gd_t)); -#ifdef CONFIG_LS2085A +#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) arch_cpu_init(); #endif #ifdef CONFIG_FSL_IFC @@ -56,7 +54,7 @@ void board_init_f(ulong dummy) #endif board_early_init_f(); timer_init(); -#ifdef CONFIG_LS2085A +#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A) env_init(); #endif get_clocks(); |