]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
authorTom Rini <trini@ti.com>
Fri, 26 Sep 2014 13:57:52 +0000 (09:57 -0400)
committerTom Rini <trini@ti.com>
Fri, 26 Sep 2014 13:57:52 +0000 (09:57 -0400)
39 files changed:
README
arch/arm/cpu/armv8/fsl-lsch3/Makefile
arch/arm/cpu/armv8/fsl-lsch3/cpu.c
arch/arm/cpu/armv8/fsl-lsch3/cpu.h
arch/arm/cpu/armv8/fsl-lsch3/fdt.c [new file with mode: 0644]
arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
arch/arm/cpu/armv8/fsl-lsch3/mp.c [new file with mode: 0644]
arch/arm/cpu/armv8/fsl-lsch3/mp.h [new file with mode: 0644]
arch/arm/cpu/armv8/transition.S
arch/arm/include/asm/arch-fsl-lsch3/config.h
arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h
arch/arm/include/asm/arch-ls102xa/config.h
arch/arm/include/asm/macro.h
arch/arm/lib/gic_64.S
arch/powerpc/cpu/mpc85xx/cpu.c
board/freescale/ls1021aqds/MAINTAINERS
board/freescale/ls1021aqds/ddr.c
board/freescale/ls1021aqds/ddr.h
board/freescale/ls2085a/ddr.c
board/freescale/ls2085a/ddr.h
board/freescale/ls2085a/ls2085a.c
common/fdt_support.c
configs/ls1021aqds_ddr4_nor_defconfig [new file with mode: 0644]
drivers/ddr/fsl/ctrl_regs.c
drivers/ddr/fsl/ddr4_dimm_params.c
drivers/ddr/fsl/fsl_ddr_gen4.c
drivers/ddr/fsl/interactive.c
drivers/ddr/fsl/main.c
drivers/ddr/fsl/options.c
drivers/ddr/fsl/util.c
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_ifc_nand.c
include/configs/ls1021aqds.h
include/configs/ls2085a_common.h
include/configs/ls2085a_emu.h
include/configs/ls2085a_simu.h
include/fdt_support.h
include/fsl_ddr.h
include/fsl_ddr_sdram.h

diff --git a/README b/README
index 766e9e0ebd88f05741ea6cf34657ace277dd75d6..46def0086b8f3d95c77a78bda532eacdbab91c6e 100644 (file)
--- a/README
+++ b/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
 
index 9249537c65ac2b8d4f6d5ee5bb0b84f4ca5d533e..f920eebc56b8eddb77c3bf8fb0c9b4b07a7cfdd2 100644 (file)
@@ -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
index c129d032f4094bc7abfb749945035e9b6009552b..47b947f44fadb466da62872b82cacb103d45937e 100644 (file)
@@ -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;
+}
index 28544d7c14d84266e5131a5377dd4529425f6b66..2e3312b99beec55f38d76b895c199750f3a67fac 100644 (file)
@@ -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 (file)
index 0000000..e392eb9
--- /dev/null
@@ -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
+}
index ad32b6cd52071fb9105ad72d96ed8ead85acbe7f..2a88aab283d7e2438017cee238fb732acd6c3352 100644 (file)
@@ -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 (file)
index 0000000..94998bf
--- /dev/null
@@ -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 (file)
index 0000000..06ac0bc
--- /dev/null
@@ -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 */
index 38dea5c51871eb4e20abf86f67aaf5bd9c4f6b10..ade1cdead83920dea59b38ecc895552c18fd442a 100644 (file)
 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)
index b17410a58a76da526ab47d59e60ca7ea7a17d2d4..da551e883997b4aacfc111d5af277e0e47e5354c 100644 (file)
@@ -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)
 #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
index 18e66bdf411af70de20624cfa0eaba2fccb2a9b4..ee1d6512d90056686775cb07368c465f30ee4088 100644 (file)
@@ -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 */
index ed78c33e0a3ef4ffc19f84dbf16f81218a079ca6..a500b5bc3b6581b9e72a73998d8ee3ded1d55034 100644 (file)
 #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
