avionic design with actual uboot and tooling
submodule of avionic design uboot bootloader and with included tools to get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
20
u-boot/arch/arm/cpu/armv7/ls102xa/Makefile
Normal file
20
u-boot/arch/arm/cpu/armv7/ls102xa/Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# 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_SCSI_AHCI_PLAT) += ls102xa_sata.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
|
||||
endif
|
||||
130
u-boot/arch/arm/cpu/armv7/ls102xa/clock.c
Normal file
130
u-boot/arch/arm/cpu/armv7/ls102xa/clock.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <fsl_ifc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
|
||||
#define CONFIG_SYS_FSL_NUM_CC_PLLS 2
|
||||
#endif
|
||||
|
||||
void get_sys_info(struct sys_info *sys_info)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
#ifdef CONFIG_FSL_IFC
|
||||
struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
|
||||
u32 ccr;
|
||||
#endif
|
||||
struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR);
|
||||
unsigned int cpu;
|
||||
const u8 core_cplx_pll[6] = {
|
||||
[0] = 0, /* CC1 PPL / 1 */
|
||||
[1] = 0, /* CC1 PPL / 2 */
|
||||
[4] = 1, /* CC2 PPL / 1 */
|
||||
[5] = 1, /* CC2 PPL / 2 */
|
||||
};
|
||||
|
||||
const u8 core_cplx_pll_div[6] = {
|
||||
[0] = 1, /* CC1 PPL / 1 */
|
||||
[1] = 2, /* CC1 PPL / 2 */
|
||||
[4] = 1, /* CC2 PPL / 1 */
|
||||
[5] = 2, /* CC2 PPL / 2 */
|
||||
};
|
||||
|
||||
uint i;
|
||||
uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
|
||||
uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
|
||||
unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
|
||||
|
||||
sys_info->freq_systembus = sysclk;
|
||||
#ifdef CONFIG_DDR_CLK_FREQ
|
||||
sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
|
||||
#else
|
||||
sys_info->freq_ddrbus = sysclk;
|
||||
#endif
|
||||
|
||||
sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >>
|
||||
RCWSR0_SYS_PLL_RAT_SHIFT) & RCWSR0_SYS_PLL_RAT_MASK;
|
||||
sys_info->freq_ddrbus *= (in_be32(&gur->rcwsr[0]) >>
|
||||
RCWSR0_MEM_PLL_RAT_SHIFT) & RCWSR0_MEM_PLL_RAT_MASK;
|
||||
|
||||
for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
|
||||
ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0x3f;
|
||||
if (ratio[i] > 4)
|
||||
freq_c_pll[i] = sysclk * ratio[i];
|
||||
else
|
||||
freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
|
||||
}
|
||||
|
||||
for (cpu = 0; cpu < CONFIG_MAX_CPUS; cpu++) {
|
||||
u32 c_pll_sel = (in_be32(&clk->clkcsr[cpu].clkcncsr) >> 27)
|
||||
& 0xf;
|
||||
u32 cplx_pll = core_cplx_pll[c_pll_sel];
|
||||
|
||||
sys_info->freq_processor[cpu] =
|
||||
freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FSL_IFC)
|
||||
ccr = in_be32(&ifc_regs.gregs->ifc_ccr);
|
||||
ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
|
||||
|
||||
sys_info->freq_localbus = sys_info->freq_systembus / ccr;
|
||||
#endif
|
||||
}
|
||||
|
||||
int get_clocks(void)
|
||||
{
|
||||
struct sys_info sys_info;
|
||||
|
||||
get_sys_info(&sys_info);
|
||||
gd->cpu_clk = sys_info.freq_processor[0];
|
||||
gd->bus_clk = sys_info.freq_systembus;
|
||||
gd->mem_clk = sys_info.freq_ddrbus * 2;
|
||||
|
||||
#if defined(CONFIG_FSL_ESDHC)
|
||||
gd->arch.sdhc_clk = gd->bus_clk;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_bus_freq(ulong dummy)
|
||||
{
|
||||
return gd->bus_clk;
|
||||
}
|
||||
|
||||
ulong get_ddr_freq(ulong dummy)
|
||||
{
|
||||
return gd->mem_clk;
|
||||
}
|
||||
|
||||
int get_serial_clock(void)
|
||||
{
|
||||
return gd->bus_clk / 2;
|
||||
}
|
||||
|
||||
unsigned int mxc_get_clock(enum mxc_clock clk)
|
||||
{
|
||||
switch (clk) {
|
||||
case MXC_I2C_CLK:
|
||||
return get_bus_freq(0) / 2;
|
||||
case MXC_ESDHC_CLK:
|
||||
return get_bus_freq(0);
|
||||
case MXC_DSPI_CLK:
|
||||
return get_bus_freq(0) / 2;
|
||||
case MXC_UART_CLK:
|
||||
return get_bus_freq(0) / 2;
|
||||
default:
|
||||
printf("Unsupported clock\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
392
u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c
Normal file
392
u-boot/arch/arm/cpu/armv7/ls102xa/cpu.c
Normal file
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#include <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 "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;
|
||||
|
||||
#ifndef CONFIG_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 /* #ifndef CONFIG_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(bd_t *bis)
|
||||
{
|
||||
return fsl_esdhc_mmc_init(bis);
|
||||
}
|
||||
#endif
|
||||
|
||||
int cpu_eth_init(bd_t *bis)
|
||||
{
|
||||
#ifdef CONFIG_TSEC_ENET
|
||||
tsec_standard_init(bis);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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(ulong addr)
|
||||
{
|
||||
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));
|
||||
}
|
||||
182
u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c
Normal file
182
u-boot/arch/arm/cpu/armv7/ls102xa/fdt.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <linux/ctype.h>
|
||||
#ifdef CONFIG_FSL_ESDHC
|
||||
#include <fsl_esdhc.h>
|
||||
#endif
|
||||
#include <tsec.h>
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#include <fsl_sec.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void ft_fixup_enet_phy_connect_type(void *fdt)
|
||||
{
|
||||
struct eth_device *dev;
|
||||
struct tsec_private *priv;
|
||||
const char *enet_path, *phy_path;
|
||||
char enet[16];
|
||||
char phy[16];
|
||||
int phy_node;
|
||||
int i = 0;
|
||||
uint32_t ph;
|
||||
char *name[3] = { "eTSEC1", "eTSEC2", "eTSEC3" };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
priv = dev->priv;
|
||||
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),
|
||||
sizeof(phy_string_for_interface(
|
||||
PHY_INTERFACE_MODE_RGMII_ID)),
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
int off;
|
||||
int val;
|
||||
const char *sysclk_path;
|
||||
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
|
||||
|
||||
fdt_fixup_ethernet(blob);
|
||||
|
||||
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
|
||||
while (off != -FDT_ERR_NOTFOUND) {
|
||||
val = gd->cpu_clk;
|
||||
fdt_setprop(blob, off, "clock-frequency", &val, 4);
|
||||
off = fdt_node_offset_by_prop_value(blob, off,
|
||||
"device_type", "cpu", 4);
|
||||
}
|
||||
|
||||
do_fixup_by_prop_u32(blob, "device_type", "soc",
|
||||
4, "bus-frequency", busclk, 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
|
||||
}
|
||||
57
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c
Normal file
57
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include "fsl_epu.h"
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
68
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h
Normal file
68
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_epu.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
void fsl_epu_clean(void *epu_base);
|
||||
|
||||
#endif
|
||||
120
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
Normal file
120
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/fsl_serdes.h>
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#include <asm/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
|
||||
ret |= (1ULL << device) & serdes1_prtcl_map;
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
ret |= (1ULL << device) & serdes2_prtcl_map;
|
||||
#endif
|
||||
|
||||
return !!ret;
|
||||
}
|
||||
|
||||
int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u32 cfg = in_be32(&gur->rcwsr[4]);
|
||||
int i;
|
||||
|
||||
switch (sd) {
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
case FSL_SRDS_1:
|
||||
cfg &= RCWSR4_SRDS1_PRTCL_MASK;
|
||||
cfg >>= RCWSR4_SRDS1_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
case FSL_SRDS_2:
|
||||
cfg &= RCWSR4_SRDS2_PRTCL_MASK;
|
||||
cfg >>= RCWSR4_SRDS2_PRTCL_SHIFT;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("invalid SerDes%d\n", sd);
|
||||
break;
|
||||
}
|
||||
/* Is serdes enabled at all? */
|
||||
if (unlikely(cfg == 0))
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < SRDS_MAX_LANES; i++) {
|
||||
if (serdes_get_prtcl(sd, cfg, i) == device)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
u64 serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
u64 serdes_prtcl_map = 0;
|
||||
u32 cfg;
|
||||
int lane;
|
||||
|
||||
cfg = in_be32(&gur->rcwsr[4]) & sd_prctl_mask;
|
||||
cfg >>= sd_prctl_shift;
|
||||
printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
|
||||
|
||||
if (!is_serdes_prtcl_valid(sd, cfg))
|
||||
printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
|
||||
|
||||
for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
|
||||
enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
|
||||
|
||||
serdes_prtcl_map |= (1ULL << lane_prtcl);
|
||||
}
|
||||
|
||||
return serdes_prtcl_map;
|
||||
}
|
||||
|
||||
void fsl_serdes_init(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_1
|
||||
serdes1_prtcl_map = serdes_init(FSL_SRDS_1,
|
||||
CONFIG_SYS_FSL_SERDES_ADDR,
|
||||
RCWSR4_SRDS1_PRTCL_MASK,
|
||||
RCWSR4_SRDS1_PRTCL_SHIFT);
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_FSL_SRDS_2
|
||||
serdes2_prtcl_map = serdes_init(FSL_SRDS_2,
|
||||
CONFIG_SYS_FSL_SERDES_ADDR +
|
||||
FSL_SRDS_2 * 0x1000,
|
||||
RCWSR4_SRDS2_PRTCL_MASK,
|
||||
RCWSR4_SRDS2_PRTCL_SHIFT);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *serdes_clock_to_string(u32 clock)
|
||||
{
|
||||
switch (clock) {
|
||||
case SRDS_PLLCR0_RFCK_SEL_100:
|
||||
return "100";
|
||||
case SRDS_PLLCR0_RFCK_SEL_125:
|
||||
return "125";
|
||||
default:
|
||||
return "100";
|
||||
}
|
||||
}
|
||||
12
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h
Normal file
12
u-boot/arch/arm/cpu/armv7/ls102xa/fsl_ls1_serdes.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __FSL_LS1_SERDES_H
|
||||
#define __FSL_LS1_SERDES_H
|
||||
|
||||
int is_serdes_prtcl_valid(int serdes, u32 prtcl);
|
||||
int serdes_lane_enabled(int lane);
|
||||
#endif /* __FSL_LS1_SERDES_H */
|
||||
42
u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_sata.c
Normal file
42
u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_sata.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#include <ahci.h>
|
||||
#include <scsi.h>
|
||||
|
||||
/* port register default value */
|
||||
#define AHCI_PORT_PHY_1_CFG 0xa003fffe
|
||||
#define AHCI_PORT_PHY_2_CFG 0x28183414
|
||||
#define AHCI_PORT_PHY_3_CFG 0x0e080e06
|
||||
#define AHCI_PORT_PHY_4_CFG 0x064a080b
|
||||
#define AHCI_PORT_PHY_5_CFG 0x2aa86470
|
||||
#define AHCI_PORT_TRANS_CFG 0x08000029
|
||||
|
||||
#define SATA_ECC_REG_ADDR 0x20220520
|
||||
#define SATA_ECC_DISABLE 0x00020000
|
||||
|
||||
int ls1021a_sata_init(void)
|
||||
{
|
||||
struct ccsr_ahci __iomem *ccsr_ahci = (void *)AHCI_BASE_ADDR;
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_ERRATUM_A008407
|
||||
out_le32((void *)SATA_ECC_REG_ADDR, SATA_ECC_DISABLE);
|
||||
#endif
|
||||
|
||||
out_le32(&ccsr_ahci->ppcfg, AHCI_PORT_PHY_1_CFG);
|
||||
out_le32(&ccsr_ahci->pp2c, AHCI_PORT_PHY_2_CFG);
|
||||
out_le32(&ccsr_ahci->pp3c, AHCI_PORT_PHY_3_CFG);
|
||||
out_le32(&ccsr_ahci->pp4c, AHCI_PORT_PHY_4_CFG);
|
||||
out_le32(&ccsr_ahci->pp5c, AHCI_PORT_PHY_5_CFG);
|
||||
out_le32(&ccsr_ahci->ptc, AHCI_PORT_TRANS_CFG);
|
||||
|
||||
ahci_init((void __iomem *)AHCI_BASE_ADDR);
|
||||
scsi_scan(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c
Normal file
41
u-boot/arch/arm/cpu/armv7/ls102xa/ls102xa_serdes.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
126
u-boot/arch/arm/cpu/armv7/ls102xa/psci.S
Normal file
126
u-boot/arch/arm/cpu/armv7/ls102xa/psci.S
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
* Author: Wang Dongsheng <dongsheng.wang@freescale.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/armv7.h>
|
||||
#include <asm/arch-armv7/generictimer.h>
|
||||
#include <asm/psci.h>
|
||||
|
||||
#define SCFG_CORE0_SFT_RST 0x130
|
||||
#define SCFG_CORESRENCR 0x204
|
||||
|
||||
#define DCFG_CCSR_BRR 0x0E4
|
||||
#define DCFG_CCSR_SCRATCHRW1 0x200
|
||||
|
||||
.pushsection ._secure.text, "ax"
|
||||
|
||||
.arch_extension sec
|
||||
|
||||
#define ONE_MS (GENERIC_TIMER_CLK / 1000)
|
||||
#define RESET_WAIT (30 * ONE_MS)
|
||||
|
||||
@ r1 = target CPU
|
||||
@ r2 = target PC
|
||||
.globl psci_cpu_on
|
||||
psci_cpu_on:
|
||||
push {lr}
|
||||
|
||||
@ Clear and Get the correct CPU number
|
||||
@ r1 = 0xf01
|
||||
and r1, r1, #0xff
|
||||
|
||||
mov r0, r1
|
||||
bl psci_get_cpu_stack_top
|
||||
str r2, [r0]
|
||||
dsb
|
||||
|
||||
@ 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
|
||||
|
||||
pop {lr}
|
||||
bx lr
|
||||
|
||||
.globl psci_cpu_off
|
||||
psci_cpu_off:
|
||||
bl psci_cpu_off_common
|
||||
|
||||
1: wfi
|
||||
b 1b
|
||||
|
||||
.globl psci_arch_init
|
||||
psci_arch_init:
|
||||
mov r6, lr
|
||||
|
||||
bl psci_get_cpu_id
|
||||
bl psci_get_cpu_stack_top
|
||||
mov sp, r0
|
||||
|
||||
bx r6
|
||||
|
||||
.globl psci_text_end
|
||||
psci_text_end:
|
||||
.popsection
|
||||
138
u-boot/arch/arm/cpu/armv7/ls102xa/soc.c
Normal file
138
u-boot/arch/arm/cpu/armv7/ls102xa/soc.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#include <asm/arch/ls102xa_soc.h>
|
||||
#include <asm/arch/ls102xa_stream_id.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;
|
||||
}
|
||||
|
||||
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_CCI400_ADDR;
|
||||
unsigned int major;
|
||||
|
||||
#ifdef CONFIG_FSL_QSPI
|
||||
out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_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);
|
||||
|
||||
/* Workaround for the issue that DDR could not respond to
|
||||
* barrier transaction which is generated by executing DSB/ISB
|
||||
* instruction. Set CCI-400 control override register to
|
||||
* terminate the barrier transaction. After DDR is initialized,
|
||||
* allow barrier transaction to DDR again */
|
||||
out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
33
u-boot/arch/arm/cpu/armv7/ls102xa/spl.c
Normal file
33
u-boot/arch/arm/cpu/armv7/ls102xa/spl.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
u32 spl_boot_mode(const u32 boot_device)
|
||||
{
|
||||
switch (spl_boot_device()) {
|
||||
case BOOT_DEVICE_MMC1:
|
||||
#ifdef CONFIG_SPL_FAT_SUPPORT
|
||||
return MMCSD_MODE_FS;
|
||||
#else
|
||||
return MMCSD_MODE_RAW;
|
||||
#endif
|
||||
case BOOT_DEVICE_NAND:
|
||||
return 0;
|
||||
default:
|
||||
puts("spl: error: unsupported device\n");
|
||||
hang();
|
||||
}
|
||||
}
|
||||
128
u-boot/arch/arm/cpu/armv7/ls102xa/timer.c
Normal file
128
u-boot/arch/arm/cpu/armv7/ls102xa/timer.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <div64.h>
|
||||
#include <asm/arch/immap_ls102xa.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* This function is intended for SHORT delays only.
|
||||
* It will overflow at around 10 seconds @ 400MHz,
|
||||
* or 20 seconds @ 200MHz.
|
||||
*/
|
||||
unsigned long usec2ticks(unsigned long usec)
|
||||
{
|
||||
ulong ticks;
|
||||
|
||||
if (usec < 1000)
|
||||
ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000;
|
||||
else
|
||||
ticks = ((usec / 10) * (get_tbclk() / 100000));
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
||||
static inline unsigned long long tick_to_time(unsigned long long tick)
|
||||
{
|
||||
unsigned long freq;
|
||||
|
||||
asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq));
|
||||
|
||||
tick *= CONFIG_SYS_HZ;
|
||||
do_div(tick, freq);
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
||||
static inline unsigned long long us_to_tick(unsigned long long usec)
|
||||
{
|
||||
unsigned long freq;
|
||||
|
||||
asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq));
|
||||
|
||||
usec = usec * freq + 999999;
|
||||
do_div(usec, 1000000);
|
||||
|
||||
return usec;
|
||||
}
|
||||
|
||||
int timer_init(void)
|
||||
{
|
||||
struct sctr_regs *sctr = (struct sctr_regs *)SCTR_BASE_ADDR;
|
||||
unsigned long ctrl, freq;
|
||||
unsigned long long val;
|
||||
|
||||
/* Enable System Counter */
|
||||
writel(SYS_COUNTER_CTRL_ENABLE, &sctr->cntcr);
|
||||
|
||||
freq = GENERIC_TIMER_CLK;
|
||||
asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
|
||||
|
||||
/* Set PL1 Physical Timer Ctrl */
|
||||
ctrl = ARCH_TIMER_CTRL_ENABLE;
|
||||
asm("mcr p15, 0, %0, c14, c2, 1" : : "r" (ctrl));
|
||||
|
||||
/* Set PL1 Physical Comp Value */
|
||||
val = TIMER_COMP_VAL;
|
||||
asm("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
|
||||
|
||||
gd->arch.tbl = 0;
|
||||
gd->arch.tbu = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long long get_ticks(void)
|
||||
{
|
||||
unsigned long long now;
|
||||
|
||||
asm("mrrc p15, 0, %Q0, %R0, c14" : "=r" (now));
|
||||
|
||||
gd->arch.tbl = (unsigned long)(now & 0xffffffff);
|
||||
gd->arch.tbu = (unsigned long)(now >> 32);
|
||||
|
||||
return now;
|
||||
}
|
||||
|
||||
unsigned long get_timer_masked(void)
|
||||
{
|
||||
return tick_to_time(get_ticks());
|
||||
}
|
||||
|
||||
unsigned long get_timer(ulong base)
|
||||
{
|
||||
return get_timer_masked() - base;
|
||||
}
|
||||
|
||||
/* delay x useconds and preserve advance timstamp value */
|
||||
void __udelay(unsigned long usec)
|
||||
{
|
||||
unsigned long long start;
|
||||
unsigned long tmo;
|
||||
|
||||
start = get_ticks(); /* get current timestamp */
|
||||
tmo = us_to_tick(usec); /* convert usecs to ticks */
|
||||
|
||||
while ((get_ticks() - start) < tmo)
|
||||
; /* loop till time has passed */
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is derived from PowerPC code (timebase clock frequency).
|
||||
* On ARM it returns the number of timer ticks per second.
|
||||
*/
|
||||
unsigned long get_tbclk(void)
|
||||
{
|
||||
unsigned long freq;
|
||||
|
||||
asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (freq));
|
||||
|
||||
return freq;
|
||||
}
|
||||
Reference in New Issue
Block a user