Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
This commit is contained in:
commit
2c2277f15c
6
README
6
README
@ -538,6 +538,12 @@ The following options need to be configured:
|
||||
interleaving mode, handled by Dickens for Freescale layerscape
|
||||
SoCs with ARM core.
|
||||
|
||||
CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS
|
||||
Number of controllers used as main memory.
|
||||
|
||||
CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS
|
||||
Number of controllers used for other than main memory.
|
||||
|
||||
- Intel Monahans options:
|
||||
CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
|
||||
|
||||
|
@ -7,3 +7,5 @@
|
||||
obj-y += cpu.o
|
||||
obj-y += lowlevel.o
|
||||
obj-y += speed.o
|
||||
obj-$(CONFIG_MP) += mp.o
|
||||
obj-$(CONFIG_OF_LIBFDT) += fdt.o
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
#include "cpu.h"
|
||||
#include "mp.h"
|
||||
#include "speed.h"
|
||||
#include <fsl_mc.h>
|
||||
|
||||
@ -434,3 +435,15 @@ int cpu_eth_init(bd_t *bis)
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int arch_early_init_r(void)
|
||||
{
|
||||
int rv;
|
||||
rv = fsl_lsch3_wake_seconday_cores();
|
||||
|
||||
if (rv)
|
||||
printf("Did not wake secondary cores\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,3 +5,4 @@
|
||||
*/
|
||||
|
||||
int fsl_qoriq_core_to_cluster(unsigned int core);
|
||||
u32 cpu_mask(void);
|
||||
|
58
arch/arm/cpu/armv8/fsl-lsch3/fdt.c
Normal file
58
arch/arm/cpu/armv8/fsl-lsch3/fdt.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <libfdt.h>
|
||||
#include <fdt_support.h>
|
||||
#include "mp.h"
|
||||
|
||||
#ifdef CONFIG_MP
|
||||
void ft_fixup_cpu(void *blob)
|
||||
{
|
||||
int off;
|
||||
__maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
|
||||
fdt32_t *reg;
|
||||
int addr_cells;
|
||||
u64 val;
|
||||
size_t *boot_code_size = &(__secondary_boot_code_size);
|
||||
|
||||
off = fdt_path_offset(blob, "/cpus");
|
||||
if (off < 0) {
|
||||
puts("couldn't find /cpus node\n");
|
||||
return;
|
||||
}
|
||||
of_bus_default_count_cells(blob, off, &addr_cells, NULL);
|
||||
|
||||
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);
|
||||
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));
|
||||
} else {
|
||||
puts("Warning: found cpu node without reg property\n");
|
||||
}
|
||||
off = fdt_node_offset_by_prop_value(blob, off, "device_type",
|
||||
"cpu", 4);
|
||||
}
|
||||
|
||||
fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
|
||||
*boot_code_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ft_cpu_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
#ifdef CONFIG_MP
|
||||
ft_fixup_cpu(blob);
|
||||
#endif
|
||||
}
|
@ -8,7 +8,9 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/gic.h>
|
||||
#include <asm/macro.h>
|
||||
#include "mp.h"
|
||||
|
||||
ENTRY(lowlevel_init)
|
||||
mov x29, lr /* Save LR */
|
||||
@ -35,31 +37,114 @@ ENTRY(lowlevel_init)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
branch_if_master x0, x1, 1f
|
||||
branch_if_master x0, x1, 2f
|
||||
|
||||
/*
|
||||
* Slave should wait for master clearing spin table.
|
||||
* This sync prevent salves observing incorrect
|
||||
* value of spin table and jumping to wrong place.
|
||||
*/
|
||||
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
|
||||
#ifdef CONFIG_GICV2
|
||||
ldr x0, =GICC_BASE
|
||||
#endif
|
||||
bl gic_wait_for_interrupt
|
||||
#endif
|
||||
|
||||
/*
|
||||
* All processors will enter EL2 and optionally EL1.
|
||||
*/
|
||||
bl armv8_switch_to_el2
|
||||
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
|
||||
bl armv8_switch_to_el1
|
||||
#endif
|
||||
b 2f
|
||||
|
||||
1:
|
||||
ldr x0, =secondary_boot_func
|
||||
blr x0
|
||||
2:
|
||||
mov lr, x29 /* Restore LR */
|
||||
ret
|
||||
ENDPROC(lowlevel_init)
|
||||
|
||||
/* Keep literals not used by the secondary boot code outside it */
|
||||
.ltorg
|
||||
|
||||
/* Using 64 bit alignment since the spin table is accessed as data */
|
||||
.align 4
|
||||
.global secondary_boot_code
|
||||
/* Secondary Boot Code starts here */
|
||||
secondary_boot_code:
|
||||
.global __spin_table
|
||||
__spin_table:
|
||||
.space CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE
|
||||
|
||||
.align 2
|
||||
ENTRY(secondary_boot_func)
|
||||
/*
|
||||
* MPIDR_EL1 Fields:
|
||||
* MPIDR[1:0] = AFF0_CPUID <- Core ID (0,1)
|
||||
* MPIDR[7:2] = AFF0_RES
|
||||
* MPIDR[15:8] = AFF1_CLUSTERID <- Cluster ID (0,1,2,3)
|
||||
* MPIDR[23:16] = AFF2_CLUSTERID
|
||||
* MPIDR[24] = MT
|
||||
* MPIDR[29:25] = RES0
|
||||
* MPIDR[30] = U
|
||||
* MPIDR[31] = ME
|
||||
* MPIDR[39:32] = AFF3
|
||||
*
|
||||
* Linear Processor ID (LPID) calculation from MPIDR_EL1:
|
||||
* (We only use AFF0_CPUID and AFF1_CLUSTERID for now
|
||||
* until AFF2_CLUSTERID and AFF3 have non-zero values)
|
||||
*
|
||||
* LPID = MPIDR[15:8] | MPIDR[1:0]
|
||||
*/
|
||||
mrs x0, mpidr_el1
|
||||
ubfm x1, x0, #8, #15
|
||||
ubfm x2, x0, #0, #1
|
||||
orr x10, x2, x1, lsl #2 /* x10 has LPID */
|
||||
ubfm x9, x0, #0, #15 /* x9 contains MPIDR[15:0] */
|
||||
/*
|
||||
* offset of the spin table element for this core from start of spin
|
||||
* table (each elem is padded to 64 bytes)
|
||||
*/
|
||||
lsl x1, x10, #6
|
||||
ldr x0, =__spin_table
|
||||
/* physical address of this cpus spin table element */
|
||||
add x11, x1, x0
|
||||
|
||||
str x9, [x11, #16] /* LPID */
|
||||
mov x4, #1
|
||||
str x4, [x11, #8] /* STATUS */
|
||||
dsb sy
|
||||
#if defined(CONFIG_GICV3)
|
||||
gic_wait_for_interrupt_m x0
|
||||
#elif defined(CONFIG_GICV2)
|
||||
ldr x0, =GICC_BASE
|
||||
gic_wait_for_interrupt_m x0, w1
|
||||
#endif
|
||||
|
||||
bl secondary_switch_to_el2
|
||||
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
|
||||
bl secondary_switch_to_el1
|
||||
#endif
|
||||
|
||||
slave_cpu:
|
||||
wfe
|
||||
ldr x0, [x11]
|
||||
cbz x0, slave_cpu
|
||||
#ifndef CONFIG_ARMV8_SWITCH_TO_EL1
|
||||
mrs x1, sctlr_el2
|
||||
#else
|
||||
mrs x1, sctlr_el1
|
||||
#endif
|
||||
tbz x1, #25, cpu_is_le
|
||||
rev x0, x0 /* BE to LE conversion */
|
||||
cpu_is_le:
|
||||
br x0 /* branch to the given address */
|
||||
ENDPROC(secondary_boot_func)
|
||||
|
||||
ENTRY(secondary_switch_to_el2)
|
||||
switch_el x0, 1f, 0f, 0f
|
||||
0: ret
|
||||
1: armv8_switch_to_el2_m x0
|
||||
ENDPROC(secondary_switch_to_el2)
|
||||
|
||||
ENTRY(secondary_switch_to_el1)
|
||||
switch_el x0, 0f, 1f, 0f
|
||||
0: ret
|
||||
1: armv8_switch_to_el1_m x0, x1
|
||||
ENDPROC(secondary_switch_to_el1)
|
||||
|
||||
/* Ensure that the literals used by the secondary boot code are
|
||||
* assembled within it (this is required so that we can protect
|
||||
* this area with a single memreserve region
|
||||
*/
|
||||
.ltorg
|
||||
|
||||
/* 64 bit alignment for elements accessed as data */
|
||||
.align 4
|
||||
.globl __secondary_boot_code_size
|
||||
.type __secondary_boot_code_size, %object
|
||||
/* Secondary Boot Code ends here */
|
||||
__secondary_boot_code_size:
|
||||
.quad .-secondary_boot_code
|
||||
|
168
arch/arm/cpu/armv8/fsl-lsch3/mp.c
Normal file
168
arch/arm/cpu/armv8/fsl-lsch3/mp.c
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2014 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
|
||||
#include "mp.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
void *get_spin_tbl_addr(void)
|
||||
{
|
||||
return &__spin_table;
|
||||
}
|
||||
|
||||
phys_addr_t determine_mp_bootpg(void)
|
||||
{
|
||||
return (phys_addr_t)&secondary_boot_code;
|
||||
}
|
||||
|
||||
int fsl_lsch3_wake_seconday_cores(void)
|
||||
{
|
||||
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
|
||||
struct ccsr_reset __iomem *rst = (void *)(CONFIG_SYS_FSL_RST_ADDR);
|
||||
u32 cores, cpu_up_mask = 1;
|
||||
int i, timeout = 10;
|
||||
u64 *table = get_spin_tbl_addr();
|
||||
|
||||
cores = cpu_mask();
|
||||
/* Clear spin table so that secondary processors
|
||||
* observe the correct value after waking up from wfe.
|
||||
*/
|
||||
memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE);
|
||||
flush_dcache_range((unsigned long)table,
|
||||
(unsigned long)table +
|
||||
(CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE));
|
||||
|
||||
printf("Waking secondary cores to start from %lx\n", gd->relocaddr);
|
||||
out_le32(&gur->bootlocptrh, (u32)(gd->relocaddr >> 32));
|
||||
out_le32(&gur->bootlocptrl, (u32)gd->relocaddr);
|
||||
out_le32(&gur->scratchrw[6], 1);
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
rst->brrl = cores;
|
||||
asm volatile("dsb st" : : : "memory");
|
||||
|
||||
/* This is needed as a precautionary measure.
|
||||
* If some code before this has accidentally released the secondary
|
||||
* cores then the pre-bootloader code will trap them in a "wfe" unless
|
||||
* the scratchrw[6] is set. In this case we need a sev here to get these
|
||||
* cores moving again.
|
||||
*/
|
||||
asm volatile("sev");
|
||||
|
||||
while (timeout--) {
|
||||
flush_dcache_range((unsigned long)table, (unsigned long)table +
|
||||
CONFIG_MAX_CPUS * 64);
|
||||
for (i = 1; i < CONFIG_MAX_CPUS; i++) {
|
||||
if (table[i * WORDS_PER_SPIN_TABLE_ENTRY +
|
||||
SPIN_TABLE_ELEM_STATUS_IDX])
|
||||
cpu_up_mask |= 1 << i;
|
||||
}
|
||||
if (hweight32(cpu_up_mask) == hweight32(cores))
|
||||
break;
|
||||
udelay(10);
|
||||
}
|
||||
if (timeout <= 0) {
|
||||
printf("Not all cores (0x%x) are up (0x%x)\n",
|
||||
cores, cpu_up_mask);
|
||||
return 1;
|
||||
}
|
||||
printf("All (%d) cores are up.\n", hweight32(cores));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_core_valid(unsigned int core)
|
||||
{
|
||||
return !!((1 << core) & cpu_mask());
|
||||
}
|
||||
|
||||
int cpu_reset(int nr)
|
||||
{
|
||||
puts("Feature is not implemented.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_disable(int nr)
|
||||
{
|
||||
puts("Feature is not implemented.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int core_to_pos(int nr)
|
||||
{
|
||||
u32 cores = cpu_mask();
|
||||
int i, count = 0;
|
||||
|
||||
if (nr == 0) {
|
||||
return 0;
|
||||
} else if (nr >= hweight32(cores)) {
|
||||
puts("Not a valid core number.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 1; i < 32; i++) {
|
||||
if (is_core_valid(i)) {
|
||||
count++;
|
||||
if (count == nr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int cpu_status(int nr)
|
||||
{
|
||||
u64 *table;
|
||||
int pos;
|
||||
|
||||
if (nr == 0) {
|
||||
table = (u64 *)get_spin_tbl_addr();
|
||||
printf("table base @ 0x%p\n", table);
|
||||
} else {
|
||||
pos = core_to_pos(nr);
|
||||
if (pos < 0)
|
||||
return -1;
|
||||
table = (u64 *)get_spin_tbl_addr() + pos *
|
||||
WORDS_PER_SPIN_TABLE_ENTRY;
|
||||
printf("table @ 0x%p\n", table);
|
||||
printf(" addr - 0x%016llx\n",
|
||||
table[SPIN_TABLE_ELEM_ENTRY_ADDR_IDX]);
|
||||
printf(" status - 0x%016llx\n",
|
||||
table[SPIN_TABLE_ELEM_STATUS_IDX]);
|
||||
printf(" lpid - 0x%016llx\n",
|
||||
table[SPIN_TABLE_ELEM_LPID_IDX]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_release(int nr, int argc, char * const argv[])
|
||||
{
|
||||
u64 boot_addr;
|
||||
u64 *table = (u64 *)get_spin_tbl_addr();
|
||||
int pos;
|
||||
|
||||
pos = core_to_pos(nr);
|
||||
if (pos <= 0)
|
||||
return -1;
|
||||
|
||||
table += pos * WORDS_PER_SPIN_TABLE_ENTRY;
|
||||
boot_addr = simple_strtoull(argv[0], NULL, 16);
|
||||
table[SPIN_TABLE_ELEM_ENTRY_ADDR_IDX] = boot_addr;
|
||||
flush_dcache_range((unsigned long)table,
|
||||
(unsigned long)table + SPIN_TABLE_ELEM_SIZE);
|
||||
asm volatile("dsb st");
|
||||
smp_kick_all_cpus(); /* only those with entry addr set will run */
|
||||
|
||||
return 0;
|
||||
}
|
36
arch/arm/cpu/armv8/fsl-lsch3/mp.h
Normal file
36
arch/arm/cpu/armv8/fsl-lsch3/mp.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2014, Freescale Semiconductor
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _FSL_CH3_MP_H
|
||||
#define _FSL_CH3_MP_H
|
||||
|
||||
/*
|
||||
* Each spin table element is defined as
|
||||
* struct {
|
||||
* uint64_t entry_addr;
|
||||
* uint64_t status;
|
||||
* uint64_t lpid;
|
||||
* };
|
||||
* we pad this struct to 64 bytes so each entry is in its own cacheline
|
||||
* the actual spin table is an array of these structures
|
||||
*/
|
||||
#define SPIN_TABLE_ELEM_ENTRY_ADDR_IDX 0
|
||||
#define SPIN_TABLE_ELEM_STATUS_IDX 1
|
||||
#define SPIN_TABLE_ELEM_LPID_IDX 2
|
||||
#define WORDS_PER_SPIN_TABLE_ENTRY 8 /* pad to 64 bytes */
|
||||
#define SPIN_TABLE_ELEM_SIZE 64
|
||||
|
||||
#define id_to_core(x) ((x & 3) | (x >> 6))
|
||||
#ifndef __ASSEMBLY__
|
||||
extern u64 __spin_table[];
|
||||
extern u64 *secondary_boot_code;
|
||||
extern size_t __secondary_boot_code_size;
|
||||
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);
|
||||
#endif
|
||||
#endif /* _FSL_CH3_MP_H */
|
@ -14,70 +14,11 @@
|
||||
ENTRY(armv8_switch_to_el2)
|
||||
switch_el x0, 1f, 0f, 0f
|
||||
0: ret
|
||||
1:
|
||||
mov x0, #0x5b1 /* Non-secure EL0/EL1 | HVC | 64bit EL2 */
|
||||
msr scr_el3, x0
|
||||
msr cptr_el3, xzr /* Disable coprocessor traps to EL3 */
|
||||
mov x0, #0x33ff
|
||||
msr cptr_el2, x0 /* Disable coprocessor traps to EL2 */
|
||||
|
||||
/* Initialize SCTLR_EL2 */
|
||||
msr sctlr_el2, xzr
|
||||
|
||||
/* Return to the EL2_SP2 mode from EL3 */
|
||||
mov x0, sp
|
||||
msr sp_el2, x0 /* Migrate SP */
|
||||
mrs x0, vbar_el3
|
||||
msr vbar_el2, x0 /* Migrate VBAR */
|
||||
mov x0, #0x3c9
|
||||
msr spsr_el3, x0 /* EL2_SP2 | D | A | I | F */
|
||||
msr elr_el3, lr
|
||||
eret
|
||||
1: armv8_switch_to_el2_m x0
|
||||
ENDPROC(armv8_switch_to_el2)
|
||||
|
||||
ENTRY(armv8_switch_to_el1)
|
||||
switch_el x0, 0f, 1f, 0f
|
||||
0: ret
|
||||
1:
|
||||
/* Initialize Generic Timers */
|
||||
mrs x0, cnthctl_el2
|
||||
orr x0, x0, #0x3 /* Enable EL1 access to timers */
|
||||
msr cnthctl_el2, x0
|
||||
msr cntvoff_el2, xzr
|
||||
mrs x0, cntkctl_el1
|
||||
orr x0, x0, #0x3 /* Enable EL0 access to timers */
|
||||
msr cntkctl_el1, x0
|
||||
|
||||
/* Initilize MPID/MPIDR registers */
|
||||
mrs x0, midr_el1
|
||||
mrs x1, mpidr_el1
|
||||
msr vpidr_el2, x0
|
||||
msr vmpidr_el2, x1
|
||||
|
||||
/* Disable coprocessor traps */
|
||||
mov x0, #0x33ff
|
||||
msr cptr_el2, x0 /* Disable coprocessor traps to EL2 */
|
||||
msr hstr_el2, xzr /* Disable coprocessor traps to EL2 */
|
||||
mov x0, #3 << 20
|
||||
msr cpacr_el1, x0 /* Enable FP/SIMD at EL1 */
|
||||
|
||||
/* Initialize HCR_EL2 */
|
||||
mov x0, #(1 << 31) /* 64bit EL1 */
|
||||
orr x0, x0, #(1 << 29) /* Disable HVC */
|
||||
msr hcr_el2, x0
|
||||
|
||||
/* SCTLR_EL1 initialization */
|
||||
mov x0, #0x0800
|
||||
movk x0, #0x30d0, lsl #16
|
||||
msr sctlr_el1, x0
|
||||
|
||||
/* Return to the EL1_SP1 mode from EL2 */
|
||||
mov x0, sp
|
||||
msr sp_el1, x0 /* Migrate SP */
|
||||
mrs x0, vbar_el2
|
||||
msr vbar_el1, x0 /* Migrate VBAR */
|
||||
mov x0, #0x3c5
|
||||
msr spsr_el2, x0 /* EL1_SP1 | D | A | I | F */
|
||||
msr elr_el2, lr
|
||||
eret
|
||||
1: armv8_switch_to_el1_m x0, x1
|
||||
ENDPROC(armv8_switch_to_el1)
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define _ASM_ARMV8_FSL_LSCH3_CONFIG_
|
||||
|
||||
#include <fsl_ddrc_version.h>
|
||||
|
||||
#define CONFIG_MP
|
||||
#define CONFIG_SYS_FSL_OCRAM_BASE 0x18000000 /* initial RAM */
|
||||
/* Link Definitions */
|
||||
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_FSL_OCRAM_BASE + 0xfff0)
|
||||
@ -16,8 +16,10 @@
|
||||
#define CONFIG_SYS_IMMR 0x01000000
|
||||
#define CONFIG_SYS_FSL_DDR_ADDR (CONFIG_SYS_IMMR + 0x00080000)
|
||||
#define CONFIG_SYS_FSL_DDR2_ADDR (CONFIG_SYS_IMMR + 0x00090000)
|
||||
#define CONFIG_SYS_FSL_DDR3_ADDR 0x08210000
|
||||
#define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00E00000)
|
||||
#define CONFIG_SYS_FSL_PMU_ADDR (CONFIG_SYS_IMMR + 0x00E30000)
|
||||
#define CONFIG_SYS_FSL_RST_ADDR (CONFIG_SYS_IMMR + 0x00E60000)
|
||||
#define CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR (CONFIG_SYS_IMMR + 0x00300000)
|
||||
#define CONFIG_SYS_FSL_CH3_CLK_GRPB_ADDR (CONFIG_SYS_IMMR + 0x00310000)
|
||||
#define CONFIG_SYS_FSL_CH3_CLK_CTRL_ADDR (CONFIG_SYS_IMMR + 0x00370000)
|
||||
@ -60,7 +62,7 @@
|
||||
#ifdef CONFIG_LS2085A
|
||||
#define CONFIG_MAX_CPUS 16
|
||||
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 2
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 3
|
||||
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 4, 4 }
|
||||
#else
|
||||
#error SoC not defined
|
||||
|
@ -113,4 +113,39 @@ struct ccsr_clk_ctrl {
|
||||
u8 res_04[0x20-0x04];
|
||||
} clkcncsr[8];
|
||||
};
|
||||
|
||||
struct ccsr_reset {
|
||||
u32 rstcr; /* 0x000 */
|
||||
u32 rstcrsp; /* 0x004 */
|
||||
u8 res_008[0x10-0x08]; /* 0x008 */
|
||||
u32 rstrqmr1; /* 0x010 */
|
||||
u32 rstrqmr2; /* 0x014 */
|
||||
u32 rstrqsr1; /* 0x018 */
|
||||
u32 rstrqsr2; /* 0x01c */
|
||||
u32 rstrqwdtmrl; /* 0x020 */
|
||||
u32 rstrqwdtmru; /* 0x024 */
|
||||
u8 res_028[0x30-0x28]; /* 0x028 */
|
||||
u32 rstrqwdtsrl; /* 0x030 */
|
||||
u32 rstrqwdtsru; /* 0x034 */
|
||||
u8 res_038[0x60-0x38]; /* 0x038 */
|
||||
u32 brrl; /* 0x060 */
|
||||
u32 brru; /* 0x064 */
|
||||
u8 res_068[0x80-0x68]; /* 0x068 */
|
||||
u32 pirset; /* 0x080 */
|
||||
u32 pirclr; /* 0x084 */
|
||||
u8 res_088[0x90-0x88]; /* 0x088 */
|
||||
u32 brcorenbr; /* 0x090 */
|
||||
u8 res_094[0x100-0x94]; /* 0x094 */
|
||||
u32 rcw_reqr; /* 0x100 */
|
||||
u32 rcw_completion; /* 0x104 */
|
||||
u8 res_108[0x110-0x108]; /* 0x108 */
|
||||
u32 pbi_reqr; /* 0x110 */
|
||||
u32 pbi_completion; /* 0x114 */
|
||||
u8 res_118[0xa00-0x118]; /* 0x118 */
|
||||
u32 qmbm_warmrst; /* 0xa00 */
|
||||
u32 soc_warmrst; /* 0xa04 */
|
||||
u8 res_a08[0xbf8-0xa08]; /* 0xa08 */
|
||||
u32 ip_rev1; /* 0xbf8 */
|
||||
u32 ip_rev2; /* 0xbfc */
|
||||
};
|
||||
#endif /* __ARCH_FSL_LSCH3_IMMAP_H */
|
||||
|
@ -50,7 +50,11 @@
|
||||
#ifdef CONFIG_DDR_SPD
|
||||
#define CONFIG_SYS_FSL_DDR_BE
|
||||
#define CONFIG_VERY_BIG_RAM
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
#define CONFIG_SYS_FSL_DDRC_GEN4
|
||||
#else
|
||||
#define CONFIG_SYS_FSL_DDRC_ARM_GEN3
|
||||
#endif
|
||||
#define CONFIG_SYS_FSL_DDR
|
||||
#define CONFIG_SYS_LS1_DDR_BLOCK1_SIZE ((phys_size_t)2 << 30)
|
||||
#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_LS1_DDR_BLOCK1_SIZE
|
||||
@ -71,6 +75,7 @@
|
||||
#define CONFIG_MAX_CPUS 2
|
||||
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
|
||||
#define CONFIG_NUM_DDR_CONTROLLERS 1
|
||||
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0
|
||||
#else
|
||||
#error SoC not defined
|
||||
#endif
|
||||
|
@ -105,6 +105,99 @@ lr .req x30
|
||||
cbz \xreg1, \master_label
|
||||
.endm
|
||||
|
||||
.macro armv8_switch_to_el2_m, xreg1
|
||||
/* 64bit EL2 | HCE | SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1 */
|
||||
mov \xreg1, #0x5b1
|
||||
msr scr_el3, \xreg1
|
||||
msr cptr_el3, xzr /* Disable coprocessor traps to EL3 */
|
||||
mov \xreg1, #0x33ff
|
||||
msr cptr_el2, \xreg1 /* Disable coprocessor traps to EL2 */
|
||||
|
||||
/* Initialize SCTLR_EL2
|
||||
*
|
||||
* setting RES1 bits (29,28,23,22,18,16,11,5,4) to 1
|
||||
* and RES0 bits (31,30,27,26,24,21,20,17,15-13,10-6) +
|
||||
* EE,WXN,I,SA,C,A,M to 0
|
||||
*/
|
||||
mov \xreg1, #0x0830
|
||||
movk \xreg1, #0x30C5, lsl #16
|
||||
msr sctlr_el2, \xreg1
|
||||
|
||||
/* Return to the EL2_SP2 mode from EL3 */
|
||||
mov \xreg1, sp
|
||||
msr sp_el2, \xreg1 /* Migrate SP */
|
||||
mrs \xreg1, vbar_el3
|
||||
msr vbar_el2, \xreg1 /* Migrate VBAR */
|
||||
mov \xreg1, #0x3c9
|
||||
msr spsr_el3, \xreg1 /* EL2_SP2 | D | A | I | F */
|
||||
msr elr_el3, lr
|
||||
eret
|
||||
.endm
|
||||
|
||||
.macro armv8_switch_to_el1_m, xreg1, xreg2
|
||||
/* Initialize Generic Timers */
|
||||
mrs \xreg1, cnthctl_el2
|
||||
orr \xreg1, \xreg1, #0x3 /* Enable EL1 access to timers */
|
||||
msr cnthctl_el2, \xreg1
|
||||
msr cntvoff_el2, xzr
|
||||
|
||||
/* Initilize MPID/MPIDR registers */
|
||||
mrs \xreg1, midr_el1
|
||||
mrs \xreg2, mpidr_el1
|
||||
msr vpidr_el2, \xreg1
|
||||
msr vmpidr_el2, \xreg2
|
||||
|
||||
/* Disable coprocessor traps */
|
||||
mov \xreg1, #0x33ff
|
||||
msr cptr_el2, \xreg1 /* Disable coprocessor traps to EL2 */
|
||||
msr hstr_el2, xzr /* Disable coprocessor traps to EL2 */
|
||||
mov \xreg1, #3 << 20
|
||||
msr cpacr_el1, \xreg1 /* Enable FP/SIMD at EL1 */
|
||||
|
||||
/* Initialize HCR_EL2 */
|
||||
mov \xreg1, #(1 << 31) /* 64bit EL1 */
|
||||
orr \xreg1, \xreg1, #(1 << 29) /* Disable HVC */
|
||||
msr hcr_el2, \xreg1
|
||||
|
||||
/* SCTLR_EL1 initialization
|
||||
*
|
||||
* setting RES1 bits (29,28,23,22,20,11) to 1
|
||||
* and RES0 bits (31,30,27,21,17,13,10,6) +
|
||||
* UCI,EE,EOE,WXN,nTWE,nTWI,UCT,DZE,I,UMA,SED,ITD,
|
||||
* CP15BEN,SA0,SA,C,A,M to 0
|
||||
*/
|
||||
mov \xreg1, #0x0800
|
||||
movk \xreg1, #0x30d0, lsl #16
|
||||
msr sctlr_el1, \xreg1
|
||||
|
||||
/* Return to the EL1_SP1 mode from EL2 */
|
||||
mov \xreg1, sp
|
||||
msr sp_el1, \xreg1 /* Migrate SP */
|
||||
mrs \xreg1, vbar_el2
|
||||
msr vbar_el1, \xreg1 /* Migrate VBAR */
|
||||
mov \xreg1, #0x3c5
|
||||
msr spsr_el2, \xreg1 /* EL1_SP1 | D | A | I | F */
|
||||
msr elr_el2, lr
|
||||
eret
|
||||
.endm
|
||||
|
||||
#if defined(CONFIG_GICV3)
|
||||
.macro gic_wait_for_interrupt_m xreg1
|
||||
0 : wfi
|
||||
mrs \xreg1, ICC_IAR1_EL1
|
||||
msr ICC_EOIR1_EL1, \xreg1
|
||||
cbnz \xreg1, 0b
|
||||
.endm
|
||||
#elif defined(CONFIG_GICV2)
|
||||
.macro gic_wait_for_interrupt_m xreg1, wreg2
|
||||
0 : wfi
|
||||
ldr \wreg2, [\xreg1, GICC_AIAR]
|
||||
str \wreg2, [\xreg1, GICC_AEOIR]
|
||||
and \wreg2, \wreg2, #3ff
|
||||
cbnz \wreg2, 0b
|
||||
.endm
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_ARM64 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -10,8 +10,8 @@
|
||||
#include <asm-offsets.h>
|
||||
#include <config.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/macro.h>
|
||||
#include <asm/gic.h>
|
||||
#include <asm/macro.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@ -181,14 +181,10 @@ ENDPROC(gic_kick_secondary_cpus)
|
||||
*
|
||||
*************************************************************************/
|
||||
ENTRY(gic_wait_for_interrupt)
|
||||
0: wfi
|
||||
#if defined(CONFIG_GICV3)
|
||||
mrs x9, ICC_IAR1_EL1
|
||||
msr ICC_EOIR1_EL1, x9
|
||||
gic_wait_for_interrupt_m x9
|
||||
#elif defined(CONFIG_GICV2)
|
||||
ldr w9, [x0, GICC_AIAR]
|
||||
str w9, [x0, GICC_AEOIR]
|
||||
gic_wait_for_interrupt_m x0, w9
|
||||
#endif
|
||||
cbnz w9, 0b
|
||||
ret
|
||||
ENDPROC(gic_wait_for_interrupt)
|
||||
|
@ -441,7 +441,7 @@ phys_size_t initdram(int board_type)
|
||||
|
||||
/* Board-specific functions defined in each board's ddr.c */
|
||||
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
|
||||
unsigned int ctrl_num);
|
||||
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl);
|
||||
void read_tlbcam_entry(int idx, u32 *valid, u32 *tsize, unsigned long *epn,
|
||||
phys_addr_t *rpn);
|
||||
unsigned int
|
||||
@ -459,7 +459,7 @@ static void dump_spd_ddr_reg(void)
|
||||
spd[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR];
|
||||
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
|
||||
fsl_ddr_get_spd(spd[i], i);
|
||||
fsl_ddr_get_spd(spd[i], i, CONFIG_DIMM_SLOTS_PER_CTLR);
|
||||
|
||||
puts("SPD data of all dimms (zero vaule is omitted)...\n");
|
||||
puts("Byte (hex) ");
|
||||
|
@ -4,3 +4,4 @@ S: Maintained
|
||||
F: board/freescale/ls1021aqds/
|
||||
F: include/configs/ls1021aqds.h
|
||||
F: configs/ls1021aqds_nor_defconfig
|
||||
F: configs/ls1021aqds_ddr4_nor_defconfig
|
||||
|
@ -79,7 +79,6 @@ found:
|
||||
*/
|
||||
popts->wrlvl_override = 1;
|
||||
popts->wrlvl_sample = 0xf;
|
||||
popts->cswl_override = DDR_CSWL_CS0;
|
||||
|
||||
/*
|
||||
* Rtt and Rtt_WR override
|
||||
@ -89,9 +88,17 @@ found:
|
||||
/* Enable ZQ calibration */
|
||||
popts->zq_en = 1;
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_80ohm);
|
||||
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_80ohm) |
|
||||
DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
|
||||
#else
|
||||
popts->cswl_override = DDR_CSWL_CS0;
|
||||
|
||||
/* DHC_EN =1, ODT = 75 Ohm */
|
||||
popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm);
|
||||
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_DDR_RAW_TIMING
|
||||
|
@ -30,6 +30,13 @@ static const struct board_specific_parameters udimm0[] = {
|
||||
* num| hi| rank| clk| wrlvl | wrlvl | wrlvl | cpo |wrdata|2T
|
||||
* ranks| mhz| GB |adjst| start | ctl2 | ctl3 | |delay |
|
||||
*/
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
{2, 1666, 0, 4, 7, 0x0808090B, 0x0C0D0E0A,},
|
||||
{2, 1900, 0, 4, 6, 0x08080A0C, 0x0D0E0F0A,},
|
||||
{1, 1666, 0, 4, 8, 0x090A0B0B, 0x0C0D0E0C,},
|
||||
{1, 1900, 0, 4, 9, 0x0A0B0C0B, 0x0D0E0F0D,},
|
||||
{1, 2200, 0, 4, 10, 0x0B0C0D0C, 0x0E0F110E,},
|
||||
#elif defined(CONFIG_SYS_FSL_DDR3)
|
||||
{1, 833, 1, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0},
|
||||
{1, 1350, 1, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0},
|
||||
{1, 833, 2, 6, 8, 0x06060607, 0x08080807, 0x1f, 2, 0},
|
||||
@ -39,6 +46,9 @@ static const struct board_specific_parameters udimm0[] = {
|
||||
{2, 1350, 0, 6, 8, 0x0708080A, 0x0A0B0C09, 0x1f, 2, 0},
|
||||
{2, 1666, 4, 4, 0xa, 0x0B08090C, 0x0B0E0D0A, 0x1f, 2, 0},
|
||||
{2, 1666, 0, 4, 0xa, 0x0B08090C, 0x0B0E0D0A, 0x1f, 2, 0},
|
||||
#else
|
||||
#error DDR type not defined
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -30,9 +30,9 @@ void fsl_ddr_board_options(memctl_options_t *popts,
|
||||
* to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
|
||||
*/
|
||||
if (popts->registered_dimm_en)
|
||||
pbsp = rdimms[0];
|
||||
pbsp = rdimms[ctrl_num];
|
||||
else
|
||||
pbsp = udimms[0];
|
||||
pbsp = udimms[ctrl_num];
|
||||
|
||||
|
||||
/* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
|
||||
@ -72,6 +72,12 @@ found:
|
||||
pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
|
||||
pbsp->wrlvl_ctl_3);
|
||||
|
||||
if (ctrl_num == CONFIG_DP_DDR_CTRL) {
|
||||
/* force DDR bus width to 32 bits */
|
||||
popts->data_bus_width = 1;
|
||||
popts->otf_burst_chop_en = 0;
|
||||
popts->burst_length = DDR_BL8;
|
||||
}
|
||||
/*
|
||||
* Factors to consider for half-strength driver enable:
|
||||
* - number of DIMMs installed
|
||||
@ -163,6 +169,10 @@ phys_size_t initdram(int board_type)
|
||||
|
||||
void dram_init_banksize(void)
|
||||
{
|
||||
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
|
||||
phys_size_t dp_ddr_size;
|
||||
#endif
|
||||
|
||||
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
|
||||
if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
|
||||
gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
|
||||
@ -172,4 +182,24 @@ void dram_init_banksize(void)
|
||||
} else {
|
||||
gd->bd->bi_dram[0].size = gd->ram_size;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
|
||||
/* initialize DP-DDR here */
|
||||
puts("DP-DDR: ");
|
||||
/*
|
||||
* DDR controller use 0 as the base address for binding.
|
||||
* It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
|
||||
*/
|
||||
dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
|
||||
CONFIG_DP_DDR_CTRL,
|
||||
CONFIG_DP_DDR_NUM_CTRLS,
|
||||
CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
|
||||
NULL, NULL, NULL);
|
||||
if (dp_ddr_size) {
|
||||
gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
|
||||
gd->bd->bi_dram[2].size = dp_ddr_size;
|
||||
} else {
|
||||
puts("Not detected");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -33,6 +33,18 @@ static const struct board_specific_parameters udimm0[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
/* DP-DDR DIMM */
|
||||
static const struct board_specific_parameters udimm2[] = {
|
||||
/*
|
||||
* memory controller 2
|
||||
* num| hi| rank| clk| wrlvl | wrlvl | wrlvl
|
||||
* ranks| mhz| GB |adjst| start | ctl2 | ctl3
|
||||
*/
|
||||
{2, 2140, 0, 4, 4, 0x0, 0x0},
|
||||
{1, 2140, 0, 4, 4, 0x0, 0x0},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct board_specific_parameters rdimm0[] = {
|
||||
/*
|
||||
* memory controller 0
|
||||
@ -45,12 +57,29 @@ static const struct board_specific_parameters rdimm0[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
/* DP-DDR DIMM */
|
||||
static const struct board_specific_parameters rdimm2[] = {
|
||||
/*
|
||||
* memory controller 2
|
||||
* num| hi| rank| clk| wrlvl | wrlvl | wrlvl
|
||||
* ranks| mhz| GB |adjst| start | ctl2 | ctl3
|
||||
*/
|
||||
{4, 2140, 0, 5, 4, 0x0, 0x0},
|
||||
{2, 2140, 0, 5, 4, 0x0, 0x0},
|
||||
{1, 2140, 0, 4, 4, 0x0, 0x0},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct board_specific_parameters *udimms[] = {
|
||||
udimm0,
|
||||
udimm0,
|
||||
udimm2,
|
||||
};
|
||||
|
||||
static const struct board_specific_parameters *rdimms[] = {
|
||||
rdimm0,
|
||||
rdimm0,
|
||||
rdimm2,
|
||||
};
|
||||
|
||||
|
||||
|
@ -13,12 +13,18 @@
|
||||
#include <fdt_support.h>
|
||||
#include <libfdt.h>
|
||||
#include <fsl_mc.h>
|
||||
#include <environment.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
init_final_memctl_regs();
|
||||
|
||||
#ifdef CONFIG_ENV_IS_NOWHERE
|
||||
gd->env_addr = (ulong)&default_environment[0];
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -29,9 +35,20 @@ int board_early_init_f(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void detail_board_ddr_info(void)
|
||||
{
|
||||
puts("\nDDR ");
|
||||
print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
|
||||
print_ddr_info(0);
|
||||
if (gd->bd->bi_dram[2].size) {
|
||||
puts("\nDP-DDR ");
|
||||
print_size(gd->bd->bi_dram[2].size, "");
|
||||
print_ddr_info(CONFIG_DP_DDR_CTRL);
|
||||
}
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
printf("DRAM: ");
|
||||
gd->ram_size = initdram(0);
|
||||
|
||||
return 0;
|
||||
@ -88,6 +105,8 @@ void ft_board_setup(void *blob, bd_t *bd)
|
||||
phys_addr_t base;
|
||||
phys_size_t size;
|
||||
|
||||
ft_cpu_setup(blob, bd);
|
||||
|
||||
/* limit the memory size to bank 1 until Linux can handle 40-bit PA */
|
||||
base = getenv_bootm_low();
|
||||
size = getenv_bootm_size();
|
||||
|
@ -930,15 +930,6 @@ void fdt_del_node_and_alias(void *blob, const char *alias)
|
||||
fdt_delprop(blob, off, alias);
|
||||
}
|
||||
|
||||
/* Helper to read a big number; size is in cells (not bytes) */
|
||||
static inline u64 of_read_number(const fdt32_t *cell, int size)
|
||||
{
|
||||
u64 r = 0;
|
||||
while (size--)
|
||||
r = (r << 32) | fdt32_to_cpu(*(cell++));
|
||||
return r;
|
||||
}
|
||||
|
||||
#define PRu64 "%llx"
|
||||
|
||||
/* Max address size we deal with */
|
||||
@ -972,7 +963,7 @@ struct of_bus {
|
||||
};
|
||||
|
||||
/* Default translator (generic bus) */
|
||||
static void of_bus_default_count_cells(void *blob, int parentoffset,
|
||||
void of_bus_default_count_cells(void *blob, int parentoffset,
|
||||
int *addrc, int *sizec)
|
||||
{
|
||||
const fdt32_t *prop;
|
||||
|
3
configs/ls1021aqds_ddr4_nor_defconfig
Normal file
3
configs/ls1021aqds_ddr4_nor_defconfig
Normal file
@ -0,0 +1,3 @@
|
||||
CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
|
||||
CONFIG_ARM=y
|
||||
CONFIG_TARGET_LS1021AQDS=y
|
@ -297,10 +297,13 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
|
||||
unsigned char taxpd_mclk = 0;
|
||||
/* 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();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
/* tXP=max(4nCK, 6ns) */
|
||||
int txp = max((get_memory_clk_period_ps() * 4), 6000); /* unit=ps */
|
||||
int txp = max(mclk_ps * 4, 6000); /* unit=ps */
|
||||
trwt_mclk = 2;
|
||||
twrt_mclk = 1;
|
||||
act_pd_exit_mclk = picos_to_mclk(txp);
|
||||
@ -311,16 +314,19 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
|
||||
*/
|
||||
tmrd_mclk = max(24, picos_to_mclk(15000));
|
||||
#elif defined(CONFIG_SYS_FSL_DDR3)
|
||||
unsigned int data_rate = get_ddr_freq(0);
|
||||
int txp;
|
||||
/*
|
||||
* (tXARD and tXARDS). Empirical?
|
||||
* The DDR3 spec has not tXARD,
|
||||
* we use the tXP instead of it.
|
||||
* tXP=max(3nCK, 7.5ns) for DDR3.
|
||||
* tXP=max(3nCK, 7.5ns) for DDR3-800, 1066
|
||||
* max(3nCK, 6ns) for DDR3-1333, 1600, 1866, 2133
|
||||
* spec has not the tAXPD, we use
|
||||
* tAXPD=1, need design to confirm.
|
||||
*/
|
||||
int txp = max((get_memory_clk_period_ps() * 3), 7500); /* unit=ps */
|
||||
unsigned int data_rate = get_ddr_freq(0);
|
||||
txp = max(mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
|
||||
|
||||
tmrd_mclk = 4;
|
||||
/* set the turnaround time */
|
||||
|
||||
@ -578,6 +584,9 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
|
||||
unsigned char cke_pls;
|
||||
/* Window for four activates (tFAW) */
|
||||
unsigned short four_act;
|
||||
#ifdef CONFIG_SYS_FSL_DDR3
|
||||
const unsigned int mclk_ps = get_memory_clk_period_ps();
|
||||
#endif
|
||||
|
||||
/* FIXME add check that this must be less than acttorw_mclk */
|
||||
add_lat_mclk = additive_latency;
|
||||
@ -619,10 +628,17 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
|
||||
#ifdef CONFIG_SYS_FSL_DDR4
|
||||
cpo = 0;
|
||||
cke_pls = max(3, picos_to_mclk(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(3, picos_to_mclk(mclk_ps > 1870 ? 7500 :
|
||||
(mclk_ps > 1245 ? 5625 : 5000)));
|
||||
#else
|
||||
cke_pls = picos_to_mclk(popts->tcke_clock_pulse_width_ps);
|
||||
cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR;
|
||||
#endif
|
||||
|
||||
four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps);
|
||||
|
||||
ddr->timing_cfg_2 = (0
|
||||
@ -1886,9 +1902,12 @@ static void set_timing_cfg_9(fsl_ddr_cfg_regs_t *ddr)
|
||||
debug("FSLDDR: timing_cfg_9 = 0x%08x\n", ddr->timing_cfg_9);
|
||||
}
|
||||
|
||||
/* This function needs to be called after set_ddr_sdram_cfg() is called */
|
||||
static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr,
|
||||
const dimm_params_t *dimm_params)
|
||||
{
|
||||
unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1;
|
||||
|
||||
ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) |
|
||||
((dimm_params->dq_mapping[1] & 0x3F) << 20) |
|
||||
((dimm_params->dq_mapping[2] & 0x3F) << 14) |
|
||||
@ -1907,9 +1926,11 @@ static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr,
|
||||
((dimm_params->dq_mapping[15] & 0x3F) << 8) |
|
||||
((dimm_params->dq_mapping[16] & 0x3F) << 2);
|
||||
|
||||
/* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */
|
||||
ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) |
|
||||
((dimm_params->dq_mapping[8] & 0x3F) << 20) |
|
||||
((dimm_params->dq_mapping[9] & 0x3F) << 14) |
|
||||
(acc_ecc_en ? 0 :
|
||||
(dimm_params->dq_mapping[9] & 0x3F) << 14) |
|
||||
dimm_params->dq_mapping_ors;
|
||||
|
||||
debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0);
|
||||
@ -2276,7 +2297,7 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
|
||||
if (ip_rev > 0x40400)
|
||||
unq_mrs_en = 1;
|
||||
|
||||
if (ip_rev > 0x40700)
|
||||
if ((ip_rev > 0x40700) && (popts->cswl_override != 0))
|
||||
ddr->debug[18] = popts->cswl_override;
|
||||
|
||||
set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en);
|
||||
|
@ -113,7 +113,7 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
|
||||
#define spd_to_ps(mtb, ftb) \
|
||||
(mtb * pdimm->mtb_ps + (ftb * pdimm->ftb_10th_ps) / 10)
|
||||
/*
|
||||
* ddr_compute_dimm_parameters for DDR3 SPD
|
||||
* ddr_compute_dimm_parameters for DDR4 SPD
|
||||
*
|
||||
* Compute DIMM parameters based upon the SPD information in spd.
|
||||
* Writes the results to the dimm_params_t structure pointed by pdimm.
|
||||
@ -165,17 +165,17 @@ ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd,
|
||||
+ pdimm->ec_sdram_width;
|
||||
pdimm->device_width = 1 << ((spd->organization & 0x7) + 2);
|
||||
|
||||
/* These are the types defined by the JEDEC DDR3 SPD spec */
|
||||
/* These are the types defined by the JEDEC SPD spec */
|
||||
pdimm->mirrored_dimm = 0;
|
||||
pdimm->registered_dimm = 0;
|
||||
switch (spd->module_type & DDR3_SPD_MODULETYPE_MASK) {
|
||||
case DDR3_SPD_MODULETYPE_RDIMM:
|
||||
switch (spd->module_type & DDR4_SPD_MODULETYPE_MASK) {
|
||||
case DDR4_SPD_MODULETYPE_RDIMM:
|
||||
/* Registered/buffered DIMMs */
|
||||
pdimm->registered_dimm = 1;
|
||||
break;
|
||||
|
||||
case DDR3_SPD_MODULETYPE_UDIMM:
|
||||
case DDR3_SPD_MODULETYPE_SO_DIMM:
|
||||
case DDR4_SPD_MODULETYPE_UDIMM:
|
||||
case DDR4_SPD_MODULETYPE_SO_DIMM:
|
||||
/* Unbuffered DIMMs */
|
||||
if (spd->mod_section.unbuffered.addr_mapping & 0x1)
|
||||
pdimm->mirrored_dimm = 1;
|
||||
|
@ -216,7 +216,7 @@ step2:
|
||||
* For example, 2GB on 666MT/s 64-bit bus takes about 402ms
|
||||
* Let's wait for 800ms
|
||||
*/
|
||||
bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
|
||||
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;
|
||||
@ -233,5 +233,4 @@ step2:
|
||||
|
||||
if (timeout <= 0)
|
||||
printf("Waiting for D_INIT timeout. Memory may not work.\n");
|
||||
|
||||
}
|
||||
|
@ -517,7 +517,6 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
|
||||
CTRL_OPTIONS(rcw_2),
|
||||
CTRL_OPTIONS(ddr_cdr1),
|
||||
CTRL_OPTIONS(ddr_cdr2),
|
||||
CTRL_OPTIONS(tcke_clock_pulse_width_ps),
|
||||
CTRL_OPTIONS(tfaw_window_four_activates_ps),
|
||||
CTRL_OPTIONS(trwt_override),
|
||||
CTRL_OPTIONS(trwt),
|
||||
@ -808,7 +807,6 @@ static void print_memctl_options(const memctl_options_t *popts)
|
||||
CTRL_OPTIONS(rcw_2),
|
||||
CTRL_OPTIONS_HEX(ddr_cdr1),
|
||||
CTRL_OPTIONS_HEX(ddr_cdr2),
|
||||
CTRL_OPTIONS(tcke_clock_pulse_width_ps),
|
||||
CTRL_OPTIONS(tfaw_window_four_activates_ps),
|
||||
CTRL_OPTIONS(trwt_override),
|
||||
CTRL_OPTIONS(trwt),
|
||||
|
@ -135,7 +135,7 @@ __attribute__((weak, alias("__get_spd")))
|
||||
void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address);
|
||||
|
||||
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
|
||||
unsigned int ctrl_num)
|
||||
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i2c_address = 0;
|
||||
@ -145,14 +145,14 @@ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
|
||||
for (i = 0; i < dimm_slots_per_ctrl; i++) {
|
||||
i2c_address = spd_i2c_addr[ctrl_num][i];
|
||||
get_spd(&(ctrl_dimms_spd[i]), i2c_address);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
|
||||
unsigned int ctrl_num)
|
||||
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl)
|
||||
{
|
||||
}
|
||||
#endif /* SPD_EEPROM_ADDRESSx */
|
||||
@ -231,9 +231,11 @@ const char * step_to_string(unsigned int step) {
|
||||
static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo,
|
||||
unsigned int dbw_cap_adj[])
|
||||
{
|
||||
int i, j;
|
||||
unsigned int i, j;
|
||||
unsigned long long total_mem, current_mem_base, total_ctlr_mem;
|
||||
unsigned long long rank_density, ctlr_density = 0;
|
||||
unsigned int first_ctrl = pinfo->first_ctrl;
|
||||
unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
|
||||
|
||||
/*
|
||||
* If a reduced data width is requested, but the SPD
|
||||
@ -241,7 +243,7 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo,
|
||||
* computed dimm capacities accordingly before
|
||||
* assigning addresses.
|
||||
*/
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
unsigned int found = 0;
|
||||
|
||||
switch (pinfo->memctl_opts[i].data_bus_width) {
|
||||
@ -295,12 +297,12 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo,
|
||||
debug("dbw_cap_adj[%d]=%d\n", i, dbw_cap_adj[i]);
|
||||
}
|
||||
|
||||
current_mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY;
|
||||
current_mem_base = pinfo->mem_base;
|
||||
total_mem = 0;
|
||||
if (pinfo->memctl_opts[0].memctl_interleaving) {
|
||||
rank_density = pinfo->dimm_params[0][0].rank_density >>
|
||||
dbw_cap_adj[0];
|
||||
switch (pinfo->memctl_opts[0].ba_intlv_ctl &
|
||||
if (pinfo->memctl_opts[first_ctrl].memctl_interleaving) {
|
||||
rank_density = pinfo->dimm_params[first_ctrl][0].rank_density >>
|
||||
dbw_cap_adj[first_ctrl];
|
||||
switch (pinfo->memctl_opts[first_ctrl].ba_intlv_ctl &
|
||||
FSL_DDR_CS0_CS1_CS2_CS3) {
|
||||
case FSL_DDR_CS0_CS1_CS2_CS3:
|
||||
ctlr_density = 4 * rank_density;
|
||||
@ -316,7 +318,7 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo,
|
||||
}
|
||||
debug("rank density is 0x%llx, ctlr density is 0x%llx\n",
|
||||
rank_density, ctlr_density);
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
if (pinfo->memctl_opts[i].memctl_interleaving) {
|
||||
switch (pinfo->memctl_opts[i].memctl_interleaving_mode) {
|
||||
case FSL_DDR_256B_INTERLEAVING:
|
||||
@ -372,7 +374,7 @@ static unsigned long long __step_assign_addresses(fsl_ddr_info_t *pinfo,
|
||||
* Simple linear assignment if memory
|
||||
* controllers are not interleaved.
|
||||
*/
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
total_ctlr_mem = 0;
|
||||
pinfo->common_timing_params[i].base_address =
|
||||
current_mem_base;
|
||||
@ -408,18 +410,23 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned long long total_mem = 0;
|
||||
int assert_reset;
|
||||
int assert_reset = 0;
|
||||
unsigned int first_ctrl = pinfo->first_ctrl;
|
||||
unsigned int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
|
||||
__maybe_unused int retval;
|
||||
__maybe_unused bool goodspd = false;
|
||||
__maybe_unused int dimm_slots_per_ctrl = pinfo->dimm_slots_per_ctrl;
|
||||
|
||||
fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
|
||||
common_timing_params_t *timing_params = pinfo->common_timing_params;
|
||||
assert_reset = board_need_mem_reset();
|
||||
if (pinfo->board_need_mem_reset)
|
||||
assert_reset = pinfo->board_need_mem_reset();
|
||||
|
||||
/* data bus width capacity adjust shift amount */
|
||||
unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS];
|
||||
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++)
|
||||
dbw_capacity_adjust[i] = 0;
|
||||
}
|
||||
|
||||
debug("starting at step %u (%s)\n",
|
||||
start_step, step_to_string(start_step));
|
||||
@ -428,28 +435,28 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
case STEP_GET_SPD:
|
||||
#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
|
||||
/* STEP 1: Gather all DIMM SPD data */
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i);
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i,
|
||||
dimm_slots_per_ctrl);
|
||||
}
|
||||
|
||||
case STEP_COMPUTE_DIMM_PARMS:
|
||||
/* STEP 2: Compute DIMM parameters from SPD data */
|
||||
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
|
||||
unsigned int retval;
|
||||
generic_spd_eeprom_t *spd =
|
||||
&(pinfo->spd_installed_dimms[i][j]);
|
||||
dimm_params_t *pdimm =
|
||||
&(pinfo->dimm_params[i][j]);
|
||||
|
||||
retval = compute_dimm_parameters(spd, pdimm, i);
|
||||
#ifdef CONFIG_SYS_DDR_RAW_TIMING
|
||||
if (!i && !j && retval) {
|
||||
printf("SPD error on controller %d! "
|
||||
"Trying fallback to raw timing "
|
||||
"calculation\n", i);
|
||||
fsl_ddr_get_dimm_params(pdimm, i, j);
|
||||
retval = fsl_ddr_get_dimm_params(pdimm,
|
||||
i, j);
|
||||
}
|
||||
#else
|
||||
if (retval == 2) {
|
||||
@ -463,13 +470,26 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
debug("Warning: compute_dimm_parameters"
|
||||
" non-zero return value for memctl=%u "
|
||||
"dimm=%u\n", i, j);
|
||||
} else {
|
||||
goodspd = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!goodspd) {
|
||||
/*
|
||||
* No valid SPD found
|
||||
* Throw an error if this is for main memory, i.e.
|
||||
* first_ctrl == 0. Otherwise, siliently return 0
|
||||
* as the memory size.
|
||||
*/
|
||||
if (first_ctrl == 0)
|
||||
printf("Error: No valid SPD detected.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#elif defined(CONFIG_SYS_DDR_RAW_TIMING)
|
||||
case STEP_COMPUTE_DIMM_PARMS:
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
|
||||
dimm_params_t *pdimm =
|
||||
&(pinfo->dimm_params[i][j]);
|
||||
@ -483,7 +503,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
* STEP 3: Compute a common set of timing parameters
|
||||
* suitable for all of the DIMMs on each memory controller
|
||||
*/
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
debug("Computing lowest common DIMM"
|
||||
" parameters for memctl=%u\n", i);
|
||||
compute_lowest_common_dimm_parameters(
|
||||
@ -494,7 +514,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
|
||||
case STEP_GATHER_OPTS:
|
||||
/* STEP 4: Gather configuration requirements from user */
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
debug("Reloading memory controller "
|
||||
"configuration options for memctl=%u\n", i);
|
||||
/*
|
||||
@ -516,9 +536,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
if (timing_params[i].all_dimms_registered)
|
||||
assert_reset = 1;
|
||||
}
|
||||
if (assert_reset) {
|
||||
debug("Asserting mem reset\n");
|
||||
board_assert_mem_reset();
|
||||
if (assert_reset && !size_only) {
|
||||
if (pinfo->board_mem_reset) {
|
||||
debug("Asserting mem reset\n");
|
||||
pinfo->board_mem_reset();
|
||||
} else {
|
||||
debug("Asserting mem reset missing\n");
|
||||
}
|
||||
}
|
||||
|
||||
case STEP_ASSIGN_ADDRESSES:
|
||||
@ -530,7 +554,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
case STEP_COMPUTE_REGS:
|
||||
/* STEP 6: compute controller register values */
|
||||
debug("FSL Memory ctrl register computation\n");
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
if (timing_params[i].ndimms_present == 0) {
|
||||
memset(&ddr_reg[i], 0,
|
||||
sizeof(fsl_ddr_cfg_regs_t));
|
||||
@ -558,7 +582,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
*/
|
||||
unsigned int max_end = 0;
|
||||
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
for (j = 0; j < CONFIG_CHIP_SELECTS_PER_CTRL; j++) {
|
||||
fsl_ddr_cfg_regs_t *reg = &ddr_reg[i];
|
||||
if (reg->cs[j].config & 0x80000000) {
|
||||
@ -578,53 +602,45 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
|
||||
}
|
||||
|
||||
total_mem = 1 + (((unsigned long long)max_end << 24ULL) |
|
||||
0xFFFFFFULL) - CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY;
|
||||
0xFFFFFFULL) - pinfo->mem_base;
|
||||
}
|
||||
|
||||
return total_mem;
|
||||
}
|
||||
|
||||
/*
|
||||
* fsl_ddr_sdram() -- this is the main function to be called by
|
||||
* initdram() in the board file.
|
||||
*
|
||||
* It returns amount of memory configured in bytes.
|
||||
*/
|
||||
phys_size_t fsl_ddr_sdram(void)
|
||||
phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i, first_ctrl, last_ctrl;
|
||||
#ifdef CONFIG_PPC
|
||||
unsigned int law_memctl = LAW_TRGT_IF_DDR_1;
|
||||
#endif
|
||||
unsigned long long total_memory;
|
||||
fsl_ddr_info_t info;
|
||||
int deassert_reset;
|
||||
int deassert_reset = 0;
|
||||
|
||||
/* Reset info structure. */
|
||||
memset(&info, 0, sizeof(fsl_ddr_info_t));
|
||||
first_ctrl = pinfo->first_ctrl;
|
||||
last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
|
||||
|
||||
/* Compute it once normally. */
|
||||
#ifdef CONFIG_FSL_DDR_INTERACTIVE
|
||||
if (tstc() && (getc() == 'd')) { /* we got a key press of 'd' */
|
||||
total_memory = fsl_ddr_interactive(&info, 0);
|
||||
total_memory = fsl_ddr_interactive(pinfo, 0);
|
||||
} else if (fsl_ddr_interactive_env_var_exists()) {
|
||||
total_memory = fsl_ddr_interactive(&info, 1);
|
||||
total_memory = fsl_ddr_interactive(pinfo, 1);
|
||||
} else
|
||||
#endif
|
||||
total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 0);
|
||||
total_memory = fsl_ddr_compute(pinfo, STEP_GET_SPD, 0);
|
||||
|
||||
/* setup 3-way interleaving before enabling DDRC */
|
||||
if (info.memctl_opts[0].memctl_interleaving) {
|
||||
switch (info.memctl_opts[0].memctl_interleaving_mode) {
|
||||
case FSL_DDR_3WAY_1KB_INTERLEAVING:
|
||||
case FSL_DDR_3WAY_4KB_INTERLEAVING:
|
||||
case FSL_DDR_3WAY_8KB_INTERLEAVING:
|
||||
fsl_ddr_set_intl3r(
|
||||
info.memctl_opts[0].memctl_interleaving_mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode) {
|
||||
case FSL_DDR_3WAY_1KB_INTERLEAVING:
|
||||
case FSL_DDR_3WAY_4KB_INTERLEAVING:
|
||||
case FSL_DDR_3WAY_8KB_INTERLEAVING:
|
||||
fsl_ddr_set_intl3r(
|
||||
pinfo->memctl_opts[first_ctrl].
|
||||
memctl_interleaving_mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -637,14 +653,15 @@ phys_size_t fsl_ddr_sdram(void)
|
||||
* For non-registered DIMMs, initialization can go through but it is
|
||||
* also OK to follow the same flow.
|
||||
*/
|
||||
deassert_reset = board_need_mem_reset();
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
if (info.common_timing_params[i].all_dimms_registered)
|
||||
if (pinfo->board_need_mem_reset)
|
||||
deassert_reset = pinfo->board_need_mem_reset();
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
if (pinfo->common_timing_params[i].all_dimms_registered)
|
||||
deassert_reset = 1;
|
||||
}
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
debug("Programming controller %u\n", i);
|
||||
if (info.common_timing_params[i].ndimms_present == 0) {
|
||||
if (pinfo->common_timing_params[i].ndimms_present == 0) {
|
||||
debug("No dimms present on controller %u; "
|
||||
"skipping programming\n", i);
|
||||
continue;
|
||||
@ -653,45 +670,58 @@ phys_size_t fsl_ddr_sdram(void)
|
||||
* The following call with step = 1 returns before enabling
|
||||
* the controller. It has to finish with step = 2 later.
|
||||
*/
|
||||
fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i,
|
||||
fsl_ddr_set_memctl_regs(&(pinfo->fsl_ddr_config_reg[i]), i,
|
||||
deassert_reset ? 1 : 0);
|
||||
}
|
||||
if (deassert_reset) {
|
||||
/* Use board FPGA or GPIO to deassert reset signal */
|
||||
debug("Deasserting mem reset\n");
|
||||
board_deassert_mem_reset();
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
if (pinfo->board_mem_de_reset) {
|
||||
debug("Deasserting mem reset\n");
|
||||
pinfo->board_mem_de_reset();
|
||||
} else {
|
||||
debug("Deasserting mem reset missing\n");
|
||||
}
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
/* Call with step = 2 to continue initialization */
|
||||
fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]),
|
||||
fsl_ddr_set_memctl_regs(&(pinfo->fsl_ddr_config_reg[i]),
|
||||
i, 2);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC
|
||||
/* program LAWs */
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
if (info.memctl_opts[i].memctl_interleaving) {
|
||||
switch (info.memctl_opts[i].memctl_interleaving_mode) {
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
if (pinfo->memctl_opts[i].memctl_interleaving) {
|
||||
switch (pinfo->memctl_opts[i].
|
||||
memctl_interleaving_mode) {
|
||||
case FSL_DDR_CACHE_LINE_INTERLEAVING:
|
||||
case FSL_DDR_PAGE_INTERLEAVING:
|
||||
case FSL_DDR_BANK_INTERLEAVING:
|
||||
case FSL_DDR_SUPERBANK_INTERLEAVING:
|
||||
if (i % 2)
|
||||
break;
|
||||
if (i == 0) {
|
||||
law_memctl = LAW_TRGT_IF_DDR_INTRLV;
|
||||
fsl_ddr_set_lawbar(&info.common_timing_params[i],
|
||||
law_memctl, i);
|
||||
} else if (i == 2) {
|
||||
law_memctl = LAW_TRGT_IF_DDR_INTLV_34;
|
||||
fsl_ddr_set_lawbar(&info.common_timing_params[i],
|
||||
fsl_ddr_set_lawbar(
|
||||
&pinfo->common_timing_params[i],
|
||||
law_memctl, i);
|
||||
}
|
||||
#if CONFIG_NUM_DDR_CONTROLLERS > 3
|
||||
else if (i == 2) {
|
||||
law_memctl = LAW_TRGT_IF_DDR_INTLV_34;
|
||||
fsl_ddr_set_lawbar(
|
||||
&pinfo->common_timing_params[i],
|
||||
law_memctl, i);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case FSL_DDR_3WAY_1KB_INTERLEAVING:
|
||||
case FSL_DDR_3WAY_4KB_INTERLEAVING:
|
||||
case FSL_DDR_3WAY_8KB_INTERLEAVING:
|
||||
law_memctl = LAW_TRGT_IF_DDR_INTLV_123;
|
||||
if (i == 0) {
|
||||
fsl_ddr_set_lawbar(&info.common_timing_params[i],
|
||||
fsl_ddr_set_lawbar(
|
||||
&pinfo->common_timing_params[i],
|
||||
law_memctl, i);
|
||||
}
|
||||
break;
|
||||
@ -700,7 +730,8 @@ phys_size_t fsl_ddr_sdram(void)
|
||||
case FSL_DDR_4WAY_8KB_INTERLEAVING:
|
||||
law_memctl = LAW_TRGT_IF_DDR_INTLV_1234;
|
||||
if (i == 0)
|
||||
fsl_ddr_set_lawbar(&info.common_timing_params[i],
|
||||
fsl_ddr_set_lawbar(
|
||||
&pinfo->common_timing_params[i],
|
||||
law_memctl, i);
|
||||
/* place holder for future 4-way interleaving */
|
||||
break;
|
||||
@ -724,8 +755,8 @@ phys_size_t fsl_ddr_sdram(void)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fsl_ddr_set_lawbar(&info.common_timing_params[i],
|
||||
law_memctl, i);
|
||||
fsl_ddr_set_lawbar(&pinfo->common_timing_params[i],
|
||||
law_memctl, i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -734,7 +765,7 @@ phys_size_t fsl_ddr_sdram(void)
|
||||
|
||||
#if !defined(CONFIG_PHYS_64BIT)
|
||||
/* Check for 4G or more. Bad. */
|
||||
if (total_memory >= (1ull << 32)) {
|
||||
if ((first_ctrl == 0) && (total_memory >= (1ull << 32))) {
|
||||
puts("Detected ");
|
||||
print_size(total_memory, " of memory\n");
|
||||
printf(" This U-Boot only supports < 4G of DDR\n");
|
||||
@ -748,8 +779,56 @@ phys_size_t fsl_ddr_sdram(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* fsl_ddr_sdram_size() - This function only returns the size of the total
|
||||
* memory without setting ddr control registers.
|
||||
* fsl_ddr_sdram(void) -- this is the main function to be
|
||||
* called by initdram() in the board file.
|
||||
*
|
||||
* It returns amount of memory configured in bytes.
|
||||
*/
|
||||
phys_size_t fsl_ddr_sdram(void)
|
||||
{
|
||||
fsl_ddr_info_t info;
|
||||
|
||||
/* Reset info structure. */
|
||||
memset(&info, 0, sizeof(fsl_ddr_info_t));
|
||||
info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY;
|
||||
info.first_ctrl = 0;
|
||||
info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS;
|
||||
info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR;
|
||||
info.board_need_mem_reset = board_need_mem_reset;
|
||||
info.board_mem_reset = board_assert_mem_reset;
|
||||
info.board_mem_de_reset = board_deassert_mem_reset;
|
||||
|
||||
return __fsl_ddr_sdram(&info);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS
|
||||
phys_size_t fsl_other_ddr_sdram(unsigned long long base,
|
||||
unsigned int first_ctrl,
|
||||
unsigned int num_ctrls,
|
||||
unsigned int dimm_slots_per_ctrl,
|
||||
int (*board_need_reset)(void),
|
||||
void (*board_reset)(void),
|
||||
void (*board_de_reset)(void))
|
||||
{
|
||||
fsl_ddr_info_t info;
|
||||
|
||||
/* Reset info structure. */
|
||||
memset(&info, 0, sizeof(fsl_ddr_info_t));
|
||||
info.mem_base = base;
|
||||
info.first_ctrl = first_ctrl;
|
||||
info.num_ctrls = num_ctrls;
|
||||
info.dimm_slots_per_ctrl = dimm_slots_per_ctrl;
|
||||
info.board_need_mem_reset = board_need_reset;
|
||||
info.board_mem_reset = board_reset;
|
||||
info.board_mem_de_reset = board_de_reset;
|
||||
|
||||
return __fsl_ddr_sdram(&info);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fsl_ddr_sdram_size(first_ctrl, last_intlv) - This function only returns the
|
||||
* size of the total memory without setting ddr control registers.
|
||||
*/
|
||||
phys_size_t
|
||||
fsl_ddr_sdram_size(void)
|
||||
@ -758,6 +837,11 @@ fsl_ddr_sdram_size(void)
|
||||
unsigned long long total_memory = 0;
|
||||
|
||||
memset(&info, 0 , sizeof(fsl_ddr_info_t));
|
||||
info.mem_base = CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY;
|
||||
info.first_ctrl = 0;
|
||||
info.num_ctrls = CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS;
|
||||
info.dimm_slots_per_ctrl = CONFIG_DIMM_SLOTS_PER_CTLR;
|
||||
info.board_need_mem_reset = NULL;
|
||||
|
||||
/* Compute it once normally. */
|
||||
total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1);
|
||||
|
@ -777,10 +777,6 @@ unsigned int populate_memctl_options(int all_dimms_registered,
|
||||
*/
|
||||
popts->bstopre = 0x100;
|
||||
|
||||
/* Minimum CKE pulse width -- tCKE(MIN) */
|
||||
popts->tcke_clock_pulse_width_ps
|
||||
= mclk_to_picos(FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR);
|
||||
|
||||
/*
|
||||
* Window for four activates -- tFAW
|
||||
*
|
||||
@ -1065,18 +1061,21 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo)
|
||||
unsigned int check_intlv, check_n_row_addr, check_n_col_addr;
|
||||
unsigned long long check_rank_density;
|
||||
struct dimm_params_s *dimm;
|
||||
int first_ctrl = pinfo->first_ctrl;
|
||||
int last_ctrl = first_ctrl + pinfo->num_ctrls - 1;
|
||||
|
||||
/*
|
||||
* Check if all controllers are configured for memory
|
||||
* controller interleaving. Identical dimms are recommended. At least
|
||||
* the size, row and col address should be checked.
|
||||
*/
|
||||
j = 0;
|
||||
check_n_ranks = pinfo->dimm_params[0][0].n_ranks;
|
||||
check_rank_density = pinfo->dimm_params[0][0].rank_density;
|
||||
check_n_row_addr = pinfo->dimm_params[0][0].n_row_addr;
|
||||
check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr;
|
||||
check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode;
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
|
||||
check_n_ranks = pinfo->dimm_params[first_ctrl][0].n_ranks;
|
||||
check_rank_density = pinfo->dimm_params[first_ctrl][0].rank_density;
|
||||
check_n_row_addr = pinfo->dimm_params[first_ctrl][0].n_row_addr;
|
||||
check_n_col_addr = pinfo->dimm_params[first_ctrl][0].n_col_addr;
|
||||
check_intlv = pinfo->memctl_opts[first_ctrl].memctl_interleaving_mode;
|
||||
for (i = first_ctrl; i <= last_ctrl; i++) {
|
||||
dimm = &pinfo->dimm_params[i][0];
|
||||
if (!pinfo->memctl_opts[i].memctl_interleaving) {
|
||||
continue;
|
||||
@ -1094,7 +1093,7 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo)
|
||||
|
||||
}
|
||||
if (intlv_invalid) {
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
|
||||
for (i = first_ctrl; i <= last_ctrl; i++)
|
||||
pinfo->memctl_opts[i].memctl_interleaving = 0;
|
||||
printf("Not all DIMMs are identical. "
|
||||
"Memory controller interleaving disabled.\n");
|
||||
@ -1123,10 +1122,10 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo)
|
||||
}
|
||||
debug("%d of %d controllers are interleaving.\n", j, k);
|
||||
if (j && (j != k)) {
|
||||
for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
|
||||
for (i = first_ctrl; i <= last_ctrl; i++)
|
||||
pinfo->memctl_opts[i].memctl_interleaving = 0;
|
||||
printf("Not all controllers have compatible "
|
||||
"interleaving mode. All disabled.\n");
|
||||
if ((last_ctrl - first_ctrl) > 1)
|
||||
puts("Not all controllers have compatible interleaving mode. All disabled.\n");
|
||||
}
|
||||
}
|
||||
debug("Checking interleaving options completed\n");
|
||||
|
@ -149,7 +149,7 @@ u32 fsl_ddr_get_intl3r(void)
|
||||
return val;
|
||||
}
|
||||
|
||||
void board_add_ram_info(int use_default)
|
||||
void print_ddr_info(unsigned int start_ctrl)
|
||||
{
|
||||
struct ccsr_ddr __iomem *ddr =
|
||||
(struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR);
|
||||
@ -164,17 +164,25 @@ void board_add_ram_info(int use_default)
|
||||
int cas_lat;
|
||||
|
||||
#if CONFIG_NUM_DDR_CONTROLLERS >= 2
|
||||
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
|
||||
if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
|
||||
(start_ctrl == 1)) {
|
||||
ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR;
|
||||
sdram_cfg = ddr_in32(&ddr->sdram_cfg);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_NUM_DDR_CONTROLLERS >= 3
|
||||
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
|
||||
if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
|
||||
(start_ctrl == 2)) {
|
||||
ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR;
|
||||
sdram_cfg = ddr_in32(&ddr->sdram_cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
|
||||
puts(" (DDR not enabled)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
puts(" (DDR");
|
||||
switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >>
|
||||
SDRAM_CFG_SDRAM_TYPE_SHIFT) {
|
||||
@ -241,7 +249,7 @@ void board_add_ram_info(int use_default)
|
||||
#endif
|
||||
#endif
|
||||
#if (CONFIG_NUM_DDR_CONTROLLERS >= 2)
|
||||
if (cs0_config & 0x20000000) {
|
||||
if ((cs0_config & 0x20000000) && (start_ctrl == 0)) {
|
||||
puts("\n");
|
||||
puts(" DDR Controller Interleaving Mode: ");
|
||||
|
||||
@ -290,3 +298,13 @@ void board_add_ram_info(int use_default)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __weak detail_board_ddr_info(void)
|
||||
{
|
||||
print_ddr_info(0);
|
||||
}
|
||||
|
||||
void board_add_ram_info(int use_default)
|
||||
{
|
||||
detail_board_ddr_info();
|
||||
}
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#define MAX_BANKS 8
|
||||
#define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */
|
||||
#define FCM_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for FCM */
|
||||
|
||||
#define LTESR_NAND_MASK (LTESR_FCT | LTESR_PAR | LTESR_CC)
|
||||
|
||||
@ -199,7 +198,8 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
|
||||
struct fsl_elbc_mtd *priv = chip->priv;
|
||||
struct fsl_elbc_ctrl *ctrl = priv->ctrl;
|
||||
fsl_lbc_t *lbc = ctrl->regs;
|
||||
long long end_tick;
|
||||
u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
|
||||
u32 time_start;
|
||||
u32 ltesr;
|
||||
|
||||
/* Setup the FMR[OP] to execute without write protection */
|
||||
@ -218,10 +218,10 @@ static int fsl_elbc_run_command(struct mtd_info *mtd)
|
||||
out_be32(&lbc->lsor, priv->bank);
|
||||
|
||||
/* wait for FCM complete flag or timeout */
|
||||
end_tick = usec2ticks(FCM_TIMEOUT_MSECS * 1000) + get_ticks();
|
||||
time_start = get_timer(0);
|
||||
|
||||
ltesr = 0;
|
||||
while (end_tick > get_ticks()) {
|
||||
while (get_timer(time_start) < timeo) {
|
||||
ltesr = in_be32(&lbc->ltesr);
|
||||
if (ltesr & LTESR_CC)
|
||||
break;
|
||||
|
@ -26,8 +26,6 @@
|
||||
#define MAX_BANKS CONFIG_SYS_FSL_IFC_BANK_COUNT
|
||||
#define ERR_BYTE 0xFF /* Value returned for read bytes
|
||||
when read failed */
|
||||
#define IFC_TIMEOUT_MSECS 10 /* Maximum number of mSecs to wait for IFC
|
||||
NAND Machine */
|
||||
|
||||
struct fsl_ifc_ctrl;
|
||||
|
||||
@ -292,7 +290,8 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
|
||||
struct fsl_ifc_mtd *priv = chip->priv;
|
||||
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
|
||||
struct fsl_ifc *ifc = ctrl->regs;
|
||||
long long end_tick;
|
||||
u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
|
||||
u32 time_start;
|
||||
u32 eccstat[4];
|
||||
int i;
|
||||
|
||||
@ -304,9 +303,9 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
|
||||
IFC_NAND_SEQ_STRT_FIR_STRT);
|
||||
|
||||
/* wait for NAND Machine complete flag or timeout */
|
||||
end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
|
||||
time_start = get_timer(0);
|
||||
|
||||
while (end_tick > get_ticks()) {
|
||||
while (get_timer(time_start) < timeo) {
|
||||
ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
|
||||
|
||||
if (ctrl->status & IFC_NAND_EVTER_STAT_OPC)
|
||||
@ -812,15 +811,16 @@ static int fsl_ifc_sram_init(uint32_t ver)
|
||||
struct fsl_ifc *ifc = ifc_ctrl->regs;
|
||||
uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
|
||||
uint32_t ncfgr = 0;
|
||||
long long end_tick;
|
||||
u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
|
||||
u32 time_start;
|
||||
|
||||
if (ver > FSL_IFC_V1_1_0) {
|
||||
ncfgr = ifc_in32(&ifc->ifc_nand.ncfgr);
|
||||
ifc_out32(&ifc->ifc_nand.ncfgr, ncfgr | IFC_NAND_SRAM_INIT_EN);
|
||||
|
||||
/* wait for SRAM_INIT bit to be clear or timeout */
|
||||
end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
|
||||
while (end_tick > get_ticks()) {
|
||||
time_start = get_timer(0);
|
||||
while (get_timer(time_start) < timeo) {
|
||||
ifc_ctrl->status =
|
||||
ifc_in32(&ifc->ifc_nand.nand_evter_stat);
|
||||
|
||||
@ -863,10 +863,9 @@ static int fsl_ifc_sram_init(uint32_t ver)
|
||||
/* start read seq */
|
||||
ifc_out32(&ifc->ifc_nand.nandseq_strt, IFC_NAND_SEQ_STRT_FIR_STRT);
|
||||
|
||||
/* wait for NAND Machine complete flag or timeout */
|
||||
end_tick = usec2ticks(IFC_TIMEOUT_MSECS * 1000) + get_ticks();
|
||||
time_start = get_timer(0);
|
||||
|
||||
while (end_tick > get_ticks()) {
|
||||
while (get_timer(time_start) < timeo) {
|
||||
ifc_ctrl->status = ifc_in32(&ifc->ifc_nand.nand_evter_stat);
|
||||
|
||||
if (ifc_ctrl->status & IFC_NAND_EVTER_STAT_OPC)
|
||||
|
@ -49,10 +49,12 @@ unsigned long get_board_ddr_clk(void);
|
||||
#define CONFIG_DDR_SPD
|
||||
#define SPD_EEPROM_ADDRESS 0x51
|
||||
#define CONFIG_SYS_SPD_BUS_NUM 0
|
||||
#define CONFIG_SYS_DDR_RAW_TIMING
|
||||
|
||||
#define CONFIG_FSL_DDR_INTERACTIVE /* Interactive debugging */
|
||||
#ifndef CONFIG_SYS_FSL_DDR4
|
||||
#define CONFIG_SYS_FSL_DDR3 /* Use DDR3 memory */
|
||||
#define CONFIG_SYS_DDR_RAW_TIMING
|
||||
#endif
|
||||
#define CONFIG_DIMM_SLOTS_PER_CTLR 1
|
||||
#define CONFIG_CHIP_SELECTS_PER_CTRL 4
|
||||
|
||||
|
@ -15,9 +15,11 @@
|
||||
#define CONFIG_GICV3
|
||||
|
||||
/* Link Definitions */
|
||||
#define CONFIG_SYS_TEXT_BASE 0x30000000
|
||||
#define CONFIG_SYS_TEXT_BASE 0x30001000
|
||||
|
||||
#ifdef CONFIG_EMU
|
||||
#define CONFIG_SYS_NO_FLASH
|
||||
#endif
|
||||
|
||||
#define CONFIG_SUPPORT_RAW_INITRD
|
||||
|
||||
@ -45,13 +47,27 @@
|
||||
|
||||
#define CONFIG_SYS_FSL_DDR_INTLV_256B /* force 256 byte interleaving */
|
||||
|
||||
/* SMP Definitions */
|
||||
#define CPU_RELEASE_ADDR CONFIG_SYS_INIT_SP_ADDR
|
||||
|
||||
#define CONFIG_SYS_DDR_SDRAM_BASE 0x80000000UL
|
||||
#define CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY 0
|
||||
#define CONFIG_SYS_SDRAM_BASE CONFIG_SYS_DDR_SDRAM_BASE
|
||||
#define CONFIG_SYS_DDR_BLOCK2_BASE 0x8080000000ULL
|
||||
#define CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS 2
|
||||
|
||||
/*
|
||||
* SMP Definitinos
|
||||
*/
|
||||
#define CPU_RELEASE_ADDR secondary_boot_func
|
||||
|
||||
#define CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS
|
||||
#define CONFIG_SYS_DP_DDR_BASE 0x6000000000ULL
|
||||
/*
|
||||
* DDR controller use 0 as the base address for binding.
|
||||
* It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
|
||||
*/
|
||||
#define CONFIG_SYS_DP_DDR_BASE_PHY 0
|
||||
#define CONFIG_DP_DDR_CTRL 2
|
||||
#define CONFIG_DP_DDR_NUM_CTRLS 1
|
||||
#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1
|
||||
|
||||
/* Generic Timer Definitions */
|
||||
#define COUNTER_FREQUENCY 12000000 /* 12MHz */
|
||||
@ -118,6 +134,66 @@
|
||||
#define CONFIG_SYS_NOR_FTIM3 0x04000000
|
||||
#define CONFIG_SYS_IFC_CCR 0x01000000
|
||||
|
||||
#ifndef CONFIG_SYS_NO_FLASH
|
||||
#define CONFIG_FLASH_CFI_DRIVER
|
||||
#define CONFIG_SYS_FLASH_CFI
|
||||
#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
|
||||
#define CONFIG_SYS_FLASH_QUIET_TEST
|
||||
#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */
|
||||
|
||||
#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */
|
||||
#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */
|
||||
#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
|
||||
#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
|
||||
|
||||
#define CONFIG_SYS_FLASH_EMPTY_INFO
|
||||
#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
|
||||
#endif
|
||||
|
||||
#define CONFIG_NAND_FSL_IFC
|
||||
#define CONFIG_SYS_NAND_MAX_ECCPOS 256
|
||||
#define CONFIG_SYS_NAND_MAX_OOBFREE 2
|
||||
#define CONFIG_SYS_NAND_BASE 0x520000000
|
||||
#define CONFIG_SYS_NAND_BASE_PHYS 0x20000000
|
||||
|
||||
#define CONFIG_SYS_NAND_CSPR_EXT (0x0)
|
||||
#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
|
||||
| CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \
|
||||
| CSPR_MSEL_NAND /* MSEL = NAND */ \
|
||||
| CSPR_V)
|
||||
#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024)
|
||||
|
||||
#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \
|
||||
| CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \
|
||||
| CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \
|
||||
| CSOR_NAND_RAL_3 /* RAL = 2Byes */ \
|
||||
| CSOR_NAND_PGS_2K /* Page Size = 2K */ \
|
||||
| CSOR_NAND_SPRZ_64/* Spare size = 64 */ \
|
||||
| CSOR_NAND_PB(64)) /*Pages Per Block = 64*/
|
||||
|
||||
#define CONFIG_SYS_NAND_ONFI_DETECTION
|
||||
|
||||
/* ONFI NAND Flash mode0 Timing Params */
|
||||
#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x07) | \
|
||||
FTIM0_NAND_TWP(0x18) | \
|
||||
FTIM0_NAND_TWCHT(0x07) | \
|
||||
FTIM0_NAND_TWH(0x0a))
|
||||
#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \
|
||||
FTIM1_NAND_TWBE(0x39) | \
|
||||
FTIM1_NAND_TRR(0x0e) | \
|
||||
FTIM1_NAND_TRP(0x18))
|
||||
#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x0f) | \
|
||||
FTIM2_NAND_TREH(0x0a) | \
|
||||
FTIM2_NAND_TWHRE(0x1e))
|
||||
#define CONFIG_SYS_NAND_FTIM3 0x0
|
||||
|
||||
#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
|
||||
#define CONFIG_SYS_MAX_NAND_DEVICE 1
|
||||
#define CONFIG_MTD_NAND_VERIFY_WRITE
|
||||
#define CONFIG_CMD_NAND
|
||||
|
||||
#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024)
|
||||
|
||||
#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT
|
||||
#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY
|
||||
#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR
|
||||
@ -167,6 +243,7 @@
|
||||
|
||||
/* Miscellaneous configurable options */
|
||||
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000)
|
||||
#define CONFIG_ARCH_EARLY_INIT_R
|
||||
|
||||
/* Physical Memory Map */
|
||||
/* fixme: these need to be checked against the board */
|
||||
@ -174,7 +251,7 @@
|
||||
#define CONFIG_SYS_CLK_FREQ 133333333
|
||||
|
||||
|
||||
#define CONFIG_NR_DRAM_BANKS 2
|
||||
#define CONFIG_NR_DRAM_BANKS 3
|
||||
|
||||
#define CONFIG_SYS_HZ 1000
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#define CONFIG_SYS_FSL_DDR_EMU /* Support emulator */
|
||||
#define SPD_EEPROM_ADDRESS1 0x51
|
||||
#define SPD_EEPROM_ADDRESS2 0x52
|
||||
#define SPD_EEPROM_ADDRESS3 0x53
|
||||
#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1
|
||||
#define CONFIG_SYS_SPD_BUS_NUM 1 /* SPD on I2C bus 1 */
|
||||
|
||||
|
@ -13,4 +13,13 @@
|
||||
#define CONFIG_SMC91111
|
||||
#define CONFIG_SMC91111_BASE (0x2210000)
|
||||
|
||||
#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NAND_CSPR_EXT
|
||||
#define CONFIG_SYS_CSPR1 CONFIG_SYS_NAND_CSPR
|
||||
#define CONFIG_SYS_AMASK1 CONFIG_SYS_NAND_AMASK
|
||||
#define CONFIG_SYS_CSOR1 CONFIG_SYS_NAND_CSOR
|
||||
#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NAND_FTIM0
|
||||
#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NAND_FTIM1
|
||||
#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NAND_FTIM2
|
||||
#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NAND_FTIM3
|
||||
|
||||
#endif /* __LS2_SIMU_H */
|
||||
|
@ -133,6 +133,18 @@ static inline int fdt_status_fail_by_alias(void *fdt, const char *alias)
|
||||
return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_FAIL, 0);
|
||||
}
|
||||
|
||||
/* Helper to read a big number; size is in cells (not bytes) */
|
||||
static inline u64 of_read_number(const fdt32_t *cell, int size)
|
||||
{
|
||||
u64 r = 0;
|
||||
while (size--)
|
||||
r = (r << 32) | fdt32_to_cpu(*(cell++));
|
||||
return r;
|
||||
}
|
||||
|
||||
void of_bus_default_count_cells(void *blob, int parentoffset,
|
||||
int *addrc, int *sizec);
|
||||
|
||||
#endif /* ifdef CONFIG_OF_LIBFDT */
|
||||
|
||||
#ifdef USE_HOSTCC
|
||||
|
@ -15,6 +15,11 @@
|
||||
|
||||
#include <common_timing_params.h>
|
||||
|
||||
#ifndef CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS
|
||||
/* All controllers are for main memory */
|
||||
#define CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS CONFIG_NUM_DDR_CONTROLLERS
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SYS_FSL_DDR_LE
|
||||
#define ddr_in32(a) in_le32(a)
|
||||
#define ddr_out32(a, v) out_le32(a, v)
|
||||
@ -57,6 +62,13 @@ typedef struct {
|
||||
memctl_options_t memctl_opts[CONFIG_SYS_NUM_DDR_CTLRS];
|
||||
common_timing_params_t common_timing_params[CONFIG_SYS_NUM_DDR_CTLRS];
|
||||
fsl_ddr_cfg_regs_t fsl_ddr_config_reg[CONFIG_SYS_NUM_DDR_CTLRS];
|
||||
unsigned int first_ctrl;
|
||||
unsigned int num_ctrls;
|
||||
unsigned long long mem_base;
|
||||
unsigned int dimm_slots_per_ctrl;
|
||||
int (*board_need_mem_reset)(void);
|
||||
void (*board_mem_reset)(void);
|
||||
void (*board_mem_de_reset)(void);
|
||||
} fsl_ddr_info_t;
|
||||
|
||||
/* Compute steps */
|
||||
@ -72,7 +84,6 @@ typedef struct {
|
||||
unsigned long long
|
||||
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,
|
||||
@ -102,7 +113,7 @@ void fsl_ddr_set_lawbar(
|
||||
int fsl_ddr_interactive_env_var_exists(void);
|
||||
unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set);
|
||||
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
|
||||
unsigned int ctrl_num);
|
||||
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl);
|
||||
|
||||
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
|
||||
unsigned int check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr);
|
||||
|
@ -51,7 +51,6 @@ typedef ddr2_spd_eeprom_t generic_spd_eeprom_t;
|
||||
#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR2
|
||||
#endif
|
||||
#elif defined(CONFIG_SYS_FSL_DDR3)
|
||||
#define FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR (3) /* FIXME */
|
||||
typedef ddr3_spd_eeprom_t generic_spd_eeprom_t;
|
||||
#ifndef CONFIG_FSL_SDRAM_TYPE
|
||||
#define CONFIG_FSL_SDRAM_TYPE SDRAM_TYPE_DDR3
|
||||
@ -352,7 +351,6 @@ typedef struct memctl_options_s {
|
||||
unsigned int twot_en;
|
||||
unsigned int threet_en;
|
||||
unsigned int bstopre;
|
||||
unsigned int tcke_clock_pulse_width_ps; /* tCKE */
|
||||
unsigned int tfaw_window_four_activates_ps; /* tFAW -- FOUR_ACT */
|
||||
|
||||
/* Rtt impedance */
|
||||
@ -379,12 +377,20 @@ typedef struct memctl_options_s {
|
||||
unsigned int trwt; /* read-to-write turnaround */
|
||||
} memctl_options_t;
|
||||
|
||||
extern phys_size_t fsl_ddr_sdram(void);
|
||||
extern phys_size_t fsl_ddr_sdram_size(void);
|
||||
phys_size_t fsl_ddr_sdram(void);
|
||||
phys_size_t fsl_ddr_sdram_size(void);
|
||||
phys_size_t fsl_other_ddr_sdram(unsigned long long base,
|
||||
unsigned int first_ctrl,
|
||||
unsigned int num_ctrls,
|
||||
unsigned int dimm_slots_per_ctrl,
|
||||
int (*board_need_reset)(void),
|
||||
void (*board_reset)(void),
|
||||
void (*board_de_reset)(void));
|
||||
extern int fsl_use_spd(void);
|
||||
extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||
unsigned int ctrl_num, int step);
|
||||
void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
|
||||
unsigned int ctrl_num, int step);
|
||||
u32 fsl_ddr_get_intl3r(void);
|
||||
void print_ddr_info(unsigned int start_ctrl);
|
||||
|
||||
static void __board_assert_mem_reset(void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user