1
0
Fork 0

Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq

utp
Tom Rini 2015-02-25 18:14:18 -05:00
commit 1606b34aa5
67 changed files with 2404 additions and 334 deletions

View File

@ -123,7 +123,9 @@ config FIT_SIGNATURE
select RSA
help
This option enables signature verification of FIT uImages,
using a hash signed and verified using RSA.
using a hash signed and verified using RSA. If
CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
hashing is available using hardware, RSA library will use it.
See doc/uImage.FIT/signature.txt for more details.
config SYS_EXTRA_OPTIONS

23
README
View File

@ -3152,8 +3152,18 @@ CBFS (Coreboot Filesystem) support
Enable the hash verify command (hash -v). This adds to code
size a little.
CONFIG_SHA1 - support SHA1 hashing
CONFIG_SHA256 - support SHA256 hashing
CONFIG_SHA1 - This option enables support of hashing using SHA1
algorithm. The hash is calculated in software.
CONFIG_SHA256 - This option enables support of hashing using
SHA256 algorithm. The hash is calculated in software.
CONFIG_SHA_HW_ACCEL - This option enables hardware acceleration
for SHA1/SHA256 hashing.
This affects the 'hash' command and also the
hash_lookup_algo() function.
CONFIG_SHA_PROG_HW_ACCEL - This option enables
hardware-acceleration for SHA1/SHA256 progressive hashing.
Data can be streamed in a block at a time and the hashing
is performed in hardware.
Note: There is also a sha1sum command, which should perhaps
be deprecated in favour of 'hash sha1'.
@ -3447,8 +3457,10 @@ FIT uImage format:
CONFIG_FIT_SIGNATURE
This option enables signature verification of FIT uImages,
using a hash signed and verified using RSA. See
doc/uImage.FIT/signature.txt for more details.
using a hash signed and verified using RSA. If
CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
hashing is available using hardware, RSA library will use it.
See doc/uImage.FIT/signature.txt for more details.
WARNING: When relying on signed FIT images with required
signature check the legacy image format is default
@ -4916,6 +4928,9 @@ Low Level (hardware related) configuration options:
- CONFIG_FSL_DDR_INTERACTIVE
Enable interactive DDR debugging. See doc/README.fsl-ddr.
- CONFIG_FSL_DDR_SYNC_REFRESH
Enable sync of refresh for multiple controllers.
- CONFIG_SYS_83XX_DDR_USES_CS0
Only for 83xx systems. If specified, then DDR should
be configured using CS0 and CS1 instead of CS2 and CS3.

View File

@ -8,14 +8,214 @@
#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 "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 */
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
@ -78,16 +278,6 @@ int print_cpuinfo(void)
}
#endif
void enable_caches(void)
{
#ifndef CONFIG_SYS_ICACHE_OFF
icache_enable();
#endif
#ifndef CONFIG_SYS_DCACHE_OFF
dcache_enable();
#endif
}
#ifdef CONFIG_FSL_ESDHC
int cpu_mmc_init(bd_t *bis)
{
@ -107,6 +297,27 @@ int cpu_eth_init(bd_t *bis)
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);
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

View File

@ -155,3 +155,9 @@ ENTRY(__asm_invalidate_icache_all)
isb sy
ret
ENDPROC(__asm_invalidate_icache_all)
ENTRY(__asm_flush_l3_cache)
mov x0, #0 /* return status as success */
ret
ENDPROC(__asm_flush_l3_cache)
.weak __asm_flush_l3_cache

View File

