summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2015-11-30 15:18:30 -0500
committerTom Rini <trini@konsulko.com>2015-11-30 15:18:30 -0500
commit1670c8c219f6e47de624b4ed557b5a995265cd40 (patch)
tree9b9daf857ab9b16642d79e28f7094c26eb162e67 /arch/arm/cpu
parent2a8696dfc2c6547c41836ceda573ad4548cba357 (diff)
parent3785f57015dbd7582f85fd1c34dcaa26638bf976 (diff)
downloadblackbird-obmc-uboot-1670c8c219f6e47de624b4ed557b5a995265cd40.tar.gz
blackbird-obmc-uboot-1670c8c219f6e47de624b4ed557b5a995265cd40.zip
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.c10
-rw-r--r--arch/arm/cpu/armv7/ls102xa/timer.c3
-rw-r--r--arch/arm/cpu/armv8/cache_v8.c4
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/Makefile10
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/README.lsch385
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/cpu.c10
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fdt.c2
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_serdes.c25
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch3_speed.c11
-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.c6
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/soc.c45
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/spl.c6
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();
OpenPOWER on IntegriCloud