Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq master
authorTom Rini <trini@ti.com>
Wed, 25 Feb 2015 23:14:18 +0000 (18:14 -0500)
committerTom Rini <trini@ti.com>
Wed, 25 Feb 2015 23:14:18 +0000 (18:14 -0500)
67 files changed:
Kconfig
README
arch/arm/cpu/armv7/ls102xa/cpu.c
arch/arm/cpu/armv8/cache.S
arch/arm/cpu/armv8/cache_v8.c
arch/arm/cpu/armv8/fsl-lsch3/cpu.c
arch/arm/cpu/armv8/fsl-lsch3/fdt.c
arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
arch/arm/cpu/armv8/fsl-lsch3/mp.c
arch/arm/cpu/armv8/fsl-lsch3/mp.h
arch/arm/cpu/armv8/fsl-lsch3/speed.c
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/arch-ls102xa/immap_ls102xa.h
arch/arm/include/asm/arch-ls102xa/ls102xa_stream_id.h
arch/arm/include/asm/armv8/mmu.h
arch/arm/include/asm/global_data.h
arch/arm/include/asm/system.h
arch/arm/lib/bootm.c
board/freescale/common/ls102xa_stream_id.c
board/freescale/ls1021aqds/ls1021aqds.c
board/freescale/ls1021atwr/ls1021atwr.c
board/freescale/ls2085a/ddr.c
board/freescale/ls2085a/ls2085a.c
common/cmd_blob.c
common/hash.c
doc/README.fsl-trustzone-components [new file with mode: 0644]
drivers/crypto/fsl/fsl_blob.c
drivers/crypto/fsl/fsl_hash.c
drivers/crypto/fsl/fsl_hash.h [new file with mode: 0644]
drivers/ddr/fsl/arm_ddr_gen3.c
drivers/ddr/fsl/ctrl_regs.c
drivers/ddr/fsl/ddr1_dimm_params.c
drivers/ddr/fsl/ddr2_dimm_params.c
drivers/ddr/fsl/ddr3_dimm_params.c
drivers/ddr/fsl/ddr4_dimm_params.c
drivers/ddr/fsl/fsl_ddr_gen4.c
drivers/ddr/fsl/lc_common_dimm_params.c
drivers/ddr/fsl/main.c
drivers/ddr/fsl/mpc85xx_ddr_gen3.c
drivers/ddr/fsl/options.c
drivers/ddr/fsl/util.c
drivers/mmc/fsl_esdhc.c
drivers/net/Makefile
drivers/net/fsl-mc/Makefile [moved from drivers/net/fsl_mc/Makefile with 75% similarity]
drivers/net/fsl-mc/dpmng.c [new file with mode: 0644]
drivers/net/fsl-mc/fsl_dpmng_cmd.h [new file with mode: 0644]
drivers/net/fsl-mc/mc.c [moved from drivers/net/fsl_mc/mc.c with 67% similarity]
drivers/net/fsl-mc/mc_sys.c [new file with mode: 0644]
drivers/pci/pcie_layerscape.c
include/configs/ls1021aqds.h
include/configs/ls1021atwr.h
include/configs/ls2085a_common.h
include/configs/ls2085a_emu.h
include/configs/ls2085a_simu.h
include/configs/mx6_common.h
include/fsl-mc/fsl_dpmng.h [new file with mode: 0644]
include/fsl-mc/fsl_mc.h [moved from include/fsl_mc.h with 100% similarity]
include/fsl-mc/fsl_mc_cmd.h [new file with mode: 0644]
include/fsl-mc/fsl_mc_sys.h [new file with mode: 0644]
include/fsl_ddr.h
include/fsl_ddr_dimm_params.h
include/fsl_esdhc.h
include/fsl_sec.h
include/hw_sha.h
lib/Kconfig

diff --git a/Kconfig b/Kconfig
index d0318cc..91a0618 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -123,7 +123,9 @@ config FIT_SIGNATURE
        select RSA
        help
          This option enables signature verification of FIT uImages,
-         using a hash signed and verified using RSA.
+         using a hash signed and verified using RSA. If
+         CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
+         hashing is available using hardware, RSA library will use it.
          See doc/uImage.FIT/signature.txt for more details.
 
 config SYS_EXTRA_OPTIONS
diff --git a/README b/README
index ba57dc5..febefb5 100644 (file)
--- a/README
+++ b/README
@@ -3152,8 +3152,18 @@ CBFS (Coreboot Filesystem) support
                Enable the hash verify command (hash -v). This adds to code
                size a little.
 
-               CONFIG_SHA1 - support SHA1 hashing
-               CONFIG_SHA256 - support SHA256 hashing
+               CONFIG_SHA1 - This option enables support of hashing using SHA1
+               algorithm. The hash is calculated in software.
+               CONFIG_SHA256 - This option enables support of hashing using
+               SHA256 algorithm. The hash is calculated in software.
+               CONFIG_SHA_HW_ACCEL - This option enables hardware acceleration
+               for SHA1/SHA256 hashing.
+               This affects the 'hash' command and also the
+               hash_lookup_algo() function.
+               CONFIG_SHA_PROG_HW_ACCEL - This option enables
+               hardware-acceleration for SHA1/SHA256 progressive hashing.
+               Data can be streamed in a block at a time and the hashing
+               is performed in hardware.
 
                Note: There is also a sha1sum command, which should perhaps
                be deprecated in favour of 'hash sha1'.
@@ -3447,8 +3457,10 @@ FIT uImage format:
 
                CONFIG_FIT_SIGNATURE
                This option enables signature verification of FIT uImages,
-               using a hash signed and verified using RSA. See
-               doc/uImage.FIT/signature.txt for more details.
+               using a hash signed and verified using RSA. If
+               CONFIG_SHA_PROG_HW_ACCEL is defined, i.e support for progressive
+               hashing is available using hardware, RSA library will use it.
+               See doc/uImage.FIT/signature.txt for more details.
 
                WARNING: When relying on signed FIT images with required
                signature check the legacy image format is default
@@ -4916,6 +4928,9 @@ Low Level (hardware related) configuration options:
 - CONFIG_FSL_DDR_INTERACTIVE
                Enable interactive DDR debugging. See doc/README.fsl-ddr.
 
+- CONFIG_FSL_DDR_SYNC_REFRESH
+               Enable sync of refresh for multiple controllers.
+
 - CONFIG_SYS_83XX_DDR_USES_CS0
                Only for 83xx systems. If specified, then DDR should
                be configured using CS0 and CS1 instead of CS2 and CS3.
index ce2d92f..1a640bb 100644 (file)
 #include <asm/arch/clock.h>
 #include <asm/io.h>
 #include <asm/arch/immap_ls102xa.h>
+#include <asm/cache.h>
+#include <asm/system.h>
 #include <tsec.h>
 #include <netdev.h>
 #include <fsl_esdhc.h>
 
 #include "fsl_epu.h"
 
+#define DCSR_RCPM2_BLOCK_OFFSET        0x223000
+#define DCSR_RCPM2_CPMFSMCR0   0x400
+#define DCSR_RCPM2_CPMFSMSR0   0x404
+#define DCSR_RCPM2_CPMFSMCR1   0x414
+#define DCSR_RCPM2_CPMFSMSR1   0x418
+#define CPMFSMSR_FSM_STATE_MASK        0x7f
+
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SYS_DCACHE_OFF
+
+/*
+ * Bit[1] of the descriptor indicates the descriptor type,
+ * and bit[0] indicates whether the descriptor is valid.
+ */
+#define PMD_TYPE_TABLE         0x3
+#define PMD_TYPE_SECT          0x1
+
+/* AttrIndx[2:0] */
+#define PMD_ATTRINDX(t)                ((t) << 2)
+
+/* Section */
+#define PMD_SECT_AF            (1 << 10)
+
+#define BLOCK_SIZE_L1          (1UL << 30)
+#define BLOCK_SIZE_L2          (1UL << 21)
+
+/* TTBCR flags */
+#define TTBCR_EAE              (1 << 31)
+#define TTBCR_T0SZ(x)          ((x) << 0)
+#define TTBCR_T1SZ(x)          ((x) << 16)
+#define TTBCR_USING_TTBR0      (TTBCR_T0SZ(0) | TTBCR_T1SZ(0))
+#define TTBCR_IRGN0_NC         (0 << 8)
+#define TTBCR_IRGN0_WBWA       (1 << 8)
+#define TTBCR_IRGN0_WT         (2 << 8)
+#define TTBCR_IRGN0_WBNWA      (3 << 8)
+#define TTBCR_IRGN0_MASK       (3 << 8)
+#define TTBCR_ORGN0_NC         (0 << 10)
+#define TTBCR_ORGN0_WBWA       (1 << 10)
+#define TTBCR_ORGN0_WT         (2 << 10)
+#define TTBCR_ORGN0_WBNWA      (3 << 10)
+#define TTBCR_ORGN0_MASK       (3 << 10)
+#define TTBCR_SHARED_NON       (0 << 12)
+#define TTBCR_SHARED_OUTER     (2 << 12)
+#define TTBCR_SHARED_INNER     (3 << 12)
+#define TTBCR_EPD0             (0 << 7)
+#define TTBCR                  (TTBCR_SHARED_NON | \
+                                TTBCR_ORGN0_NC | \
+                                TTBCR_IRGN0_NC | \
+                                TTBCR_USING_TTBR0 | \
+                                TTBCR_EAE)
+
+/*
+ * Memory region attributes for LPAE (defined in pgtable):
+ *
+ * n = AttrIndx[2:0]
+ *
+ *                           n       MAIR
+ *     UNCACHED              000     00000000
+ *     BUFFERABLE            001     01000100
+ *     DEV_WC                001     01000100
+ *     WRITETHROUGH          010     10101010
+ *     WRITEBACK             011     11101110
+ *     DEV_CACHED            011     11101110
+ *     DEV_SHARED            100     00000100
+ *     DEV_NONSHARED         100     00000100
+ *     unused                101
+ *     unused                110
+ *     WRITEALLOC            111     11111111
+ */
+#define MT_MAIR0               0xeeaa4400
+#define MT_MAIR1               0xff000004
+#define MT_STRONLY_ORDER       0
+#define MT_NORMAL_NC           1
+#define MT_DEVICE_MEM          4
+#define MT_NORMAL              7
+
+/* The phy_addr must be aligned to 4KB */
+static inline void set_pgtable(u32 *page_table, u32 index, u32 phy_addr)
+{
+       u32 value = phy_addr | PMD_TYPE_TABLE;
+
+       page_table[2 * index] = value;
+       page_table[2 * index + 1] = 0;
+}
+
+/* The phy_addr must be aligned to 4KB */
+static inline void set_pgsection(u32 *page_table, u32 index, u64 phy_addr,
+                                u32 memory_type)
+{
+       u64 value;
+
+       value = phy_addr | PMD_TYPE_SECT | PMD_SECT_AF;
+       value |= PMD_ATTRINDX(memory_type);
+       page_table[2 * index] = value & 0xFFFFFFFF;
+       page_table[2 * index + 1] = (value >> 32) & 0xFFFFFFFF;
+}
+
+/*
+ * Start MMU after DDR is available, we create MMU table in DRAM.
+ * The base address of TTLB is gd->arch.tlb_addr. We use two
+ * levels of translation tables here to cover 40-bit address space.
+ *
+ * The TTLBs are located at PHY 2G~4G.
+ *
+ * VA mapping:
+ *
+ *  -------  <---- 0GB
+ * |       |
+ * |       |
+ * |-------| <---- 0x24000000
+ * |///////|  ===> 192MB VA map for PCIe1 with offset 0x40_0000_0000
+ * |-------| <---- 0x300000000
+ * |       |
+ * |-------| <---- 0x34000000
+ * |///////|  ===> 192MB VA map for PCIe2 with offset 0x48_0000_0000
+ * |-------| <---- 0x40000000
+ * |       |
+ * |-------| <---- 0x80000000 DDR0 space start
+ * |\\\\\\\|
+ *.|\\\\\\\|  ===> 2GB VA map for 2GB DDR0 Memory space
+ * |\\\\\\\|
+ *  -------  <---- 4GB DDR0 space end
+ */
+static void mmu_setup(void)
+{
+       u32 *level0_table = (u32 *)gd->arch.tlb_addr;
+       u32 *level1_table = (u32 *)(gd->arch.tlb_addr + 0x1000);
+       u64 va_start = 0;
+       u32 reg;
+       int i;
+
+       /* Level 0 Table 2-3 are used to map DDR */
+       set_pgsection(level0_table, 3, 3 * BLOCK_SIZE_L1, MT_NORMAL);
+       set_pgsection(level0_table, 2, 2 * BLOCK_SIZE_L1, MT_NORMAL);
+       /* Level 0 Table 1 is used to map device */
+       set_pgsection(level0_table, 1, 1 * BLOCK_SIZE_L1, MT_DEVICE_MEM);
+       /* Level 0 Table 0 is used to map device including PCIe MEM */
+       set_pgtable(level0_table, 0, (u32)level1_table);
+
+       /* Level 1 has 512 entries */
+       for (i = 0; i < 512; i++) {
+               /* Mapping for PCIe 1 */
+               if (va_start >= CONFIG_SYS_PCIE1_VIRT_ADDR &&
+                   va_start < (CONFIG_SYS_PCIE1_VIRT_ADDR +
+                                CONFIG_SYS_PCIE_MMAP_SIZE))
+                       set_pgsection(level1_table, i,
+                                     CONFIG_SYS_PCIE1_PHYS_BASE + va_start,
+                                     MT_DEVICE_MEM);
+               /* Mapping for PCIe 2 */
+               else if (va_start >= CONFIG_SYS_PCIE2_VIRT_ADDR &&
+                        va_start < (CONFIG_SYS_PCIE2_VIRT_ADDR +
+                                    CONFIG_SYS_PCIE_MMAP_SIZE))
+                       set_pgsection(level1_table, i,
+                                     CONFIG_SYS_PCIE2_PHYS_BASE + va_start,
+                                     MT_DEVICE_MEM);
+               else
+                       set_pgsection(level1_table, i,
+                                     va_start,
+                                     MT_DEVICE_MEM);
+               va_start += BLOCK_SIZE_L2;
+       }
+
+       asm volatile("dsb sy;isb");
+       asm volatile("mcr p15, 0, %0, c2, c0, 2" /* Write RT to TTBCR */
+                       : : "r" (TTBCR) : "memory");
+       asm volatile("mcrr p15, 0, %0, %1, c2" /* TTBR 0 */
+                       : : "r" ((u32)level0_table), "r" (0) : "memory");
+       asm volatile("mcr p15, 0, %0, c10, c2, 0" /* write MAIR 0 */
+                       : : "r" (MT_MAIR0) : "memory");
+       asm volatile("mcr p15, 0, %0, c10, c2, 1" /* write MAIR 1 */
+                       : : "r" (MT_MAIR1) : "memory");
+
+       /* Set the access control to all-supervisor */
+       asm volatile("mcr p15, 0, %0, c3, c0, 0"
+                    : : "r" (~0));
+
+       /* Enable the mmu */
+       reg = get_cr();
+       set_cr(reg | CR_M);
+}
+
+/*
+ * This function is called from lib/board.c. It recreates MMU
+ * table in main memory. MMU and i/d-cache are enabled here.
+ */
+void enable_caches(void)
+{
+       /* Invalidate all TLB */
+       mmu_page_table_flush(gd->arch.tlb_addr,
+                            gd->arch.tlb_addr +  gd->arch.tlb_size);
+       /* Set up and enable mmu */
+       mmu_setup();
+
+       /* Invalidate & Enable d-cache */
+       invalidate_dcache_all();
+       set_cr(get_cr() | CR_C);
+}
+#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
 int print_cpuinfo(void)
 {
@@ -78,16 +278,6 @@ int print_cpuinfo(void)
 }
 #endif
 
-void enable_caches(void)
-{
-#ifndef CONFIG_SYS_ICACHE_OFF
-       icache_enable();
-#endif
-#ifndef CONFIG_SYS_DCACHE_OFF
-       dcache_enable();
-#endif
-}
-
 #ifdef CONFIG_FSL_ESDHC
 int cpu_mmc_init(bd_t *bis)
 {
@@ -107,6 +297,27 @@ int cpu_eth_init(bd_t *bis)
 int arch_cpu_init(void)
 {
        void *epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET);
+       void *rcpm2_base =
+               (void *)(CONFIG_SYS_DCSRBAR + DCSR_RCPM2_BLOCK_OFFSET);
+       u32 state;
+
+       /*
+        * The RCPM FSM state may not be reset after power-on.
+        * So, reset them.
+        */
+       state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR0) &
+               CPMFSMSR_FSM_STATE_MASK;
+       if (state != 0) {
+               out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x80);
+               out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x0);
+       }
+
+       state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR1) &
+               CPMFSMSR_FSM_STATE_MASK;
+       if (state != 0) {
+               out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x80);
+               out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x0);
+       }
 
        /*
         * After wakeup from deep sleep, Clear EPU registers
index 9c6e824..fa447bc 100644 (file)
@@ -155,3 +155,9 @@ ENTRY(__asm_invalidate_icache_all)
        isb     sy
        ret
 ENDPROC(__asm_invalidate_icache_all)
+
+ENTRY(__asm_flush_l3_cache)
+       mov     x0, #0                  /* return status as success */
+       ret
+ENDPROC(__asm_flush_l3_cache)
+       .weak   __asm_flush_l3_cache
index 9dbcdf2..c5ec529 100644 (file)
@@ -73,17 +73,21 @@ void invalidate_dcache_all(void)
        __asm_invalidate_dcache_all();
 }
 
-void __weak flush_l3_cache(void)
-{
-}
-
 /*
- * Performs a clean & invalidation of the entire data cache at all levels
+ * Performs a clean & invalidation of the entire data cache at all levels.
+ * This function needs to be inline to avoid using stack.
+ * __asm_flush_l3_cache return status of timeout
  */
-void flush_dcache_all(void)
+inline void flush_dcache_all(void)
 {
+       int ret;
+
        __asm_flush_dcache_all();
-       flush_l3_cache();
+       ret = __asm_flush_l3_cache();
+       if (ret)
+               debug("flushing dcache returns 0x%x\n", ret);
+       else
+               debug("flushing dcache successfully.\n");
 }
 
 /*
index 47b947f..4997487 100644 (file)
 #include <asm/armv8/mmu.h>
 #include <asm/io.h>
 #include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <fsl-mc/fsl_mc.h>
 #include "cpu.h"
 #include "mp.h"
 #include "speed.h"
-#include <fsl_mc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -150,7 +150,7 @@ static inline void final_mmu_setup(void)
         * set level 2 table 0 to cache-inhibit, covering 0 to 1GB
         */
        section_l1t0 = 0;