@ -73,17 +73,21 @@ void invalidate_dcache_all(void)
__asm_invalidate_dcache_all();
}
void __weak flush_l3_cache(void)
{
}
/*
* Performs a clean & invalidation of the entire data cache at all levels
* Performs a clean & invalidation of the entire data cache at all levels.
* This function needs to be inline to avoid using stack.
* __asm_flush_l3_cache return status of timeout
*/
void flush_dcache_all(void)
inline void flush_dcache_all(void)
{
int ret;
__asm_flush_dcache_all();
flush_l3_cache();
ret = __asm_flush_l3_cache();
if (ret)
debug("flushing dcache returns 0x%x\n", ret);
else
debug("flushing dcache successfully.\n");
}
/*

View File

@ -10,10 +10,10 @@
#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
#include <fsl-mc/fsl_mc.h>
#include "cpu.h"
#include "mp.h"
#include "speed.h"
#include <fsl_mc.h>
DECLARE_GLOBAL_DATA_PTR;
@ -150,7 +150,7 @@ static inline void final_mmu_setup(void)
* set level 2 table 0 to cache-inhibit, covering 0 to 1GB
*/
section_l1t0 = 0;
section_l1t1 = BLOCK_SIZE_L0;
section_l1t1 = BLOCK_SIZE_L0 | PMD_SECT_OUTER_SHARE;
section_l2 = 0;
for (i = 0; i < 512; i++) {
set_pgtable_section(level1_table_0, i, section_l1t0,
@ -168,10 +168,10 @@ static inline void final_mmu_setup(void)
(u64)level2_table_0 | PMD_TYPE_TABLE;
level1_table_0[2] =
0x80000000 | PMD_SECT_AF | PMD_TYPE_SECT |
PMD_ATTRINDX(MT_NORMAL);
PMD_SECT_OUTER_SHARE | PMD_ATTRINDX(MT_NORMAL);
level1_table_0[3] =
0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT |
PMD_ATTRINDX(MT_NORMAL);
PMD_SECT_OUTER_SHARE | PMD_ATTRINDX(MT_NORMAL);
/* Rewrite table to enable cache */
set_pgtable_section(level2_table_0,
@ -242,59 +242,6 @@ int arch_cpu_init(void)
return 0;
}
/*
* flush_l3_cache
* Dickens L3 cache can be flushed by transitioning from FAM to SFONLY power
* state, by writing to HP-F P-state request register.
* Fixme: This function should moved to a common file if other SoCs also use
* the same Dickens.
*/
#define HNF0_PSTATE_REQ 0x04200010
#define HNF1_PSTATE_REQ 0x04210010
#define HNF2_PSTATE_REQ 0x04220010
#define HNF3_PSTATE_REQ 0x04230010
#define HNF4_PSTATE_REQ 0x04240010
#define HNF5_PSTATE_REQ 0x04250010
#define HNF6_PSTATE_REQ 0x04260010
#define HNF7_PSTATE_REQ 0x04270010
#define HNFPSTAT_MASK (0xFFFFFFFFFFFFFFFC)
#define HNFPSTAT_FAM 0x3
#define HNFPSTAT_SFONLY 0x01
static void hnf_pstate_req(u64 *ptr, u64 state)
{
int timeout = 1000;
out_le64(ptr, (in_le64(ptr) & HNFPSTAT_MASK) | (state & 0x3));
ptr++;
/* checking if the transition is completed */
while (timeout > 0) {
if (((in_le64(ptr) & 0x0c) >> 2) == (state & 0x3))
break;
udelay(100);
timeout--;
}
}
void flush_l3_cache(void)
{
hnf_pstate_req((u64 *)HNF0_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF1_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF2_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF3_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF4_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF5_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF6_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF7_PSTATE_REQ, HNFPSTAT_SFONLY);
hnf_pstate_req((u64 *)HNF0_PSTATE_REQ, HNFPSTAT_FAM);
hnf_pstate_req((u64 *)HNF1_PSTATE_REQ, HNFPSTAT_FAM);
hnf_pstate_req((u64 *)HNF2_PSTATE_REQ, HNFPSTAT_FAM);
hnf_pstate_req((u64 *)HNF3_PSTATE_REQ, HNFPSTAT_FAM);
hnf_pstate_req((u64 *)HNF4_PSTATE_REQ, HNFPSTAT_FAM);
hnf_pstate_req((u64 *)HNF5_PSTATE_REQ, HNFPSTAT_FAM);
hnf_pstate_req((u64 *)HNF6_PSTATE_REQ, HNFPSTAT_FAM);
hnf_pstate_req((u64 *)HNF7_PSTATE_REQ, HNFPSTAT_FAM);
}
/*
* This function is called from lib/board.c.
* It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
@ -420,6 +367,7 @@ int print_cpuinfo(void)
printf("\n Bus: %-4s MHz ",
strmhz(buf, sysinfo.freq_systembus));
printf("DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus));
printf(" DP-DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2));
puts("\n");
return 0;

View File

@ -16,7 +16,7 @@ void ft_fixup_cpu(void *blob)
__maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
fdt32_t *reg;
int addr_cells;
u64 val;
u64 val, core_id;
size_t *boot_code_size = &(__secondary_boot_code_size);
off = fdt_path_offset(blob, "/cpus");
@ -29,15 +29,20 @@ void ft_fixup_cpu(void *blob)
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
while (off != -FDT_ERR_NOTFOUND) {
reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
core_id = of_read_number(reg, addr_cells);
if (reg) {
val = spin_tbl_addr;
val += id_to_core(of_read_number(reg, addr_cells))
* SPIN_TABLE_ELEM_SIZE;
val = cpu_to_fdt64(val);
fdt_setprop_string(blob, off, "enable-method",
"spin-table");
fdt_setprop(blob, off, "cpu-release-addr",
&val, sizeof(val));
if (core_id == 0 || (is_core_online(core_id))) {
val = spin_tbl_addr;
val += id_to_core(core_id) *
SPIN_TABLE_ELEM_SIZE;
val = cpu_to_fdt64(val);
fdt_setprop_string(blob, off, "enable-method",
"spin-table");
fdt_setprop(blob, off, "cpu-release-addr",
&val, sizeof(val));
} else {
debug("skipping offline core\n");
}
} else {
puts("Warning: found cpu node without reg property\n");
}
@ -55,4 +60,9 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#ifdef CONFIG_MP
ft_fixup_cpu(blob);
#endif
#ifdef CONFIG_SYS_NS16550
do_fixup_by_compat_u32(blob, "ns16550",
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
#endif
}

View File

@ -42,10 +42,142 @@ ENTRY(lowlevel_init)
ldr x0, =secondary_boot_func
blr x0
2:
#ifdef CONFIG_FSL_TZPC_BP147
/* Set Non Secure access for all devices protected via TZPC */
ldr x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
orr w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
str w0, [x1]
isb
dsb sy
#endif
#ifdef CONFIG_FSL_TZASC_400
/* Set TZASC so that:
* a. We use only Region0 whose global secure write/read is EN
* b. We use only Region0 whose NSAID write/read is EN
*
* NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
* placeholders.
*/
ldr x1, =TZASC_GATE_KEEPER(0)
ldr x0, [x1] /* Filter 0 Gate Keeper Register */
orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
str x0, [x1]
ldr x1, =TZASC_GATE_KEEPER(1)
ldr x0, [x1] /* Filter 0 Gate Keeper Register */
orr x0, x0, #1 << 0 /* Set open_request for Filter 0 */
str x0, [x1]
ldr x1, =TZASC_REGION_ATTRIBUTES_0(0)
ldr x0, [x1] /* Region-0 Attributes Register */
orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
str x0, [x1]
ldr x1, =TZASC_REGION_ATTRIBUTES_0(1)
ldr x0, [x1] /* Region-1 Attributes Register */
orr x0, x0, #1 << 31 /* Set Sec global write en, Bit[31] */
orr x0, x0, #1 << 30 /* Set Sec global read en, Bit[30] */
str x0, [x1]
ldr x1, =TZASC_REGION_ID_ACCESS_0(0)
ldr w0, [x1] /* Region-0 Access Register */
mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
str w0, [x1]
ldr x1, =TZASC_REGION_ID_ACCESS_0(1)
ldr w0, [x1] /* Region-1 Attributes Register */
mov w0, #0xFFFFFFFF /* Set nsaid_wr_en and nsaid_rd_en */
str w0, [x1]
isb
dsb sy
#endif
mov lr, x29 /* Restore LR */
ret
ENDPROC(lowlevel_init)
hnf_pstate_poll:
/* x0 has the desired status, return 0 for success, 1 for timeout
* clobber x1, x2, x3, x4, x6, x7
*/
mov x1, x0
mov x7, #0 /* flag for timeout */
mrs x3, cntpct_el0 /* read timer */
add x3, x3, #1200 /* timeout after 100 microseconds */
mov x0, #0x18
movk x0, #0x420, lsl #16 /* HNF0_PSTATE_STATUS */
mov w6, #8 /* HN-F node count */
1:
ldr x2, [x0]
cmp x2, x1 /* check status */
b.eq 2f
mrs x4, cntpct_el0
cmp x4, x3
b.ls 1b
mov x7, #1 /* timeout */
b 3f
2:
add x0, x0, #0x10000 /* move to next node */
subs w6, w6, #1
cbnz w6, 1b
3:
mov x0, x7
ret
hnf_set_pstate:
/* x0 has the desired state, clobber x1, x2, x6 */
mov x1, x0
/* power state to SFONLY */
mov w6, #8 /* HN-F node count */
mov x0, #0x10
movk x0, #0x420, lsl #16 /* HNF0_PSTATE_REQ */
1: /* set pstate to sfonly */
ldr x2, [x0]
and x2, x2, #0xfffffffffffffffc /* & HNFPSTAT_MASK */
orr x2, x2, x1
str x2, [x0]
add x0, x0, #0x10000 /* move to next node */
subs w6, w6, #1
cbnz w6, 1b
ret
ENTRY(__asm_flush_l3_cache)
/*
* Return status in x0
* success 0
* tmeout 1 for setting SFONLY, 2 for FAM, 3 for both
*/
mov x29, lr
mov x8, #0
dsb sy
mov x0, #0x1 /* HNFPSTAT_SFONLY */
bl hnf_set_pstate
mov x0, #0x4 /* SFONLY status */
bl hnf_pstate_poll
cbz x0, 1f
mov x8, #1 /* timeout */
1:
dsb sy
mov x0, #0x3 /* HNFPSTAT_FAM */
bl hnf_set_pstate
mov x0, #0xc /* FAM status */
bl hnf_pstate_poll
cbz x0, 1f
add x8, x8, #0x2
1:
mov x0, x8
mov lr, x29
ret
ENDPROC(__asm_flush_l3_cache)
/* Keep literals not used by the secondary boot code outside it */
.ltorg

View File

@ -83,6 +83,14 @@ int is_core_valid(unsigned int core)
return !!((1 << core) & cpu_mask());
}
int is_core_online(u64 cpu_id)
{
u64 *table;
int pos = id_to_core(cpu_id);
table = (u64 *)get_spin_tbl_addr() + pos * WORDS_PER_SPIN_TABLE_ENTRY;
return table[SPIN_TABLE_ELEM_STATUS_IDX] == 1;
}
int cpu_reset(int nr)
{
puts("Feature is not implemented.\n");

View File

@ -32,5 +32,6 @@ int fsl_lsch3_wake_seconday_cores(void);
void *get_spin_tbl_addr(void);
phys_addr_t determine_mp_bootpg(void);
void secondary_boot_func(void);
int is_core_online(u64 cpu_id);
#endif
#endif /* _FSL_CH3_MP_H */

View File

@ -77,8 +77,10 @@ void get_sys_info(struct sys_info *sys_info)
sys_info->freq_systembus = sysclk;
#ifdef CONFIG_DDR_CLK_FREQ
sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
sys_info->freq_ddrbus2 = CONFIG_DDR_CLK_FREQ;
#else
sys_info->freq_ddrbus = sysclk;
sys_info->freq_ddrbus2 = sysclk;
#endif
sys_info->freq_systembus *= (in_le32(&gur->rcwsr[0]) >>
@ -87,6 +89,9 @@ void get_sys_info(struct sys_info *sys_info)
sys_info->freq_ddrbus *= (in_le32(&gur->rcwsr[0]) >>
FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) &
FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK;
sys_info->freq_ddrbus2 *= (in_le32(&gur->rcwsr[0]) >>
FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT) &
FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK;
for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
/*
@ -129,7 +134,7 @@ int get_clocks(void)
gd->cpu_clk = sys_info.freq_processor[0];
gd->bus_clk = sys_info.freq_systembus;
gd->mem_clk = sys_info.freq_ddrbus;
gd->arch.mem2_clk = sys_info.freq_ddrbus2;
#if defined(CONFIG_FSL_ESDHC)
gd->arch.sdhc_clk = gd->bus_clk / 2;
#endif /* defined(CONFIG_FSL_ESDHC) */
@ -156,11 +161,18 @@ ulong get_bus_freq(ulong dummy)
* get_ddr_freq
* return ddr bus freq in Hz
*********************************************/
ulong get_ddr_freq(ulong dummy)
ulong get_ddr_freq(ulong ctrl_num)
{
if (!gd->mem_clk)
get_clocks();
/*
* DDR controller 0 & 1 are on memory complex 0
* DDR controler 2 is on memory complext 1
*/
if (ctrl_num >= 2)
return gd->arch.mem2_clk;
return gd->mem_clk;
}

View File

@ -30,11 +30,44 @@
#define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \
0x18A0)
#define CONFIG_SYS_FSL_DCSR_DDR_ADDR 0x70012c000ULL
#define CONFIG_SYS_FSL_DCSR_DDR2_ADDR 0x70012d000ULL
#define CONFIG_SYS_FSL_DCSR_DDR3_ADDR 0x700132000ULL
#define CONFIG_SYS_FSL_DCSR_DDR4_ADDR 0x700133000ULL
#define I2C1_BASE_ADDR (CONFIG_SYS_IMMR + 0x01000000)
#define I2C2_BASE_ADDR (CONFIG_SYS_IMMR + 0x01010000)
#define I2C3_BASE_ADDR (CONFIG_SYS_IMMR + 0x01020000)
#define I2C4_BASE_ADDR (CONFIG_SYS_IMMR + 0x01030000)
/* TZ Protection Controller Definitions */
#define TZPC_BASE 0x02200000
#define TZPCR0SIZE_BASE (TZPC_BASE)
#define TZPCDECPROT_0_STAT_BASE (TZPC_BASE + 0x800)
#define TZPCDECPROT_0_SET_BASE (TZPC_BASE + 0x804)
#define TZPCDECPROT_0_CLR_BASE (TZPC_BASE + 0x808)
#define TZPCDECPROT_1_STAT_BASE (TZPC_BASE + 0x80C)
#define TZPCDECPROT_1_SET_BASE (TZPC_BASE + 0x810)
#define TZPCDECPROT_1_CLR_BASE (TZPC_BASE + 0x814)
#define TZPCDECPROT_2_STAT_BASE (TZPC_BASE + 0x818)
#define TZPCDECPROT_2_SET_BASE (TZPC_BASE + 0x81C)
#define TZPCDECPROT_2_CLR_BASE (TZPC_BASE + 0x820)
/* TZ Address Space Controller Definitions */
#define TZASC1_BASE 0x01100000 /* as per CCSR map. */
#define TZASC2_BASE 0x01110000 /* as per CCSR map. */
#define TZASC3_BASE 0x01120000 /* as per CCSR map. */
#define TZASC4_BASE 0x01130000 /* as per CCSR map. */
#define TZASC_BUILD_CONFIG_REG(x) ((TZASC1_BASE + (x * 0x10000)))
#define TZASC_ACTION_REG(x) ((TZASC1_BASE + (x * 0x10000)) + 0x004)
#define TZASC_GATE_KEEPER(x) ((TZASC1_BASE + (x * 0x10000)) + 0x008)
#define TZASC_REGION_BASE_LOW_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x100)
#define TZASC_REGION_BASE_HIGH_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x104)
#define TZASC_REGION_TOP_LOW_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x108)
#define TZASC_REGION_TOP_HIGH_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x10C)
#define TZASC_REGION_ATTRIBUTES_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x110)
#define TZASC_REGION_ID_ACCESS_0(x) ((TZASC1_BASE + (x * 0x10000)) + 0x114)
/* Generic Interrupt Controller Definitions */
#define GICD_BASE 0x06000000
#define GICR_BASE 0x06100000
@ -68,4 +101,9 @@
#error SoC not defined
#endif
#ifdef CONFIG_LS2085A
#define CONFIG_SYS_FSL_ERRATUM_A008336
#define CONFIG_SYS_FSL_ERRATUM_A008514
#endif
#endif /* _ASM_ARMV8_FSL_LSCH3_CONFIG_ */

View File

@ -15,6 +15,7 @@ struct sys_info {
unsigned long freq_processor[CONFIG_MAX_CPUS];
unsigned long freq_systembus;
unsigned long freq_ddrbus;
unsigned long freq_ddrbus2;
unsigned long freq_localbus;
unsigned long freq_qe;
#ifdef CONFIG_SYS_DPAA_FMAN
@ -60,6 +61,8 @@ struct ccsr_gur {
#define FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK 0x1f
#define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT 10
#define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK 0x3f
#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT 18
#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK 0x3f
u8 res_180[0x200-0x180];
u32 scratchrw[32]; /* Scratch Read/Write */
u8 res_280[0x300-0x280];

View File

@ -36,6 +36,7 @@
#define CONFIG_SYS_LS102XA_USB1_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_LS102XA_USB1_OFFSET)
#define CONFIG_SYS_FSL_SEC_OFFSET 0x00700000
#define CONFIG_SYS_LS102XA_USB1_OFFSET 0x07600000
#define CONFIG_SYS_TSEC1_OFFSET 0x01d10000
#define CONFIG_SYS_TSEC2_OFFSET 0x01d50000
@ -61,6 +62,20 @@
#define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_IMMR + 0x2400000)
#define CONFIG_SYS_PCIE2_ADDR (CONFIG_SYS_IMMR + 0x2500000)
#define CONFIG_SYS_PCIE1_PHYS_BASE 0x4000000000ULL
#define CONFIG_SYS_PCIE2_PHYS_BASE 0x4800000000ULL
#define CONFIG_SYS_PCIE1_VIRT_ADDR 0x24000000UL
#define CONFIG_SYS_PCIE2_VIRT_ADDR 0x34000000UL
#define CONFIG_SYS_PCIE_MMAP_SIZE (192 * 1024 * 1024) /* 192M */
/*
* TLB will map VIRT_ADDR to (PHYS_BASE + VIRT_ADDR)
* So 40bit PCIe PHY addr can directly be converted to a 32bit virtual addr.
*/
#define CONFIG_SYS_PCIE1_PHYS_ADDR (CONFIG_SYS_PCIE1_PHYS_BASE + \
CONFIG_SYS_PCIE1_VIRT_ADDR)
#define CONFIG_SYS_PCIE2_PHYS_ADDR (CONFIG_SYS_PCIE2_PHYS_BASE + \
CONFIG_SYS_PCIE2_VIRT_ADDR)
#ifdef CONFIG_DDR_SPD
#define CONFIG_SYS_FSL_DDR_BE
#define CONFIG_VERY_BIG_RAM

View File

@ -37,6 +37,43 @@
#define DCFG_DCSR_PORCR1 0
/*
* Define default values for some CCSR macros to make header files cleaner
*
* To completely disable CCSR relocation in a board header file, define
* CONFIG_SYS_CCSR_DO_NOT_RELOCATE. This will force CONFIG_SYS_CCSRBAR_PHYS
* to a value that is the same as CONFIG_SYS_CCSRBAR.
*/
#ifdef CONFIG_SYS_CCSRBAR_PHYS
#error "Do not define CONFIG_SYS_CCSRBAR_PHYS directly."
#endif
#ifdef CONFIG_SYS_CCSR_DO_NOT_RELOCATE
#undef CONFIG_SYS_CCSRBAR_PHYS_HIGH
#undef CONFIG_SYS_CCSRBAR_PHYS_LOW
#define CONFIG_SYS_CCSRBAR_PHYS_HIGH 0
#endif
#ifndef CONFIG_SYS_CCSRBAR
#define CONFIG_SYS_CCSRBAR CONFIG_SYS_IMMR
#endif
#ifndef CONFIG_SYS_CCSRBAR_PHYS_HIGH
#ifdef CONFIG_PHYS_64BIT
#define CONFIG_SYS_CCSRBAR_PHYS_HIGH 0xf
#else
#define CONFIG_SYS_CCSRBAR_PHYS_HIGH 0
#endif
#endif
#ifndef CONFIG_SYS_CCSRBAR_PHYS_LOW
#define CONFIG_SYS_CCSRBAR_PHYS_LOW CONFIG_SYS_IMMR
#endif
#define CONFIG_SYS_CCSRBAR_PHYS ((CONFIG_SYS_CCSRBAR_PHYS_HIGH * 1ull) << 32 | \
CONFIG_SYS_CCSRBAR_PHYS_LOW)
struct sys_info {
unsigned long freq_processor[CONFIG_MAX_CPUS];
unsigned long freq_systembus;
@ -133,8 +170,7 @@ struct ccsr_scfg {
u32 pex1rdmmsgrqsr;
u32 pex2rdmmsgrqsr;
u32 spimsiclrcr;
u32 pex1mscportsr;
u32 pex2mscportsr;
u32 pexmscportsr[2];
u32 pex2pmwrcr;
u32 resv5[24];
u32 mac1_streamid;

View File

@ -7,11 +7,68 @@
#ifndef __FSL_LS102XA_STREAM_ID_H_
#define __FSL_LS102XA_STREAM_ID_H_
#include <fsl_sec.h>
#define SET_LIODN_ENTRY_1(name, idA, off, compatoff) \
{ .compat = name, \
.id = { idA }, .num_ids = 1, \
.reg_offset = off + CONFIG_SYS_IMMR, \
.compat_offset = compatoff + CONFIG_SYS_CCSRBAR_PHYS, \
}
#define SET_LIODN_ENTRY_2(name, idA, idB, off, compatoff) \
{ .compat = name, \
.id = { idA, idB }, .num_ids = 2, \
.reg_offset = off + CONFIG_SYS_IMMR, \
.compat_offset = compatoff + CONFIG_SYS_CCSRBAR_PHYS, \
}
/*
* handle both old and new versioned SEC properties:
* "fsl,secX.Y" became "fsl,sec-vX.Y" during development
*/
#define SET_SEC_JR_LIODN_ENTRY(jrnum, liodnA, liodnB) \
SET_LIODN_ENTRY_2("fsl,sec4.0-job-ring", liodnA, liodnB, \
offsetof(ccsr_sec_t, jrliodnr[jrnum].ls) + \
CONFIG_SYS_FSL_SEC_OFFSET, \
CONFIG_SYS_FSL_SEC_OFFSET + 0x1000 + 0x1000 * jrnum), \
SET_LIODN_ENTRY_2("fsl,sec-v4.0-job-ring", liodnA, liodnB,\
offsetof(ccsr_sec_t, jrliodnr[jrnum].ls) + \
CONFIG_SYS_FSL_SEC_OFFSET, \
CONFIG_SYS_FSL_SEC_OFFSET + 0x1000 + 0x1000 * jrnum)
/* This is a bit evil since we treat rtic param as both a string & hex value */
#define SET_SEC_RTIC_LIODN_ENTRY(rtic, liodnA) \
SET_LIODN_ENTRY_1("fsl,sec4.0-rtic-memory", \
liodnA, \
offsetof(ccsr_sec_t, rticliodnr[0x##rtic-0xa].ls) + \
CONFIG_SYS_FSL_SEC_OFFSET, \
CONFIG_SYS_FSL_SEC_OFFSET + 0x6100 + 0x20 * (0x##rtic-0xa)), \
SET_LIODN_ENTRY_1("fsl,sec-v4.0-rtic-memory", \
liodnA, \
offsetof(ccsr_sec_t, rticliodnr[0x##rtic-0xa].ls) + \
CONFIG_SYS_FSL_SEC_OFFSET, \
CONFIG_SYS_FSL_SEC_OFFSET + 0x6100 + 0x20 * (0x##rtic-0xa))
#define SET_SEC_DECO_LIODN_ENTRY(num, liodnA, liodnB) \
SET_LIODN_ENTRY_2(NULL, liodnA, liodnB, \
offsetof(ccsr_sec_t, decoliodnr[num].ls) + \
CONFIG_SYS_FSL_SEC_OFFSET, 0)
struct liodn_id_table {
const char *compat;
u32 id[2];
u8 num_ids;
phys_addr_t compat_offset;
unsigned long reg_offset;
};
struct smmu_stream_id {
uint16_t offset;
uint16_t stream_id;
char dev_name[32];
};
void ls1021x_config_caam_stream_id(struct liodn_id_table *tbl, int size);
void ls102xa_config_smmu_stream_id(struct smmu_stream_id *id, uint32_t num);
#endif

View File

@ -65,7 +65,8 @@
/*
* Section
*/
#define PMD_SECT_S (3 << 8)
#define PMD_SECT_OUTER_SHARE (2 << 8)
#define PMD_SECT_INNER_SHARE (3 << 8)
#define PMD_SECT_AF (1 << 10)
#define PMD_SECT_NG (1 << 11)
#define PMD_SECT_PXN (UL(1) << 53)

View File

@ -48,6 +48,9 @@ struct arch_global_data {
#ifdef CONFIG_OMAP
struct omap_boot_parameters omap_boot_params;
#endif
#ifdef CONFIG_FSL_LSCH3
unsigned long mem2_clk;
#endif
};
#include <asm-generic/global_data.h>

View File

@ -70,6 +70,7 @@ void __asm_invalidate_dcache_all(void);
void __asm_flush_dcache_range(u64 start, u64 end);
void __asm_invalidate_tlb_all(void);
void __asm_invalidate_icache_all(void);
int __asm_flush_l3_cache(void);
void armv8_switch_to_el2(void);
void armv8_switch_to_el1(void);

View File

@ -191,7 +191,7 @@ __weak void setup_board_tags(struct tag **in_params) {}
static void do_nonsec_virt_switch(void)
{
smp_kick_all_cpus();
flush_dcache_all(); /* flush cache before swtiching to EL2 */
dcache_disable(); /* flush cache before swtiching to EL2 */
armv8_switch_to_el2();
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
armv8_switch_to_el1();

View File

@ -16,3 +16,18 @@ void ls102xa_config_smmu_stream_id(struct smmu_stream_id *id, uint32_t num)
for (i = 0; i < num; i++)
out_be32(scfg + id[i].offset, id[i].stream_id);
}
void ls1021x_config_caam_stream_id(struct liodn_id_table *tbl, int size)
{
int i;
u32 liodn;
for (i = 0; i < size; i++) {
if (tbl[i].num_ids == 2)
liodn = (tbl[i].id[0] << 16) | tbl[i].id[1];
else
liodn = tbl[i].id[0];
out_le32((uint32_t *)(tbl[i].reg_offset), liodn);
}
}

View File

@ -509,6 +509,25 @@ static struct csu_ns_dev ns_dev[] = {
};
#endif
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" },
@ -541,6 +560,8 @@ int board_init(void)
config_serdes_mux();
#endif
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));

View File

@ -401,6 +401,25 @@ static struct csu_ns_dev ns_dev[] = {
};
#endif
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" },
@ -427,6 +446,8 @@ int board_init(void)
#endif
#endif
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));

View File

@ -77,6 +77,7 @@ found:
popts->data_bus_width = 1;
popts->otf_burst_chop_en = 0;
popts->burst_length = DDR_BL8;
popts->bstopre = 0; /* enable auto precharge */
}
/*
* Factors to consider for half-strength driver enable:

View File

@ -12,7 +12,7 @@
#include <asm/io.h>
#include <fdt_support.h>
#include <libfdt.h>
#include <fsl_mc.h>
#include <fsl-mc/fsl_mc.h>
#include <environment.h>
DECLARE_GLOBAL_DATA_PTR;
@ -59,8 +59,15 @@ int timer_init(void)
u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
out_le32(cltbenr, 0x1); /* enable cluster0 timebase */
out_le32(cntcr, 0x1); /* enable clock for timer */
/* Enable timebase for all clusters.
* It is safe to do so even some clusters are not enabled.
*/
out_le32(cltbenr, 0xf);
/* Enable clock for timer
* This is a global setting.
*/
out_le32(cntcr, 0x1);
return 0;
}
@ -91,7 +98,21 @@ void fdt_fixup_board_enet(void *fdt)
{
int offset;
offset = fdt_path_offset(fdt, "/fsl,dprc@0");
offset = fdt_path_offset(fdt, "/fsl-mc");
/*
* TODO: Remove this when backward compatibility
* with old DT node (fsl,dprc@0) is no longer needed.
*/
if (offset < 0)
offset = fdt_path_offset(fdt, "/fsl,dprc@0");
if (offset < 0) {
printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
__func__, offset);
return;
}
if (get_mc_boot_status() == 0)
fdt_status_okay(fdt, offset);
else

View File

@ -90,17 +90,19 @@ static char blob_help_text[] =
"enc src dst len km - Encapsulate and create blob of data\n"
" $len bytes long at address $src and\n"
" store the result at address $dst.\n"
" $km is the 16 byte key modifier\n"
" is also required for generation/use as\n"
" key for cryptographic operation. Key\n"
" modifier should be 16 byte long.\n"
" $km is the address where the key\n"
" modifier is stored.\n"
" The modifier is required for generation\n"
" /use as key for cryptographic operation.\n"
" Key modifier should be 16 byte long.\n"
"blob dec src dst len km - Decapsulate the blob of data at address\n"
" $src and store result of $len byte at\n"
" addr $dst.\n"
" $km is the 16 byte key modifier\n"
" is also required for generation/use as\n"
" key for cryptographic operation. Key\n"
" modifier should be 16 byte long.\n";
" $km is the address where the key\n"
" modifier is stored.\n"
" The modifier is required for generation\n"
" /use as key for cryptographic operation.\n"
" Key modifier should be 16 byte long.\n";
U_BOOT_CMD(
blob, 6, 1, do_blob,

View File

@ -127,11 +127,21 @@ static struct hash_algo hash_algo[] = {
SHA1_SUM_LEN,
hw_sha1,
CHUNKSZ_SHA1,
#ifdef CONFIG_SHA_PROG_HW_ACCEL
hw_sha_init,
hw_sha_update,
hw_sha_finish,
#endif
}, {
"sha256",
SHA256_SUM_LEN,
hw_sha256,
CHUNKSZ_SHA256,
#ifdef CONFIG_SHA_PROG_HW_ACCEL
hw_sha_init,
hw_sha_update,
hw_sha_finish,
#endif
},
#endif
#ifdef CONFIG_SHA1

View File

@ -0,0 +1,25 @@
Freescale ARM64 SoCs like LS2085A have ARM TrustZone components like
TZPC-BP147 (TrustZone Protection Controller) and TZASC-400 (TrustZone
Address Space Controller).
While most of the configuration related programming of these peripherals
is left to a root-of-trust security software layer (running in EL3
privilege mode), but still some configurations of these peripherals
might be required while the bootloader is executing in EL3 privilege
mode. The following sections define how to turn on these features for
LS2085A like SoCs.
TZPC-BP147 (TrustZone Protection Controller)
============================================
- Depends on CONFIG_FSL_TZPC_BP147 configuration flag.
- Separates Secure World and Normal World on-chip RAM (OCRAM) spaces.
- Provides a programming model to set access control policy via the TZPC
TZDECPROT Registers.
TZASC-400 (TrustZone Address Space Controller)
==============================================
- Depends on CONFIG_FSL_TZASC_400 configuration flag.
- Separates Secure World and Normal World external memory spaces for bus masters
such as processors and DMA-equipped peripherals.
- Supports 8 fully programmable address regions, initially inactive at reset,
and one base region, always active, that covers the remaining address space.

View File

@ -11,7 +11,7 @@
#include "desc.h"
#include "jr.h"
int blob_decrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
{
int ret, i = 0;
u32 *desc;
@ -36,7 +36,7 @@ int blob_decrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
return ret;
}
int blob_encrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
{
int ret, i = 0;
u32 *desc;

View File

@ -10,6 +10,9 @@
#include "jobdesc.h"
#include "desc.h"
#include "jr.h"
#include "fsl_hash.h"
#include <hw_sha.h>
#include <asm-generic/errno.h>
#define CRYPTO_MAX_ALG_NAME 80
#define SHA1_DIGEST_SIZE 20
@ -39,6 +42,122 @@ static struct caam_hash_template driver_hash[] = {
},
};
static enum caam_hash_algos get_hash_type(struct hash_algo *algo)
{
if (!strcmp(algo->name, driver_hash[SHA1].name))
return SHA1;
else
return SHA256;
}
/* Create the context for progressive hashing using h/w acceleration.
*
* @ctxp: Pointer to the pointer of the context for hashing
* @caam_algo: Enum for SHA1 or SHA256
* @return 0 if ok, -ENOMEM on error
*/
static int caam_hash_init(void **ctxp, enum caam_hash_algos caam_algo)
{
*ctxp = calloc(1, sizeof(struct sha_ctx));
if (*ctxp == NULL) {
debug("Cannot allocate memory for context\n");
return -ENOMEM;
}
return 0;
}
/*
* Update sg table for progressive hashing using h/w acceleration
*
* The context is freed by this function if an error occurs.
* We support at most 32 Scatter/Gather Entries.
*
* @hash_ctx: Pointer to the context for hashing
* @buf: Pointer to the buffer being hashed
* @size: Size of the buffer being hashed
* @is_last: 1 if this is the last update; 0 otherwise
* @caam_algo: Enum for SHA1 or SHA256
* @return 0 if ok, -EINVAL on error
*/
static int caam_hash_update(void *hash_ctx, const void *buf,
unsigned int size, int is_last,
enum caam_hash_algos caam_algo)
{
uint32_t final = 0;
dma_addr_t addr = virt_to_phys((void *)buf);
struct sha_ctx *ctx = hash_ctx;
if (ctx->sg_num >= MAX_SG_32) {
free(ctx);
return -EINVAL;
}
#ifdef CONFIG_PHYS_64BIT
ctx->sg_tbl[ctx->sg_num].addr_hi = addr >> 32;
#else
ctx->sg_tbl[ctx->sg_num].addr_hi = 0x0;
#endif
ctx->sg_tbl[ctx->sg_num].addr_lo = addr;
sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag,
(size & SG_ENTRY_LENGTH_MASK));
ctx->sg_num++;
if (is_last) {
final = sec_in32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag) |
SG_ENTRY_FINAL_BIT;
sec_out32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag, final);
}
return 0;
}
/*
* Perform progressive hashing on the given buffer and copy hash at
* destination buffer
*
* The context is freed after completion of hash operation.
*
* @hash_ctx: Pointer to the context for hashing
* @dest_buf: Pointer to the destination buffer where hash is to be copied
* @size: Size of the buffer being hashed
* @caam_algo: Enum for SHA1 or SHA256
* @return 0 if ok, -EINVAL on error
*/
static int caam_hash_finish(void *hash_ctx, void *dest_buf,
int size, enum caam_hash_algos caam_algo)
{
uint32_t len = 0;
struct sha_ctx *ctx = hash_ctx;
int i = 0, ret = 0;
if (size < driver_hash[caam_algo].digestsize) {
free(ctx);
return -EINVAL;
}
for (i = 0; i < ctx->sg_num; i++)
len += (sec_in32(&ctx->sg_tbl[i].len_flag) &
SG_ENTRY_LENGTH_MASK);
inline_cnstr_jobdesc_hash(ctx->sha_desc, (uint8_t *)ctx->sg_tbl, len,
ctx->hash,
driver_hash[caam_algo].alg_type,
driver_hash[caam_algo].digestsize,
1);
ret = run_descriptor_jr(ctx->sha_desc);
if (ret)
debug("Error %x\n", ret);
else
memcpy(dest_buf, ctx->hash, sizeof(ctx->hash));
free(ctx);
return ret;
}
int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
unsigned char *pout, enum caam_hash_algos algo)
{
@ -48,7 +167,7 @@ int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
if (!desc) {
debug("Not enough memory for descriptor allocation\n");
return -1;
return -ENOMEM;
}
inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
@ -75,3 +194,20 @@ void hw_sha1(const unsigned char *pbuf, unsigned int buf_len,
if (caam_hash(pbuf, buf_len, pout, SHA1))
printf("CAAM was not setup properly or it is faulty\n");
}
int hw_sha_init(struct hash_algo *algo, void **ctxp)
{
return caam_hash_init(ctxp, get_hash_type(algo));
}
int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
unsigned int size, int is_last)
{
return caam_hash_update(ctx, buf, size, is_last, get_hash_type(algo));
}
int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
int size)
{
return caam_hash_finish(ctx, dest_buf, size, get_hash_type(algo));
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*
*/
#ifndef _SHA_H
#define _SHA_H
#include <fsl_sec.h>
#include <hash.h>
#include "jr.h"
/* We support at most 32 Scatter/Gather Entries.*/
#define MAX_SG_32 32
/*
* Hash context contains the following fields
* @sha_desc: Sha Descriptor
* @sg_num: number of entries in sg table
* @len: total length of buffer
* @sg_tbl: sg entry table
* @hash: index to the hash calculated
*/
struct sha_ctx {
uint32_t sha_desc[64];
uint32_t sg_num;
uint32_t len;
struct sg_entry sg_tbl[MAX_SG_32];
u8 hash[HASH_MAX_DIGEST_SIZE];
};
#endif

View File

@ -222,7 +222,7 @@ step2:
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 20)) << 1;
(get_ddr_freq(ctrl_num) >> 20)) << 1;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);

