diff options
39 files changed, 1018 insertions, 251 deletions
@@ -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 diff --git a/arch/arm/cpu/armv8/fsl-lsch3/Makefile b/arch/arm/cpu/armv8/fsl-lsch3/Makefile index 9249537..f920eeb 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/Makefile +++ b/arch/arm/cpu/armv8/fsl-lsch3/Makefile @@ -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 diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c index c129d03..47b947f 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c @@ -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; +} diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.h b/arch/arm/cpu/armv8/fsl-lsch3/cpu.h index 28544d7..2e3312b 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.h +++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.h @@ -5,3 +5,4 @@ */ int fsl_qoriq_core_to_cluster(unsigned int core); +u32 cpu_mask(void); diff --git a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c new file mode 100644 index 0000000..e392eb9 --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c @@ -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 +} diff --git a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S index ad32b6c..2a88aab 100644 --- a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S +++ b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S @@ -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 + 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) /* - * Slave should wait for master clearing spin table. - * This sync prevent salves observing incorrect - * value of spin table and jumping to wrong place. + * 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] */ -#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3) -#ifdef CONFIG_GICV2 - ldr x0, =GICC_BASE -#endif - bl gic_wait_for_interrupt -#endif - + 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] */ /* - * All processors will enter EL2 and optionally EL1. + * offset of the spin table element for this core from start of spin + * table (each elem is padded to 64 bytes) */ - bl armv8_switch_to_el2 + 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 armv8_switch_to_el1 + bl secondary_switch_to_el1 #endif - b 2f -1: -2: - mov lr, x29 /* Restore LR */ - ret -ENDPROC(lowlevel_init) +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 diff --git a/arch/arm/cpu/armv8/fsl-lsch3/mp.c b/arch/arm/cpu/armv8/fsl-lsch3/mp.c new file mode 100644 index 0000000..94998bf --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-lsch3/mp.c @@ -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; +} diff --git a/arch/arm/cpu/armv8/fsl-lsch3/mp.h b/arch/arm/cpu/armv8/fsl-lsch3/mp.h new file mode 100644 index 0000000..06ac0bc --- /dev/null +++ b/arch/arm/cpu/armv8/fsl-lsch3/mp.h @@ -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 */ diff --git a/arch/arm/cpu/armv8/transition.S b/arch/arm/cpu/armv8/transition.S index 38dea5c..ade1cde 100644 --- a/arch/arm/cpu/armv8/transition.S +++ b/arch/arm/cpu/armv8/transition.S @@ -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) diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h index b17410a..da551e8 100644 --- a/arch/arm/include/asm/arch-fsl-lsch3/config.h +++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h @@ -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 diff --git a/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h index 18e66bd..ee1d651 100644 --- a/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h +++ b/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h @@ -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 */ diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h index ed78c33..a500b5b 100644 --- a/arch/arm/include/asm/arch-ls102xa/config.h +++ b/arch/arm/include/asm/arch-ls102xa/config.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 diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h index f77e4b8..541b443 100644 --- a/arch/arm/include/asm/macro.h +++ b/arch/arm/include/asm/macro.h @@ -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__ */ diff --git a/arch/arm/lib/gic_64.S b/arch/arm/lib/gic_64.S index d56396e..a3e18f7 100644 --- a/arch/arm/lib/gic_64.S +++ b/arch/arm/lib/gic_64.S @@ -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) diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index 6274f92..3d6ec84 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -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) "); diff --git a/board/freescale/ls1021aqds/MAINTAINERS b/board/freescale/ls1021aqds/MAINTAINERS index 021d82b..ccf4513 100644 --- a/board/freescale/ls1021aqds/MAINTAINERS +++ b/board/freescale/ls1021aqds/MAINTAINERS @@ -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 diff --git a/board/freescale/ls1021aqds/ddr.c b/board/freescale/ls1021aqds/ddr.c index 679c654..5898e33 100644 --- a/board/freescale/ls1021aqds/ddr.c +++ b/board/freescale/ls1021aqds/ddr.c @@ -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 diff --git a/board/freescale/ls1021aqds/ddr.h b/board/freescale/ls1021aqds/ddr.h index 16d87cb..f819c99 100644 --- a/board/freescale/ls1021aqds/ddr.h +++ b/board/freescale/ls1021aqds/ddr.h @@ -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 {} }; diff --git a/board/freescale/ls2085a/ddr.c b/board/freescale/ls2085a/ddr.c index 257bc16..b4a3fc9 100644 --- a/board/freescale/ls2085a/ddr.c +++ b/board/freescale/ls2085a/ddr.c @@ -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 } diff --git a/board/freescale/ls2085a/ddr.h b/board/freescale/ls2085a/ddr.h index 77f6aaf..9958a68 100644 --- a/board/freescale/ls2085a/ddr.h +++ b/board/freescale/ls2085a/ddr.h @@ -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, }; diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c index a18db1d..2c79a71 100644 --- a/board/freescale/ls2085a/ls2085a.c +++ b/board/freescale/ls2085a/ls2085a.c @@ -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(); diff --git a/common/fdt_support.c b/common/fdt_support.c index 784a570..3f64156 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -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; diff --git a/configs/ls1021aqds_ddr4_nor_defconfig b/configs/ls1021aqds_ddr4_nor_defconfig new file mode 100644 index 0000000..3c57481 --- /dev/null +++ b/configs/ls1021aqds_ddr4_nor_defconfig @@ -0,0 +1,3 @@ +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4" +CONFIG_ARM=y +CONFIG_TARGET_LS1021AQDS=y diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index d9cac22..9a156bf 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -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); diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c index 4745b7f..2418dca 100644 --- a/drivers/ddr/fsl/ddr4_dimm_params.c +++ b/drivers/ddr/fsl/ddr4_dimm_params.c @@ -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; diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index bfc76b3..e024db9 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -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"); - } diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index 6aa16b2..32ba6d8 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -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), diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 5e001fc..b43b669 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -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], + fsl_ddr_set_lawbar( + &pinfo->common_timing_params[i], law_memctl, i); - } else if (i == 2) { + } +#if CONFIG_NUM_DDR_CONTROLLERS > 3 + 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); } +#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); diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index 5986e1a..6d098d1 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -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"); diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c index 7a22aa3..58b519b 100644 --- a/drivers/ddr/fsl/util.c +++ b/drivers/ddr/fsl/util.c @@ -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(); +} diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 7e1e6ec..3372b64 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -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; diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 2f04c69..81b5070 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -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) diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 657e3b6..bb47813 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -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 diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h index 2bd5a47..a72e1f3 100644 --- a/include/configs/ls2085a_common.h +++ b/include/configs/ls2085a_common.h @@ -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 diff --git a/include/configs/ls2085a_emu.h b/include/configs/ls2085a_emu.h index a5cea63..487cd99 100644 --- a/include/configs/ls2085a_emu.h +++ b/include/configs/ls2085a_emu.h @@ -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 */ diff --git a/include/configs/ls2085a_simu.h b/include/configs/ls2085a_simu.h index 46d47b0..0f40b78 100644 --- a/include/configs/ls2085a_simu.h +++ b/include/configs/ls2085a_simu.h @@ -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 */ diff --git a/include/fdt_support.h b/include/fdt_support.h index 1bda686..c3d1fbc 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.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 diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h index 5c49b22..675557a 100644 --- a/include/fsl_ddr.h +++ b/include/fsl_ddr.h @@ -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); diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h index 987119b..5b03c14 100644 --- a/include/fsl_ddr_sdram.h +++ b/include/fsl_ddr_sdram.h @@ -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) { |