-       section_l1t1 = BLOCK_SIZE_L0;
+       section_l1t1 = BLOCK_SIZE_L0 | PMD_SECT_OUTER_SHARE;
        section_l2 = 0;
        for (i = 0; i < 512; i++) {
                set_pgtable_section(level1_table_0, i, section_l1t0,
@@ -168,10 +168,10 @@ static inline void final_mmu_setup(void)
                (u64)level2_table_0 | PMD_TYPE_TABLE;
        level1_table_0[2] =
                0x80000000 | PMD_SECT_AF | PMD_TYPE_SECT |
-               PMD_ATTRINDX(MT_NORMAL);
+               PMD_SECT_OUTER_SHARE | PMD_ATTRINDX(MT_NORMAL);
        level1_table_0[3] =
                0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT |
-               PMD_ATTRINDX(MT_NORMAL);
+               PMD_SECT_OUTER_SHARE | PMD_ATTRINDX(MT_NORMAL);
 
        /* Rewrite table to enable cache */
        set_pgtable_section(level2_table_0,
@@ -243,59 +243,6 @@ int arch_cpu_init(void)
 }
 
 /*
- * flush_l3_cache
- * Dickens L3 cache can be flushed by transitioning from FAM to SFONLY power
- * state, by writing to HP-F P-state request register.
- * Fixme: This function should moved to a common file if other SoCs also use
- * the same Dickens.
- */
-#define HNF0_PSTATE_REQ 0x04200010
-#define HNF1_PSTATE_REQ 0x04210010
-#define HNF2_PSTATE_REQ 0x04220010
-#define HNF3_PSTATE_REQ 0x04230010
-#define HNF4_PSTATE_REQ 0x04240010
-#define HNF5_PSTATE_REQ 0x04250010
-#define HNF6_PSTATE_REQ 0x04260010
-#define HNF7_PSTATE_REQ 0x04270010
-#define HNFPSTAT_MASK (0xFFFFFFFFFFFFFFFC)
-#define HNFPSTAT_FAM   0x3
-#define HNFPSTAT_SFONLY 0x01
-
-static void hnf_pstate_req(u64 *ptr, u64 state)
-{
-       int timeout = 1000;
-       out_le64(ptr, (in_le64(ptr) & HNFPSTAT_MASK) | (state & 0x3));
-       ptr++;
-       /* checking if the transition is completed */
-       while (timeout > 0) {
-               if (((in_le64(ptr) & 0x0c) >> 2) == (state & 0x3))
-                       break;
-               udelay(100);
-               timeout--;
-       }
-}
-
-void flush_l3_cache(void)
-{
-       hnf_pstate_req((u64 *)HNF0_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF1_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF2_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF3_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF4_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF5_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF6_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF7_PSTATE_REQ, HNFPSTAT_SFONLY);
-       hnf_pstate_req((u64 *)HNF0_PSTATE_REQ, HNFPSTAT_FAM);
-       hnf_pstate_req((u64 *)HNF1_PSTATE_REQ, HNFPSTAT_FAM);
-       hnf_pstate_req((u64 *)HNF2_PSTATE_REQ, HNFPSTAT_FAM);
-       hnf_pstate_req((u64 *)HNF3_PSTATE_REQ, HNFPSTAT_FAM);
-       hnf_pstate_req((u64 *)HNF4_PSTATE_REQ, HNFPSTAT_FAM);
-       hnf_pstate_req((u64 *)HNF5_PSTATE_REQ, HNFPSTAT_FAM);
-       hnf_pstate_req((u64 *)HNF6_PSTATE_REQ, HNFPSTAT_FAM);
-       hnf_pstate_req((u64 *)HNF7_PSTATE_REQ, HNFPSTAT_FAM);
-}
-
-/*
  * This function is called from lib/board.c.
  * It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
  * There is no need to disable d-cache for this operation.
@@ -420,6 +367,7 @@ int print_cpuinfo(void)
        printf("\n       Bus:      %-4s MHz  ",
               strmhz(buf, sysinfo.freq_systembus));
        printf("DDR:      %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus));
+       printf("     DP-DDR:   %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2));
        puts("\n");
 
        return 0;
index e392eb9..7eb9b6a 100644 (file)
@@ -16,7 +16,7 @@ void ft_fixup_cpu(void *blob)
        __maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
        fdt32_t *reg;
        int addr_cells;
-       u64 val;
+       u64 val, core_id;
        size_t *boot_code_size = &(__secondary_boot_code_size);
 
        off = fdt_path_offset(blob, "/cpus");
@@ -29,15 +29,20 @@ void ft_fixup_cpu(void *blob)
        off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
        while (off != -FDT_ERR_NOTFOUND) {
                reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
+               core_id = of_read_number(reg, addr_cells);
                if (reg) {
-                       val = spin_tbl_addr;
-                       val += id_to_core(of_read_number(reg, addr_cells))
-                               * SPIN_TABLE_ELEM_SIZE;
-                       val = cpu_to_fdt64(val);
-                       fdt_setprop_string(blob, off, "enable-method",
-                                          "spin-table");
-                       fdt_setprop(blob, off, "cpu-release-addr",
-                                   &val, sizeof(val));
+                       if (core_id  == 0 || (is_core_online(core_id))) {
+                               val = spin_tbl_addr;
+                               val += id_to_core(core_id) *
+                                      SPIN_TABLE_ELEM_SIZE;
+                               val = cpu_to_fdt64(val);
+                               fdt_setprop_string(blob, off, "enable-method",
+                                                  "spin-table");
+                               fdt_setprop(blob, off, "cpu-release-addr",
+                                           &val, sizeof(val));
+                       } else {
+                               debug("skipping offline core\n");
+                       }
                } else {
                        puts("Warning: found cpu node without reg property\n");
                }
@@ -55,4 +60,9 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 #ifdef CONFIG_MP
        ft_fixup_cpu(blob);
 #endif
+
+#ifdef CONFIG_SYS_NS16550
+       do_fixup_by_compat_u32(blob, "ns16550",
+                              "clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
+#endif
 }
index 2a88aab..886576e 100644 (file)
@@ -42,10 +42,142 @@ ENTRY(lowlevel_init)
        ldr     x0, =secondary_boot_func
        blr     x0
 2:
+
+#ifdef CONFIG_FSL_TZPC_BP147
+       /* Set Non Secure access for all devices protected via TZPC */
+       ldr     x1, =TZPCDECPROT_0_SET_BASE /* Decode Protection-0 Set Reg */
+       orr     w0, w0, #1 << 3 /* DCFG_RESET is accessible from NS world */
+       str     w0, [x1]
+
+       isb
+       dsb     sy
+#endif
+
+#ifdef CONFIG_FSL_TZASC_400
+       /* Set TZASC so that:
+        * a. We use only Region0 whose global secure write/read is EN
+        * b. We use only Region0 whose NSAID write/read is EN
+        *
+        * NOTE: As per the CCSR map doc, TZASC 3 and TZASC 4 are just
+        *       placeholders.
+        */
+       ldr     x1, =TZASC_GATE_KEEPER(0)
+       ldr     x0, [x1]                /* Filter 0 Gate Keeper Register */
+       orr     x0, x0, #1 << 0         /* Set open_request for Filter 0 */
+       str     x0, [x1]
+
+       ldr     x1, =TZASC_GATE_KEEPER(1)
+       ldr     x0, [x1]                /* Filter 0 Gate Keeper Register */
+       orr     x0, x0, #1 << 0         /* Set open_request for Filter 0 */
+       str     x0, [x1]
+
+       ldr     x1, =TZASC_REGION_ATTRIBUTES_0(0)
+       ldr     x0, [x1]                /* Region-0 Attributes Register */
+       orr     x0, x0, #1 << 31        /* Set Sec global write en, Bit[31] */
+       orr     x0, x0, #1 << 30        /* Set Sec global read en, Bit[30] */
+       str     x0, [x1]
+
+       ldr     x1, =TZASC_REGION_ATTRIBUTES_0(1)
+       ldr     x0, [x1]                /* Region-1 Attributes Register */
+       orr     x0, x0, #1 << 31        /* Set Sec global write en, Bit[31] */
+       orr     x0, x0, #1 << 30        /* Set Sec global read en, Bit[30] */
+       str     x0, [x1]
+
+       ldr     x1, =TZASC_REGION_ID_ACCESS_0(0)
+       ldr     w0, [x1]                /* Region-0 Access Register */
+       mov     w0, #0xFFFFFFFF         /* Set nsaid_wr_en and nsaid_rd_en */
+       str     w0, [x1]
+
+       ldr     x1, =TZASC_REGION_ID_ACCESS_0(1)
+       ldr     w0, [x1]                /* Region-1 Attributes Register */
+       mov     w0, #0xFFFFFFFF         /* Set nsaid_wr_en and nsaid_rd_en */
+       str     w0, [x1]
+
+       isb
+       dsb     sy
+#endif
        mov     lr, x29                 /* Restore LR */
        ret
 ENDPROC(lowlevel_init)
 
+hnf_pstate_poll:
+       /* x0 has the desired status, return 0 for success, 1 for timeout
+        * clobber x1, x2, x3, x4, x6, x7
+        */
+       mov     x1, x0
+       mov     x7, #0                  /* flag for timeout */
+       mrs     x3, cntpct_el0          /* read timer */
+       add     x3, x3, #1200           /* timeout after 100 microseconds */
+       mov     x0, #0x18
+       movk    x0, #0x420, lsl #16     /* HNF0_PSTATE_STATUS */
+       mov     w6, #8                  /* HN-F node count */
+1:
+       ldr     x2, [x0]
+       cmp     x2, x1                  /* check status */
+       b.eq    2f
+       mrs     x4, cntpct_el0
+       cmp     x4, x3
+       b.ls    1b
+       mov     x7, #1                  /* timeout */
+       b       3f
+2:
+       add     x0, x0, #0x10000        /* move to next node */
+       subs    w6, w6, #1
+       cbnz    w6, 1b
+3:
+       mov     x0, x7
+       ret
+
+hnf_set_pstate:
+       /* x0 has the desired state, clobber x1, x2, x6 */
+       mov     x1, x0
+       /* power state to SFONLY */
+       mov     w6, #8                  /* HN-F node count */
+       mov     x0, #0x10
+       movk    x0, #0x420, lsl #16     /* HNF0_PSTATE_REQ */
+1:     /* set pstate to sfonly */
+       ldr     x2, [x0]
+       and     x2, x2, #0xfffffffffffffffc     /* & HNFPSTAT_MASK */
+       orr     x2, x2, x1
+       str     x2, [x0]
+       add     x0, x0, #0x10000        /* move to next node */
+       subs    w6, w6, #1
+       cbnz    w6, 1b
+
+       ret
+
+ENTRY(__asm_flush_l3_cache)
+       /*
+        * Return status in x0
+        *    success 0
+        *    tmeout 1 for setting SFONLY, 2 for FAM, 3 for both
+        */
+       mov     x29, lr
+       mov     x8, #0
+
+       dsb     sy
+       mov     x0, #0x1                /* HNFPSTAT_SFONLY */
+       bl      hnf_set_pstate
+
+       mov     x0, #0x4                /* SFONLY status */
+       bl      hnf_pstate_poll
+       cbz     x0, 1f
+       mov     x8, #1                  /* timeout */
+1:
+       dsb     sy
+       mov     x0, #0x3                /* HNFPSTAT_FAM */
+       bl      hnf_set_pstate
+
+       mov     x0, #0xc                /* FAM status */
+       bl      hnf_pstate_poll
+       cbz     x0, 1f
+       add     x8, x8, #0x2
+1:
+       mov     x0, x8
+       mov     lr, x29
+       ret
+ENDPROC(__asm_flush_l3_cache)
+
        /* Keep literals not used by the secondary boot code outside it */
        .ltorg
 
index 94998bf..ce9c0c1 100644 (file)
@@ -83,6 +83,14 @@ int is_core_valid(unsigned int core)
        return !!((1 << core) & cpu_mask());
 }
 
+int is_core_online(u64 cpu_id)
+{
+       u64 *table;
+       int pos = id_to_core(cpu_id);
+       table = (u64 *)get_spin_tbl_addr() + pos * WORDS_PER_SPIN_TABLE_ENTRY;
+       return table[SPIN_TABLE_ELEM_STATUS_IDX] == 1;
+}
+
 int cpu_reset(int nr)
 {
        puts("Feature is not implemented.\n");
index 06ac0bc..66144d6 100644 (file)
@@ -32,5 +32,6 @@ int fsl_lsch3_wake_seconday_cores(void);
 void *get_spin_tbl_addr(void);
 phys_addr_t determine_mp_bootpg(void);
 void secondary_boot_func(void);
+int is_core_online(u64 cpu_id);
 #endif
 #endif /* _FSL_CH3_MP_H */
index dc4a34b..72cd999 100644 (file)
@@ -77,8 +77,10 @@ void get_sys_info(struct sys_info *sys_info)
        sys_info->freq_systembus = sysclk;
 #ifdef CONFIG_DDR_CLK_FREQ
        sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
+       sys_info->freq_ddrbus2 = CONFIG_DDR_CLK_FREQ;
 #else
        sys_info->freq_ddrbus = sysclk;
+       sys_info->freq_ddrbus2 = sysclk;
 #endif
 
        sys_info->freq_systembus *= (in_le32(&gur->rcwsr[0]) >>
@@ -87,6 +89,9 @@ void get_sys_info(struct sys_info *sys_info)
        sys_info->freq_ddrbus *= (in_le32(&gur->rcwsr[0]) >>
                        FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) &
                        FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK;
+       sys_info->freq_ddrbus2 *= (in_le32(&gur->rcwsr[0]) >>
+                       FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT) &
+                       FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK;
 
        for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
                /*
@@ -129,7 +134,7 @@ int get_clocks(void)
        gd->cpu_clk = sys_info.freq_processor[0];
        gd->bus_clk = sys_info.freq_systembus;
        gd->mem_clk = sys_info.freq_ddrbus;
-
+       gd->arch.mem2_clk = sys_info.freq_ddrbus2;
 #if defined(CONFIG_FSL_ESDHC)
        gd->arch.sdhc_clk = gd->bus_clk / 2;
 #endif /* defined(CONFIG_FSL_ESDHC) */
@@ -156,11 +161,18 @@ ulong get_bus_freq(ulong dummy)
  * get_ddr_freq
  * return ddr bus freq in Hz
  *********************************************/
-ulong get_ddr_freq(ulong dummy)
+ulong get_ddr_freq(ulong ctrl_num)
 {
        if (!gd->mem_clk)
                get_clocks();
 
+       /*
+        * DDR controller 0 & 1 are on memory complex 0
+        * DDR controler 2 is on memory complext 1
+        */
+       if (ctrl_num >= 2)
+               return gd->arch.mem2_clk;
+
        return gd->mem_clk;
 }
 
index da551e8..b140c1f 100644 (file)
 #define CONFIG_SYS_FSL_PMU_CLTBENR             (CONFIG_SYS_FSL_PMU_ADDR + \
                                                 0x18A0)
 
+#define CONFIG_SYS_FSL_DCSR_DDR_ADDR           0x70012c000ULL
+#define CONFIG_SYS_FSL_DCSR_DDR2_ADDR          0x70012d000ULL
+#define CONFIG_SYS_FSL_DCSR_DDR3_ADDR          0x700132000ULL
+#define CONFIG_SYS_FSL_DCSR_DDR4_ADDR          0x700133000ULL
+
 #define I2C1_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x01000000)
 #define I2C2_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x01010000)
 #define I2C3_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x01020000)
 #define I2C4_BASE_ADDR                         (CONFIG_SYS_IMMR + 0x01030000)
 
+/* TZ Protection Controller Definitions */
+#define TZPC_BASE                              0x02200000
+#define TZPCR0SIZE_BASE                                (TZPC_BASE)
+#define TZPCDECPROT_0_STAT_BASE                        (TZPC_BASE + 0x800)
+#define TZPCDECPROT_0_SET_BASE                 (TZPC_BASE + 0x804)
+#define TZPCDECPROT_0_CLR_BASE                 (TZPC_BASE + 0x808)
+#define TZPCDECPROT_1_STAT_BASE                        (TZPC_BASE + 0x80C)
+#define TZPCDECPROT_1_SET_BASE                 (TZPC_BASE + 0x810)
+#define TZPCDECPROT_1_CLR_BASE                 (TZPC_BASE + 0x814)
+#define TZPCDECPROT_2_STAT_BASE                        (TZPC_BASE + 0x818)
+#define TZPCDECPROT_2_SET_BASE                 (TZPC_BASE + 0x81C)
+#define TZPCDECPROT_2_CLR_BASE                 (TZPC_BASE + 0x820)
+
+/* TZ Address Space Controller Definitions */
+#define TZASC1_BASE                    0x01100000      /* as per CCSR map. */
+#define TZASC2_BASE                    0x01110000      /* as per CCSR map. */
+#define TZASC3_BASE                    0x01120000      /* as per CCSR map. */
+#define TZASC4_BASE                    0x01130000      /* as per CCSR map. */
+#define TZASC_BUILD_CONFIG_REG(x)      ((TZASC1_BASE + (x * 0x10000)))
+#define TZASC_ACTION_REG(x)            ((TZASC1_BASE + (x * 0x10000)) + 0x004)
+#define TZASC_GATE_KEEPER(x)           ((TZASC1_BASE + (x * 0x10000)) + 0x008)
+#define TZASC_REGION_BASE_LOW_0(x)     ((TZASC1_BASE + (x * 0x10000)) + 0x100)
+#define TZASC_REGION_BASE_HIGH_0(x)    ((TZASC1_BASE + (x * 0x10000)) + 0x104)
+#define TZASC_REGION_TOP_LOW_0(x)      ((TZASC1_BASE + (x * 0x10000)) + 0x108)
+#define TZASC_REGION_TOP_HIGH_0(x)     ((TZASC1_BASE + (x * 0x10000)) + 0x10C)
+#define TZASC_REGION_ATTRIBUTES_0(x)   ((TZASC1_BASE + (x * 0x10000)) + 0x110)
+#define TZASC_REGION_ID_ACCESS_0(x)    ((TZASC1_BASE + (x * 0x10000)) + 0x114)
+
 /* Generic Interrupt Controller Definitions */
 #define GICD_BASE              0x06000000
 #define GICR_BASE              0x06100000
 #error SoC not defined
 #endif
 
+#ifdef CONFIG_LS2085A
+#define CONFIG_SYS_FSL_ERRATUM_A008336
+#define CONFIG_SYS_FSL_ERRATUM_A008514
+#endif
+
 #endif /* _ASM_ARMV8_FSL_LSCH3_CONFIG_ */
index ee1d651..dd11ef7 100644 (file)
@@ -15,6 +15,7 @@ struct sys_info {
        unsigned long freq_processor[CONFIG_MAX_CPUS];
        unsigned long freq_systembus;
        unsigned long freq_ddrbus;
+       unsigned long freq_ddrbus2;
        unsigned long freq_localbus;
        unsigned long freq_qe;
 #ifdef CONFIG_SYS_DPAA_FMAN
@@ -60,6 +61,8 @@ struct ccsr_gur {
 #define FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK   0x1f
 #define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT  10
 #define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK   0x3f
+#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT 18
+#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK  0x3f
        u8      res_180[0x200-0x180];
        u32     scratchrw[32];  /* Scratch Read/Write */
        u8      res_280[0x300-0x280];
index 7915518..3b6a169 100644 (file)
@@ -36,6 +36,7 @@
 #define CONFIG_SYS_LS102XA_USB1_ADDR \
        (CONFIG_SYS_IMMR + CONFIG_SYS_LS102XA_USB1_OFFSET)
 
+#define CONFIG_SYS_FSL_SEC_OFFSET              0x00700000
 #define CONFIG_SYS_LS102XA_USB1_OFFSET         0x07600000
 #define CONFIG_SYS_TSEC1_OFFSET                        0x01d10000
 #define CONFIG_SYS_TSEC2_OFFSET                        0x01d50000
 #define CONFIG_SYS_PCIE1_ADDR                  (CONFIG_SYS_IMMR + 0x2400000)
 #define CONFIG_SYS_PCIE2_ADDR                  (CONFIG_SYS_IMMR + 0x2500000)
 
+#define CONFIG_SYS_PCIE1_PHYS_BASE             0x4000000000ULL
+#define CONFIG_SYS_PCIE2_PHYS_BASE             0x4800000000ULL
+#define CONFIG_SYS_PCIE1_VIRT_ADDR             0x24000000UL
+#define CONFIG_SYS_PCIE2_VIRT_ADDR             0x34000000UL
+#define CONFIG_SYS_PCIE_MMAP_SIZE              (192 * 1024 * 1024) /* 192M */
+/*
+ * TLB will map VIRT_ADDR to (PHYS_BASE + VIRT_ADDR)
+ * So 40bit PCIe PHY addr can directly be converted to a 32bit virtual addr.
+ */
+#define CONFIG_SYS_PCIE1_PHYS_ADDR             (CONFIG_SYS_PCIE1_PHYS_BASE + \
+                                                CONFIG_SYS_PCIE1_VIRT_ADDR)
+#define CONFIG_SYS_PCIE2_PHYS_ADDR             (CONFIG_SYS_PCIE2_PHYS_BASE + \
+                                                CONFIG_SYS_PCIE2_VIRT_ADDR)
+
 #ifdef CONFIG_DDR_SPD
 #define CONFIG_SYS_FSL_DDR_BE
 #define CONFIG_VERY_BIG_RAM
index f70d568..3a64afc 100644 (file)
 
 #define DCFG_DCSR_PORCR1               0
 
+/*
+ * Define default values for some CCSR macros to make header files cleaner
+ *
+ * To completely disable CCSR relocation in a board header file, define
+ * CONFIG_SYS_CCSR_DO_NOT_RELOCATE.  This will force CONFIG_SYS_CCSRBAR_PHYS
+ * to a value that is the same as CONFIG_SYS_CCSRBAR.
+ */
+
+#ifdef CONFIG_SYS_CCSRBAR_PHYS
+#error "Do not define CONFIG_SYS_CCSRBAR_PHYS directly."
+#endif
+
+#ifdef CONFIG_SYS_CCSR_DO_NOT_RELOCATE
+#undef CONFIG_SYS_CCSRBAR_PHYS_HIGH
+#undef CONFIG_SYS_CCSRBAR_PHYS_LOW
+#define CONFIG_SYS_CCSRBAR_PHYS_HIGH   0
+#endif
+
+#ifndef CONFIG_SYS_CCSRBAR
+#define CONFIG_SYS_CCSRBAR             CONFIG_SYS_IMMR
+#endif
+
+#ifndef CONFIG_SYS_CCSRBAR_PHYS_HIGH
+#ifdef CONFIG_PHYS_64BIT
+#define CONFIG_SYS_CCSRBAR_PHYS_HIGH   0xf
+#else
+#define CONFIG_SYS_CCSRBAR_PHYS_HIGH   0
+#endif
+#endif
+
+#ifndef CONFIG_SYS_CCSRBAR_PHYS_LOW
+#define CONFIG_SYS_CCSRBAR_PHYS_LOW    CONFIG_SYS_IMMR
+#endif
+
+#define CONFIG_SYS_CCSRBAR_PHYS ((CONFIG_SYS_CCSRBAR_PHYS_HIGH * 1ull) << 32 | \
+                                CONFIG_SYS_CCSRBAR_PHYS_LOW)
+
 struct sys_info {
        unsigned long freq_processor[CONFIG_MAX_CPUS];
        unsigned long freq_systembus;
@@ -133,8 +170,7 @@ struct ccsr_scfg {
        u32 pex1rdmmsgrqsr;
        u32 pex2rdmmsgrqsr;
        u32 spimsiclrcr;
-       u32 pex1mscportsr;
-       u32 pex2mscportsr;
+       u32 pexmscportsr[2];
        u32 pex2pmwrcr;
        u32 resv5[24];
        u32 mac1_streamid;
index abd70fc..fa571b3 100644 (file)
@@ -7,11 +7,68 @@
 #ifndef __FSL_LS102XA_STREAM_ID_H_
 #define __FSL_LS102XA_STREAM_ID_H_
 
+#include <fsl_sec.h>
+
+#define SET_LIODN_ENTRY_1(name, idA, off, compatoff) \
+       { .compat = name, \
+         .id = { idA }, .num_ids = 1, \
+         .reg_offset = off + CONFIG_SYS_IMMR, \
+         .compat_offset = compatoff + CONFIG_SYS_CCSRBAR_PHYS, \
+       }
+
+#define SET_LIODN_ENTRY_2(name, idA, idB, off, compatoff) \
+       { .compat = name, \
+         .id = { idA, idB }, .num_ids = 2, \
+         .reg_offset = off + CONFIG_SYS_IMMR, \
+         .compat_offset = compatoff + CONFIG_SYS_CCSRBAR_PHYS, \
+       }
+
+/*
+ * handle both old and new versioned SEC properties:
+ * "fsl,secX.Y" became "fsl,sec-vX.Y" during development
+ */
+#define SET_SEC_JR_LIODN_ENTRY(jrnum, liodnA, liodnB) \
+       SET_LIODN_ENTRY_2("fsl,sec4.0-job-ring", liodnA, liodnB, \
+               offsetof(ccsr_sec_t, jrliodnr[jrnum].ls) + \
+               CONFIG_SYS_FSL_SEC_OFFSET, \
+               CONFIG_SYS_FSL_SEC_OFFSET + 0x1000 + 0x1000 * jrnum), \
+       SET_LIODN_ENTRY_2("fsl,sec-v4.0-job-ring", liodnA, liodnB,\
+               offsetof(ccsr_sec_t, jrliodnr[jrnum].ls) + \
+               CONFIG_SYS_FSL_SEC_OFFSET, \
+               CONFIG_SYS_FSL_SEC_OFFSET + 0x1000 + 0x1000 * jrnum)
+
+/* This is a bit evil since we treat rtic param as both a string & hex value */
+#define SET_SEC_RTIC_LIODN_ENTRY(rtic, liodnA) \
+       SET_LIODN_ENTRY_1("fsl,sec4.0-rtic-memory", \
+               liodnA, \
+               offsetof(ccsr_sec_t, rticliodnr[0x##rtic-0xa].ls) + \
+               CONFIG_SYS_FSL_SEC_OFFSET, \
+               CONFIG_SYS_FSL_SEC_OFFSET + 0x6100 + 0x20 * (0x##rtic-0xa)), \
+       SET_LIODN_ENTRY_1("fsl,sec-v4.0-rtic-memory", \
+               liodnA, \
+               offsetof(ccsr_sec_t, rticliodnr[0x##rtic-0xa].ls) + \
+               CONFIG_SYS_FSL_SEC_OFFSET, \
+               CONFIG_SYS_FSL_SEC_OFFSET + 0x6100 + 0x20 * (0x##rtic-0xa))
+
+#define SET_SEC_DECO_LIODN_ENTRY(num, liodnA, liodnB) \
+       SET_LIODN_ENTRY_2(NULL, liodnA, liodnB, \
+               offsetof(ccsr_sec_t, decoliodnr[num].ls) + \
+               CONFIG_SYS_FSL_SEC_OFFSET, 0)
+
+struct liodn_id_table {
+       const char *compat;
+       u32 id[2];
+       u8 num_ids;
+       phys_addr_t compat_offset;
+       unsigned long reg_offset;
+};
+
 struct smmu_stream_id {
        uint16_t offset;
        uint16_t stream_id;
        char dev_name[32];
 };
 
+void ls1021x_config_caam_stream_id(struct liodn_id_table *tbl, int size);
 void ls102xa_config_smmu_stream_id(struct smmu_stream_id *id, uint32_t num);
 #endif
index 4b7b67b..4b9cb52 100644 (file)
@@ -65,7 +65,8 @@
 /*
  * Section
  */
-#define PMD_SECT_S             (3 << 8)
+#define PMD_SECT_OUTER_SHARE   (2 << 8)
+#define PMD_SECT_INNER_SHARE   (3 << 8)
 #define PMD_SECT_AF            (1 << 10)
 #define PMD_SECT_NG            (1 << 11)
 #define PMD_SECT_PXN           (UL(1) << 53)
index 438f128..bb24f33 100644 (file)
@@ -48,6 +48,9 @@ struct arch_global_data {
 #ifdef CONFIG_OMAP
        struct omap_boot_parameters omap_boot_params;
 #endif
+#ifdef CONFIG_FSL_LSCH3
+       unsigned long mem2_clk;
+#endif
 };
 
 #include <asm-generic/global_data.h>
index 7820486..2a5bed2 100644 (file)
@@ -70,6 +70,7 @@ void __asm_invalidate_dcache_all(void);
 void __asm_flush_dcache_range(u64 start, u64 end);
 void __asm_invalidate_tlb_all(void);
 void __asm_invalidate_icache_all(void);
+int __asm_flush_l3_cache(void);
 
 void armv8_switch_to_el2(void);
 void armv8_switch_to_el1(void);
index 0c1298a..2d6b676 100644 (file)
@@ -191,7 +191,7 @@ __weak void setup_board_tags(struct tag **in_params) {}
 static void do_nonsec_virt_switch(void)
 {
        smp_kick_all_cpus();
-       flush_dcache_all();     /* flush cache before swtiching to EL2 */
+       dcache_disable();       /* flush cache before swtiching to EL2 */
        armv8_switch_to_el2();
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
        armv8_switch_to_el1();
index 6154c9c..f434269 100644 (file)
@@ -16,3 +16,18 @@ void ls102xa_config_smmu_stream_id(struct smmu_stream_id *id, uint32_t num)
        for (i = 0; i < num; i++)
                out_be32(scfg + id[i].offset, id[i].stream_id);
 }
+
+void ls1021x_config_caam_stream_id(struct liodn_id_table *tbl, int size)
+{
+       int i;
+       u32 liodn;
+
+       for (i = 0; i < size; i++) {
+               if (tbl[i].num_ids == 2)
+                       liodn = (tbl[i].id[0] << 16) | tbl[i].id[1];
+               else
+                       liodn = tbl[i].id[0];
+
+               out_le32((uint32_t *)(tbl[i].reg_offset), liodn);
+       }
+}
index 20eade4..722b88f 100644 (file)
@@ -509,6 +509,25 @@ static struct csu_ns_dev ns_dev[] = {
 };
 #endif
 
+struct liodn_id_table sec_liodn_tbl[] = {
+       SET_SEC_JR_LIODN_ENTRY(0, 0x10, 0x10),
+       SET_SEC_JR_LIODN_ENTRY(1, 0x10, 0x10),
+       SET_SEC_JR_LIODN_ENTRY(2, 0x10, 0x10),
+       SET_SEC_JR_LIODN_ENTRY(3, 0x10, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(a, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(b, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(c, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(d, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(0, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(1, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(2, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(3, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(4, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(5, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(6, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(7, 0x10, 0x10),
+};
+
 struct smmu_stream_id dev_stream_id[] = {
        { 0x100, 0x01, "ETSEC MAC1" },
        { 0x104, 0x02, "ETSEC MAC2" },
@@ -541,6 +560,8 @@ int board_init(void)
        config_serdes_mux();
 #endif
 
+       ls1021x_config_caam_stream_id(sec_liodn_tbl,
+                                     ARRAY_SIZE(sec_liodn_tbl));
        ls102xa_config_smmu_stream_id(dev_stream_id,
                                      ARRAY_SIZE(dev_stream_id));
 
index bc8b006..fb8525f 100644 (file)
@@ -401,6 +401,25 @@ static struct csu_ns_dev ns_dev[] = {
 };
 #endif
 
+struct liodn_id_table sec_liodn_tbl[] = {
+       SET_SEC_JR_LIODN_ENTRY(0, 0x10, 0x10),
+       SET_SEC_JR_LIODN_ENTRY(1, 0x10, 0x10),
+       SET_SEC_JR_LIODN_ENTRY(2, 0x10, 0x10),
+       SET_SEC_JR_LIODN_ENTRY(3, 0x10, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(a, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(b, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(c, 0x10),
+       SET_SEC_RTIC_LIODN_ENTRY(d, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(0, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(1, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(2, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(3, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(4, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(5, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(6, 0x10, 0x10),
+       SET_SEC_DECO_LIODN_ENTRY(7, 0x10, 0x10),
+};
+
 struct smmu_stream_id dev_stream_id[] = {
        { 0x100, 0x01, "ETSEC MAC1" },
        { 0x104, 0x02, "ETSEC MAC2" },
@@ -427,6 +446,8 @@ int board_init(void)
 #endif
 #endif
 
+       ls1021x_config_caam_stream_id(sec_liodn_tbl,
+                                     ARRAY_SIZE(sec_liodn_tbl));
        ls102xa_config_smmu_stream_id(dev_stream_id,
                                      ARRAY_SIZE(dev_stream_id));
 
index b4a3fc9..4884fa2 100644 (file)
@@ -77,6 +77,7 @@ found:
                popts->data_bus_width = 1;
                popts->otf_burst_chop_en = 0;
                popts->burst_length = DDR_BL8;
+               popts->bstopre = 0;     /* enable auto precharge */
        }
        /*
         * Factors to consider for half-strength driver enable:
index 163a4c4..519d61c 100644 (file)
@@ -12,7 +12,7 @@
 #include <asm/io.h>
 #include <fdt_support.h>
 #include <libfdt.h>
-#include <fsl_mc.h>
+#include <fsl-mc/fsl_mc.h>
 #include <environment.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -59,8 +59,15 @@ int timer_init(void)
        u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
        u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
 
-       out_le32(cltbenr, 0x1);         /* enable cluster0 timebase */
-       out_le32(cntcr, 0x1);           /* enable clock for timer */
+       /* Enable timebase for all clusters.
+        * It is safe to do so even some clusters are not enabled.
+        */
+       out_le32(cltbenr, 0xf);
+
+       /* Enable clock for timer
+        * This is a global setting.
+        */
+       out_le32(cntcr, 0x1);
 
        return 0;
 }
@@ -91,7 +98,21 @@ void fdt_fixup_board_enet(void *fdt)
 {
        int offset;
 
-       offset = fdt_path_offset(fdt, "/fsl,dprc@0");
+       offset = fdt_path_offset(fdt, "/fsl-mc");
+
+       /*
+        * TODO: Remove this when backward compatibility
+        * with old DT node (fsl,dprc@0) is no longer needed.
+        */
+       if (offset < 0)
+               offset = fdt_path_offset(fdt, "/fsl,dprc@0");
+
+       if (offset < 0) {
+               printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
+                      __func__, offset);
+               return;
+       }
+
        if (get_mc_boot_status() == 0)
                fdt_status_okay(fdt, offset);
        else
index 82ecaf0..d3f22a1 100644 (file)
@@ -90,17 +90,19 @@ static char blob_help_text[] =
        "enc src dst len km - Encapsulate and create blob of data\n"
        "                          $len bytes long at address $src and\n"
        "                          store the result at address $dst.\n"
-       "                          $km is the 16 byte key modifier\n"
-       "                          is also required for generation/use as\n"
-       "                          key for cryptographic operation. Key\n"
-       "                          modifier should be 16 byte long.\n"
+       "                          $km is the address where the key\n"
+       "                          modifier is stored.\n"
+       "                          The modifier is required for generation\n"
+       "                          /use as key for cryptographic operation.\n"
+       "                          Key modifier should be 16 byte long.\n"
        "blob dec src dst len km - Decapsulate the  blob of data at address\n"
        "                          $src and store result of $len byte at\n"
        "                          addr $dst.\n"
-       "                          $km is the 16 byte key modifier\n"
-       "                          is also required for generation/use as\n"
-       "                          key for cryptographic operation. Key\n"
-       "                          modifier should be 16 byte long.\n";
+       "                          $km is the address where the key\n"
+       "                          modifier is stored.\n"
+       "                          The modifier is required for generation\n"
+       "                          /use as key for cryptographic operation.\n"
+       "                          Key modifier should be 16 byte long.\n";
 
 U_BOOT_CMD(
        blob, 6, 1, do_blob,
index d154d02..9e9f84b 100644 (file)
@@ -127,11 +127,21 @@ static struct hash_algo hash_algo[] = {
                SHA1_SUM_LEN,
                hw_sha1,
                CHUNKSZ_SHA1,
+#ifdef CONFIG_SHA_PROG_HW_ACCEL
+               hw_sha_init,
+               hw_sha_update,
+               hw_sha_finish,
+#endif
        }, {
                "sha256",
                SHA256_SUM_LEN,
                hw_sha256,
                CHUNKSZ_SHA256,
+#ifdef CONFIG_SHA_PROG_HW_ACCEL
+               hw_sha_init,
+               hw_sha_update,
+               hw_sha_finish,
+#endif
        },
 #endif
 #ifdef CONFIG_SHA1
diff --git a/doc/README.fsl-trustzone-components b/doc/README.fsl-trustzone-components
new file mode 100644 (file)
index 0000000..a3afd1f
--- /dev/null
@@ -0,0 +1,25 @@
+Freescale ARM64 SoCs like LS2085A have ARM TrustZone components like
+TZPC-BP147 (TrustZone Protection Controller) and TZASC-400 (TrustZone
+Address Space Controller).
+
+While most of the configuration related programming of these peripherals
+is left to a root-of-trust security software layer (running in EL3
+privilege mode), but still some configurations of these peripherals
+might be required while the bootloader is executing in EL3 privilege
+mode. The following sections define how to turn on these features for
+LS2085A like SoCs.
+
+TZPC-BP147 (TrustZone Protection Controller)
+============================================
+- Depends on CONFIG_FSL_TZPC_BP147 configuration flag.
+- Separates Secure World and Normal World on-chip RAM (OCRAM) spaces.
+- Provides a programming model to set access control policy via the TZPC
+  TZDECPROT Registers.
+
+TZASC-400 (TrustZone Address Space Controller)
+==============================================
+- Depends on CONFIG_FSL_TZASC_400 configuration flag.
+- Separates Secure World and Normal World external memory spaces for bus masters
+  such as processors and DMA-equipped peripherals.
+- Supports 8 fully programmable address regions, initially inactive at reset,
+  and one base region, always active, that covers the remaining address space.
index bc01075..9923bcb 100644 (file)
@@ -11,7 +11,7 @@
 #include "desc.h"
 #include "jr.h"
 
-int blob_decrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
+int blob_decap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
 {
        int ret, i = 0;
        u32 *desc;
@@ -36,7 +36,7 @@ int blob_decrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
        return ret;
 }
 
-int blob_encrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len)
+int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
 {
        int ret, i = 0;
        u32 *desc;
index d77f257..c298404 100644 (file)
@@ -10,6 +10,9 @@
 #include "jobdesc.h"
 #include "desc.h"
 #include "jr.h"
+#include "fsl_hash.h"
+#include <hw_sha.h>
+#include <asm-generic/errno.h>
 
 #define CRYPTO_MAX_ALG_NAME    80
 #define SHA1_DIGEST_SIZE        20
@@ -39,6 +42,122 @@ static struct caam_hash_template driver_hash[] = {
        },
 };
 
+static enum caam_hash_algos get_hash_type(struct hash_algo *algo)
+{
+       if (!strcmp(algo->name, driver_hash[SHA1].name))
+               return SHA1;
+       else
+               return SHA256;
+}
+
+/* Create the context for progressive hashing using h/w acceleration.
+ *
+ * @ctxp: Pointer to the pointer of the context for hashing
+ * @caam_algo: Enum for SHA1 or SHA256
+ * @return 0 if ok, -ENOMEM on error
+ */
+static int caam_hash_init(void **ctxp, enum caam_hash_algos caam_algo)
+{
+       *ctxp = calloc(1, sizeof(struct sha_ctx));
+       if (*ctxp == NULL) {
+               debug("Cannot allocate memory for context\n");
+               return -ENOMEM;
+       }
+       return 0;
+}
+
+/*
+ * Update sg table for progressive hashing using h/w acceleration
+ *
+ * The context is freed by this function if an error occurs.
+ * We support at most 32 Scatter/Gather Entries.
+ *
+ * @hash_ctx: Pointer to the context for hashing
+ * @buf: Pointer to the buffer being hashed
+ * @size: Size of the buffer being hashed
+ * @is_last: 1 if this is the last update; 0 otherwise
+ * @caam_algo: Enum for SHA1 or SHA256
+ * @return 0 if ok, -EINVAL on error
+ */
+static int caam_hash_update(void *hash_ctx, const void *buf,
+                           unsigned int size, int is_last,
+                           enum caam_hash_algos caam_algo)
+{
+       uint32_t final = 0;
+       dma_addr_t addr = virt_to_phys((void *)buf);
+       struct sha_ctx *ctx = hash_ctx;
+
+       if (ctx->sg_num >= MAX_SG_32) {
+               free(ctx);
+               return -EINVAL;
+       }
+
+#ifdef CONFIG_PHYS_64BIT
+       ctx->sg_tbl[ctx->sg_num].addr_hi = addr >> 32;
+#else
+       ctx->sg_tbl[ctx->sg_num].addr_hi = 0x0;
+#endif
+       ctx->sg_tbl[ctx->sg_num].addr_lo = addr;
+
+       sec_out32(&ctx->sg_tbl[ctx->sg_num].len_flag,
+                 (size & SG_ENTRY_LENGTH_MASK));
+
+       ctx->sg_num++;
+
+       if (is_last) {
+               final = sec_in32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag) |
+                       SG_ENTRY_FINAL_BIT;
+               sec_out32(&ctx->sg_tbl[ctx->sg_num - 1].len_flag, final);
+       }
+
+       return 0;
+}
+
+/*
+ * Perform progressive hashing on the given buffer and copy hash at
+ * destination buffer
+ *
+ * The context is freed after completion of hash operation.
+ *
+ * @hash_ctx: Pointer to the context for hashing
+ * @dest_buf: Pointer to the destination buffer where hash is to be copied
+ * @size: Size of the buffer being hashed
+ * @caam_algo: Enum for SHA1 or SHA256
+ * @return 0 if ok, -EINVAL on error
+ */
+static int caam_hash_finish(void *hash_ctx, void *dest_buf,
+                           int size, enum caam_hash_algos caam_algo)
+{
+       uint32_t len = 0;
+       struct sha_ctx *ctx = hash_ctx;
+       int i = 0, ret = 0;
+
+       if (size < driver_hash[caam_algo].digestsize) {
+               free(ctx);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ctx->sg_num; i++)
+               len += (sec_in32(&ctx->sg_tbl[i].len_flag) &
+                       SG_ENTRY_LENGTH_MASK);
+
+       inline_cnstr_jobdesc_hash(ctx->sha_desc, (uint8_t *)ctx->sg_tbl, len,
+                                 ctx->hash,
+                                 driver_hash[caam_algo].alg_type,
+                                 driver_hash[caam_algo].digestsize,
+                                 1);
+
+       ret = run_descriptor_jr(ctx->sha_desc);
+
+       if (ret)
+               debug("Error %x\n", ret);
+       else
+               memcpy(dest_buf, ctx->hash, sizeof(ctx->hash));
+
+       free(ctx);
+       return ret;
+}
+
 int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
              unsigned char *pout, enum caam_hash_algos algo)
 {
@@ -48,7 +167,7 @@ int caam_hash(const unsigned char *pbuf, unsigned int buf_len,
        desc = malloc(sizeof(int) * MAX_CAAM_DESCSIZE);
        if (!desc) {
                debug("Not enough memory for descriptor allocation\n");
-               return -1;
+               return -ENOMEM;
        }
 
        inline_cnstr_jobdesc_hash(desc, pbuf, buf_len, pout,
@@ -75,3 +194,20 @@ void hw_sha1(const unsigned char *pbuf, unsigned int buf_len,
        if (caam_hash(pbuf, buf_len, pout, SHA1))
                printf("CAAM was not setup properly or it is faulty\n");
 }
+
+int hw_sha_init(struct hash_algo *algo, void **ctxp)
+{
+       return caam_hash_init(ctxp, get_hash_type(algo));
+}
+
+int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
+                           unsigned int size, int is_last)
+{
+       return caam_hash_update(ctx, buf, size, is_last, get_hash_type(algo));
+}
+
+int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
+                    int size)
+{
+       return caam_hash_finish(ctx, dest_buf, size, get_hash_type(algo));
+}
diff --git a/drivers/crypto/fsl/fsl_hash.h b/drivers/crypto/fsl/fsl_hash.h
new file mode 100644 (file)
index 0000000..f5be651
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+ */
+
+#ifndef _SHA_H
+#define _SHA_H
+
+#include <fsl_sec.h>
+#include <hash.h>
+#include "jr.h"
+
+/* We support at most 32 Scatter/Gather Entries.*/
+#define MAX_SG_32      32
+
+/*
+ * Hash context contains the following fields
+ * @sha_desc: Sha Descriptor
+ * @sg_num: number of entries in sg table
+ * @len: total length of buffer
+ * @sg_tbl: sg entry table
+ * @hash: index to the hash calculated
+ */
+struct sha_ctx {
+       uint32_t sha_desc[64];
+       uint32_t sg_num;
+       uint32_t len;
+       struct sg_entry sg_tbl[MAX_SG_32];
+       u8 hash[HASH_MAX_DIGEST_SIZE];
+};
+
+#endif
index c139da6..7160da4 100644 (file)
@@ -222,7 +222,7 @@ step2:
        bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
                        >> SDRAM_CFG_DBW_SHIFT);
        timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
-               (get_ddr_freq(0) >> 20)) << 1;
+               (get_ddr_freq(ctrl_num) >> 20)) << 1;
        total_gb_size_per_controller >>= 4;     /* shift down to gb size */
        debug("total %d GB\n", total_gb_size_per_controller);
        debug("Need to wait up to %d * 10ms\n", timeout);
index 03d7ff1..690e73d 100644 (file)
@@ -17,8 +17,6 @@
 #include <fsl_immap.h>
 #include <asm/io.h>
 
-unsigned int picos_to_mclk(unsigned int picos);
-
 /*
  * Determine Rtt value.
  *
@@ -78,10 +76,11 @@ static inline int fsl_ddr_get_rtt(void)
  *       16 for <= 2933MT/s
  *       18 for higher
  */
-static inline unsigned int compute_cas_write_latency(void)
+static inline unsigned int compute_cas_write_latency(
+                               const unsigned int ctrl_num)
 {
        unsigned int cwl;
-       const unsigned int mclk_ps = get_memory_clk_period_ps();
+       const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
        if (mclk_ps >= 1250)
                cwl = 9;
        else if (mclk_ps >= 1070)
@@ -111,10 +110,11 @@ static inline unsigned int compute_cas_write_latency(void)
  *       11 if 0.935ns > tCK >= 0.833ns
  *       12 if 0.833ns > tCK >= 0.75ns
  */
-static inline unsigned int compute_cas_write_latency(void)
+static inline unsigned int compute_cas_write_latency(
+                               const unsigned int ctrl_num)
 {
        unsigned int cwl;
-       const unsigned int mclk_ps = get_memory_clk_period_ps();
+       const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
 
        if (mclk_ps >= 2500)
                cwl = 5;
@@ -287,7 +287,8 @@ static inline int avoid_odt_overlap(const dimm_params_t *dimm_params)
  * Avoid writing for DDR I.  The new PQ38 DDR controller
  * dreams up non-zero default values to be backwards compatible.
  */
-static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
+static void set_timing_cfg_0(const unsigned int ctrl_num,
+                               fsl_ddr_cfg_regs_t *ddr,
                                const memctl_options_t *popts,
                                const dimm_params_t *dimm_params)
 {
@@ -306,7 +307,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
        /* Mode register set cycle time (tMRD). */
        unsigned char tmrd_mclk;
 #if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
-       const unsigned int mclk_ps = get_memory_clk_period_ps();
+       const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
 #endif
 
 #ifdef CONFIG_SYS_FSL_DDR4
@@ -314,15 +315,15 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
        int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
        trwt_mclk = 2;
        twrt_mclk = 1;
-       act_pd_exit_mclk = picos_to_mclk(txp);
+       act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
        pre_pd_exit_mclk = act_pd_exit_mclk;
        /*
         * MRS_CYC = max(tMRD, tMOD)
         * tMRD = 8nCK, tMOD = max(24nCK, 15ns)
         */
-       tmrd_mclk = max(24U, picos_to_mclk(15000));
+       tmrd_mclk = max(24U, picos_to_mclk(ctrl_num, 15000));
 #elif defined(CONFIG_SYS_FSL_DDR3)
-       unsigned int data_rate = get_ddr_freq(0);
+       unsigned int data_rate = get_ddr_freq(ctrl_num);
        int txp;
        unsigned int ip_rev;
        int odt_overlap;
@@ -344,7 +345,8 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
                 * tMRD = 4nCK (8nCK for RDIMM)
                 * tMOD = max(12nCK, 15ns)
                 */
-               tmrd_mclk = max((unsigned int)12, picos_to_mclk(15000));
+               tmrd_mclk = max((unsigned int)12,
+                               picos_to_mclk(ctrl_num, 15000));
        } else {
                /*
                 * MRS_CYC = tMRD
@@ -388,7 +390,7 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
                taxpd_mclk = 1;
        } else {
                /* act_pd_exit_mclk = tXARD, see above */
-               act_pd_exit_mclk = picos_to_mclk(txp);
+               act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
                /* Mode register MR0[A12] is '1' - fast exit */
                pre_pd_exit_mclk = act_pd_exit_mclk;
                taxpd_mclk = 1;
@@ -424,11 +426,12 @@ static void set_timing_cfg_0(fsl_ddr_cfg_regs_t *ddr,
 #endif /* !defined(CONFIG_SYS_FSL_DDR1) */
 
 /* DDR SDRAM Timing Configuration 3 (TIMING_CFG_3) */
-static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
-                              const memctl_options_t *popts,
-                              const common_timing_params_t *common_dimm,
-                              unsigned int cas_latency,
-                              unsigned int additive_latency)
+static void set_timing_cfg_3(const unsigned int ctrl_num,
+                            fsl_ddr_cfg_regs_t *ddr,
+                            const memctl_options_t *popts,
+                            const common_timing_params_t *common_dimm,
+                            unsigned int cas_latency,
+                            unsigned int additive_latency)
 {
        /* Extended precharge to activate interval (tRP) */
        unsigned int ext_pretoact = 0;
@@ -447,18 +450,18 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
        /* Control Adjust */
        unsigned int cntl_adj = 0;
 
-       ext_pretoact = picos_to_mclk(common_dimm->trp_ps) >> 4;
-       ext_acttopre = picos_to_mclk(common_dimm->tras_ps) >> 4;
-       ext_acttorw = picos_to_mclk(common_dimm->trcd_ps) >> 4;
+       ext_pretoact = picos_to_mclk(ctrl_num, common_dimm->trp_ps) >> 4;
+       ext_acttopre = picos_to_mclk(ctrl_num, common_dimm->tras_ps) >> 4;
+       ext_acttorw = picos_to_mclk(ctrl_num, common_dimm->trcd_ps) >> 4;
        ext_caslat = (2 * cas_latency - 1) >> 4;
        ext_add_lat = additive_latency >> 4;
 #ifdef CONFIG_SYS_FSL_DDR4
-       ext_refrec = (picos_to_mclk(common_dimm->trfc1_ps) - 8) >> 4;
+       ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8) >> 4;
 #else
-       ext_refrec = (picos_to_mclk(common_dimm->trfc_ps) - 8) >> 4;
+       ext_refrec = (picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8) >> 4;
        /* ext_wrrec only deals with 16 clock and above, or 14 with OTF */
 #endif
-       ext_wrrec = (picos_to_mclk(common_dimm->twr_ps) +
+       ext_wrrec = (picos_to_mclk(ctrl_num, common_dimm->twr_ps) +
                (popts->otf_burst_chop_en ? 2 : 0)) >> 4;
 
        ddr->timing_cfg_3 = (0
@@ -475,10 +478,11 @@ static void set_timing_cfg_3(fsl_ddr_cfg_regs_t *ddr,
 }
 
 /* DDR SDRAM Timing Configuration 1 (TIMING_CFG_1) */
-static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
-                              const memctl_options_t *popts,
-                              const common_timing_params_t *common_dimm,
-                              unsigned int cas_latency)
+static void set_timing_cfg_1(const unsigned int ctrl_num,
+                            fsl_ddr_cfg_regs_t *ddr,
+                            const memctl_options_t *popts,
+                            const common_timing_params_t *common_dimm,
+                            unsigned int cas_latency)
 {
        /* Precharge-to-activate interval (tRP) */
        unsigned char pretoact_mclk;
@@ -510,9 +514,9 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
                1, 2, 3, 4, 5, 6, 7, 8, 10, 10, 12, 12, 14, 14, 0, 0};
 #endif
 
-       pretoact_mclk = picos_to_mclk(common_dimm->trp_ps);
-       acttopre_mclk = picos_to_mclk(common_dimm->tras_ps);
-       acttorw_mclk = picos_to_mclk(common_dimm->trcd_ps);
+       pretoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trp_ps);
+       acttopre_mclk = picos_to_mclk(ctrl_num, common_dimm->tras_ps);
+       acttorw_mclk = picos_to_mclk(ctrl_num, common_dimm->trcd_ps);
 
        /*
         * Translate CAS Latency to a DDR controller field value:
@@ -547,19 +551,19 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
 #endif
 
 #ifdef CONFIG_SYS_FSL_DDR4
-       refrec_ctrl = picos_to_mclk(common_dimm->trfc1_ps) - 8;
-       wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
-       acttoact_mclk = max(picos_to_mclk(common_dimm->trrds_ps), 4U);
-       wrtord_mclk = max(2U, picos_to_mclk(2500));
+       refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc1_ps) - 8;
+       wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
+       acttoact_mclk = max(picos_to_mclk(ctrl_num, common_dimm->trrds_ps), 4U);
+       wrtord_mclk = max(2U, picos_to_mclk(ctrl_num, 2500));
        if ((wrrec_mclk < 1) || (wrrec_mclk > 24))
                printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
        else
                wrrec_mclk = wrrec_table[wrrec_mclk - 1];
 #else
-       refrec_ctrl = picos_to_mclk(common_dimm->trfc_ps) - 8;
-       wrrec_mclk = picos_to_mclk(common_dimm->twr_ps);
-       acttoact_mclk = picos_to_mclk(common_dimm->trrd_ps);
-       wrtord_mclk = picos_to_mclk(common_dimm->twtr_ps);
+       refrec_ctrl = picos_to_mclk(ctrl_num, common_dimm->trfc_ps) - 8;
+       wrrec_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
+       acttoact_mclk = picos_to_mclk(ctrl_num, common_dimm->trrd_ps);
+       wrtord_mclk = picos_to_mclk(ctrl_num, common_dimm->twtr_ps);
        if ((wrrec_mclk < 1) || (wrrec_mclk > 16))
                printf("Error: WRREC doesn't support %d clocks\n", wrrec_mclk);
        else
@@ -602,11 +606,12 @@ static void set_timing_cfg_1(fsl_ddr_cfg_regs_t *ddr,
 }
 
 /* DDR SDRAM Timing Configuration 2 (TIMING_CFG_2) */
-static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
-                              const memctl_options_t *popts,
-                              const common_timing_params_t *common_dimm,
-                              unsigned int cas_latency,
-                              unsigned int additive_latency)
+static void set_timing_cfg_2(const unsigned int ctrl_num,
+                            fsl_ddr_cfg_regs_t *ddr,
+                            const memctl_options_t *popts,
+                            const common_timing_params_t *common_dimm,
+                            unsigned int cas_latency,
+                            unsigned int additive_latency)
 {
        /* Additive latency */
        unsigned char add_lat_mclk;
@@ -623,7 +628,7 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
        /* Window for four activates (tFAW) */
        unsigned short four_act;
 #ifdef CONFIG_SYS_FSL_DDR3
-       const unsigned int mclk_ps = get_memory_clk_period_ps();
+       const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
 #endif
 
        /* FIXME add check that this must be less than acttorw_mclk */
@@ -641,13 +646,13 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 #elif defined(CONFIG_SYS_FSL_DDR2)
        wr_lat = cas_latency - 1;
 #else
-       wr_lat = compute_cas_write_latency();
+       wr_lat = compute_cas_write_latency(ctrl_num);
 #endif
 
 #ifdef CONFIG_SYS_FSL_DDR4
-       rd_to_pre = picos_to_mclk(7500);
+       rd_to_pre = picos_to_mclk(ctrl_num, 7500);
 #else
-       rd_to_pre = picos_to_mclk(common_dimm->trtp_ps);
+       rd_to_pre = picos_to_mclk(ctrl_num, common_dimm->trtp_ps);
 #endif
        /*
         * JEDEC has some min requirements for tRTP
@@ -665,19 +670,20 @@ static void set_timing_cfg_2(fsl_ddr_cfg_regs_t *ddr,
        wr_data_delay = popts->write_data_delay;
 #ifdef CONFIG_SYS_FSL_DDR4
        cpo = 0;
-       cke_pls = max(3U, picos_to_mclk(5000));
+       cke_pls = max(3U, picos_to_mclk(ctrl_num, 5000));
 #elif defined(CONFIG_SYS_FSL_DDR3)
        /*
         * cke pulse = max(3nCK, 7.5ns) for DDR3-800
         *             max(3nCK, 5.625ns) for DDR3-1066, 1333
         *             max(3nCK, 5ns) for DDR3-1600, 1866, 2133
         */
-       cke_pls = max(3U, picos_to_mclk(mclk_ps > 1870 ? 7500 :
-                                      (mclk_ps > 1245 ? 5625 : 5000)));
+       cke_pls = max(3U, picos_to_mclk(ctrl_num, mclk_ps > 1870 ? 7500 :
+                                       (mclk_ps > 1245 ? 5625 : 5000)));
 #else
        cke_pls = FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR;
 #endif
-       four_act = picos_to_mclk(popts->tfaw_window_four_activates_ps);
+       four_act = picos_to_mclk(ctrl_num,
+                                popts->tfaw_window_four_activates_ps);
 
        ddr->timing_cfg_2 = (0
                | ((add_lat_mclk & 0xf) << 28)
@@ -818,7 +824,8 @@ static void set_ddr_sdram_cfg(fsl_ddr_cfg_regs_t *ddr,
 }
 
 /* DDR SDRAM control configuration 2 (DDR_SDRAM_CFG_2) */
-static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_cfg_2(const unsigned int ctrl_num,
+                              fsl_ddr_cfg_regs_t *ddr,
                               const memctl_options_t *popts,
                               const unsigned int unq_mrs_en)
 {
@@ -865,7 +872,7 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 #endif
 
 #if (CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7)
-       slow = get_ddr_freq(0) < 1249000000;
+       slow = get_ddr_freq(ctrl_num) < 1249000000;
 #endif
 
        if (popts->registered_dimm_en) {
@@ -915,7 +922,8 @@ static void set_ddr_sdram_cfg_2(fsl_ddr_cfg_regs_t *ddr,
 
 #ifdef CONFIG_SYS_FSL_DDR4
 /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
+                               fsl_ddr_cfg_regs_t *ddr,
                                const memctl_options_t *popts,
                                const common_timing_params_t *common_dimm,
                                const unsigned int unq_mrs_en)
@@ -926,10 +934,10 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
        unsigned int wr_crc = 0;        /* Disable */
        unsigned int rtt_wr = 0;        /* Rtt_WR - dynamic ODT off */
        unsigned int srt = 0;   /* self-refresh temerature, normal range */
-       unsigned int cwl = compute_cas_write_latency() - 9;
+       unsigned int cwl = compute_cas_write_latency(ctrl_num) - 9;
        unsigned int mpr = 0;   /* serial */
        unsigned int wc_lat;
-       const unsigned int mclk_ps = get_memory_clk_period_ps();
+       const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
 
        if (popts->rtt_override)
                rtt_wr = popts->rtt_wr_override_value;
@@ -1002,7 +1010,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
 }
 #elif defined(CONFIG_SYS_FSL_DDR3)
 /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
+                               fsl_ddr_cfg_regs_t *ddr,
                                const memctl_options_t *popts,
                                const common_timing_params_t *common_dimm,
                                const unsigned int unq_mrs_en)
@@ -1013,7 +1022,7 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
        unsigned int rtt_wr = 0;        /* Rtt_WR - dynamic ODT off */
        unsigned int srt = 0;   /* self-refresh temerature, normal range */
        unsigned int asr = 0;   /* auto self-refresh disable */
-       unsigned int cwl = compute_cas_write_latency() - 5;
+       unsigned int cwl = compute_cas_write_latency(ctrl_num) - 5;
        unsigned int pasr = 0;  /* partial array self refresh disable */
 
        if (popts->rtt_override)
@@ -1077,7 +1086,8 @@ static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
 
 #else /* for DDR2 and DDR1 */
 /* DDR SDRAM Mode configuration 2 (DDR_SDRAM_MODE_2) */
-static void set_ddr_sdram_mode_2(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_2(const unsigned int ctrl_num,
+                               fsl_ddr_cfg_regs_t *ddr,
                                const memctl_options_t *popts,
                                const common_timing_params_t *common_dimm,
                                const unsigned int unq_mrs_en)
@@ -1144,7 +1154,8 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
 }
 
 /* DDR SDRAM Mode configuration 10 (DDR_SDRAM_MODE_10) */
-static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode_10(const unsigned int ctrl_num,
+                               fsl_ddr_cfg_regs_t *ddr,
                                const memctl_options_t *popts,
                                const common_timing_params_t *common_dimm,
                                const unsigned int unq_mrs_en)
@@ -1152,7 +1163,7 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
        int i;
        unsigned short esdmode6 = 0;    /* Extended SDRAM mode 6 */
        unsigned short esdmode7 = 0;    /* Extended SDRAM mode 7 */
-       unsigned int tccdl_min = picos_to_mclk(common_dimm->tccdl_ps);
+       unsigned int tccdl_min = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
 
        esdmode6 = ((tccdl_min - 4) & 0x7) << 10;
 
@@ -1196,14 +1207,15 @@ static void set_ddr_sdram_mode_10(fsl_ddr_cfg_regs_t *ddr,
 #endif
 
 /* DDR SDRAM Interval Configuration (DDR_SDRAM_INTERVAL) */
-static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
-                              const memctl_options_t *popts,
-                              const common_timing_params_t *common_dimm)
+static void set_ddr_sdram_interval(const unsigned int ctrl_num,
+                               fsl_ddr_cfg_regs_t *ddr,
+                               const memctl_options_t *popts,
+                               const common_timing_params_t *common_dimm)
 {
        unsigned int refint;    /* Refresh interval */
        unsigned int bstopre;   /* Precharge interval */
 
-       refint = picos_to_mclk(common_dimm->refresh_rate_ps);
+       refint = picos_to_mclk(ctrl_num, common_dimm->refresh_rate_ps);
 
        bstopre = popts->bstopre;
 
@@ -1217,7 +1229,8 @@ static void set_ddr_sdram_interval(fsl_ddr_cfg_regs_t *ddr,
 
 #ifdef CONFIG_SYS_FSL_DDR4
 /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
-static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode(const unsigned int ctrl_num,
+                              fsl_ddr_cfg_regs_t *ddr,
                               const memctl_options_t *popts,
                               const common_timing_params_t *common_dimm,
                               unsigned int cas_latency,
@@ -1292,7 +1305,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
         * 1=fast exit DLL on (tXP)
         */
 
-       wr_mclk = picos_to_mclk(common_dimm->twr_ps);
+       wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
        if (wr_mclk <= 24) {
                wr = wr_table[wr_mclk - 10];
        } else {
@@ -1387,7 +1400,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
 
 #elif defined(CONFIG_SYS_FSL_DDR3)
 /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
-static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode(const unsigned int ctrl_num,
+                              fsl_ddr_cfg_regs_t *ddr,
                               const memctl_options_t *popts,
                               const common_timing_params_t *common_dimm,
                               unsigned int cas_latency,
@@ -1466,7 +1480,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
         */
        dll_on = 1;
 
-       wr_mclk = picos_to_mclk(common_dimm->twr_ps);
+       wr_mclk = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
        if (wr_mclk <= 16) {
                wr = wr_table[wr_mclk - 5];
        } else {
@@ -1582,7 +1596,8 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
 #else /* !CONFIG_SYS_FSL_DDR3 */
 
 /* DDR SDRAM Mode configuration set (DDR_SDRAM_MODE) */
-static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
+static void set_ddr_sdram_mode(const unsigned int ctrl_num,
+                              fsl_ddr_cfg_regs_t *ddr,
                               const memctl_options_t *popts,
                               const common_timing_params_t *common_dimm,
                               unsigned int cas_latency,
@@ -1654,7 +1669,7 @@ static void set_ddr_sdram_mode(fsl_ddr_cfg_regs_t *ddr,
 #if defined(CONFIG_SYS_FSL_DDR1)
        wr = 0;       /* Historical */
 #elif defined(CONFIG_SYS_FSL_DDR2)
-       wr = picos_to_mclk(common_dimm->twr_ps);
+       wr = picos_to_mclk(ctrl_num, common_dimm->twr_ps);
 #endif
        dll_res = 0;
        mode = 0;
@@ -1842,15 +1857,16 @@ static void set_timing_cfg_6(fsl_ddr_cfg_regs_t *ddr)
        debug("FSLDDR: timing_cfg_6 = 0x%08x\n", ddr->timing_cfg_6);
 }
 
-static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr,
-                       const common_timing_params_t *common_dimm)
+static void set_timing_cfg_7(const unsigned int ctrl_num,
+                            fsl_ddr_cfg_regs_t *ddr,
+                            const common_timing_params_t *common_dimm)
 {
        unsigned int txpr, tcksre, tcksrx;
        unsigned int cke_rst, cksre, cksrx, par_lat, cs_to_cmd;
 
-       txpr = max(5U, picos_to_mclk(common_dimm->trfc1_ps + 10000));
-       tcksre = max(5U, picos_to_mclk(10000));
-       tcksrx = max(5U, picos_to_mclk(10000));
+       txpr = max(5U, picos_to_mclk(ctrl_num, common_dimm->trfc1_ps + 10000));
+       tcksre = max(5U, picos_to_mclk(ctrl_num, 10000));
+       tcksrx = max(5U, picos_to_mclk(ctrl_num, 10000));
        par_lat = 0;
        cs_to_cmd = 0;
 
@@ -1883,14 +1899,15 @@ static void set_timing_cfg_7(fsl_ddr_cfg_regs_t *ddr,
        debug("FSLDDR: timing_cfg_7 = 0x%08x\n", ddr->timing_cfg_7);
 }
 
-static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr,
+static void set_timing_cfg_8(const unsigned int ctrl_num,
+                            fsl_ddr_cfg_regs_t *ddr,
                             const memctl_options_t *popts,
                             const common_timing_params_t *common_dimm,
                             unsigned int cas_latency)
 {
        unsigned int rwt_bg, wrt_bg, rrt_bg, wwt_bg;
        unsigned int acttoact_bg, wrtord_bg, pre_all_rec;
-       unsigned int tccdl = picos_to_mclk(common_dimm->tccdl_ps);
+       unsigned int tccdl = picos_to_mclk(ctrl_num, common_dimm->tccdl_ps);
        unsigned int wr_lat = ((ddr->timing_cfg_2 & 0x00780000) >> 19) +
                              ((ddr->timing_cfg_2 & 0x00040000) >> 14);
 
@@ -1911,11 +1928,11 @@ static void set_timing_cfg_8(fsl_ddr_cfg_regs_t *ddr,
                wwt_bg = tccdl - 4;
        } else {
                rrt_bg = tccdl - 2;
-               wwt_bg = tccdl - 4;
+               wwt_bg = tccdl - 2;
        }
 
-       acttoact_bg = picos_to_mclk(common_dimm->trrdl_ps);
-       wrtord_bg = max(4U, picos_to_mclk(7500));
+       acttoact_bg = picos_to_mclk(ctrl_num, common_dimm->trrdl_ps);
+       wrtord_bg = max(4U, picos_to_mclk(ctrl_num, 7500));
        if (popts->otf_burst_chop_en)
                wrtord_bg += 2;
 
@@ -2147,7 +2164,8 @@ check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr)
 }
 
 unsigned int
-compute_fsl_memctl_config_regs(const memctl_options_t *popts,
+compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
+                              const memctl_options_t *popts,
                               fsl_ddr_cfg_regs_t *ddr,
                               const common_timing_params_t *common_dimm,
                               const dimm_params_t *dimm_params,
@@ -2319,14 +2337,14 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
        set_ddr_eor(ddr, popts);
 
 #if !defined(CONFIG_SYS_FSL_DDR1)
-       set_timing_cfg_0(ddr, popts, dimm_params);
+       set_timing_cfg_0(ctrl_num, ddr, popts, dimm_params);
 #endif
 
-       set_timing_cfg_3(ddr, popts, common_dimm, cas_latency,
+       set_timing_cfg_3(ctrl_num, ddr, popts, common_dimm, cas_latency,
                         additive_latency);
-       set_timing_cfg_1(ddr, popts, common_dimm, cas_latency);
-       set_timing_cfg_2(ddr, popts, common_dimm,
-                               cas_latency, additive_latency);
+       set_timing_cfg_1(ctrl_num, ddr, popts, common_dimm, cas_latency);
+       set_timing_cfg_2(ctrl_num, ddr, popts, common_dimm,
+                        cas_latency, additive_latency);
 
        set_ddr_cdr1(ddr, popts);
        set_ddr_cdr2(ddr, popts);
@@ -2338,15 +2356,15 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
        if ((ip_rev > 0x40700) && (popts->cswl_override != 0))
                ddr->debug[18] = popts->cswl_override;
 
-       set_ddr_sdram_cfg_2(ddr, popts, unq_mrs_en);
-       set_ddr_sdram_mode(ddr, popts, common_dimm,
-                               cas_latency, additive_latency, unq_mrs_en);
-       set_ddr_sdram_mode_2(ddr, popts, common_dimm, unq_mrs_en);
+       set_ddr_sdram_cfg_2(ctrl_num, ddr, popts, unq_mrs_en);
+       set_ddr_sdram_mode(ctrl_num, ddr, popts, common_dimm,
+                          cas_latency, additive_latency, unq_mrs_en);
+       set_ddr_sdram_mode_2(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
 #ifdef CONFIG_SYS_FSL_DDR4
        set_ddr_sdram_mode_9(ddr, popts, common_dimm, unq_mrs_en);
-       set_ddr_sdram_mode_10(ddr, popts, common_dimm, unq_mrs_en);
+       set_ddr_sdram_mode_10(ctrl_num, ddr, popts, common_dimm, unq_mrs_en);
 #endif
-       set_ddr_sdram_interval(ddr, popts, common_dimm);
+       set_ddr_sdram_interval(ctrl_num, ddr, popts, common_dimm);
        set_ddr_data_init(ddr);
        set_ddr_sdram_clk_cntl(ddr, popts);
        set_ddr_init_addr(ddr);
@@ -2356,8 +2374,8 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
 #ifdef CONFIG_SYS_FSL_DDR4
        set_ddr_sdram_cfg_3(ddr, popts);
        set_timing_cfg_6(ddr);
-       set_timing_cfg_7(ddr, common_dimm);
-       set_timing_cfg_8(ddr, popts, common_dimm, cas_latency);
+       set_timing_cfg_7(ctrl_num, ddr, common_dimm);
+       set_timing_cfg_8(ctrl_num, ddr, popts, common_dimm, cas_latency);
        set_timing_cfg_9(ddr);
        set_ddr_dq_mapping(ddr, dimm_params);
 #endif
@@ -2372,7 +2390,11 @@ compute_fsl_memctl_config_regs(const memctl_options_t *popts,
 #ifdef CONFIG_SYS_FSL_DDR_EMU
        /* disble DDR training for emulator */
        ddr->debug[2] = 0x00000400;
-       ddr->debug[4] = 0xff800000;
+       ddr->debug[4] = 0xff800800;
+       ddr->debug[5] = 0x08000800;
+       ddr->debug[6] = 0x08000800;
+       ddr->debug[7] = 0x08000800;
+       ddr->debug[8] = 0x08000800;
 #endif
 #ifdef CONFIG_SYS_FSL_ERRATUM_A004508
        if ((ip_rev >= 0x40000) && (ip_rev < 0x40400))
index 7df27b9..7f1c3af 100644 (file)
@@ -228,10 +228,10 @@ compute_derated_DDR1_CAS_latency(unsigned int mclk_ps)
  *
  * FIXME: use #define for the retvals
  */
-unsigned int
-ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
-                            dimm_params_t *pdimm,
-                            unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+                                        const ddr1_spd_eeprom_t *spd,
+                                        dimm_params_t *pdimm,
+                                        unsigned int dimm_number)
 {
        unsigned int retval;
 
@@ -311,16 +311,16 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
                                          & ~(1 << pdimm->caslat_x_minus_1));
 
        /* Compute CAS latencies below that defined by SPD */
-       pdimm->caslat_lowest_derated
-               = compute_derated_DDR1_CAS_latency(get_memory_clk_period_ps());
+       pdimm->caslat_lowest_derated = compute_derated_DDR1_CAS_latency(
+                                       get_memory_clk_period_ps(ctrl_num));
 
        /* Compute timing parameters */
        pdimm->trcd_ps = spd->trcd * 250;
        pdimm->trp_ps = spd->trp * 250;
        pdimm->tras_ps = spd->tras * 1000;
 
-       pdimm->twr_ps = mclk_to_picos(3);
-       pdimm->twtr_ps = mclk_to_picos(1);
+       pdimm->twr_ps = mclk_to_picos(ctrl_num, 3);
+       pdimm->twtr_ps = mclk_to_picos(ctrl_num, 1);
        pdimm->trfc_ps = compute_trfc_ps_from_spd(0, spd->trfc);
 
        pdimm->trrd_ps = spd->trrd * 250;
@@ -335,7 +335,7 @@ ddr_compute_dimm_parameters(const ddr1_spd_eeprom_t *spd,
        pdimm->tdh_ps
                = convert_bcd_hundredths_to_cycle_time_ps(spd->data_hold);
 
-       pdimm->trtp_ps = mclk_to_picos(2);      /* By the book. */
+       pdimm->trtp_ps = mclk_to_picos(ctrl_num, 2);    /* By the book. */
        pdimm->tdqsq_max_ps = spd->tdqsq * 10;
        pdimm->tqhs_ps = spd->tqhs * 10;
 
index d865df7..49cc1a0 100644 (file)
@@ -211,10 +211,10 @@ compute_derated_DDR2_CAS_latency(unsigned int mclk_ps)
  *
  * FIXME: use #define for the retvals
  */
-unsigned int
-ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
-                            dimm_params_t *pdimm,
-                            unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+                                        const ddr2_spd_eeprom_t *spd,
+                                        dimm_params_t *pdimm,
+                                        unsigned int dimm_number)
 {
        unsigned int retval;
 
@@ -310,8 +310,8 @@ ddr_compute_dimm_parameters(const ddr2_spd_eeprom_t *spd,
                                          & ~(1 << pdimm->caslat_x_minus_1));
 
        /* Compute CAS latencies below that defined by SPD */
-       pdimm->caslat_lowest_derated
-               = compute_derated_DDR2_CAS_latency(get_memory_clk_period_ps());
+       pdimm->caslat_lowest_derated = compute_derated_DDR2_CAS_latency(
+                                       get_memory_clk_period_ps(ctrl_num));
 
        /* Compute timing parameters */
        pdimm->trcd_ps = spd->trcd * 250;
index a4b8c10..6917715 100644 (file)
@@ -83,10 +83,10 @@ compute_ranksize(const ddr3_spd_eeprom_t *spd)
  * Writes the results to the dimm_params_t structure pointed by pdimm.
  *
  */
-unsigned int
-ddr_compute_dimm_parameters(const ddr3_spd_eeprom_t *spd,
-                            dimm_params_t *pdimm,
-                            unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+                                        const ddr3_spd_eeprom_t *spd,
+                                        dimm_params_t *pdimm,
+                                        unsigned int dimm_number)
 {
        unsigned int retval;
        unsigned int mtb_ps;
index aaddc8f..bbfb4ee 100644 (file)
@@ -119,10 +119,10 @@ compute_ranksize(const struct ddr4_spd_eeprom_s *spd)
  * Writes the results to the dimm_params_t structure pointed by pdimm.
  *
  */
-unsigned int
-ddr_compute_dimm_parameters(const generic_spd_eeprom_t *spd,
-                           dimm_params_t *pdimm,
-                           unsigned int dimm_number)
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
+                                        const generic_spd_eeprom_t *spd,
+                                        dimm_params_t *pdimm,
+                                        unsigned int dimm_number)
 {
        unsigned int retval;
        int i;
index 4eef047..d9fce7d 100644 (file)
@@ -32,24 +32,44 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
        u32 temp_sdram_cfg;
        u32 total_gb_size_per_controller;
        int timeout;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+       defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+       u32 *eddrtqcr1;
+#endif
 
        switch (ctrl_num) {
        case 0:
                ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+       defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+               eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR_ADDR + 0x800;
+#endif
                break;
 #if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
        case 1:
                ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+       defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+               eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR2_ADDR + 0x800;
+#endif
                break;
 #endif
 #if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
        case 2:
                ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+       defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+               eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR3_ADDR + 0x800;
+#endif
                break;
 #endif
 #if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
        case 3:
                ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+#if defined(CONFIG_SYS_FSL_ERRATUM_A008336) || \
+       defined(CONFIG_SYS_FSL_ERRATUM_A008514)
+               eddrtqcr1 = (void *)CONFIG_SYS_FSL_DCSR_DDR4_ADDR + 0x800;
+#endif
                break;
 #endif
        default:
@@ -60,6 +80,20 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
        if (step == 2)
                goto step2;
 
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008336
+#ifdef CONFIG_LS2085A
+       /* A008336 only applies to general DDR controllers */
+       if ((ctrl_num == 0) || (ctrl_num == 1))
+#endif
+               ddr_out32(eddrtqcr1, 0x63b30002);
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008514
+#ifdef CONFIG_LS2085A
+       /* A008514 only applies to DP-DDR controler */
+       if (ctrl_num == 2)
+#endif
+               ddr_out32(eddrtqcr1, 0x63b20002);
+#endif
        if (regs->ddr_eor)
                ddr_out32(&ddr->eor, regs->ddr_eor);
 
@@ -253,7 +287,7 @@ step2:
        bus_width = 3 - ((ddr_in32(&ddr->sdram_cfg) & SDRAM_CFG_DBW_MASK)
                        >> SDRAM_CFG_DBW_SHIFT);
        timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
-               (get_ddr_freq(0) >> 20)) << 2;
+               (get_ddr_freq(ctrl_num) >> 20)) << 2;
        total_gb_size_per_controller >>= 4;     /* shift down to gb size */
        debug("total %d GB\n", total_gb_size_per_controller);
        debug("Need to wait up to %d * 10ms\n", timeout);
index 73db444..b295344 100644 (file)
@@ -13,7 +13,8 @@
 
 #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
 static unsigned int
-compute_cas_latency(const dimm_params_t *dimm_params,
+compute_cas_latency(const unsigned int ctrl_num,
+                   const dimm_params_t *dimm_params,
                    common_timing_params_t *outpdimm,
                    unsigned int number_of_dimms)
 {
@@ -22,7 +23,7 @@ compute_cas_latency(const dimm_params_t *dimm_params,
        unsigned int caslat_actual;
        unsigned int retry = 16;
        unsigned int tmp;
-       const unsigned int mclk_ps = get_memory_clk_period_ps();
+       const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
 #ifdef CONFIG_SYS_FSL_DDR3
        const unsigned int taamax = 20000;
 #else
@@ -72,12 +73,13 @@ compute_cas_latency(const dimm_params_t *dimm_params,
 }
 #else  /* for DDR1 and DDR2 */
 static unsigned int
-compute_cas_latency(const dimm_params_t *dimm_params,
+compute_cas_latency(const unsigned int ctrl_num,
+                   const dimm_params_t *dimm_params,
                    common_timing_params_t *outpdimm,
                    unsigned int number_of_dimms)
 {
        int i;
-       const unsigned int mclk_ps = get_memory_clk_period_ps();
+       const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
        unsigned int lowest_good_caslat;
        unsigned int not_ok;
        unsigned int temp1, temp2;
@@ -212,7 +214,8 @@ compute_cas_latency(const dimm_params_t *dimm_params,
  * by dimm_params.
  */
 unsigned int
-compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
+compute_lowest_common_dimm_parameters(const unsigned int ctrl_num,
+                                     const dimm_params_t *dimm_params,
                                      common_timing_params_t *outpdimm,
                                      const unsigned int number_of_dimms)
 {
@@ -442,7 +445,8 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
                printf("ERROR: Mix different RDIMM detected!\n");
 
        /* calculate cas latency for all DDR types */
-       if (compute_cas_latency(dimm_params, outpdimm, number_of_dimms))
+       if (compute_cas_latency(ctrl_num, dimm_params,
+                               outpdimm, number_of_dimms))
                return 1;
 
        /* Determine if all DIMMs ECC capable. */
@@ -518,11 +522,12 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
 
 #if defined(CONFIG_SYS_FSL_DDR2)
        if ((outpdimm->lowest_common_spd_caslat < 4) &&
-           (picos_to_mclk(trcd_ps) > outpdimm->lowest_common_spd_caslat)) {
-               additive_latency = picos_to_mclk(trcd_ps) -
+           (picos_to_mclk(ctrl_num, trcd_ps) >
+            outpdimm->lowest_common_spd_caslat)) {
+               additive_latency = picos_to_mclk(ctrl_num, trcd_ps) -
                                   outpdimm->lowest_common_spd_caslat;
-               if (mclk_to_picos(additive_latency) > trcd_ps) {
-                       additive_latency = picos_to_mclk(trcd_ps);
+               if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
+                       additive_latency = picos_to_mclk(ctrl_num, trcd_ps);
                        debug("setting additive_latency to %u because it was "
                                " greater than tRCD_ps\n", additive_latency);
                }
@@ -534,7 +539,7 @@ compute_lowest_common_dimm_parameters(const dimm_params_t *dimm_params,
         *
         * AL <= tRCD(min)
         */
-       if (mclk_to_picos(additive_latency) > trcd_ps) {
+       if (mclk_to_picos(ctrl_num, additive_latency) > trcd_ps) {
                printf("Error: invalid additive latency exceeds tRCD(min).\n");
                return 1;
        }
index 6f291eb..b72b242 100644 (file)
@@ -450,7 +450,8 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
                                        &(pinfo->spd_installed_dimms[i][j]);
                                dimm_params_t *pdimm =
                                        &(pinfo->dimm_params[i][j]);
-                               retval = compute_dimm_parameters(spd, pdimm, i);
+                               retval = compute_dimm_parameters(
+                                                       i, spd, pdimm, j);
 #ifdef CONFIG_SYS_DDR_RAW_TIMING
                                if (!i && !j && retval) {
                                        printf("SPD error on controller %d! "
@@ -507,10 +508,11 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
                for (i = first_ctrl; i <= last_ctrl; i++) {
                        debug("Computing lowest common DIMM"
                                " parameters for memctl=%u\n", i);
-                       compute_lowest_common_dimm_parameters(
-                               pinfo->dimm_params[i],
-                               &timing_params[i],
-                               CONFIG_DIMM_SLOTS_PER_CTLR);
+                       compute_lowest_common_dimm_parameters
+                               (i,
+                                pinfo->dimm_params[i],
+                                &timing_params[i],
+                                CONFIG_DIMM_SLOTS_PER_CTLR);
                }
 
        case STEP_GATHER_OPTS:
@@ -562,12 +564,13 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
                                continue;
                        }
 
-                       compute_fsl_memctl_config_regs(
-                                       &pinfo->memctl_opts[i],
-                                       &ddr_reg[i], &timing_params[i],
-                                       pinfo->dimm_params[i],
-                                       dbw_capacity_adjust[i],
-                                       size_only);
+                       compute_fsl_memctl_config_regs
+                               (i,
+                                &pinfo->memctl_opts[i],
+                                &ddr_reg[i], &timing_params[i],
+                                pinfo->dimm_params[i],
+                                dbw_capacity_adjust[i],
+                                size_only);
                }
 
        default:
@@ -689,6 +692,10 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo)
                }
        }
 
+#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
+       fsl_ddr_sync_memctl_refresh(first_ctrl, last_ctrl);
+#endif
+
 #ifdef CONFIG_PPC
        /* program LAWs */
        for (i = first_ctrl; i <= last_ctrl; i++) {
index 8f4d01a..6752d4d 100644 (file)
@@ -426,7 +426,7 @@ step2:
        bus_width = 3 - ((ddr->sdram_cfg & SDRAM_CFG_DBW_MASK)
                        >> SDRAM_CFG_DBW_SHIFT);
        timeout = ((total_gb_size_per_controller << (6 - bus_width)) * 100 /
-               (get_ddr_freq(0) >> 20)) << 1;
+               (get_ddr_freq(ctrl_num) >> 20)) << 1;
 #ifdef CONFIG_SYS_FSL_ERRATUM_DDR111_DDR134
        timeout_save = timeout;
 #endif
@@ -538,12 +538,14 @@ step2:
                case 1:
                        out_be32(&ddr->cs1_bnds, regs->cs[csn].bnds);
                        break;
+#if CONFIG_CHIP_SELECTS_PER_CTRL > 2
                case 2:
                        out_be32(&ddr->cs2_bnds, regs->cs[csn].bnds);
                        break;
                case 3:
                        out_be32(&ddr->cs3_bnds, regs->cs[csn].bnds);
                        break;
+#endif
                }
                clrbits_be32(&ddr->sdram_cfg, 0x2);
        }
index 6d098d1..5beb11b 100644 (file)
@@ -732,7 +732,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
 #endif
 
        /* Global Timing Parameters. */
-       debug("mclk_ps = %u ps\n", get_memory_clk_period_ps());
+       debug("mclk_ps = %u ps\n", get_memory_clk_period_ps(ctrl_num));
 
        /* Pick a caslat override. */
        popts->cas_latency_override = 0;
@@ -785,7 +785,7 @@ unsigned int populate_memctl_options(int all_dimms_registered,
         * FIXME: width, was considering looking at pdimm->primary_sdram_width
         */
 #if defined(CONFIG_SYS_FSL_DDR1)
-       popts->tfaw_window_four_activates_ps = mclk_to_picos(1);
+       popts->tfaw_window_four_activates_ps = mclk_to_picos(ctrl_num, 1);
 
 #elif defined(CONFIG_SYS_FSL_DDR2)
        /*
@@ -1036,7 +1036,7 @@ done:
        if (pdimm[0].n_ranks == 4)
                popts->quad_rank_present = 1;
 
-       ddr_freq = get_ddr_freq(0) / 1000000;
+       ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
        if (popts->registered_dimm_en) {
                popts->rcw_override = 1;
                popts->rcw_1 = 0x000a5a00;
index 58b519b..664081b 100644 (file)
@@ -43,9 +43,9 @@ u32 fsl_ddr_get_version(void)
  * propagation, compute a suitably rounded mclk_ps to compute
  * a working memory controller configuration.
  */
-unsigned int get_memory_clk_period_ps(void)
+unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num)
 {
-       unsigned int data_rate = get_ddr_freq(0);
+       unsigned int data_rate = get_ddr_freq(ctrl_num);
        unsigned int result;
 
        /* Round to nearest 10ps, being careful about 64-bit multiply/divide */
@@ -59,10 +59,10 @@ unsigned int get_memory_clk_period_ps(void)
 }
 
 /* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
-unsigned int picos_to_mclk(unsigned int picos)
+unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos)
 {
        unsigned long long clks, clks_rem;
-       unsigned long data_rate = get_ddr_freq(0);
+       unsigned long data_rate = get_ddr_freq(ctrl_num);
 
        /* Short circuit for zero picos */
        if (!picos)
@@ -88,9 +88,9 @@ unsigned int picos_to_mclk(unsigned int picos)
        return (unsigned int) clks;
 }
 
-unsigned int mclk_to_picos(unsigned int mclk)
+unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk)
 {
-       return get_memory_clk_period_ps() * mclk;
+       return get_memory_clk_period_ps(ctrl_num) * mclk;
 }
 
 #ifdef CONFIG_PPC
@@ -308,3 +308,58 @@ void board_add_ram_info(int use_default)
 {
        detail_board_ddr_info();
 }
+
+#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
+#define DDRC_DEBUG20_INIT_DONE 0x80000000
+#define DDRC_DEBUG2_RF         0x00000040
+void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
+                                unsigned int last_ctrl)
+{
+       unsigned int i;
+       u32 ddrc_debug20;
+       u32 ddrc_debug2[CONFIG_NUM_DDR_CONTROLLERS] = {};
+       u32 *ddrc_debug2_p[CONFIG_NUM_DDR_CONTROLLERS] = {};
+       struct ccsr_ddr __iomem *ddr;
+
+       for (i = first_ctrl; i <= last_ctrl; i++) {
+               switch (i) {
+               case 0:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+                       break;
+#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+               case 1:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+                       break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+               case 2:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+                       break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+               case 3:
+                       ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+                       break;
+#endif
+               default:
+                       printf("%s unexpected ctrl = %u\n", __func__, i);
+                       return;
+               }
+               ddrc_debug20 = ddr_in32(&ddr->debug[19]);
+               ddrc_debug2_p[i] = &ddr->debug[1];
+               while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) {
+                       /* keep polling until DDRC init is done */
+                       udelay(100);
+                       ddrc_debug20 = ddr_in32(&ddr->debug[19]);
+               }
+               ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF;
+       }
+       /*
+        * Sync refresh
+        * This is put together to make sure the refresh reqeusts are sent
+        * closely to each other.
+        */
+       for (i = first_ctrl; i <= last_ctrl; i++)
+               ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
+}
+#endif /* CONFIG_FSL_DDR_SYNC_REFRESH */
index c55eb28..f5d2ccb 100644 (file)
@@ -319,7 +319,8 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        esdhc_write32(&regs->cmdarg, cmd->cmdarg);
 #if defined(CONFIG_FSL_USDHC)
        esdhc_write32(&regs->mixctrl,
-       (esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F));
+       (esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F)
+                       | (mmc->ddr_mode ? XFERTYP_DDREN : 0));
        esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
 #else
        esdhc_write32(&regs->xfertyp, xfertyp);
@@ -442,7 +443,7 @@ static void set_sysctl(struct mmc *mmc, uint clock)
                if ((sdhc_clk / (div * pre_div)) <= clock)
                        break;
 
-       pre_div >>= 1;
+       pre_div >>= mmc->ddr_mode ? 2 : 1;
        div -= 1;
 
        clk = (pre_div << 8) | (div << 4);
@@ -601,6 +602,9 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        }
 
        cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
+       cfg->cfg.host_caps |= MMC_MODE_DDR_52MHz;
+#endif
 
        if (cfg->max_bus_width > 0) {
                if (cfg->max_bus_width < 8)
index da5e2bc..b8b0803 100644 (file)
@@ -64,5 +64,5 @@ obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
 obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
                xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
 obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
-obj-$(CONFIG_FSL_MC_ENET) += fsl_mc/
+obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/
 obj-$(CONFIG_VSC9953) += vsc9953.o
similarity index 75%
rename from drivers/net/fsl_mc/Makefile
rename to drivers/net/fsl-mc/Makefile
index 4834086..206ac6b 100644 (file)
@@ -5,4 +5,6 @@
 #
 
 # Layerscape MC driver
-obj-y += mc.o
+obj-y += mc.o \
+       mc_sys.o \
+       dpmng.o
diff --git a/drivers/net/fsl-mc/dpmng.c b/drivers/net/fsl-mc/dpmng.c
new file mode 100644 (file)
index 0000000..cc14c7b
--- /dev/null
@@ -0,0 +1,91 @@
+/* Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpmng.h>
+#include "fsl_dpmng_cmd.h"
+
+int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
+{
+       struct mc_command cmd = { 0 };
+       int err;
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPMNG_CMDID_GET_VERSION,
+                                         MC_CMD_PRI_LOW, 0);
+
+       /* send command to mc*/
+       err = mc_send_command(mc_io, &cmd);
+       if (err)
+               return err;
+
+       /* retrieve response parameters */
+       DPMNG_RSP_GET_VERSION(cmd, mc_ver_info);
+
+       return 0;
+}
+
+int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id,
+                    int aiop_tile_id)
+{
+       struct mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP,
+                                         MC_CMD_PRI_LOW, 0);
+       DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id);
+
+       /* send command to mc*/
+       return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_load_aiop(struct fsl_mc_io *mc_io,
+                   int container_id,
+                   int aiop_tile_id,
+                   uint64_t img_iova,
+                   uint32_t img_size)
+{
+       struct mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP,
+                                         MC_CMD_PRI_LOW,
+                                         0);
+       DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size,
+                           img_iova);
+
+       /* send command to mc*/
+       return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_run_aiop(struct fsl_mc_io *mc_io,
+                  int container_id,
+                  int aiop_tile_id,
+                  const struct dpmng_aiop_run_cfg *cfg)
+{
+       struct mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP,
+                                         MC_CMD_PRI_LOW,
+                                         0);
+       DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg);
+
+       /* send command to mc*/
+       return mc_send_command(mc_io, &cmd);
+}
+
+int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io)
+{
+       struct mc_command cmd = { 0 };
+
+       /* prepare command */
+       cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL,
+                                         MC_CMD_PRI_LOW,
+                                         0);
+
+       /* send command to mc*/
+       return mc_send_command(mc_io, &cmd);
+}
diff --git a/drivers/net/fsl-mc/fsl_dpmng_cmd.h b/drivers/net/fsl-mc/fsl_dpmng_cmd.h
new file mode 100644 (file)
index 0000000..c9fe021
--- /dev/null
@@ -0,0 +1,49 @@
+/* Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef __FSL_DPMNG_CMD_H
+#define __FSL_DPMNG_CMD_H
+
+/* Command IDs */
+#define DPMNG_CMDID_GET_VERSION                        0x831
+#define DPMNG_CMDID_RESET_AIOP                 0x832
+#define DPMNG_CMDID_LOAD_AIOP                  0x833
+#define DPMNG_CMDID_RUN_AIOP                   0x834
+#define DPMNG_CMDID_RESET_MC_PORTAL            0x835
+
+/*                cmd, param, offset, width, type, arg_name */
+#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \
+do { \
+       MC_RSP_OP(cmd, 0, 0,  32, uint32_t, mc_ver_info->revision); \
+       MC_RSP_OP(cmd, 0, 32, 32, uint32_t, mc_ver_info->major); \
+       MC_RSP_OP(cmd, 1, 0,  32, uint32_t, mc_ver_info->minor); \
+} while (0)
+
+/*                cmd, param, offset, width, type, arg_name */
+#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \
+do { \
+       MC_CMD_OP(cmd, 0, 0,  32, int,      aiop_tile_id); \
+       MC_CMD_OP(cmd, 0, 32, 32, int,      container_id); \
+} while (0)
+
+/*                cmd, param, offset, width, type, arg_name */
+#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \
+                           img_iova) \
+do { \
+       MC_CMD_OP(cmd, 0, 0,  32, int,      aiop_tile_id); \
+       MC_CMD_OP(cmd, 0, 32, 32, int,      container_id); \
+       MC_CMD_OP(cmd, 1, 0,  32, uint32_t, img_size); \
+       MC_CMD_OP(cmd, 2, 0,  64, uint64_t, img_iova); \
+} while (0)
+
+/*                cmd, param, offset, width, type, arg_name */
+#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \
+do { \
+       MC_CMD_OP(cmd, 0, 0,  32, int,      aiop_tile_id); \
+       MC_CMD_OP(cmd, 0, 32, 32, int,      container_id); \
+       MC_CMD_OP(cmd, 1, 0,  32, uint32_t, cfg->cores_mask); \
+       MC_CMD_OP(cmd, 2, 0,  64, uint64_t, cfg->options); \
+} while (0)
+
+#endif /* __FSL_DPMNG_CMD_H */
similarity index 67%
rename from drivers/net/fsl_mc/mc.c
rename to drivers/net/fsl-mc/mc.c
index df84568..74b0085 100644 (file)
@@ -3,9 +3,12 @@
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
+
 #include <errno.h>
 #include <asm/io.h>
-#include <fsl_mc.h>
+#include <fsl-mc/fsl_mc.h>
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_dpmng.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 static int mc_boot_status;
@@ -14,7 +17,7 @@ static int mc_boot_status;
  * Copying MC firmware or DPL image to DDR
  */
 static int mc_copy_image(const char *title,
-                   u64 image_addr, u32 image_size, u64 mc_ram_addr)
+                        u64 image_addr, u32 image_size, u64 mc_ram_addr)
 {
        debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
        memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
@@ -25,10 +28,9 @@ static int mc_copy_image(const char *title,
  * MC firmware FIT image parser checks if the image is in FIT
  * format, verifies integrity of the image and calculates
  * raw image address and size values.
- * Returns 0 if success and 1 if any of the above mentioned
+ * Returns 0 on success and a negative errno on error.
  * task fail.
  **/
-
 int parse_mc_firmware_fit_image(const void **raw_image_addr,
                                size_t *raw_image_size)
 {
@@ -39,7 +41,7 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
        size_t size;
        const char *uname = "firmware";
 
-       /* Check if the image is in NOR flash*/
+       /* Check if the image is in NOR flash */
 #ifdef CONFIG_SYS_LS_MC_FW_IN_NOR
        fit_hdr = (void *)CONFIG_SYS_LS_MC_FW_ADDR;
 #else
@@ -50,26 +52,26 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
        format = genimg_get_format(fit_hdr);
 
        if (format != IMAGE_FORMAT_FIT) {
-               debug("Not a FIT image\n");
-               return 1;
+               printf("fsl-mc: ERROR: Bad firmware image (not a FIT image)\n");
+               return -EINVAL;
        }
 
        if (!fit_check_format(fit_hdr)) {
-               debug("Bad FIT image format\n");
-               return 1;
+               printf("fsl-mc: ERROR: Bad firmware image (bad FIT header)\n");
+               return -EINVAL;
        }
 
        node_offset = fit_image_get_node(fit_hdr, uname);
 
        if (node_offset < 0) {
-               debug("Can not find %s subimage\n", uname);
-               return 1;
+               printf("fsl-mc: ERROR: Bad firmware image (missing subimage)\n");
+               return -ENOENT;
        }
 
        /* Verify MC firmware image */
        if (!(fit_image_verify(fit_hdr, node_offset))) {
-               debug("Bad MC firmware hash");
-               return 1;
+               printf("fsl-mc: ERROR: Bad firmware image (bad CRC)\n");
+               return -EINVAL;
        }
 
        /* Get address and size of raw image */
@@ -90,12 +92,13 @@ int mc_init(bd_t *bis)
        u64 mc_dpl_offset;
        u32 reg_gsr;
        u32 mc_fw_boot_status;
-       void *fdt_hdr;
+       void *dpl_fdt_hdr;
        int dpl_size;
        const void *raw_image_addr;
        size_t raw_image_size = 0;
-
-       BUILD_BUG_ON(CONFIG_SYS_LS_MC_FW_LENGTH % 4 != 0);
+       struct fsl_mc_io mc_io;
+       int portal_id;
+       struct mc_version mc_ver_info;
 
        /*
         * The MC private DRAM block was already carved at the end of DRAM
@@ -130,25 +133,44 @@ int mc_init(bd_t *bis)
        /*
         * Load the MC FW at the beginning of the MC private DRAM block:
         */
-       mc_copy_image(
-               "MC Firmware",
-               (u64)raw_image_addr,
-               raw_image_size,
-               mc_ram_addr);
+       mc_copy_image("MC Firmware",
+                     (u64)raw_image_addr, raw_image_size, mc_ram_addr);
+
+       /*
+        * Get address and size of the DPL blob stored in flash:
+        */
+#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
+       dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
+#else
+#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
+#endif
+
+       error = fdt_check_header(dpl_fdt_hdr);
+       if (error != 0) {
+               printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
+               goto out;
+       }
+
+       dpl_size = fdt_totalsize(dpl_fdt_hdr);
+       if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
+               printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
+                      dpl_size);
+               error = -EINVAL;
+               goto out;
+       }
 
        /*
         * Calculate offset in the MC private DRAM block at which the MC DPL
         * blob is to be placed:
         */
 #ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
-       BUILD_BUG_ON(
-               (CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
-               CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
+       BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
+                    CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
 
        mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
 #else
        mc_dpl_offset = mc_get_dram_block_size() -
-                       roundup(CONFIG_SYS_LS_MC_DPL_LENGTH, 4096);
+                       roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096);
 
        if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) {
                printf("%s: Invalid MC DPL offset: %llu\n",
@@ -158,23 +180,14 @@ int mc_init(bd_t *bis)
        }
 #endif
 
-       /* Check if DPL image is in NOR flash */
-#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
-       fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
-#else
-#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
-#endif
-
-       dpl_size = fdt_totalsize(fdt_hdr);
-
        /*
         * Load the MC DPL blob at the far end of the MC private DRAM block:
+        *
+        * TODO: Should we place the DPL at a different location to match
+        * assumptions of MC firmware about its memory layout?
         */
-       mc_copy_image(
-               "MC DPL blob",
-               (u64)fdt_hdr,
-               dpl_size,
-               mc_ram_addr + mc_dpl_offset);
+       mc_copy_image("MC DPL blob",
+                     (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
 
        debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
 
@@ -200,6 +213,8 @@ int mc_init(bd_t *bis)
         */
        out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
 
+       printf("\nfsl-mc: Booting Management Complex ...\n");
+
        /*
         * Deassert reset and release MC core 0 to run
         */
@@ -219,17 +234,13 @@ int mc_init(bd_t *bis)
        }
 
        if (timeout <= 0) {
-               printf("%s: timeout booting management complex firmware\n",
-                      __func__);
+               printf("fsl-mc: timeout booting management complex firmware\n");
 
                /* TODO: Get an error status from an MC CCSR register */
                error = -ETIMEDOUT;
                goto out;
        }
 
-       printf("Management complex booted (boot status: %#x)\n",
-              mc_fw_boot_status);
-
        if (mc_fw_boot_status != 0x1) {
                /*
                 * TODO: Identify critical errors from the GSR register's FS
@@ -237,8 +248,41 @@ int mc_init(bd_t *bis)
                 * appropriate errno, so that the status property is set to
                 * failure in the fsl,dprc device tree node.
                 */
+               printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
+                      reg_gsr);
        }
 
+       /*
+        * TODO: need to obtain the portal_id for the root container from the
+        * DPL
+        */
+       portal_id = 0;
+
+       /*
+        * Check that the MC firmware is responding portal commands:
+        */
+       mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
+       debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
+             portal_id, mc_io.mmio_regs);
+
+       error = mc_get_version(&mc_io, &mc_ver_info);
+       if (error != 0) {
+               printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
+                      error);
+               goto out;
+       }
+
+       if (MC_VER_MAJOR != mc_ver_info.major)
+               printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
+                      mc_ver_info.major, MC_VER_MAJOR);
+
+       if (MC_VER_MINOR != mc_ver_info.minor)
+               printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
+                      mc_ver_info.minor, MC_VER_MINOR);
+
+       printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
+              mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
+              mc_fw_boot_status);
 out:
        if (error != 0)
                mc_boot_status = -error;
diff --git a/drivers/net/fsl-mc/mc_sys.c b/drivers/net/fsl-mc/mc_sys.c
new file mode 100644 (file)
index 0000000..7c8e003
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+
+#define MC_CMD_HDR_READ_CMDID(_hdr) \
+       ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S))
+
+/**
+ * mc_send_command - Send MC command and wait for response
+ *
+ * @mc_io: Pointer to MC I/O object to be used
+ * @cmd: MC command buffer. On input, it contains the command to send to the MC.
+ * On output, it contains the response from the MC if any.
+ *
+ * Depending on the sharing option specified when creating the MC portal
+ * wrapper, this function will use a spinlock or mutex to ensure exclusive
+ * access to the MC portal from the point when the command is sent until a
+ * response is received from the MC.
+ */
+int mc_send_command(struct fsl_mc_io *mc_io,
+                   struct mc_command *cmd)
+{
+       enum mc_cmd_status status;
+       int timeout = 2000;
+
+       mc_write_command(mc_io->mmio_regs, cmd);
+
+       for ( ; ; ) {
+               status = mc_read_response(mc_io->mmio_regs, cmd);
+               if (status != MC_CMD_STATUS_READY)
+                       break;
+
+               if (--timeout == 0) {
+                       printf("Error: Timeout waiting for MC response\n");
+                       return -ETIMEDOUT;
+               }
+
+               udelay(500);
+       }
+
+       if (status != MC_CMD_STATUS_OK) {
+               printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n",
+                      mc_io->mmio_regs,
+                      (unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header),
+                      (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
+                      (unsigned int)status);
+
+               return -EIO;
+       }
+
+       return 0;
+}
index 291c249..bcad8f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
  * Layerscape PCIe driver
  *
  * SPDX-License-Identifier:    GPL-2.0+
@@ -9,8 +9,465 @@
 #include <asm/arch/fsl_serdes.h>
 #include <pci.h>
 #include <asm/io.h>
+#include <errno.h>
+#include <malloc.h>
 #include <asm/pcie_layerscape.h>
 
+#ifndef CONFIG_SYS_PCI_MEMORY_BUS
+#define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
+#endif
+
+#ifndef CONFIG_SYS_PCI_MEMORY_PHYS
+#define CONFIG_SYS_PCI_MEMORY_PHYS CONFIG_SYS_SDRAM_BASE
+#endif
+
+#ifndef CONFIG_SYS_PCI_MEMORY_SIZE
+#define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */
+#endif
+
+/* iATU registers */
+#define PCIE_ATU_VIEWPORT              0x900
+#define PCIE_ATU_REGION_INBOUND                (0x1 << 31)
+#define PCIE_ATU_REGION_OUTBOUND       (0x0 << 31)
+#define PCIE_ATU_REGION_INDEX0         (0x0 << 0)
+#define PCIE_ATU_REGION_INDEX1         (0x1 << 0)
+#define PCIE_ATU_REGION_INDEX2         (0x2 << 0)
+#define PCIE_ATU_REGION_INDEX3         (0x3 << 0)
+#define PCIE_ATU_CR1                   0x904
+#define PCIE_ATU_TYPE_MEM              (0x0 << 0)
+#define PCIE_ATU_TYPE_IO               (0x2 << 0)
+#define PCIE_ATU_TYPE_CFG0             (0x4 << 0)
+#define PCIE_ATU_TYPE_CFG1             (0x5 << 0)
+#define PCIE_ATU_CR2                   0x908
+#define PCIE_ATU_ENABLE                        (0x1 << 31)
+#define PCIE_ATU_BAR_MODE_ENABLE       (0x1 << 30)
+#define PCIE_ATU_LOWER_BASE            0x90C
+#define PCIE_ATU_UPPER_BASE            0x910
+#define PCIE_ATU_LIMIT                 0x914
+#define PCIE_ATU_LOWER_TARGET          0x918
+#define PCIE_ATU_BUS(x)                        (((x) & 0xff) << 24)
+#define PCIE_ATU_DEV(x)                        (((x) & 0x1f) << 19)
+#define PCIE_ATU_FUNC(x)               (((x) & 0x7) << 16)
+#define PCIE_ATU_UPPER_TARGET          0x91C
+
+#define PCIE_LINK_CAP          0x7c
+#define PCIE_LINK_SPEED_MASK   0xf
+#define PCIE_LINK_STA          0x82
+
+#define PCIE_DBI_SIZE          (4 * 1024) /* 4K */
+
+struct ls_pcie {
+       int idx;
+       void __iomem *dbi;
+       void __iomem *va_cfg0;
+       void __iomem *va_cfg1;
+       struct pci_controller hose;
+};
+
+struct ls_pcie_info {
+       unsigned long regs;
+       int pci_num;
+       u64 cfg0_phys;
+       u64 cfg0_size;
+       u64 cfg1_phys;
+       u64 cfg1_size;
+       u64 mem_bus;
+       u64 mem_phys;
+       u64 mem_size;
+       u64 io_bus;
+       u64 io_phys;
+       u64 io_size;
+};
+
+#define SET_LS_PCIE_INFO(x, num)                       \
+{                                                      \
+       x.regs = CONFIG_SYS_PCIE##num##_ADDR;           \
+       x.cfg0_phys = CONFIG_SYS_PCIE_CFG0_PHYS_OFF +   \
+                     CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
+       x.cfg0_size = CONFIG_SYS_PCIE_CFG0_SIZE;        \
+       x.cfg1_phys = CONFIG_SYS_PCIE_CFG1_PHYS_OFF +   \
+                     CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
+       x.cfg1_size = CONFIG_SYS_PCIE_CFG1_SIZE;        \
+       x.mem_bus = CONFIG_SYS_PCIE_MEM_BUS;            \
+       x.mem_phys = CONFIG_SYS_PCIE_MEM_PHYS_OFF +     \
+                    CONFIG_SYS_PCIE##num##_PHYS_ADDR;  \
+       x.mem_size = CONFIG_SYS_PCIE_MEM_SIZE;          \
+       x.io_bus = CONFIG_SYS_PCIE_IO_BUS;              \
+       x.io_phys = CONFIG_SYS_PCIE_IO_PHYS_OFF +       \
+                   CONFIG_SYS_PCIE##num##_PHYS_ADDR;   \
+       x.io_size = CONFIG_SYS_PCIE_IO_SIZE;            \
+       x.pci_num = num;                                \
+}
+
+#ifdef CONFIG_LS102XA
+#include <asm/arch/immap_ls102xa.h>
+
+/* PEX1/2 Misc Ports Status Register */
+#define LTSSM_STATE_SHIFT      20
+#define LTSSM_STATE_MASK       0x3f
+#define LTSSM_PCIE_L0          0x11 /* L0 state */
+
+static int ls_pcie_link_state(struct ls_pcie *pcie)
+{
+       u32 state;
+       struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
+
+       state = in_be32(&scfg->pexmscportsr[pcie->idx]);
+       state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
+       if (state < LTSSM_PCIE_L0) {
+               debug("....PCIe link error. LTSSM=0x%02x.\n", state);
+               return 0;
+       }
+
+       return 1;
+}
+#else
+#define PCIE_LDBG 0x7FC
+
+static int ls_pcie_link_state(struct ls_pcie *pcie)
+{
+       u32 state;
+
+       state = readl(pcie->dbi + PCIE_LDBG);
+       if (state)
+               return 1;
+
+       debug("....PCIe link error.\n");
+       return 0;
+}
+#endif
+
+static int ls_pcie_link_up(struct ls_pcie *pcie)
+{
+       int state;
+       u32 cap;
+
+       state = ls_pcie_link_state(pcie);
+       if (state)
+               return state;
+
+       /* Try to download speed to gen1 */
+       cap = readl(pcie->dbi + PCIE_LINK_CAP);
+       writel((cap & (~PCIE_LINK_SPEED_MASK)) | 1, pcie->dbi + PCIE_LINK_CAP);
+       udelay(2000);
+       state = ls_pcie_link_state(pcie);
+       if (state)
+               return state;
+
+       writel(cap, pcie->dbi + PCIE_LINK_CAP);
+
+       return 0;
+}
+
+static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev)
+{
+       writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
+              pcie->dbi + PCIE_ATU_VIEWPORT);
+       writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
+}
+
+static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev)
+{
+       writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
+              pcie->dbi + PCIE_ATU_VIEWPORT);
+       writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
+}
+
+static void ls_pcie_iatu_outbound_set(struct ls_pcie *pcie, int idx, int type,
+                                     u64 phys, u64 bus_addr, pci_size_t size)
+{
+       writel(PCIE_ATU_REGION_OUTBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
+       writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_BASE);
+       writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_BASE);
+       writel(phys + size - 1, pcie->dbi + PCIE_ATU_LIMIT);
+       writel((u32)bus_addr, pcie->dbi + PCIE_ATU_LOWER_TARGET);
+       writel(bus_addr >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
+       writel(type, pcie->dbi + PCIE_ATU_CR1);
+       writel(PCIE_ATU_ENABLE, pcie->dbi + PCIE_ATU_CR2);
+}
+
+static void ls_pcie_setup_atu(struct ls_pcie *pcie, struct ls_pcie_info *info)
+{
+#ifdef DEBUG
+       int i;
+#endif
+
+       /* ATU 0 : OUTBOUND : CFG0 */
+       ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
+                                 PCIE_ATU_TYPE_CFG0,
+                                 info->cfg0_phys,
+                                 0,
+                                 info->cfg0_size);
+       /* ATU 1 : OUTBOUND : CFG1 */
+       ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
+                                 PCIE_ATU_TYPE_CFG1,
+                                 info->cfg1_phys,
+                                 0,
+                                 info->cfg1_size);
+       /* ATU 2 : OUTBOUND : MEM */
+       ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX2,
+                                 PCIE_ATU_TYPE_MEM,
+                                 info->mem_phys,
+                                 info->mem_bus,
+                                 info->mem_size);
+       /* ATU 3 : OUTBOUND : IO */
+       ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX3,
+                                 PCIE_ATU_TYPE_IO,
+                                 info->io_phys,
+                                 info->io_bus,
+                                 info->io_size);
+
+#ifdef DEBUG
+       for (i = 0; i <= PCIE_ATU_REGION_INDEX3; i++) {
+               writel(PCIE_ATU_REGION_OUTBOUND | i,
+                      pcie->dbi + PCIE_ATU_VIEWPORT);
+               debug("iATU%d:\n", i);
+               debug("\tLOWER PHYS 0x%08x\n",
+                     readl(pcie->dbi + PCIE_ATU_LOWER_BASE));
+               debug("\tUPPER PHYS 0x%08x\n",
+                     readl(pcie->dbi + PCIE_ATU_UPPER_BASE));
+               debug("\tLOWER BUS  0x%08x\n",
+                     readl(pcie->dbi + PCIE_ATU_LOWER_TARGET));
+               debug("\tUPPER BUS  0x%08x\n",
+                     readl(pcie->dbi + PCIE_ATU_UPPER_TARGET));
+               debug("\tLIMIT      0x%08x\n",
+                     readl(pcie->dbi + PCIE_ATU_LIMIT));
+               debug("\tCR1        0x%08x\n",
+                     readl(pcie->dbi + PCIE_ATU_CR1));
+               debug("\tCR2        0x%08x\n",
+                     readl(pcie->dbi + PCIE_ATU_CR2));
+       }
+#endif
+}
+
+int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
+{
+       /* Do not skip controller */
+       return 0;
+}
+
+static int ls_pcie_addr_valid(struct pci_controller *hose, pci_dev_t d)
+{
+       if (PCI_DEV(d) > 0)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int ls_pcie_read_config(struct pci_controller *hose, pci_dev_t d,
+                              int where, u32 *val)
+{
+       struct ls_pcie *pcie = hose->priv_data;
+       u32 busdev, *addr;
+
+       if (ls_pcie_addr_valid(hose, d)) {
+               *val = 0xffffffff;
+               return -EINVAL;
+       }
+
+       if (PCI_BUS(d) == hose->first_busno) {
+               addr = pcie->dbi + (where & ~0x3);
+       } else {
+               busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
+                        PCIE_ATU_DEV(PCI_DEV(d)) |
+                        PCIE_ATU_FUNC(PCI_FUNC(d));
+
+               if (PCI_BUS(d) == hose->first_busno + 1) {
+                       ls_pcie_cfg0_set_busdev(pcie, busdev);
+                       addr = pcie->va_cfg0 + (where & ~0x3);
+               } else {
+                       ls_pcie_cfg1_set_busdev(pcie, busdev);
+                       addr = pcie->va_cfg1 + (where & ~0x3);
+               }
+       }
+
+       *val = readl(addr);
+
+       return 0;
+}
+
+static int ls_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
+                               int where, u32 val)
+{
+       struct ls_pcie *pcie = hose->priv_data;
+       u32 busdev, *addr;
+
+       if (ls_pcie_addr_valid(hose, d))
+               return -EINVAL;
+
+       if (PCI_BUS(d) == hose->first_busno) {
+               addr = pcie->dbi + (where & ~0x3);
+       } else {
+               busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
+                        PCIE_ATU_DEV(PCI_DEV(d)) |
+                        PCIE_ATU_FUNC(PCI_FUNC(d));
+
+               if (PCI_BUS(d) == hose->first_busno + 1) {
+                       ls_pcie_cfg0_set_busdev(pcie, busdev);
+                       addr = pcie->va_cfg0 + (where & ~0x3);
+               } else {
+                       ls_pcie_cfg1_set_busdev(pcie, busdev);
+                       addr = pcie->va_cfg1 + (where & ~0x3);
+               }
+       }
+
+       writel(val, addr);
+
+       return 0;
+}
+
+static void ls_pcie_setup_ctrl(struct ls_pcie *pcie,
+                              struct ls_pcie_info *info)
+{
+       struct pci_controller *hose = &pcie->hose;
+       pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
+
+       ls_pcie_setup_atu(pcie, info);
+
+       pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0);
+
+       /* program correct class for RC */
+       pci_hose_write_config_word(hose, dev, PCI_CLASS_DEVICE,
+                                  PCI_CLASS_BRIDGE_PCI);
+}
+
+int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
+{
+       struct ls_pcie *pcie;
+       struct pci_controller *hose;
+       int num = dev - PCIE1;
+       pci_dev_t pdev = PCI_BDF(busno, 0, 0);
+       int i, linkup, ep_mode;
+       u8 header_type;
+       u16 temp16;
+
+       if (!is_serdes_configured(dev)) {
+               printf("PCIe%d: disabled\n", num + 1);
+               return busno;
+       }
+
+       pcie = malloc(sizeof(*pcie));
+       if (!pcie)
+               return busno;
+       memset(pcie, 0, sizeof(*pcie));
+
+       hose = &pcie->hose;
+       hose->priv_data = pcie;
+       hose->first_busno = busno;
+       pcie->idx = num;
+       pcie->dbi = map_physmem(info->regs, PCIE_DBI_SIZE, MAP_NOCACHE);
+       pcie->va_cfg0 = map_physmem(info->cfg0_phys,
+                                   info->cfg0_size,
+                                   MAP_NOCACHE);
+       pcie->va_cfg1 = map_physmem(info->cfg1_phys,
+                                   info->cfg1_size,
+                                   MAP_NOCACHE);
+
+       /* outbound memory */
+       pci_set_region(&hose->regions[0],
+                      (pci_size_t)info->mem_bus,
+                      (phys_size_t)info->mem_phys,
+                      (pci_size_t)info->mem_size,
+                      PCI_REGION_MEM);
+
+       /* outbound io */
+       pci_set_region(&hose->regions[1],
+                      (pci_size_t)info->io_bus,
+                      (phys_size_t)info->io_phys,
+                      (pci_size_t)info->io_size,
+                      PCI_REGION_IO);
+
+       /* System memory space */
+       pci_set_region(&hose->regions[2],
+                      CONFIG_SYS_PCI_MEMORY_BUS,
+                      CONFIG_SYS_PCI_MEMORY_PHYS,
+                      CONFIG_SYS_PCI_MEMORY_SIZE,
+                      PCI_REGION_SYS_MEMORY);
+
+       hose->region_count = 3;
+
+       for (i = 0; i < hose->region_count; i++)
+               debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n",
+                     i,
+                     (u64)hose->regions[i].phys_start,
+                     (u64)hose->regions[i].bus_start,
+                     (u64)hose->regions[i].size,
+                     hose->regions[i].flags);
+
+       pci_set_ops(hose,
+                   pci_hose_read_config_byte_via_dword,
+                   pci_hose_read_config_word_via_dword,
+                   ls_pcie_read_config,
+                   pci_hose_write_config_byte_via_dword,
+                   pci_hose_write_config_word_via_dword,
+                   ls_pcie_write_config);
+
+       pci_hose_read_config_byte(hose, pdev, PCI_HEADER_TYPE, &header_type);
+       ep_mode = (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
+       printf("PCIe%u: %s ", info->pci_num,
+              ep_mode ? "Endpoint" : "Root Complex");
+
+       linkup = ls_pcie_link_up(pcie);
+
+       if (!linkup) {
+               /* Let the user know there's no PCIe link */
+               printf("no link, regs @ 0x%lx\n", info->regs);
+               hose->last_busno = hose->first_busno;
+               return busno;
+       }
+
+       /* Print the negotiated PCIe link width */
+       pci_hose_read_config_word(hose, dev, PCIE_LINK_STA, &temp16);
+               printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4,
+                      (temp16 & 0xf), info->regs);
+
+       if (ep_mode)
+               return busno;
+
+       ls_pcie_setup_ctrl(pcie, info);
+
+       pci_register_hose(hose);
+
+       hose->last_busno = pci_hose_scan(hose);
+
+       printf("PCIe%x: Bus %02x - %02x\n",
+              info->pci_num, hose->first_busno, hose->last_busno);
+
+       return hose->last_busno + 1;
+}
+
+int ls_pcie_init_board(int busno)
+{
+       struct ls_pcie_info info;
+
+#ifdef CONFIG_PCIE1
+       SET_LS_PCIE_INFO(info, 1);
+       busno = ls_pcie_init_ctrl(busno, PCIE1, &info);
+#endif
+
+#ifdef CONFIG_PCIE2
+       SET_LS_PCIE_INFO(info, 2);
+       busno = ls_pcie_init_ctrl(busno, PCIE2, &info);
+#endif
+
+#ifdef CONFIG_PCIE3
+       SET_LS_PCIE_INFO(info, 3);
+       busno = ls_pcie_init_ctrl(busno, PCIE3, &info);
+#endif
+
+#ifdef CONFIG_PCIE4
+       SET_LS_PCIE_INFO(info, 4);
+       busno = ls_pcie_init_ctrl(busno, PCIE4, &info);
+#endif
+
+       return busno;
+}
+
+void pci_init_board(void)
+{
+       ls_pcie_init_board(0);
+}
+
 #ifdef CONFIG_OF_BOARD_SETUP
 #include <libfdt.h>
 #include <fdt_support.h>
@@ -38,6 +495,14 @@ void ft_pcie_setup(void *blob, bd_t *bd)
        #ifdef CONFIG_PCIE2
        ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE2_ADDR, PCIE2);
        #endif
+
+       #ifdef CONFIG_PCIE3
+       ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE3_ADDR, PCIE3);
+       #endif
+
+       #ifdef CONFIG_PCIE4
+       ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR, PCIE4);
+       #endif
 }
 
 #else
@@ -45,7 +510,3 @@ void ft_pcie_setup(void *blob, bd_t *bd)
 {
 }
 #endif
-
-void pci_init_board(void)
-{
-}
index 2874ccc..3dc4da3 100644 (file)
@@ -510,6 +510,30 @@ unsigned long get_board_ddr_clk(void);
 #define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
 #define FSL_PCIE_COMPAT "fsl,ls1021a-pcie"
 
+#define CONFIG_SYS_PCI_64BIT
+
+#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF  0x00000000
+#define CONFIG_SYS_PCIE_CFG0_SIZE      0x00001000      /* 4k */
+#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF  0x00001000
+#define CONFIG_SYS_PCIE_CFG1_SIZE      0x00001000      /* 4k */
+
+#define CONFIG_SYS_PCIE_IO_BUS         0x00000000
+#define CONFIG_SYS_PCIE_IO_PHYS_OFF    0x00010000
+#define CONFIG_SYS_PCIE_IO_SIZE                0x00010000      /* 64k */
+
+#define CONFIG_SYS_PCIE_MEM_BUS                0x08000000
+#define CONFIG_SYS_PCIE_MEM_PHYS_OFF   0x04000000
+#define CONFIG_SYS_PCIE_MEM_SIZE       0x08000000      /* 128M */
+
+#ifdef CONFIG_PCI
+#define CONFIG_NET_MULTI
+#define CONFIG_PCI_PNP
+#define CONFIG_E1000
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_NET
+#endif
+
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_MII
index 0a0bb5f..a13876b 100644 (file)
 #define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
 #define FSL_PCIE_COMPAT "fsl,ls1021a-pcie"
 
+#define CONFIG_SYS_PCI_64BIT
+
+#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF  0x00000000
+#define CONFIG_SYS_PCIE_CFG0_SIZE      0x00001000      /* 4k */
+#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF  0x00001000
+#define CONFIG_SYS_PCIE_CFG1_SIZE      0x00001000      /* 4k */
+
+#define CONFIG_SYS_PCIE_IO_BUS         0x00000000
+#define CONFIG_SYS_PCIE_IO_PHYS_OFF    0x00010000
+#define CONFIG_SYS_PCIE_IO_SIZE                0x00010000      /* 64k */
+
+#define CONFIG_SYS_PCIE_MEM_BUS                0x08000000
+#define CONFIG_SYS_PCIE_MEM_PHYS_OFF   0x04000000
+#define CONFIG_SYS_PCIE_MEM_SIZE       0x08000000      /* 128M */
+
+#ifdef CONFIG_PCI
+#define CONFIG_NET_MULTI
+#define CONFIG_PCI_PNP
+#define CONFIG_E1000
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_NET
+#endif
+
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_MII
index 6fe032c..17a1cde 100644 (file)
@@ -13,6 +13,7 @@
 #define CONFIG_FSL_LSCH3
 #define CONFIG_LS2085A
 #define CONFIG_GICV3
+#define CONFIG_FSL_TZPC_BP147
 
 /* Link Definitions */
 #define CONFIG_SYS_TEXT_BASE           0x30001000
@@ -26,9 +27,6 @@
 #define CONFIG_SKIP_LOWLEVEL_INIT
 #define CONFIG_BOARD_EARLY_INIT_F      1
 
-#define CONFIG_IDENT_STRING            " LS2085A-EMU"
-#define CONFIG_BOOTP_VCI_STRING                "U-boot.LS2085A-EMU"
-
 /* Flat Device Tree Definitions */
 #define CONFIG_OF_LIBFDT
 #define CONFIG_OF_BOARD_SETUP
 #define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE   (512UL * 1024 * 1024)
 #define CONFIG_SYS_LS_MC_FW_IN_NOR
 #define CONFIG_SYS_LS_MC_FW_ADDR       0x580200000ULL
-/* TODO Actual FW length needs to be determined at runtime from FW header */
-#define CONFIG_SYS_LS_MC_FW_LENGTH     (4U * 1024 * 1024)
 #define CONFIG_SYS_LS_MC_DPL_IN_NOR
 #define CONFIG_SYS_LS_MC_DPL_ADDR      0x5806C0000ULL
 /* TODO Actual DPL max length needs to be confirmed with the MC FW team */
-#define CONFIG_SYS_LS_MC_DPL_LENGTH    4096
+#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH        (256 * 1024)
 #define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET    0xe00000
 
 /* Carve the MC private DRAM block from the end of DRAM */
 /* Physical Memory Map */
 /* fixme: these need to be checked against the board */
 #define CONFIG_CHIP_SELECTS_PER_CTRL   4
-#define CONFIG_SYS_CLK_FREQ    133333333
+#define CONFIG_SYS_CLK_FREQ    100000000
+#define CONFIG_DDR_CLK_FREQ    133333333
 
 
 #define CONFIG_NR_DRAM_BANKS           3
        "fdt_high=0xffffffffffffffff\0"         \
        "initrd_high=0xffffffffffffffff\0"      \
        "kernel_start=0x581200000\0"            \
-       "kernel_load=0x806f0000\0"              \
+       "kernel_load=0xa0000000\0"              \
        "kernel_size=0x1000000\0"               \
        "console=ttyAMA0,38400n8\0"
 
-#define CONFIG_BOOTARGS                        "console=ttyS1,115200 root=/dev/ram0 " \
-                                       "earlyprintk=uart8250-8bit,0x21c0600"
+#define CONFIG_BOOTARGS                "console=ttyS1,115200 root=/dev/ram0 " \
+                               "earlycon=uart8250,mmio,0x21c0600,115200 " \
+                               "default_hugepagesz=2m hugepagesz=2m " \
+                               "hugepages=16"
 #define CONFIG_BOOTCOMMAND             "cp.b $kernel_start $kernel_load "     \
                                        "$kernel_size && bootm $kernel_load"
 #define CONFIG_BOOTDELAY               1
index 487cd99..a02d694 100644 (file)
@@ -9,6 +9,9 @@
 
 #include "ls2085a_common.h"
 
+#define CONFIG_IDENT_STRING            " LS2085A-EMU"
+#define CONFIG_BOOTP_VCI_STRING                "U-boot.LS2085A-EMU"
+
 #define CONFIG_DDR_SPD
 #define CONFIG_SYS_FSL_DDR_EMU         /* Support emulator */
 #define SPD_EEPROM_ADDRESS1    0x51
@@ -17,4 +20,5 @@
 #define SPD_EEPROM_ADDRESS     SPD_EEPROM_ADDRESS1
 #define CONFIG_SYS_SPD_BUS_NUM 1       /* SPD on I2C bus 1 */
 
+#define CONFIG_FSL_DDR_SYNC_REFRESH
 #endif /* __LS2_EMU_H */
index 0f40b78..af34f3f 100644 (file)
@@ -9,6 +9,9 @@
 
 #include "ls2085a_common.h"
 
+#define CONFIG_IDENT_STRING            " LS2085A-SIMU"
+#define CONFIG_BOOTP_VCI_STRING                "U-boot.LS2085A-SIMU"
+
 /* SMSC 91C111 ethernet configuration */
 #define CONFIG_SMC91111
 #define CONFIG_SMC91111_BASE   (0x2210000)
index e0528ce..29b72b2 100644 (file)
@@ -28,6 +28,8 @@
 #define CONFIG_SYS_PL310_BASE  L2_PL310_BASE
 #endif
 
+#define CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
+
 #define CONFIG_MP
 #define CONFIG_MXC_GPT_HCLK
 
diff --git a/include/fsl-mc/fsl_dpmng.h b/include/fsl-mc/fsl_dpmng.h
new file mode 100644 (file)
index 0000000..c2e1ddd
--- /dev/null
@@ -0,0 +1,121 @@
+/* Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+/*!
+ *  @file    fsl_dpmng.h
+ *  @brief   Management Complex General API
+ */
+
+#ifndef __FSL_DPMNG_H
+#define __FSL_DPMNG_H
+
+/*!
+ * @Group grp_dpmng    Management Complex General API
+ *
+ * @brief      Contains general API for the Management Complex firmware
+ * @{
+ */
+
+struct fsl_mc_io;
+
+/**
+ * @brief      Management Complex firmware version information
+ */
+#define MC_VER_MAJOR 4
+#define MC_VER_MINOR 0
+
+struct mc_version {
+       uint32_t major;
+       /*!< Major version number: incremented on API compatibility changes */
+       uint32_t minor;
+       /*!< Minor version number: incremented on API additions (that are
+        * backward compatible); reset when major version is incremented
+        */
+       uint32_t revision;
+       /*!< Internal revision number: incremented on implementation changes
+        * and/or bug fixes that have no impact on API
+        */
+};
+
+/**
+ * @brief      Retrieves the Management Complex firmware version information
+ *
+ * @param[in]  mc_io           Pointer to opaque I/O object
+ * @param[out] mc_ver_info     Pointer to version information structure
+ *
+ * @returns    '0' on Success; Error code otherwise.
+ */
+int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info);
+
+/**
+ * @brief      Resets an AIOP tile
+ *
+ * @param[in]  mc_io           Pointer to opaque I/O object
+ * @param[in]  container_id    AIOP container ID
+ * @param[in]  aiop_tile_id    AIOP tile ID to reset
+ *
+ * @returns    '0' on Success; Error code otherwise.
+ */
+int dpmng_reset_aiop(struct fsl_mc_io  *mc_io,
+                    int                container_id,
+                    int                aiop_tile_id);
+
+/**
+ * @brief      Loads an image to AIOP tile
+ *
+ * @param[in]  mc_io           Pointer to opaque I/O object
+ * @param[in]  container_id    AIOP container ID
+ * @param[in]  aiop_tile_id    AIOP tile ID to reset
+ * @param[in]  img_iova        I/O virtual address of AIOP ELF image
+ * @param[in]  img_size        Size of AIOP ELF image in memory (in bytes)
+ *
+ * @returns    '0' on Success; Error code otherwise.
+ */
+int dpmng_load_aiop(struct fsl_mc_io   *mc_io,
+                   int                 container_id,
+                   int                 aiop_tile_id,
+                   uint64_t            img_iova,
+                   uint32_t            img_size);
+
+/**
+ * @brief      AIOP run configuration
+ */
+struct dpmng_aiop_run_cfg {
+       uint32_t cores_mask;
+       /*!< Mask of AIOP cores to run (core 0 in most significant bit) */
+       uint64_t options;
+       /*!< Execution options (currently none defined) */
+};
+
+/**
+ * @brief      Starts AIOP tile execution
+ *
+ * @param[in]  mc_io           Pointer to MC portal's I/O object
+ * @param[in]  container_id    AIOP container ID
+ * @param[in]  aiop_tile_id    AIOP tile ID to reset
+ * @param[in]  cfg             AIOP run configuration
+ *
+ * @returns    '0' on Success; Error code otherwise.
+ */
+int dpmng_run_aiop(struct fsl_mc_io                    *mc_io,
+                  int                                  container_id,
+                  int                                  aiop_tile_id,
+                  const struct dpmng_aiop_run_cfg      *cfg);
+
+/**
+ * @brief      Resets MC portal
+ *
+ * This function closes all object handles (tokens) that are currently
+ * open in the MC portal on which the command is submitted. This allows
+ * cleanup of stale handles that belong to non-functional user processes.
+ *
+ * @param[in]  mc_io   Pointer to MC portal's I/O object
+ *
+ * @returns    '0' on Success; Error code otherwise.
+ */
+int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io);
+
+/** @} */
+
+#endif /* __FSL_DPMNG_H */
similarity index 100%
rename from include/fsl_mc.h
rename to include/fsl-mc/fsl_mc.h
diff --git a/include/fsl-mc/fsl_mc_cmd.h b/include/fsl-mc/fsl_mc_cmd.h
new file mode 100644 (file)
index 0000000..e7fcb5b
--- /dev/null
@@ -0,0 +1,132 @@
+/* Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef __FSL_MC_CMD_H
+#define __FSL_MC_CMD_H
+
+#define MC_CMD_NUM_OF_PARAMS   7
+
+#define MAKE_UMASK64(_width) \
+       ((uint64_t)((_width) < 64 ? ((uint64_t)1 << (_width)) - 1 : -1))
+
+static inline uint64_t u64_enc(int lsoffset, int width, uint64_t val)
+{
+       return (uint64_t)(((uint64_t)val & MAKE_UMASK64(width)) << lsoffset);
+}
+static inline uint64_t u64_dec(uint64_t val, int lsoffset, int width)
+{
+       return (uint64_t)((val >> lsoffset) & MAKE_UMASK64(width));
+}
+
+struct mc_command {
+       uint64_t header;
+       uint64_t params[MC_CMD_NUM_OF_PARAMS];
+};
+
+enum mc_cmd_status {
+       MC_CMD_STATUS_OK = 0x0, /*!< Completed successfully */
+       MC_CMD_STATUS_READY = 0x1, /*!< Ready to be processed */
+       MC_CMD_STATUS_AUTH_ERR = 0x3, /*!< Authentication error */
+       MC_CMD_STATUS_NO_PRIVILEGE = 0x4, /*!< No privilege */
+       MC_CMD_STATUS_DMA_ERR = 0x5, /*!< DMA or I/O error */
+       MC_CMD_STATUS_CONFIG_ERR = 0x6, /*!< Configuration error */
+       MC_CMD_STATUS_TIMEOUT = 0x7, /*!< Operation timed out */
+       MC_CMD_STATUS_NO_RESOURCE = 0x8, /*!< No resources */
+       MC_CMD_STATUS_NO_MEMORY = 0x9, /*!< No memory available */
+       MC_CMD_STATUS_BUSY = 0xA, /*!< Device is busy */
+       MC_CMD_STATUS_UNSUPPORTED_OP = 0xB, /*!< Unsupported operation */
+       MC_CMD_STATUS_INVALID_STATE = 0xC /*!< Invalid state */
+};
+
+#define MC_CMD_HDR_CMDID_O     52      /* Command ID field offset */
+#define MC_CMD_HDR_CMDID_S     12      /* Command ID field size */
+#define MC_CMD_HDR_AUTHID_O    38      /* Authentication ID field offset */
+#define MC_CMD_HDR_AUTHID_S    10      /* Authentication ID field size */
+#define MC_CMD_HDR_STATUS_O    16      /* Status field offset */
+#define MC_CMD_HDR_STATUS_S    8       /* Status field size*/
+#define MC_CMD_HDR_PRI_O       15      /* Priority field offset */
+#define MC_CMD_HDR_PRI_S       1       /* Priority field size */
+
+#define MC_CMD_HDR_READ_STATUS(_hdr) \
+       ((enum mc_cmd_status)u64_dec((_hdr), \
+               MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
+
+#define MC_CMD_HDR_READ_AUTHID(_hdr) \
+       ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S))
+
+#define MC_CMD_PRI_LOW         0 /*!< Low Priority command indication */
+#define MC_CMD_PRI_HIGH                1 /*!< High Priority command indication */
+
+#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
+       ((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg))
+
+#define MC_RSP_OP(_cmd, _param, _offset, _width, _type, _arg) \
+       (_arg = (_type)u64_dec(_cmd.params[_param], (_offset), (_width)))
+
+static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
+                                           uint8_t priority,
+                                           uint16_t auth_id)
+{
+       uint64_t hdr;
+
+       hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
+       hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id);
+       hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority);
+       hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
+                      MC_CMD_STATUS_READY);
+
+       return hdr;
+}
+
+/**
+ * mc_write_command - writes a command to a Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @cmd: pointer to a filled command
+ */
+static inline void mc_write_command(struct mc_command __iomem *portal,
+                                   struct mc_command *cmd)
+{
+       int i;
+
+       /* copy command parameters into the portal */
+       for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+               writeq(cmd->params[i], &portal->params[i]);
+
+       /* submit the command by writing the header */
+       writeq(cmd->header, &portal->header);
+}
+
+/**
+ * mc_read_response - reads the response for the last MC command from a
+ * Management Complex (MC) portal
+ *
+ * @portal: pointer to an MC portal
+ * @resp: pointer to command response buffer
+ *
+ * Returns MC_CMD_STATUS_OK on Success; Error code otherwise.
+ */
+static inline enum mc_cmd_status mc_read_response(
+                                       struct mc_command __iomem *portal,
+                                       struct mc_command *resp)
+{
+       int i;
+       enum mc_cmd_status status;
+
+       /* Copy command response header from MC portal: */
+       resp->header = readq(&portal->header);
+       status = MC_CMD_HDR_READ_STATUS(resp->header);
+       if (status != MC_CMD_STATUS_OK)
+               return status;
+
+       /* Copy command response data from MC portal: */
+       for (i = 0; i < MC_CMD_NUM_OF_PARAMS; i++)
+               resp->params[i] = readq(&portal->params[i]);
+
+       return status;
+}
+
+int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd);
+
+#endif /* __FSL_MC_CMD_H */
diff --git a/include/fsl-mc/fsl_mc_sys.h b/include/fsl-mc/fsl_mc_sys.h
new file mode 100644 (file)
index 0000000..c0befe0
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Freescale Layerscape Management Complex (MC) Environment-specific code
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _FSL_MC_SYS_H
+#define _FSL_MC_SYS_H
+
+#include <asm/io.h>
+
+struct mc_command;
+
+/*
+ * struct mc_portal_wrapper - MC command portal wrapper object
+ */
+struct fsl_mc_io {
+       struct mc_command __iomem *mmio_regs;
+};
+
+int mc_send_command(struct fsl_mc_io *mc_io,
+                   struct mc_command *cmd);
+
+#endif /* _FSL_MC_SYS_H */
index 3286c95..feccef9 100644 (file)
@@ -44,11 +44,12 @@ u32 fsl_ddr_get_version(void);
  * to this specific DDR technology.
  */
 static __inline__ int
-compute_dimm_parameters(const generic_spd_eeprom_t *spd,
+compute_dimm_parameters(const unsigned int ctrl_num,
+                       const generic_spd_eeprom_t *spd,
                        dimm_params_t *pdimm,
                        unsigned int dimm_number)
 {
-       return ddr_compute_dimm_parameters(spd, pdimm, dimm_number);
+       return ddr_compute_dimm_parameters(ctrl_num, spd, pdimm, dimm_number);
 }
 #endif
 
@@ -92,13 +93,15 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
                                       unsigned int size_only);
 const char *step_to_string(unsigned int step);
 
-unsigned int compute_fsl_memctl_config_regs(const memctl_options_t *popts,
+unsigned int compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
+                              const memctl_options_t *popts,
                               fsl_ddr_cfg_regs_t *ddr,
                               const common_timing_params_t *common_dimm,
                               const dimm_params_t *dimm_parameters,
                               unsigned int dbw_capacity_adjust,
                               unsigned int size_only);
 unsigned int compute_lowest_common_dimm_parameters(
+                               const unsigned int ctrl_num,
                                const dimm_params_t *dimm_params,
                                common_timing_params_t *outpdimm,
                                unsigned int number_of_dimms);
@@ -108,13 +111,15 @@ unsigned int populate_memctl_options(int all_dimms_registered,
                                unsigned int ctrl_num);
 void check_interleaving_options(fsl_ddr_info_t *pinfo);
 
-unsigned int mclk_to_picos(unsigned int mclk);
-unsigned int get_memory_clk_period_ps(void);
-unsigned int picos_to_mclk(unsigned int picos);
+unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk);
+unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num);
+unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos);
 void fsl_ddr_set_lawbar(
                const common_timing_params_t *memctl_common_params,
                unsigned int memctl_interleaved,
                unsigned int ctrl_num);
+void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
+                                unsigned int last_ctrl);
 
 int fsl_ddr_interactive_env_var_exists(void);
 unsigned long long fsl_ddr_interactive(fsl_ddr_info_t *pinfo, int var_is_set);
index 09a67a6..751e935 100644 (file)
@@ -112,7 +112,7 @@ typedef struct dimm_params_s {
 #endif
 } dimm_params_t;
 
-extern unsigned int ddr_compute_dimm_parameters(
+unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
                                         const generic_spd_eeprom_t *spd,
                                         dimm_params_t *pdimm,
                                         unsigned int dimm_number);
index c1b6648..313fa1e 100644 (file)
 #define XFERTYP_RSPTYP_48_BUSY 0x00030000
 #define XFERTYP_MSBSEL         0x00000020
 #define XFERTYP_DTDSEL         0x00000010
+#define XFERTYP_DDREN          0x00000008
 #define XFERTYP_AC12EN         0x00000004
 #define XFERTYP_BCEN           0x00000002
 #define XFERTYP_DMAEN          0x00000001
index aa850a3..b6e6f04 100644 (file)
@@ -175,6 +175,32 @@ struct jr_regs {
        u32 jrcr;
 };
 
+/*
+ * Scatter Gather Entry - Specifies the the Scatter Gather Format
+ * related information
+ */
+struct sg_entry {
+#ifdef CONFIG_SYS_FSL_SEC_LE
+       uint32_t addr_lo;       /* Memory Address - lo */
+       uint16_t addr_hi;       /* Memory Address of start of buffer - hi */
+       uint16_t reserved_zero;
+#else
+       uint16_t reserved_zero;
+       uint16_t addr_hi;       /* Memory Address of start of buffer - hi */
+       uint32_t addr_lo;       /* Memory Address - lo */
+#endif
+
+       uint32_t len_flag;      /* Length of the data in the frame */
+#define SG_ENTRY_LENGTH_MASK   0x3FFFFFFF
+#define SG_ENTRY_EXTENSION_BIT 0x80000000
+#define SG_ENTRY_FINAL_BIT     0x40000000
+       uint32_t bpid_offset;
+#define SG_ENTRY_BPID_MASK     0x00FF0000
+#define SG_ENTRY_BPID_SHIFT    16
+#define SG_ENTRY_OFFSET_MASK   0x00001FFF
+#define SG_ENTRY_OFFSET_SHIFT  0
+};
+
 int sec_init(void);
 #endif
 
index 783350d..ab19a99 100644 (file)
@@ -7,7 +7,7 @@
  */
 #ifndef __HW_SHA_H
 #define __HW_SHA_H
-
+#include <hash.h>
 
 /**
  * Computes hash value of input pbuf using h/w acceleration
@@ -34,4 +34,43 @@ void hw_sha256(const uchar * in_addr, uint buflen,
  */
 void hw_sha1(const uchar * in_addr, uint buflen,
                        uchar * out_addr, uint chunk_size);
+
+/*
+ * Create the context for sha progressive hashing using h/w acceleration
+ *
+ * @algo: Pointer to the hash_algo struct
+ * @ctxp: Pointer to the pointer of the context for hashing
+ * @return 0 if ok, -ve on error
+ */
+int hw_sha_init(struct hash_algo *algo, void **ctxp);
+
+/*
+ * Update buffer for sha progressive hashing using h/w acceleration
+ *
+ * The context is freed by this function if an error occurs.
+ *
+ * @algo: Pointer to the hash_algo struct
+ * @ctx: Pointer to the context for hashing
+ * @buf: Pointer to the buffer being hashed
+ * @size: Size of the buffer being hashed
+ * @is_last: 1 if this is the last update; 0 otherwise
+ * @return 0 if ok, -ve on error
+ */
+int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
+                    unsigned int size, int is_last);
+
+/*
+ * Copy sha hash result at destination location
+ *
+ * The context is freed after completion of hash operation or after an error.
+ *
+ * @algo: Pointer to the hash_algo struct
+ * @ctx: Pointer to the context for hashing
+ * @dest_buf: Pointer to the destination buffer where hash is to be copied
+ * @size: Size of the buffer being hashed
+ * @return 0 if ok, -ve on error
+ */
+int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf,
+                    int size);
+
 #endif