View File

@ -17,8 +17,6 @@
#include <fsl_immap.h>
#include <asm/io.h>
unsigned int picos_to_mclk(unsigned int picos);
/*
* Determine Rtt value.
*
@ -78,10 +76,11 @@ static inline int fsl_ddr_get_rtt(void)
* 16 for <= 2933MT/s
* 18 for higher
*/
static inline unsigned int compute_cas_write_latency(void)
static inline unsigned int compute_cas_write_latency(
const unsigned int ctrl_num)
{
unsigned int cwl;
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
if (mclk_ps >= 1250)
cwl = 9;
else if (mclk_ps >= 1070)
@ -111,10 +110,11 @@ static inline unsigned int compute_cas_write_latency(void)
* 11 if 0.935ns > tCK >= 0.833ns
* 12 if 0.833ns > tCK >= 0.75ns
*/
static inline unsigned int compute_cas_write_latency(void)
static inline unsigned int compute_cas_write_latency(
const unsigned int ctrl_num)
{
unsigned int cwl;
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
if (mclk_ps >= 2500)
cwl = 5;
@ -287,7 +287,8 @@ static inline int avoid_odt_overlap(const dimm_params_t *dimm_params)
* Avoid writing for DDR I. The new PQ38 DDR controller
* dreams up non-zero default values to be backwards compatible.
*/
static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
static void set_timing_cfg_0(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const dimm_params_t *dimm_params)
{
@ -306,7 +307,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
/* Mode register set cycle time (tMRD). */
unsigned char tmrd_mclk;
#if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#endif
#ifdef CONFIG_SYS_FSL_DDR4
@ -314,15 +315,15 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
trwt_mclk = 2;
twrt_mclk = 1;
act_pd_exit_mclk = picos_to_mclk(txp);
act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
pre_pd_exit_mclk = act_pd_exit_mclk;
/*
* MRS_CYC = max(tMRD, tMOD)
* tMRD = 8nCK, tMOD = max(24nCK, 15ns)
*/
tmrd_mclk = max(24U, picos_to_mclk(15000));
tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000));
#elif defined(CONFIG_SYS_FSL_DDR3)
unsigned int data_rate = get_ddr_freq(0);
unsigned int data_rate = get_ddr_freq(ctrl_num);
int txp;
unsigned int ip_rev;
int odt_overlap;
@ -344,7 +345,8 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
* tMRD = 4nCK (8nCK for RDIMM)
* tMOD = max(12nCK, 15ns)
*/
tmrd_mclk = max((unsigned int)12, picos_to_mclk(15000));
tmrd_mclk = max((unsigned int)12,
picos_to_mclk(ctrl_num, 15000));
} else {
/*
* MRS_CYC = tMRD
@ -388,7 +390,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
taxpd_mclk = 1;
} else {
/* act_pd_exit_mclk = tXARD, see above */
act_pd_exit_mclk = picos_to_mclk(txp);
act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
/* Mode register MR0[A12] is '1' - fast exit */
pre_pd_exit_mclk = act_pd_exit_mclk;
taxpd_mclk = 1;
@ -424,11 +426,12 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
#endif /* !defined(CONFIG_SYS_FSL_DDR1) */
/* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */
static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
unsigned int additive_latency)
static void set_timing_cfg_3(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
unsigned int additive_latency)
{
/* Extended precharge to activate interval (tRP) */
unsigned int ext_pretoact = 0;
@ -447,18 +450,18 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
/* Control Adjust */
unsigned int cntl_adj = 0;
ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4;
ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4;
ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4;
ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4;
ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4;
ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4;
ext_caslat = (2 * cas_latency - 1) >> 4;
ext_add_lat = additive_latency >> 4;
#ifdef CONFIG_SYS_FSL_DDR4
ext_refrec = (picos_to_mclk(common_dimm->trfc1_ps) - 8) >> 4;
ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4;
#else
ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4;
ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4;
/* ext_wrrec only deals with 16 clock and above, or 14 with OTF */
#endif
ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) +
ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) +
(popts->otf_burst_chop_en ? 2 : 0)) >> 4;
ddr->timing_cfg_3 = (0
@ -475,10 +478,11 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */
static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency)
static void set_timing_cfg_1(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency)
{
/* Precharge-to-activate interval (tRP) */
unsigned char pretoact_mclk;
@ -510,9 +514,9 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0};
#endif
pretoact_mclk = picos_to_mclk(common_dimm->trp_ps);
acttopre_mclk = picos_to_mclk(common_dimm->tras_ps);
acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps);
pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps);
acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps);
acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps);
/*
* Translate CAS Latency to a DDR controller field value:
@ -547,19 +551,19 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
#endif
#ifdef CONFIG_SYS_FSL_DDR4
refrec_ctrl = picos_to_mclk(common_dimm->trfc1_ps) - 8;
wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
acttoact_mclk = max(picos_to_mclk(common_dimm->trrds_ps), 4U);
wrtord_mclk = max(2U, picos_to_mclk(2500));
refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8;
wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U);
wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500));
if ((wrrec_mclk < 1) || (wrrec_mclk > 24))
printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
else
wrrec_mclk = wrrec_table[wrrec_mclk - 1];
#else
refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8;
wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps);
wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps);
refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8;
wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps);
wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps);
if ((wrrec_mclk < 1) || (wrrec_mclk > 16))
printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
else
@ -602,11 +606,12 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */
static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
unsigned int additive_latency)
static void set_timing_cfg_2(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
unsigned int additive_latency)
{
/* Additive latency */
unsigned char add_lat_mclk;
@ -623,7 +628,7 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
/* Window for four activates (tFAW) */
unsigned short four_act;
#ifdef CONFIG_SYS_FSL_DDR3
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#endif
/* FIXME add check that this must be less than acttorw_mclk */
@ -641,13 +646,13 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
#elif defined(CONFIG_SYS_FSL_DDR2)
wr_lat = cas_latency - 1;
#else
wr_lat = compute_cas_write_latency();
wr_lat = compute_cas_write_latency(ctrl_num);
#endif
#ifdef CONFIG_SYS_FSL_DDR4
rd_to_pre = picos_to_mclk(7500);
rd_to_pre = picos_to_mclk(ctrl_num, 7500);
#else
rd_to_pre = picos_to_mclk(common_dimm->trtp_ps);
rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps);
#endif
/*
* JEDEC has some min requirements for tRTP
@ -665,19 +670,20 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
wr_data_delay = popts->write_data_delay;
#ifdef CONFIG_SYS_FSL_DDR4
cpo = 0;
cke_pls = max(3U, picos_to_mclk(5000));
cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000));
#elif defined(CONFIG_SYS_FSL_DDR3)
/*
* cke pulse = max(3nCK, 7.5ns) for DDR3-800
* max(3nCK, 5.625ns) for DDR3-1066, 1333
* max(3nCK, 5ns) for DDR3-1600, 1866, 2133
*/
cke_pls = max(3U, picos_to_mclk(mclk_ps > 1870 ? 7500 :
(mclk_ps > 1245 ? 5625 : 5000)));
cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 :
(mclk_ps > 1245 ? 5625 : 5000)));
#else
cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR;
#endif
four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps);
four_act = picos_to_mclk(ctrl_num,
popts->tfaw_window_four_activates_ps);
ddr->timing_cfg_2 = (0
| ((add_lat_mclk & 0xf) << 28)
@ -818,7 +824,8 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */
static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const unsigned int unq_mrs_en)
{
@ -865,7 +872,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
#endif
#if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)
slow = get_ddr_freq(0) < 1249000000;
slow = get_ddr_freq(ctrl_num) < 1249000000;
#endif
if (popts->registered_dimm_en) {
@ -915,7 +922,8 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
#ifdef CONFIG_SYS_FSL_DDR4
/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@ -926,10 +934,10 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
unsigned int wr_crc = 0; /* Disable */
unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */
unsigned int srt = 0; /* self-refresh temerature, normal range */
unsigned int cwl = compute_cas_write_latency() - 9;
unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9;
unsigned int mpr = 0; /* serial */
unsigned int wc_lat;
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
if (popts->rtt_override)
rtt_wr = popts->rtt_wr_override_value;
@ -1002,7 +1010,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
}
#elif defined(CONFIG_SYS_FSL_DDR3)
/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@ -1013,7 +1022,7 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
unsigned int rtt_wr = 0; /* Rtt_WR - dynamic ODT off */
unsigned int srt = 0; /* self-refresh temerature, normal range */
unsigned int asr = 0; /* auto self-refresh disable */
unsigned int cwl = compute_cas_write_latency() - 5;
unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5;
unsigned int pasr = 0; /* partial array self refresh disable */
if (popts->rtt_override)
@ -1077,7 +1086,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
#else /* for DDR2 and DDR1 */
/* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@ -1144,7 +1154,8 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
}
/* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */
static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_mode_10(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
const unsigned int unq_mrs_en)
@ -1152,7 +1163,7 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
int i;
unsigned short esdmode6 = 0; /* Extended SDRAM mode 6 */
unsigned short esdmode7 = 0; /* Extended SDRAM mode 7 */
unsigned int tccdl_min = picos_to_mclk(common_dimm->tccdl_ps);
unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
@ -1196,14 +1207,15 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
#endif
/* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */
static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm)
static void set_ddr_sdram_interval(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm)
{
unsigned int refint; /* Refresh interval */
unsigned int bstopre; /* Precharge interval */
refint = picos_to_mclk(common_dimm->refresh_rate_ps);
refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps);
bstopre = popts->bstopre;
@ -1217,7 +1229,8 @@ static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
#ifdef CONFIG_SYS_FSL_DDR4
/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_mode(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
@ -1292,7 +1305,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
* 1=fast exit DLL on (tXP)
*/
wr_mclk = picos_to_mclk(common_dimm->twr_ps);
wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
if (wr_mclk <= 24) {
wr = wr_table[wr_mclk - 10];
} else {
@ -1387,7 +1400,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
#elif defined(CONFIG_SYS_FSL_DDR3)
/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_mode(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
@ -1466,7 +1480,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
*/
dll_on = 1;
wr_mclk = picos_to_mclk(common_dimm->twr_ps);
wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
if (wr_mclk <= 16) {
wr = wr_table[wr_mclk - 5];
} else {
@ -1582,7 +1596,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
#else /* !CONFIG_SYS_FSL_DDR3 */
/* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
static void set_ddr_sdram_mode(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency,
@ -1654,7 +1669,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
#if defined(CONFIG_SYS_FSL_DDR1)
wr = 0; /* Historical */
#elif defined(CONFIG_SYS_FSL_DDR2)
wr = picos_to_mclk(common_dimm->twr_ps);
wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
#endif
dll_res = 0;
mode = 0;
@ -1842,15 +1857,16 @@ static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr)
debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6);
}
static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr,
const common_timing_params_t *common_dimm)
static void set_timing_cfg_7(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const common_timing_params_t *common_dimm)
{
unsigned int txpr, tcksre, tcksrx;
unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
txpr = max(5U, picos_to_mclk(common_dimm->trfc1_ps + 10000));
tcksre = max(5U, picos_to_mclk(10000));
tcksrx = max(5U, picos_to_mclk(10000));
txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
par_lat = 0;
cs_to_cmd = 0;
@ -1883,14 +1899,15 @@ static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr,
debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7);
}
static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr,
static void set_timing_cfg_8(const unsigned int ctrl_num,
fsl_ddr_cfg_regs_t *ddr,
const memctl_options_t *popts,
const common_timing_params_t *common_dimm,
unsigned int cas_latency)
{
unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
unsigned int acttoact_bg, wrtord_bg, pre_all_rec;
unsigned int tccdl = picos_to_mclk(common_dimm->tccdl_ps);
unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
((ddr->timing_cfg_2 & 0x00040000) >> 14);
@ -1911,11 +1928,11 @@ static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr,
wwt_bg = tccdl - 4;
} else {
rrt_bg = tccdl - 2;
wwt_bg = tccdl - 4;
wwt_bg = tccdl - 2;
}
acttoact_bg = picos_to_mclk(common_dimm->trrdl_ps);
wrtord_bg = max(4U, picos_to_mclk(7500));
acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps);
wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500));
if (popts->otf_burst_chop_en)
wrtord_bg += 2;
@ -2147,7 +2164,8 @@ check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
}
unsigned int
compute_fsl_memctl_config_regs(const memctl_options_t *popts,
compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
const memctl_options_t *popts,
fsl_ddr_cfg_regs_t *ddr,
const common_timing_params_t *common_dimm,
const dimm_params_t *dimm_params,
@ -2319,14 +2337,14 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
set_ddr_eor(ddr, popts);
#if !defined(CONFIG_SYS_FSL_DDR1)
set_timing_cfg_0(ddr, popts, dimm_params);
set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params);
#endif
set_timing_cfg_3(ddr, popts, common_dimm, cas_latency,
set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency,
additive_latency);
set_timing_cfg_1(ddr, popts, common_dimm, cas_latency);
set_timing_cfg_2(ddr, popts, common_dimm,
cas_latency, additive_latency);
set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency);
set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm,
cas_latency, additive_latency);
set_ddr_cdr1(ddr, popts);
set_ddr_cdr2(ddr, popts);
@ -2338,15 +2356,15 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
if ((ip_rev > 0x40700) && (popts->cswl_override != 0))
ddr->debug[18] = popts->cswl_override;
set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en);
set_ddr_sdram_mode(ddr, popts, common_dimm,
cas_latency, additive_latency, unq_mrs_en);
set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en);
set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en);
set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm,
cas_latency, additive_latency, unq_mrs_en);
set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
#ifdef CONFIG_SYS_FSL_DDR4
set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en);
set_ddr_sdram_mode_10(ddr, popts, common_dimm, unq_mrs_en);
set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
#endif
set_ddr_sdram_interval(ddr, popts, common_dimm);
set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm);
set_ddr_data_init(ddr);
set_ddr_sdram_clk_cntl(ddr, popts);
set_ddr_init_addr(ddr);
@ -2356,8 +2374,8 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
#ifdef CONFIG_SYS_FSL_DDR4
set_ddr_sdram_cfg_3(ddr, popts);
set_timing_cfg_6(ddr);
set_timing_cfg_7(ddr, common_dimm);
set_timing_cfg_8(ddr, popts, common_dimm, cas_latency);
set_timing_cfg_7(ctrl_num, ddr, common_dimm);
set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency);
set_timing_cfg_9(ddr);
set_ddr_dq_mapping(ddr, dimm_params);
#endif
@ -2372,7 +2390,11 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
#ifdef CONFIG_SYS_FSL_DDR_EMU
/* disble DDR training for emulator */
ddr->debug[2] = 0x00000400;
ddr->debug[4] = 0xff800000;
ddr->debug[4] = 0xff800800;
ddr->debug[5] = 0x08000800;
ddr->debug[6] = 0x08000800;
ddr->debug[7] = 0x08000800;
ddr->debug[8] = 0x08000800;
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A004508
if ((ip_rev >= 0x40000) && (ip_rev < 0x40400))

