GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
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
|
||||
select SYS_FSL_ERRATUM_A009007
|
||||
select SYS_FSL_ERRATUM_A009008
|
||||
select SYS_FSL_ERRATUM_A009663
|
||||
select SYS_FSL_ERRATUM_A009798
|
||||
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 FSL_PCIE_COMPAT
|
||||
string "PCIe compatible of Kernel DT"
|
||||
depends on PCIE_LAYERSCAPE
|
||||
default "fsl,ls1021a-pcie" if ARCH_LS1021A
|
||||
help
|
||||
This compatible is used to find pci controller node in Kernel DT
|
||||
to complete fixup.
|
||||
|
||||
config LS1_DEEP_SLEEP
|
||||
bool "Deep sleep"
|
||||
depends on ARCH_LS1021A
|
||||
|
||||
config MAX_CPUS
|
||||
int "Maximum number of CPUs permitted for LS102xA"
|
||||
depends on ARCH_LS1021A
|
||||
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"
|
||||
depends on ARCH_LS1021A
|
||||
default 8
|
||||
|
||||
config SYS_FSL_ERRATUM_A008407
|
||||
bool
|
||||
|
||||
endmenu
|
||||
@@ -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
|
||||
@@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#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);
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,393 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <vsprintf.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;
|
||||
|
||||
#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(bd_t *bis)
|
||||
{
|
||||
return fsl_esdhc_mmc_init(bis);
|
||||
}
|
||||
#endif
|
||||
|
||||
int cpu_eth_init(bd_t *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;
|
||||
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.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;
|
||||
}
|
||||
|
||||
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),
|
||||
strlen(phy_string_for_interface(
|
||||
PHY_INTERFACE_MODE_RGMII_ID)) + 1,
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 __attribute__((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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,241 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2015 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <time.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 = 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;
|
||||
}
|
||||
Reference in New Issue
Block a user