index a1f30a2..c9d2767 100644 (file)
@@ -29,4 +29,40 @@ config SYS_HZ
 
 source lib/rsa/Kconfig
 
+menu "Hashing Support"
+
+config SHA1
+       bool "Enable SHA1 support"
+       help
+         This option enables support of hashing using SHA1 algorithm.
+         The hash is calculated in software.
+         The SHA1 algorithm produces a 160-bit (20-byte) hash value
+         (digest).
+
+config SHA256
+       bool "Enable SHA256 support"
+       help
+         This option enables support of hashing using SHA256 algorithm.
+         The hash is calculated in software.
+         The SHA256 algorithm produces a 256-bit (32-byte) hash value
+         (digest).
+
+config SHA_HW_ACCEL
+       bool "Enable hashing using hardware"
+       help
+         This option enables hardware acceleration
+         for SHA1/SHA256 hashing.
+         This affects the 'hash' command and also the
+         hash_lookup_algo() function.
+
+config SHA_PROG_HW_ACCEL
+       bool "Enable Progressive hashing support using hardware"
+       depends on SHA_HW_ACCEL
+       help
+         This option enables hardware-acceleration for
+         SHA1/SHA256 progressive hashing.
+         Data can be streamed in a block at a time and the hashing
+         is performed in hardware.
+endmenu
+
 endmenu