View File

@ -228,10 +228,10 @@ compute_derated_DDR1_CAS_latency(unsigned int mclk_ps)
*
* FIXME: use #define for the retvals
*/
unsigned int
ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const ddr1_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
@ -311,16 +311,16 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
& ~(1 << pdimm->caslat_x_minus_1));
/* Compute CAS latencies below that defined by SPD */
pdimm->caslat_lowest_derated
= compute_derated_DDR1_CAS_latency(get_memory_clk_period_ps());
pdimm->caslat_lowest_derated = compute_derated_DDR1_CAS_latency(
get_memory_clk_period_ps(ctrl_num));
/* Compute timing parameters */
pdimm->trcd_ps = spd->trcd * 250;
pdimm->trp_ps = spd->trp * 250;
pdimm->tras_ps = spd->tras * 1000;
pdimm->twr_ps = mclk_to_picos(3);
pdimm->twtr_ps = mclk_to_picos(1);
pdimm->twr_ps = mclk_to_picos(ctrl_num, 3);
pdimm->twtr_ps = mclk_to_picos(ctrl_num, 1);
pdimm->trfc_ps = compute_trfc_ps_from_spd(0, spd->trfc);
pdimm->trrd_ps = spd->trrd * 250;
@ -335,7 +335,7 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
pdimm->tdh_ps
= convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold);
pdimm->trtp_ps = mclk_to_picos(2); /* By the book. */
pdimm->trtp_ps = mclk_to_picos(ctrl_num, 2); /* By the book. */
pdimm->tdqsq_max_ps = spd->tdqsq * 10;
pdimm->tqhs_ps = spd->tqhs * 10;