index f77e4b880e48c4cba5f71d28da434e0f1e42293e..541b4432549bf38b8c99504b6299ee4d87559e98 100644 (file)
@@ -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__ */
index d56396ea225c51905fe9f978d932195bcea9c089..a3e18f7713e571ead9d9f81c6242e486e1c092da 100644 (file)
@@ -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)
index 6274f929dd0fa3d035052187f4f7e9a9f889f78a..3d6ec843df3f156b7961975f6931552c434cb2ad 100644 (file)
@@ -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)  ");
index 021d82b74d329171869d4c7cb5fdf121325cc315..ccf45131b8735da2a8081a6de39ddd1e393a7e54 100644 (file)
@@ -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
index 679c654fb57227f579e1c656afa515fd96099384..5898e337443ed790d64a7d2fee190c9b4f5d28c4 100644 (file)
@@ -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
index 16d87cbe82fd7fee9444ec31be11d96b2e5879f7..f819c99dbaaaba313ab3bd21540d33f8219c4b4b 100644 (file)
@@ -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
        {}
 };
 
index 257bc162d0ab891aa85e1fdedf69538228126826..b4a3fc9a9ed1aa5f581094de7e3885d2f43d9faa 100644 (file)
@@ -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
 }
index 77f6aafe3d937d737e339b51941993692f37e337..9958a68e3ecd1e8f3792b151fae031ca272dc385 100644 (file)
@@ -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,
 };
 
 
index a18db1d71493df35b8c2c05055cdf073a3cc00e7..2c79a7181ecc53db55eb50591470f44e3ea1efc2 100644 (file)
 #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();
index 784a570a818bd94fdb8dd086a4020f5652c91c00..3f641566b977aff76275656c86093051d2b1217c 100644 (file)
@@ -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 (file)
index 0000000..3c57481
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
+CONFIG_ARM=y
+CONFIG_TARGET_LS1021AQDS=y
index d9cac2296a20afc431dcefa64bba109cd7e6a250..9a156bfd5e18c41d9ddcdfb4add0f63937808e11 100644 (file)
@@ -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);
index 4745b7fb1bfff841d037d5a662d1a9e37c4d59f5..2418dca6ab9468c729ecd3bcccf81d1d69f05a31 100644 (file)
@@ -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;
index bfc76b3485768d51974616a72a80788efb4248d1..e024db9ee2ab4ee0bf3cee26d221a1928c1090f2 100644 (file)
@@ -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");
-
 }
index 6aa16b23ddc95f6df53077fd2c789141dee4eb19..32ba6d820b6c207578de19a6ca157469169e6c3a 100644 (file)
@@ -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),
index 5e001fcb99474605d0c5fadde287e1ef257184b5..b43b669e41ffc9be2b1bf812de30fa1eb714d6ff 100644 (file)
@@ -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);
index 5986e1a0b9da3b5099fcdac4b46594c9b1fc3180..6d098d1fa2f5023e3b4cd3f77efe3283ef78def8 100644 (file)
@@ -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");
index 7a22aa398865655b0cb8f8ca8069b648bfb1c463..58b519b4036aca64690bf9cd2e261b03934898ae 100644 (file)
@@ -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();
+}
index 7e1e6ec78b20081dc4b48d586bc0ece55e1fcebf..3372b64212559cf1c9c922ec1a0f22cbea1d3c32 100644 (file)
@@ -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;
index 2f04c698d3b850142218c31989715e97d8b6b746..81b5070b54dcaac7913d5005190cec9f52a67775 100644 (file)
@@ -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)
index 657e3b6d48d646fe4f7f7d97d8708dba4ff85576..bb4781334537b579bc07b52ab76cba69f79b5ea6 100644 (file)
@@ -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
 
index 2bd5a472b37f07f2c1ee6d991c8a6160d2d5c3e3..a72e1f3567d22144383bf94b306bfb0c5f1112cb 100644 (file)
 #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
 
 
 #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 */
 #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
 
 /* 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 */
 #define CONFIG_SYS_CLK_FREQ    133333333
 
 
-#define CONFIG_NR_DRAM_BANKS           2
+#define CONFIG_NR_DRAM_BANKS           3
 
 #define CONFIG_SYS_HZ                  1000
 
index a5cea63b337633f0735534998b8a61851454def8..487cd99c5dc018a48560733f54bdf52677dd0780 100644 (file)
@@ -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 */
 
index 46d47b06e4411679c22b7d642c589b7de5aacf11..0f40b787b47abaf056675c02e5f4a56ddcea422f 100644 (file)
 #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 */
index 1bda686a0b944c4b213f395fcb915bc4d25abedb..c3d1fbcf3566451419bff1a325a870a945743475 100644 (file)
@@ -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
index 5c49b229dafe19b14fe5866187b826385534b549..675557ad1fd3605f07fab75477f8c61f6cd58fae 100644 (file)
 
 #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);
index 987119b014ee513166fd4ba6cbaf47d405f2ef85..5b03c14c55db3f29741a4d7831c6093aa156b1c5 100644 (file)
@@ -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)
 {