View File

@ -211,10 +211,10 @@ compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)
*
* FIXME: use #define for the retvals
*/
unsigned int
ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const ddr2_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
@ -310,8 +310,8 @@ ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
& ~(1 << pdimm->caslat_x_minus_1));
/* Compute CAS latencies below that defined by SPD */
pdimm->caslat_lowest_derated
= compute_derated_DDR2_CAS_latency(get_memory_clk_period_ps());
pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency(
get_memory_clk_period_ps(ctrl_num));
/* Compute timing parameters */
pdimm->trcd_ps = spd->trcd * 250;

View File

@ -83,10 +83,10 @@ compute_ranksize(const ddr3_spd_eeprom_t *spd)
* Writes the results to the dimm_params_t structure pointed by pdimm.
*
*/
unsigned int
ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const ddr3_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
unsigned int mtb_ps;

View File

@ -119,10 +119,10 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
* Writes the results to the dimm_params_t structure pointed by pdimm.
*
*/
unsigned int
ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
unsigned int retval;
int i;

View File

@ -32,24 +32,44 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
u32 temp_sdram_cfg;
u32 total_gb_size_per_controller;
int timeout;
#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
defined(CONFIG_SYS_FSL_ERRATUM_A008514)
u32 *eddrtqcr1;
#endif
switch (ctrl_num) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
defined(CONFIG_SYS_FSL_ERRATUM_A008514)
eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
#endif
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
defined(CONFIG_SYS_FSL_ERRATUM_A008514)
eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
#endif
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
defined(CONFIG_SYS_FSL_ERRATUM_A008514)
eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
#endif
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
defined(CONFIG_SYS_FSL_ERRATUM_A008514)
eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR4_ADDR + 0x800;
#endif
break;
#endif
default:
@ -60,6 +80,20 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
if (step == 2)
goto step2;
#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
#ifdef CONFIG_LS2085A
/* A008336 only applies to general DDR controllers */
if ((ctrl_num == 0) || (ctrl_num == 1))
#endif
ddr_out32(eddrtqcr1, 0x63b30002);
#endif
#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
#ifdef CONFIG_LS2085A
/* A008514 only applies to DP-DDR controler */
if (ctrl_num == 2)
#endif
ddr_out32(eddrtqcr1, 0x63b20002);
#endif
if (regs->ddr_eor)
ddr_out32(&ddr->eor, regs->ddr_eor);
@ -253,7 +287,7 @@ step2:
bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 20)) << 2;
(get_ddr_freq(ctrl_num) >> 20)) << 2;
total_gb_size_per_controller >>= 4; /* shift down to gb size */
debug("total %d GB\n", total_gb_size_per_controller);
debug("Need to wait up to %d * 10ms\n", timeout);

View File

@ -13,7 +13,8 @@
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
static unsigned int
compute_cas_latency(const dimm_params_t *dimm_params,
compute_cas_latency(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
@ -22,7 +23,7 @@ compute_cas_latency(const dimm_params_t *dimm_params,
unsigned int caslat_actual;
unsigned int retry = 16;
unsigned int tmp;
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#ifdef CONFIG_SYS_FSL_DDR3
const unsigned int taamax = 20000;
#else
@ -72,12 +73,13 @@ compute_cas_latency(const dimm_params_t *dimm_params,
}
#else /* for DDR1 and DDR2 */
static unsigned int
compute_cas_latency(const dimm_params_t *dimm_params,
compute_cas_latency(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms)
{
int i;
const unsigned int mclk_ps = get_memory_clk_period_ps();
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
unsigned int lowest_good_caslat;
unsigned int not_ok;
unsigned int temp1, temp2;
@ -212,7 +214,8 @@ compute_cas_latency(const dimm_params_t *dimm_params,
* by dimm_params.
*/
unsigned int
compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
const unsigned int number_of_dimms)
{
@ -442,7 +445,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
printf("ERROR: Mix different RDIMM detected!\n");
/* calculate cas latency for all DDR types */
if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms))
if (compute_cas_latency(ctrl_num, dimm_params,
outpdimm, number_of_dimms))
return 1;
/* Determine if all DIMMs ECC capable. */
@ -518,11 +522,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
#if defined(CONFIG_SYS_FSL_DDR2)
if ((outpdimm->lowest_common_spd_caslat < 4) &&
(picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) {
additive_latency = picos_to_mclk(trcd_ps) -
(picos_to_mclk(ctrl_num, trcd_ps) >
outpdimm->lowest_common_spd_caslat)) {
additive_latency = picos_to_mclk(ctrl_num, trcd_ps) -
outpdimm->lowest_common_spd_caslat;
if (mclk_to_picos(additive_latency) > trcd_ps) {
additive_latency = picos_to_mclk(trcd_ps);
if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
additive_latency = picos_to_mclk(ctrl_num, trcd_ps);
debug("setting additive_latency to %u because it was "
" greater than tRCD_ps\n", additive_latency);
}
@ -534,7 +539,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
*
* AL <= tRCD(min)
*/
if (mclk_to_picos(additive_latency) > trcd_ps) {
if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
printf("Error: invalid additive latency exceeds tRCD(min).\n");
return 1;
}

View File

@ -450,7 +450,8 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
&(pinfo->spd_installed_dimms[i][j]);
dimm_params_t *pdimm =
&(pinfo->dimm_params[i][j]);
retval = compute_dimm_parameters(spd, pdimm, i);
retval = compute_dimm_parameters(
i, spd, pdimm, j);
#ifdef CONFIG_SYS_DDR_RAW_TIMING
if (!i && !j && retval) {
printf("SPD error on controller %d! "
@ -507,10 +508,11 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
for (i = first_ctrl; i <= last_ctrl; i++) {
debug("Computing lowest common DIMM"
" parameters for memctl=%u\n", i);
compute_lowest_common_dimm_parameters(
pinfo->dimm_params[i],
&timing_params[i],
CONFIG_DIMM_SLOTS_PER_CTLR);
compute_lowest_common_dimm_parameters
(i,
pinfo->dimm_params[i],
&timing_params[i],
CONFIG_DIMM_SLOTS_PER_CTLR);
}
case STEP_GATHER_OPTS:
@ -562,12 +564,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
continue;
}
compute_fsl_memctl_config_regs(
&pinfo->memctl_opts[i],
&ddr_reg[i], &timing_params[i],
pinfo->dimm_params[i],
dbw_capacity_adjust[i],
size_only);
compute_fsl_memctl_config_regs
(i,
&pinfo->memctl_opts[i],
&ddr_reg[i], &timing_params[i],
pinfo->dimm_params[i],
dbw_capacity_adjust[i],
size_only);
}
default:
@ -689,6 +692,10 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo)
}
}
#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
fsl_ddr_sync_memctl_refresh(first_ctrl, last_ctrl);
#endif
#ifdef CONFIG_PPC
/* program LAWs */
for (i = first_ctrl; i <= last_ctrl; i++) {

View File

@ -426,7 +426,7 @@ step2:
bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
>> SDRAM_CFG_DBW_SHIFT);
timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
(get_ddr_freq(0) >> 20)) << 1;
(get_ddr_freq(ctrl_num) >> 20)) << 1;
#ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
timeout_save = timeout;
#endif
@ -538,12 +538,14 @@ step2:
case 1:
out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds);
break;
#if CONFIG_CHIP_SELECTS_PER_CTRL > 2
case 2:
out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds);
break;
case 3:
out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds);
break;
#endif
}
clrbits_be32(&ddr->sdram_cfg, 0x2);
}

View File

@ -732,7 +732,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
#endif
/* Global Timing Parameters. */
debug("mclk_ps = %u ps\n", get_memory_clk_period_ps());
debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num));
/* Pick a caslat override. */
popts->cas_latency_override = 0;
@ -785,7 +785,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
* FIXME: width, was considering looking at pdimm->primary_sdram_width
*/
#if defined(CONFIG_SYS_FSL_DDR1)
popts->tfaw_window_four_activates_ps = mclk_to_picos(1);
popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1);
#elif defined(CONFIG_SYS_FSL_DDR2)
/*
@ -1036,7 +1036,7 @@ done:
if (pdimm[0].n_ranks == 4)
popts->quad_rank_present = 1;
ddr_freq = get_ddr_freq(0) / 1000000;
ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
if (popts->registered_dimm_en) {
popts->rcw_override = 1;
popts->rcw_1 = 0x000a5a00;

View File

@ -43,9 +43,9 @@ u32 fsl_ddr_get_version(void)
* propagation, compute a suitably rounded mclk_ps to compute
* a working memory controller configuration.
*/
unsigned int get_memory_clk_period_ps(void)
unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num)
{
unsigned int data_rate = get_ddr_freq(0);
unsigned int data_rate = get_ddr_freq(ctrl_num);
unsigned int result;
/* Round to nearest 10ps, being careful about 64-bit multiply/divide */
@ -59,10 +59,10 @@ unsigned int get_memory_clk_period_ps(void)
}
/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
unsigned int picos_to_mclk(unsigned int picos)
unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos)
{
unsigned long long clks, clks_rem;
unsigned long data_rate = get_ddr_freq(0);
unsigned long data_rate = get_ddr_freq(ctrl_num);
/* Short circuit for zero picos */
if (!picos)
@ -88,9 +88,9 @@ unsigned int picos_to_mclk(unsigned int picos)
return (unsigned int) clks;
}
unsigned int mclk_to_picos(unsigned int mclk)
unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk)
{
return get_memory_clk_period_ps() * mclk;
return get_memory_clk_period_ps(ctrl_num) * mclk;
}
#ifdef CONFIG_PPC
@ -308,3 +308,58 @@ void board_add_ram_info(int use_default)
{
detail_board_ddr_info();
}
#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
#define DDRC_DEBUG20_INIT_DONE 0x80000000
#define DDRC_DEBUG2_RF 0x00000040
void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
unsigned int last_ctrl)
{
unsigned int i;
u32 ddrc_debug20;
u32 ddrc_debug2[CONFIG_NUM_DDR_CONTROLLERS] = {};
u32 *ddrc_debug2_p[CONFIG_NUM_DDR_CONTROLLERS] = {};
struct ccsr_ddr __iomem *ddr;
for (i = first_ctrl; i <= last_ctrl; i++) {
switch (i) {
case 0:
ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
case 1:
ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
case 2:
ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
case 3:
ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
break;
#endif
default:
printf("%s unexpected ctrl = %u\n", __func__, i);
return;
}
ddrc_debug20 = ddr_in32(&ddr->debug[19]);
ddrc_debug2_p[i] = &ddr->debug[1];
while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) {
/* keep polling until DDRC init is done */
udelay(100);
ddrc_debug20 = ddr_in32(&ddr->debug[19]);
}
ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF;
}
/*
* Sync refresh
* This is put together to make sure the refresh reqeusts are sent
* closely to each other.
*/
for (i = first_ctrl; i <= last_ctrl; i++)
ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
}
#endif /* CONFIG_FSL_DDR_SYNC_REFRESH */

View File

@ -319,7 +319,8 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
esdhc_write32(&regs->cmdarg, cmd->cmdarg);
#if defined(CONFIG_FSL_USDHC)
esdhc_write32(&regs->mixctrl,
(esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F));
(esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F)
| (mmc->ddr_mode ? XFERTYP_DDREN : 0));
esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
#else
esdhc_write32(&regs->xfertyp, xfertyp);
@ -442,7 +443,7 @@ static void set_sysctl(struct mmc *mmc, uint clock)
if ((sdhc_clk / (div * pre_div)) <= clock)
break;
pre_div >>= 1;
pre_div >>= mmc->ddr_mode ? 2 : 1;
div -= 1;
clk = (pre_div << 8) | (div << 4);
@ -601,6 +602,9 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
}
cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
#endif
if (cfg->max_bus_width > 0) {
if (cfg->max_bus_width < 8)

View File

@ -64,5 +64,5 @@ obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
obj-$(CONFIG_FSL_MC_ENET) += fsl_mc/
obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/
obj-$(CONFIG_VSC9953) += vsc9953.o

View File

@ -5,4 +5,6 @@
#
# Layerscape MC driver
obj-y += mc.o
obj-y += mc.o \
mc_sys.o \
dpmng.o

View File

@ -0,0 +1,91 @@
/* Copyright 2014 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_mc_cmd.h>
#include <fsl-mc/fsl_dpmng.h>
#include "fsl_dpmng_cmd.h"
int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
{
struct mc_command cmd = { 0 };
int err;
/* prepare command */
cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
MC_CMD_PRI_LOW, 0);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
if (err)
return err;
/* retrieve response parameters */
DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
return 0;
}
int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id,
int aiop_tile_id)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP,
MC_CMD_PRI_LOW, 0);
DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
int dpmng_load_aiop(struct fsl_mc_io *mc_io,
int container_id,
int aiop_tile_id,
uint64_t img_iova,
uint32_t img_size)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP,
MC_CMD_PRI_LOW,
0);
DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size,
img_iova);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
int dpmng_run_aiop(struct fsl_mc_io *mc_io,
int container_id,
int aiop_tile_id,
const struct dpmng_aiop_run_cfg *cfg)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP,
MC_CMD_PRI_LOW,
0);
DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}
int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io)
{
struct mc_command cmd = { 0 };
/* prepare command */
cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL,
MC_CMD_PRI_LOW,
0);
/* send command to mc*/
return mc_send_command(mc_io, &cmd);
}

View File

@ -0,0 +1,49 @@
/* Copyright 2014 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __FSL_DPMNG_CMD_H
#define __FSL_DPMNG_CMD_H
/* Command IDs */
#define DPMNG_CMDID_GET_VERSION 0x831
#define DPMNG_CMDID_RESET_AIOP 0x832
#define DPMNG_CMDID_LOAD_AIOP 0x833
#define DPMNG_CMDID_RUN_AIOP 0x834
#define DPMNG_CMDID_RESET_MC_PORTAL 0x835
/* cmd, param, offset, width, type, arg_name */
#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \
do { \
MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mc_ver_info->revision); \
MC_RSP_OP(cmd, 0, 32, 32, uint32_t, mc_ver_info->major); \
MC_RSP_OP(cmd, 1, 0, 32, uint32_t, mc_ver_info->minor); \
} while (0)
/* cmd, param, offset, width, type, arg_name */
#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \
do { \
MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
} while (0)
/* cmd, param, offset, width, type, arg_name */
#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \
img_iova) \
do { \
MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
MC_CMD_OP(cmd, 1, 0, 32, uint32_t, img_size); \
MC_CMD_OP(cmd, 2, 0, 64, uint64_t, img_iova); \
} while (0)
/* cmd, param, offset, width, type, arg_name */
#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \
do { \
MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->cores_mask); \
MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options); \
} while (0)
#endif /* __FSL_DPMNG_CMD_H */

View File

@ -3,9 +3,12 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <errno.h>
#include <asm/io.h>
#include <fsl_mc.h>
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_dpmng.h>
DECLARE_GLOBAL_DATA_PTR;
static int mc_boot_status;
@ -14,7 +17,7 @@ static int mc_boot_status;
* Copying MC firmware or DPL image to DDR
*/
static int mc_copy_image(const char *title,
u64 image_addr, u32 image_size, u64 mc_ram_addr)
u64 image_addr, u32 image_size, u64 mc_ram_addr)
{
debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
@ -25,10 +28,9 @@ static int mc_copy_image(const char *title,
* MC firmware FIT image parser checks if the image is in FIT
* format, verifies integrity of the image and calculates
* raw image address and size values.
* Returns 0 if success and 1 if any of the above mentioned
* Returns 0 on success and a negative errno on error.
* task fail.
**/
int parse_mc_firmware_fit_image(const void **raw_image_addr,
size_t *raw_image_size)
{
@ -39,7 +41,7 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
size_t size;
const char *uname = "firmware";
/* Check if the image is in NOR flash*/
/* Check if the image is in NOR flash */
#ifdef CONFIG_SYS_LS_MC_FW_IN_NOR
fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR;
#else
@ -50,26 +52,26 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
format = genimg_get_format(fit_hdr);
if (format != IMAGE_FORMAT_FIT) {
debug("Not a FIT image\n");
return 1;
printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n");
return -EINVAL;
}
if (!fit_check_format(fit_hdr)) {
debug("Bad FIT image format\n");
return 1;
printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n");
return -EINVAL;
}
node_offset = fit_image_get_node(fit_hdr, uname);
if (node_offset < 0) {
debug("Can not find %s subimage\n", uname);
return 1;
printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n");
return -ENOENT;
}
/* Verify MC firmware image */
if (!(fit_image_verify(fit_hdr, node_offset))) {
debug("Bad MC firmware hash");
return 1;
printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n");
return -EINVAL;
}
/* Get address and size of raw image */
@ -90,12 +92,13 @@ int mc_init(bd_t *bis)
u64 mc_dpl_offset;
u32 reg_gsr;
u32 mc_fw_boot_status;
void *fdt_hdr;
void *dpl_fdt_hdr;
int dpl_size;
const void *raw_image_addr;
size_t raw_image_size = 0;
BUILD_BUG_ON(CONFIG_SYS_LS_MC_FW_LENGTH % 4 != 0);
struct fsl_mc_io mc_io;
int portal_id;
struct mc_version mc_ver_info;
/*
* The MC private DRAM block was already carved at the end of DRAM
@ -130,25 +133,44 @@ int mc_init(bd_t *bis)
/*
* Load the MC FW at the beginning of the MC private DRAM block:
*/
mc_copy_image(
"MC Firmware",
(u64)raw_image_addr,
raw_image_size,
mc_ram_addr);
mc_copy_image("MC Firmware",
(u64)raw_image_addr, raw_image_size, mc_ram_addr);
/*
* Get address and size of the DPL blob stored in flash:
*/
#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
#else
#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
#endif
error = fdt_check_header(dpl_fdt_hdr);
if (error != 0) {
printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
goto out;
}
dpl_size = fdt_totalsize(dpl_fdt_hdr);
if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
dpl_size);
error = -EINVAL;
goto out;
}
/*
* Calculate offset in the MC private DRAM block at which the MC DPL
* blob is to be placed:
*/
#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
BUILD_BUG_ON(
(CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
#else
mc_dpl_offset = mc_get_dram_block_size() -
roundup(CONFIG_SYS_LS_MC_DPL_LENGTH, 4096);
roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096);
if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) {
printf("%s: Invalid MC DPL offset: %llu\n",
@ -158,23 +180,14 @@ int mc_init(bd_t *bis)
}
#endif
/* Check if DPL image is in NOR flash */
#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
#else
#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
#endif
dpl_size = fdt_totalsize(fdt_hdr);
/*
* Load the MC DPL blob at the far end of the MC private DRAM block:
*
* TODO: Should we place the DPL at a different location to match
* assumptions of MC firmware about its memory layout?
*/
mc_copy_image(
"MC DPL blob",
(u64)fdt_hdr,
dpl_size,
mc_ram_addr + mc_dpl_offset);
mc_copy_image("MC DPL blob",
(u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
@ -200,6 +213,8 @@ int mc_init(bd_t *bis)
*/
out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
printf("\nfsl-mc: Booting Management Complex ...\n");
/*
* Deassert reset and release MC core 0 to run
*/
@ -219,17 +234,13 @@ int mc_init(bd_t *bis)
}
if (timeout <= 0) {
printf("%s: timeout booting management complex firmware\n",
__func__);
printf("fsl-mc: timeout booting management complex firmware\n");
/* TODO: Get an error status from an MC CCSR register */
error = -ETIMEDOUT;
goto out;
}
printf("Management complex booted (boot status: %#x)\n",
mc_fw_boot_status);
if (mc_fw_boot_status != 0x1) {
/*
* TODO: Identify critical errors from the GSR register's FS
@ -237,8 +248,41 @@ int mc_init(bd_t *bis)
* appropriate errno, so that the status property is set to
* failure in the fsl,dprc device tree node.
*/
printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
reg_gsr);
}
/*
* TODO: need to obtain the portal_id for the root container from the
* DPL
*/
portal_id = 0;
/*
* Check that the MC firmware is responding portal commands:
*/
mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
portal_id, mc_io.mmio_regs);
error = mc_get_version(&mc_io, &mc_ver_info);
if (error != 0) {
printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
error);
goto out;
}
if (MC_VER_MAJOR != mc_ver_info.major)
printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
mc_ver_info.major, MC_VER_MAJOR);
if (MC_VER_MINOR != mc_ver_info.minor)
printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
mc_ver_info.minor, MC_VER_MINOR);
printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
mc_fw_boot_status);
out:
if (error != 0)
mc_boot_status = -error;

View File

@ -0,0 +1,63 @@
/*
* Freescale Layerscape MC I/O wrapper
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
* Author: German Rivera <German.Rivera@freescale.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_mc_cmd.h>
#include <common.h>
#include <errno.h>
#include <asm/io.h>
#define MC_CMD_HDR_READ_CMDID(_hdr) \
((uint16_t)u64_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S))
/**
* mc_send_command - Send MC command and wait for response
*
* @mc_io: Pointer to MC I/O object to be used
* @cmd: MC command buffer. On input, it contains the command to send to the MC.
* On output, it contains the response from the MC if any.
*
* Depending on the sharing option specified when creating the MC portal
* wrapper, this function will use a spinlock or mutex to ensure exclusive
* access to the MC portal from the point when the command is sent until a
* response is received from the MC.
*/
int mc_send_command(struct fsl_mc_io *mc_io,
struct mc_command *cmd)
{
enum mc_cmd_status status;
int timeout = 2000;
mc_write_command(mc_io->mmio_regs, cmd);
for ( ; ; ) {
status = mc_read_response(mc_io->mmio_regs, cmd);
if (status != MC_CMD_STATUS_READY)
break;
if (--timeout == 0) {
printf("Error: Timeout waiting for MC response\n");
return -ETIMEDOUT;
}
udelay(500);
}
if (status != MC_CMD_STATUS_OK) {
printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n",
mc_io->mmio_regs,
(unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header),
(unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
(unsigned int)status);
return -EIO;
}
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2014 Freescale Semiconductor, Inc.
* Copyright 2014-2015 Freescale Semiconductor, Inc.
* Layerscape PCIe driver
*
* SPDX-License-Identifier: GPL-2.0+
@ -9,8 +9,465 @@
#include <asm/arch/fsl_serdes.h>
#include <pci.h>
#include <asm/io.h>
#include <errno.h>
#include <malloc.h>
#include <asm/pcie_layerscape.h>
#ifndef CONFIG_SYS_PCI_MEMORY_BUS
#define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
#endif
#ifndef CONFIG_SYS_PCI_MEMORY_PHYS
#define CONFIG_SYS_PCI_MEMORY_PHYS CONFIG_SYS_SDRAM_BASE
#endif
#ifndef CONFIG_SYS_PCI_MEMORY_SIZE
#define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */
#endif
/* iATU registers */
#define PCIE_ATU_VIEWPORT 0x900
#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
#define PCIE_ATU_REGION_INDEX2 (0x2 << 0)
#define PCIE_ATU_REGION_INDEX3 (0x3 << 0)
#define PCIE_ATU_CR1 0x904
#define PCIE_ATU_TYPE_MEM (0x0 << 0)
#define PCIE_ATU_TYPE_IO (0x2 << 0)
#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
#define PCIE_ATU_CR2 0x908
#define PCIE_ATU_ENABLE (0x1 << 31)
#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
#define PCIE_ATU_LOWER_BASE 0x90C
#define PCIE_ATU_UPPER_BASE 0x910
#define PCIE_ATU_LIMIT 0x914
#define PCIE_ATU_LOWER_TARGET 0x918
#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
#define PCIE_ATU_UPPER_TARGET 0x91C
#define PCIE_LINK_CAP 0x7c
#define PCIE_LINK_SPEED_MASK 0xf
#define PCIE_LINK_STA 0x82
#define PCIE_DBI_SIZE (4 * 1024) /* 4K */
struct ls_pcie {
int idx;
void __iomem *dbi;
void __iomem *va_cfg0;
void __iomem *va_cfg1;
struct pci_controller hose;
};
struct ls_pcie_info {
unsigned long regs;
int pci_num;
u64 cfg0_phys;
u64 cfg0_size;
u64 cfg1_phys;
u64 cfg1_size;
u64 mem_bus;
u64 mem_phys;
u64 mem_size;
u64 io_bus;
u64 io_phys;
u64 io_size;
};
#define SET_LS_PCIE_INFO(x, num) \
{ \
x.regs = CONFIG_SYS_PCIE##num##_ADDR; \
x.cfg0_phys = CONFIG_SYS_PCIE_CFG0_PHYS_OFF + \
CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
x.cfg0_size = CONFIG_SYS_PCIE_CFG0_SIZE; \
x.cfg1_phys = CONFIG_SYS_PCIE_CFG1_PHYS_OFF + \
CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
x.cfg1_size = CONFIG_SYS_PCIE_CFG1_SIZE; \
x.mem_bus = CONFIG_SYS_PCIE_MEM_BUS; \
x.mem_phys = CONFIG_SYS_PCIE_MEM_PHYS_OFF + \
CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
x.mem_size = CONFIG_SYS_PCIE_MEM_SIZE; \
x.io_bus = CONFIG_SYS_PCIE_IO_BUS; \
x.io_phys = CONFIG_SYS_PCIE_IO_PHYS_OFF + \
CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
x.io_size = CONFIG_SYS_PCIE_IO_SIZE; \
x.pci_num = num; \
}
#ifdef CONFIG_LS102XA
#include <asm/arch/immap_ls102xa.h>
/* PEX1/2 Misc Ports Status Register */
#define LTSSM_STATE_SHIFT 20
#define LTSSM_STATE_MASK 0x3f
#define LTSSM_PCIE_L0 0x11 /* L0 state */
static int ls_pcie_link_state(struct ls_pcie *pcie)
{
u32 state;
struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
state = in_be32(&scfg->pexmscportsr[pcie->idx]);
state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
if (state < LTSSM_PCIE_L0) {
debug("....PCIe link error. LTSSM=0x%02x.\n", state);
return 0;
}
return 1;
}
#else
#define PCIE_LDBG 0x7FC
static int ls_pcie_link_state(struct ls_pcie *pcie)
{
u32 state;
state = readl(pcie->dbi + PCIE_LDBG);
if (state)
return 1;
debug("....PCIe link error.\n");
return 0;
}
#endif
static int ls_pcie_link_up(struct ls_pcie *pcie)
{
int state;
u32 cap;
state = ls_pcie_link_state(pcie);
if (state)
return state;
/* Try to download speed to gen1 */
cap = readl(pcie->dbi + PCIE_LINK_CAP);
writel((cap & (~PCIE_LINK_SPEED_MASK)) | 1, pcie->dbi + PCIE_LINK_CAP);
udelay(2000);
state = ls_pcie_link_state(pcie);
if (state)
return state;
writel(cap, pcie->dbi + PCIE_LINK_CAP);
return 0;
}
static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev)
{
writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
pcie->dbi + PCIE_ATU_VIEWPORT);
writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
}
static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev)
{
writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
pcie->dbi + PCIE_ATU_VIEWPORT);
writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
}
static void ls_pcie_iatu_outbound_set(struct ls_pcie *pcie, int idx, int type,
u64 phys, u64 bus_addr, pci_size_t size)
{
writel(PCIE_ATU_REGION_OUTBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_BASE);
writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_BASE);
writel(phys + size - 1, pcie->dbi + PCIE_ATU_LIMIT);
writel((u32)bus_addr, pcie->dbi + PCIE_ATU_LOWER_TARGET);
writel(bus_addr >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
writel(type, pcie->dbi + PCIE_ATU_CR1);
writel(PCIE_ATU_ENABLE, pcie->dbi + PCIE_ATU_CR2);
}
static void ls_pcie_setup_atu(struct ls_pcie *pcie, struct ls_pcie_info *info)
{
#ifdef DEBUG
int i;
#endif
/* ATU 0 : OUTBOUND : CFG0 */
ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
PCIE_ATU_TYPE_CFG0,
info->cfg0_phys,
0,
info->cfg0_size);
/* ATU 1 : OUTBOUND : CFG1 */
ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
PCIE_ATU_TYPE_CFG1,
info->cfg1_phys,
0,
info->cfg1_size);
/* ATU 2 : OUTBOUND : MEM */
ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX2,
PCIE_ATU_TYPE_MEM,
info->mem_phys,
info->mem_bus,
info->mem_size);
/* ATU 3 : OUTBOUND : IO */
ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX3,
PCIE_ATU_TYPE_IO,
info->io_phys,
info->io_bus,
info->io_size);
#ifdef DEBUG
for (i = 0; i <= PCIE_ATU_REGION_INDEX3; i++) {
writel(PCIE_ATU_REGION_OUTBOUND | i,
pcie->dbi + PCIE_ATU_VIEWPORT);
debug("iATU%d:\n", i);
debug("\tLOWER PHYS 0x%08x\n",
readl(pcie->dbi + PCIE_ATU_LOWER_BASE));
debug("\tUPPER PHYS 0x%08x\n",
readl(pcie->dbi + PCIE_ATU_UPPER_BASE));
debug("\tLOWER BUS 0x%08x\n",
readl(pcie->dbi + PCIE_ATU_LOWER_TARGET));
debug("\tUPPER BUS 0x%08x\n",
readl(pcie->dbi + PCIE_ATU_UPPER_TARGET));
debug("\tLIMIT 0x%08x\n",
readl(pcie->dbi + PCIE_ATU_LIMIT));
debug("\tCR1 0x%08x\n",
readl(pcie->dbi + PCIE_ATU_CR1));
debug("\tCR2 0x%08x\n",
readl(pcie->dbi + PCIE_ATU_CR2));
}
#endif
}
int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
{
/* Do not skip controller */
return 0;
}
static int ls_pcie_addr_valid(struct pci_controller *hose, pci_dev_t d)
{
if (PCI_DEV(d) > 0)
return -EINVAL;
return 0;
}
static int ls_pcie_read_config(struct pci_controller *hose, pci_dev_t d,
int where, u32 *val)
{
struct ls_pcie *pcie = hose->priv_data;
u32 busdev, *addr;
if (ls_pcie_addr_valid(hose, d)) {
*val = 0xffffffff;
return -EINVAL;
}
if (PCI_BUS(d) == hose->first_busno) {
addr = pcie->dbi + (where & ~0x3);
} else {
busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
PCIE_ATU_DEV(PCI_DEV(d)) |
PCIE_ATU_FUNC(PCI_FUNC(d));
if (PCI_BUS(d) == hose->first_busno + 1) {
ls_pcie_cfg0_set_busdev(pcie, busdev);
addr = pcie->va_cfg0 + (where & ~0x3);
} else {
ls_pcie_cfg1_set_busdev(pcie, busdev);
addr = pcie->va_cfg1 + (where & ~0x3);
}
}
*val = readl(addr);
return 0;
}
static int ls_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
int where, u32 val)
{
struct ls_pcie *pcie = hose->priv_data;
u32 busdev, *addr;
if (ls_pcie_addr_valid(hose, d))
return -EINVAL;
if (PCI_BUS(d) == hose->first_busno) {
addr = pcie->dbi + (where & ~0x3);
} else {
busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
PCIE_ATU_DEV(PCI_DEV(d)) |
PCIE_ATU_FUNC(PCI_FUNC(d));
if (PCI_BUS(d) == hose->first_busno + 1) {
ls_pcie_cfg0_set_busdev(pcie, busdev);
addr = pcie->va_cfg0 + (where & ~0x3);
} else {
ls_pcie_cfg1_set_busdev(pcie, busdev);
addr = pcie->va_cfg1 + (where & ~0x3);
}
}
writel(val, addr);
return 0;
}
static void ls_pcie_setup_ctrl(struct ls_pcie *pcie,
struct ls_pcie_info *info)
{
struct pci_controller *hose = &pcie->hose;
pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
ls_pcie_setup_atu(pcie, info);
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0);
/* program correct class for RC */
pci_hose_write_config_word(hose, dev, PCI_CLASS_DEVICE,
PCI_CLASS_BRIDGE_PCI);
}
int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
{
struct ls_pcie *pcie;
struct pci_controller *hose;
int num = dev - PCIE1;
pci_dev_t pdev = PCI_BDF(busno, 0, 0);
int i, linkup, ep_mode;
u8 header_type;
u16 temp16;
if (!is_serdes_configured(dev)) {
printf("PCIe%d: disabled\n", num + 1);
return busno;
}
pcie = malloc(sizeof(*pcie));
if (!pcie)
return busno;
memset(pcie, 0, sizeof(*pcie));
hose = &pcie->hose;
hose->priv_data = pcie;
hose->first_busno = busno;
pcie->idx = num;
pcie->dbi = map_physmem(info->regs, PCIE_DBI_SIZE, MAP_NOCACHE);
pcie->va_cfg0 = map_physmem(info->cfg0_phys,
info->cfg0_size,
MAP_NOCACHE);
pcie->va_cfg1 = map_physmem(info->cfg1_phys,
info->cfg1_size,
MAP_NOCACHE);
/* outbound memory */
pci_set_region(&hose->regions[0],
(pci_size_t)info->mem_bus,
(phys_size_t)info->mem_phys,
(pci_size_t)info->mem_size,
PCI_REGION_MEM);
/* outbound io */
pci_set_region(&hose->regions[1],
(pci_size_t)info->io_bus,
(phys_size_t)info->io_phys,
(pci_size_t)info->io_size,
PCI_REGION_IO);
/* System memory space */
pci_set_region(&hose->regions[2],
CONFIG_SYS_PCI_MEMORY_BUS,
CONFIG_SYS_PCI_MEMORY_PHYS,
CONFIG_SYS_PCI_MEMORY_SIZE,
PCI_REGION_SYS_MEMORY);
hose->region_count = 3;
for (i = 0; i < hose->region_count; i++)
debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n",
i,
(u64)hose->regions[i].phys_start,
(u64)hose->regions[i].bus_start,
(u64)hose->regions[i].size,
hose->regions[i].flags);
pci_set_ops(hose,
pci_hose_read_config_byte_via_dword,
pci_hose_read_config_word_via_dword,
ls_pcie_read_config,
pci_hose_write_config_byte_via_dword,
pci_hose_write_config_word_via_dword,
ls_pcie_write_config);
pci_hose_read_config_byte(hose, pdev, PCI_HEADER_TYPE, &header_type);
ep_mode = (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
printf("PCIe%u: %s ", info->pci_num,
ep_mode ? "Endpoint" : "Root Complex");
linkup = ls_pcie_link_up(pcie);
if (!linkup) {
/* Let the user know there's no PCIe link */
printf("no link, regs @ 0x%lx\n", info->regs);
hose->last_busno = hose->first_busno;
return busno;
}
/* Print the negotiated PCIe link width */
pci_hose_read_config_word(hose, dev, PCIE_LINK_STA, &temp16);
printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4,
(temp16 & 0xf), info->regs);
if (ep_mode)
return busno;
ls_pcie_setup_ctrl(pcie, info);
pci_register_hose(hose);
hose->last_busno = pci_hose_scan(hose);
printf("PCIe%x: Bus %02x - %02x\n",
info->pci_num, hose->first_busno, hose->last_busno);
return hose->last_busno + 1;
}
int ls_pcie_init_board(int busno)
{
struct ls_pcie_info info;
#ifdef CONFIG_PCIE1
SET_LS_PCIE_INFO(info, 1);
busno = ls_pcie_init_ctrl(busno, PCIE1, &info);
#endif
#ifdef CONFIG_PCIE2
SET_LS_PCIE_INFO(info, 2);
busno = ls_pcie_init_ctrl(busno, PCIE2, &info);
#endif
#ifdef CONFIG_PCIE3
SET_LS_PCIE_INFO(info, 3);
busno = ls_pcie_init_ctrl(busno, PCIE3, &info);
#endif
#ifdef CONFIG_PCIE4
SET_LS_PCIE_INFO(info, 4);
busno = ls_pcie_init_ctrl(busno, PCIE4, &info);
#endif
return busno;
}
void pci_init_board(void)
{
ls_pcie_init_board(0);
}
#ifdef CONFIG_OF_BOARD_SETUP
#include <libfdt.h>
#include <fdt_support.h>
@ -38,6 +495,14 @@ void ft_pcie_setup(void *blob, bd_t *bd)
#ifdef CONFIG_PCIE2
ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE2_ADDR, PCIE2);
#endif
#ifdef CONFIG_PCIE3
ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE3_ADDR, PCIE3);
#endif
#ifdef CONFIG_PCIE4
ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR, PCIE4);
#endif
}
#else
@ -45,7 +510,3 @@ void ft_pcie_setup(void *blob, bd_t *bd)
{
}
#endif
void pci_init_board(void)
{
}

View File

@ -510,6 +510,30 @@ unsigned long get_board_ddr_clk(void);
#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
#define FSL_PCIE_COMPAT "fsl,ls1021a-pcie"
#define CONFIG_SYS_PCI_64BIT
#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF 0x00000000
#define CONFIG_SYS_PCIE_CFG0_SIZE 0x00001000 /* 4k */
#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF 0x00001000
#define CONFIG_SYS_PCIE_CFG1_SIZE 0x00001000 /* 4k */
#define CONFIG_SYS_PCIE_IO_BUS 0x00000000
#define CONFIG_SYS_PCIE_IO_PHYS_OFF 0x00010000
#define CONFIG_SYS_PCIE_IO_SIZE 0x00010000 /* 64k */
#define CONFIG_SYS_PCIE_MEM_BUS 0x08000000
#define CONFIG_SYS_PCIE_MEM_PHYS_OFF 0x04000000
#define CONFIG_SYS_PCIE_MEM_SIZE 0x08000000 /* 128M */
#ifdef CONFIG_PCI
#define CONFIG_NET_MULTI
#define CONFIG_PCI_PNP
#define CONFIG_E1000
#define CONFIG_PCI_SCAN_SHOW
#define CONFIG_CMD_PCI
#define CONFIG_CMD_NET
#endif
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII

View File

@ -303,6 +303,30 @@
#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
#define FSL_PCIE_COMPAT "fsl,ls1021a-pcie"
#define CONFIG_SYS_PCI_64BIT
#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF 0x00000000
#define CONFIG_SYS_PCIE_CFG0_SIZE 0x00001000 /* 4k */
#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF 0x00001000
#define CONFIG_SYS_PCIE_CFG1_SIZE 0x00001000 /* 4k */
#define CONFIG_SYS_PCIE_IO_BUS 0x00000000
#define CONFIG_SYS_PCIE_IO_PHYS_OFF 0x00010000
#define CONFIG_SYS_PCIE_IO_SIZE 0x00010000 /* 64k */
#define CONFIG_SYS_PCIE_MEM_BUS 0x08000000
#define CONFIG_SYS_PCIE_MEM_PHYS_OFF 0x04000000
#define CONFIG_SYS_PCIE_MEM_SIZE 0x08000000 /* 128M */
#ifdef CONFIG_PCI
#define CONFIG_NET_MULTI
#define CONFIG_PCI_PNP
#define CONFIG_E1000
#define CONFIG_PCI_SCAN_SHOW
#define CONFIG_CMD_PCI
#define CONFIG_CMD_NET
#endif
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII

View File

@ -13,6 +13,7 @@
#define CONFIG_FSL_LSCH3
#define CONFIG_LS2085A
#define CONFIG_GICV3
#define CONFIG_FSL_TZPC_BP147
/* Link Definitions */
#define CONFIG_SYS_TEXT_BASE 0x30001000
@ -26,9 +27,6 @@
#define CONFIG_SKIP_LOWLEVEL_INIT
#define CONFIG_BOARD_EARLY_INIT_F 1
#define CONFIG_IDENT_STRING " LS2085A-EMU"
#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-EMU"
/* Flat Device Tree Definitions */
#define CONFIG_OF_LIBFDT
#define CONFIG_OF_BOARD_SETUP
@ -209,12 +207,10 @@
#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
#define CONFIG_SYS_LS_MC_FW_IN_NOR
#define CONFIG_SYS_LS_MC_FW_ADDR 0x580200000ULL
/* TODO Actual FW length needs to be determined at runtime from FW header */
#define CONFIG_SYS_LS_MC_FW_LENGTH (4U * 1024 * 1024)
#define CONFIG_SYS_LS_MC_DPL_IN_NOR
#define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL
/* TODO Actual DPL max length needs to be confirmed with the MC FW team */
#define CONFIG_SYS_LS_MC_DPL_LENGTH 4096
#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024)
#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000
/* Carve the MC private DRAM block from the end of DRAM */
@ -248,7 +244,8 @@
/* Physical Memory Map */
/* fixme: these need to be checked against the board */
#define CONFIG_CHIP_SELECTS_PER_CTRL 4
#define CONFIG_SYS_CLK_FREQ 133333333
#define CONFIG_SYS_CLK_FREQ 100000000
#define CONFIG_DDR_CLK_FREQ 133333333
#define CONFIG_NR_DRAM_BANKS 3
@ -268,12 +265,14 @@
"fdt_high=0xffffffffffffffff\0" \
"initrd_high=0xffffffffffffffff\0" \
"kernel_start=0x581200000\0" \
"kernel_load=0x806f0000\0" \
"kernel_load=0xa0000000\0" \
"kernel_size=0x1000000\0" \
"console=ttyAMA0,38400n8\0"
#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \
"earlyprintk=uart8250-8bit,0x21c0600"
#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \
"earlycon=uart8250,mmio,0x21c0600,115200 " \
"default_hugepagesz=2m hugepagesz=2m " \
"hugepages=16"
#define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \
"$kernel_size && bootm $kernel_load"
#define CONFIG_BOOTDELAY 1

View File

@ -9,6 +9,9 @@
#include "ls2085a_common.h"
#define CONFIG_IDENT_STRING " LS2085A-EMU"
#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-EMU"
#define CONFIG_DDR_SPD
#define CONFIG_SYS_FSL_DDR_EMU /* Support emulator */
#define SPD_EEPROM_ADDRESS1 0x51
@ -17,4 +20,5 @@
#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1
#define CONFIG_SYS_SPD_BUS_NUM 1 /* SPD on I2C bus 1 */
#define CONFIG_FSL_DDR_SYNC_REFRESH
#endif /* __LS2_EMU_H */

View File

@ -9,6 +9,9 @@
#include "ls2085a_common.h"
#define CONFIG_IDENT_STRING " LS2085A-SIMU"
#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-SIMU"
/* SMSC 91C111 ethernet configuration */
#define CONFIG_SMC91111
#define CONFIG_SMC91111_BASE (0x2210000)

View File

@ -28,6 +28,8 @@
#define CONFIG_SYS_PL310_BASE L2_PL310_BASE
#endif
#define CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
#define CONFIG_MP
#define CONFIG_MXC_GPT_HCLK

View File

@ -0,0 +1,121 @@
/* Copyright 2014 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*!
* @file fsl_dpmng.h
* @brief Management Complex General API
*/
#ifndef __FSL_DPMNG_H
#define __FSL_DPMNG_H
/*!
* @Group grp_dpmng Management Complex General API
*
* @brief Contains general API for the Management Complex firmware
* @{
*/
struct fsl_mc_io;
/**
* @brief Management Complex firmware version information
*/
#define MC_VER_MAJOR 4
#define MC_VER_MINOR 0
struct mc_version {
uint32_t major;
/*!< Major version number: incremented on API compatibility changes */
uint32_t minor;
/*!< Minor version number: incremented on API additions (that are
* backward compatible); reset when major version is incremented
*/
uint32_t revision;
/*!< Internal revision number: incremented on implementation changes
* and/or bug fixes that have no impact on API
*/
};
/**
* @brief Retrieves the Management Complex firmware version information
*
* @param[in] mc_io Pointer to opaque I/O object
* @param[out] mc_ver_info Pointer to version information structure
*
* @returns '0' on Success; Error code otherwise.
*/
int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info);
/**
* @brief Resets an AIOP tile
*
* @param[in] mc_io Pointer to opaque I/O object
* @param[in] container_id AIOP container ID
* @param[in] aiop_tile_id AIOP tile ID to reset
*
* @returns '0' on Success; Error code otherwise.
*/
int dpmng_reset_aiop(struct fsl_mc_io *mc_io,
int container_id,
int aiop_tile_id);
/**
* @brief Loads an image to AIOP tile
*
* @param[in] mc_io Pointer to opaque I/O object
* @param[in] container_id AIOP container ID
* @param[in] aiop_tile_id AIOP tile ID to reset
* @param[in] img_iova I/O virtual address of AIOP ELF image
* @param[in] img_size Size of AIOP ELF image in memory (in bytes)
*
* @returns '0' on Success; Error code otherwise.
*/
int dpmng_load_aiop(struct fsl_mc_io *mc_io,
int container_id,
int aiop_tile_id,
uint64_t img_iova,
uint32_t img_size);
/**
* @brief AIOP run configuration
*/
struct dpmng_aiop_run_cfg {
uint32_t cores_mask;
/*!< Mask of AIOP cores to run (core 0 in most significant bit) */
uint64_t options;
/*!< Execution options (currently none defined) */
};
/**
* @brief Starts AIOP tile execution
*
* @param[in] mc_io Pointer to MC portal's I/O object
* @param[in] container_id AIOP container ID
* @param[in] aiop_tile_id AIOP tile ID to reset
* @param[in] cfg AIOP run configuration
*
* @returns '0' on Success; Error code otherwise.
*/
int dpmng_run_aiop(struct fsl_mc_io *mc_io,
int container_id,
int aiop_tile_id,
const struct dpmng_aiop_run_cfg *cfg);
/**
* @brief Resets MC portal
*
* This function closes all object handles (tokens) that are currently
* open in the MC portal on which the command is submitted. This allows
* cleanup of stale handles that belong to non-functional user processes.
*
* @param[in] mc_io Pointer to MC portal's I/O object
*
* @returns '0' on Success; Error code otherwise.
*/
int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io);
/** @} */
#endif /* __FSL_DPMNG_H */

View File

@ -0,0 +1,132 @@
/* Copyright 2014 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __FSL_MC_CMD_H
#define __FSL_MC_CMD_H
#define MC_CMD_NUM_OF_PARAMS 7
#define MAKE_UMASK64(_width) \
((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1))
static inline uint64_t u64_enc(int lsoffset, int width, uint64_t val)
{
return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
}
static inline uint64_t u64_dec(uint64_t val, int lsoffset, int width)
{
return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
}
struct mc_command {
uint64_t header;
uint64_t params[MC_CMD_NUM_OF_PARAMS];
};
enum mc_cmd_status {
MC_CMD_STATUS_OK = 0x0, /*!< Completed successfully */
MC_CMD_STATUS_READY = 0x1, /*!< Ready to be processed */
MC_CMD_STATUS_AUTH_ERR = 0x3, /*!< Authentication error */
MC_CMD_STATUS_NO_PRIVILEGE = 0x4, /*!< No privilege */
MC_CMD_STATUS_DMA_ERR = 0x5, /*!< DMA or I/O error */
MC_CMD_STATUS_CONFIG_ERR = 0x6, /*!< Configuration error */
MC_CMD_STATUS_TIMEOUT = 0x7, /*!< Operation timed out */
MC_CMD_STATUS_NO_RESOURCE = 0x8, /*!< No resources */
MC_CMD_STATUS_NO_MEMORY = 0x9, /*!< No memory available */
MC_CMD_STATUS_BUSY = 0xA, /*!< Device is busy */
MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, /*!< Unsupported operation */
MC_CMD_STATUS_INVALID_STATE = 0xC /*!< Invalid state */
};
#define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */
#define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */
#define MC_CMD_HDR_AUTHID_O 38 /* Authentication ID field offset */
#define MC_CMD_HDR_AUTHID_S 10 /* Authentication ID field size */
#define MC_CMD_HDR_STATUS_O 16 /* Status field offset */
#define MC_CMD_HDR_STATUS_S 8 /* Status field size*/
#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */
#define MC_CMD_HDR_PRI_S 1 /* Priority field size */
#define MC_CMD_HDR_READ_STATUS(_hdr) \
((enum mc_cmd_status)u64_dec((_hdr), \
MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
#define MC_CMD_HDR_READ_AUTHID(_hdr) \
((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S))
#define MC_CMD_PRI_LOW 0 /*!< Low Priority command indication */
#define MC_CMD_PRI_HIGH 1 /*!< High Priority command indication */
#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg))
#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
(_arg = (_type)u64_dec(_cmd.params[_param], (_offset), (_width)))
static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
uint8_t priority,
uint16_t auth_id)
{
uint64_t hdr;
hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id);
hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority);
hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
MC_CMD_STATUS_READY);
return hdr;
}
/**
* mc_write_command - writes a command to a Management Complex (MC) portal
*
* @portal: pointer to an MC portal
* @cmd: pointer to a filled command
*/
static inline void mc_write_command(struct mc_command __iomem *portal,
struct mc_command *cmd)
{
int i;
/* copy command parameters into the portal */
for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
writeq(cmd->params[i], &portal->params[i]);
/* submit the command by writing the header */
writeq(cmd->header, &portal->header);
}
/**
* mc_read_response - reads the response for the last MC command from a
* Management Complex (MC) portal
*
* @portal: pointer to an MC portal
* @resp: pointer to command response buffer
*
* Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
*/
static inline enum mc_cmd_status mc_read_response(
struct mc_command __iomem *portal,
struct mc_command *resp)
{
int i;
enum mc_cmd_status status;
/* Copy command response header from MC portal: */
resp->header = readq(&portal->header);
status = MC_CMD_HDR_READ_STATUS(resp->header);
if (status != MC_CMD_STATUS_OK)
return status;
/* Copy command response data from MC portal: */
for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
resp->params[i] = readq(&portal->params[i]);
return status;
}
int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
#endif /* __FSL_MC_CMD_H */

View File

@ -0,0 +1,26 @@
/*
* Freescale Layerscape Management Complex (MC) Environment-specific code
*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _FSL_MC_SYS_H
#define _FSL_MC_SYS_H
#include <asm/io.h>
struct mc_command;
/*
* struct mc_portal_wrapper - MC command portal wrapper object
*/
struct fsl_mc_io {
struct mc_command __iomem *mmio_regs;
};
int mc_send_command(struct fsl_mc_io *mc_io,
struct mc_command *cmd);
#endif /* _FSL_MC_SYS_H */

View File

@ -44,11 +44,12 @@ u32 fsl_ddr_get_version(void);
* to this specific DDR technology.
*/
static __inline__ int
compute_dimm_parameters(const generic_spd_eeprom_t *spd,
compute_dimm_parameters(const unsigned int ctrl_num,
const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number)
{
return ddr_compute_dimm_parameters(spd, pdimm, dimm_number);
return ddr_compute_dimm_parameters(ctrl_num, spd, pdimm, dimm_number);
}
#endif
@ -92,13 +93,15 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
unsigned int size_only);
const char *step_to_string(unsigned int step);
unsigned int compute_fsl_memctl_config_regs(const memctl_options_t *popts,
unsigned int compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
const memctl_options_t *popts,
fsl_ddr_cfg_regs_t *ddr,
const common_timing_params_t *common_dimm,
const dimm_params_t *dimm_parameters,
unsigned int dbw_capacity_adjust,
unsigned int size_only);
unsigned int compute_lowest_common_dimm_parameters(
const unsigned int ctrl_num,
const dimm_params_t *dimm_params,
common_timing_params_t *outpdimm,
unsigned int number_of_dimms);
@ -108,13 +111,15 @@ unsigned int populate_memctl_options(int all_dimms_registered,
unsigned int ctrl_num);
void check_interleaving_options(fsl_ddr_info_t *pinfo);
unsigned int mclk_to_picos(unsigned int mclk);
unsigned int get_memory_clk_period_ps(void);
unsigned int picos_to_mclk(unsigned int picos);
unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk);
unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num);
unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos);
void fsl_ddr_set_lawbar(
const common_timing_params_t *memctl_common_params,
unsigned int memctl_interleaved,
unsigned int ctrl_num);
void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
unsigned int last_ctrl);
int fsl_ddr_interactive_env_var_exists(void);
unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set);

View File

@ -112,7 +112,7 @@ typedef struct dimm_params_s {
#endif
} dimm_params_t;
extern unsigned int ddr_compute_dimm_parameters(
unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
const generic_spd_eeprom_t *spd,
dimm_params_t *pdimm,
unsigned int dimm_number);

View File

@ -108,6 +108,7 @@
#define XFERTYP_RSPTYP_48_BUSY 0x00030000
#define XFERTYP_MSBSEL 0x00000020
#define XFERTYP_DTDSEL 0x00000010
#define XFERTYP_DDREN 0x00000008
#define XFERTYP_AC12EN 0x00000004
#define XFERTYP_BCEN 0x00000002
#define XFERTYP_DMAEN 0x00000001

View File

@ -175,6 +175,32 @@ struct jr_regs {
u32 jrcr;
};
/*
* Scatter Gather Entry - Specifies the the Scatter Gather Format
* related information
*/
struct sg_entry {
#ifdef CONFIG_SYS_FSL_SEC_LE
uint32_t addr_lo; /* Memory Address - lo */
uint16_t addr_hi; /* Memory Address of start of buffer - hi */
uint16_t reserved_zero;
#else
uint16_t reserved_zero;
uint16_t addr_hi; /* Memory Address of start of buffer - hi */
uint32_t addr_lo; /* Memory Address - lo */
#endif
uint32_t len_flag; /* Length of the data in the frame */
#define SG_ENTRY_LENGTH_MASK 0x3FFFFFFF
#define SG_ENTRY_EXTENSION_BIT 0x80000000
#define SG_ENTRY_FINAL_BIT 0x40000000
uint32_t bpid_offset;
#define SG_ENTRY_BPID_MASK 0x00FF0000
#define SG_ENTRY_BPID_SHIFT 16
#define SG_ENTRY_OFFSET_MASK 0x00001FFF
#define SG_ENTRY_OFFSET_SHIFT 0
};
int sec_init(void);
#endif

View File

@ -7,7 +7,7 @@
*/
#ifndef __HW_SHA_H
#define __HW_SHA_H
#include <hash.h>
/**
* Computes hash value of input pbuf using h/w acceleration
@ -34,4 +34,43 @@ void hw_sha256(const uchar * in_addr, uint buflen,
*/
void hw_sha1(const uchar * in_addr, uint buflen,
uchar * out_addr, uint chunk_size);
/*
* Create the context for sha progressive hashing using h/w acceleration
*
* @algo: Pointer to the hash_algo struct
* @ctxp: Pointer to the pointer of the context for hashing
* @return 0 if ok, -ve on error
*/
int hw_sha_init(struct hash_algo *algo, void **ctxp);
/*
* Update buffer for sha progressive hashing using h/w acceleration
*
* The context is freed by this function if an error occurs.
*
* @algo: Pointer to the hash_algo struct
* @ctx: Pointer to the context for hashing
* @buf: Pointer to the buffer being hashed
* @size: Size of the buffer being hashed
* @is_last: 1 if this is the last update; 0 otherwise
* @return 0 if ok, -ve on error
*/
int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
unsigned int size, int is_last);
/*
* Copy sha hash result at destination location
*
* The context is freed after completion of hash operation or after an error.
*
* @algo: Pointer to the hash_algo struct
* @ctx: Pointer to the context for hashing
* @dest_buf: Pointer to the destination buffer where hash is to be copied
* @size: Size of the buffer being hashed
* @return 0 if ok, -ve on error
*/
int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
int size);
#endif

View File

@ -29,4 +29,40 @@ config SYS_HZ
source lib/rsa/Kconfig
menu "Hashing Support"
config SHA1
bool "Enable SHA1 support"
help
This option enables support of hashing using SHA1 algorithm.
The hash is calculated in software.
The SHA1 algorithm produces a 160-bit (20-byte) hash value
(digest).
config SHA256
bool "Enable SHA256 support"
help
This option enables support of hashing using SHA256 algorithm.
The hash is calculated in software.
The SHA256 algorithm produces a 256-bit (32-byte) hash value
(digest).
config SHA_HW_ACCEL
bool "Enable hashing using hardware"
help
This option enables hardware acceleration
for SHA1/SHA256 hashing.
This affects the 'hash' command and also the
hash_lookup_algo() function.
config SHA_PROG_HW_ACCEL
bool "Enable Progressive hashing support using hardware"
depends on SHA_HW_ACCEL
help
This option enables hardware-acceleration for
SHA1/SHA256 progressive hashing.
Data can be streamed in a block at a time and the hashing
is performed in hardware.
endmenu
endmenu