Browse Source

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

Tom Rini 9 years ago
parent
commit
1606b34aa5
67 changed files with 2404 additions and 334 deletions
  1. 3 1
      Kconfig
  2. 19 4
      README
  3. 221 10
      arch/arm/cpu/armv7/ls102xa/cpu.c
  4. 6 0
      arch/arm/cpu/armv8/cache.S
  5. 11 7
      arch/arm/cpu/armv8/cache_v8.c
  6. 5 57
      arch/arm/cpu/armv8/fsl-lsch3/cpu.c
  7. 19 9
      arch/arm/cpu/armv8/fsl-lsch3/fdt.c
  8. 132 0
      arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
  9. 8 0
      arch/arm/cpu/armv8/fsl-lsch3/mp.c
  10. 1 0
      arch/arm/cpu/armv8/fsl-lsch3/mp.h
  11. 14 2
      arch/arm/cpu/armv8/fsl-lsch3/speed.c
  12. 38 0
      arch/arm/include/asm/arch-fsl-lsch3/config.h
  13. 3 0
      arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h
  14. 15 0
      arch/arm/include/asm/arch-ls102xa/config.h
  15. 38 2
      arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h
  16. 57 0
      arch/arm/include/asm/arch-ls102xa/ls102xa_stream_id.h
  17. 2 1
      arch/arm/include/asm/armv8/mmu.h
  18. 3 0
      arch/arm/include/asm/global_data.h
  19. 1 0
      arch/arm/include/asm/system.h
  20. 1 1
      arch/arm/lib/bootm.c
  21. 15 0
      board/freescale/common/ls102xa_stream_id.c
  22. 21 0
      board/freescale/ls1021aqds/ls1021aqds.c
  23. 21 0
      board/freescale/ls1021atwr/ls1021atwr.c
  24. 1 0
      board/freescale/ls2085a/ddr.c
  25. 25 4
      board/freescale/ls2085a/ls2085a.c
  26. 10 8
      common/cmd_blob.c
  27. 10 0
      common/hash.c
  28. 25 0
      doc/README.fsl-trustzone-components
  29. 2 2
      drivers/crypto/fsl/fsl_blob.c
  30. 137 1
      drivers/crypto/fsl/fsl_hash.c
  31. 34 0
      drivers/crypto/fsl/fsl_hash.h
  32. 1 1
      drivers/ddr/fsl/arm_ddr_gen3.c
  33. 119 97
      drivers/ddr/fsl/ctrl_regs.c
  34. 9 9
      drivers/ddr/fsl/ddr1_dimm_params.c
  35. 6 6
      drivers/ddr/fsl/ddr2_dimm_params.c
  36. 4 4
      drivers/ddr/fsl/ddr3_dimm_params.c
  37. 4 4
      drivers/ddr/fsl/ddr4_dimm_params.c
  38. 35 1
      drivers/ddr/fsl/fsl_ddr_gen4.c
  39. 16 11
      drivers/ddr/fsl/lc_common_dimm_params.c
  40. 18 11
      drivers/ddr/fsl/main.c
  41. 3 1
      drivers/ddr/fsl/mpc85xx_ddr_gen3.c
  42. 3 3
      drivers/ddr/fsl/options.c
  43. 61 6
      drivers/ddr/fsl/util.c
  44. 6 2
      drivers/mmc/fsl_esdhc.c
  45. 1 1
      drivers/net/Makefile
  46. 3 1
      drivers/net/fsl-mc/Makefile
  47. 91 0
      drivers/net/fsl-mc/dpmng.c
  48. 49 0
      drivers/net/fsl-mc/fsl_dpmng_cmd.h
  49. 88 44
      drivers/net/fsl-mc/mc.c
  50. 63 0
      drivers/net/fsl-mc/mc_sys.c
  51. 466 5
      drivers/pci/pcie_layerscape.c
  52. 24 0
      include/configs/ls1021aqds.h
  53. 24 0
      include/configs/ls1021atwr.h
  54. 9 10
      include/configs/ls2085a_common.h
  55. 4 0
      include/configs/ls2085a_emu.h
  56. 3 0
      include/configs/ls2085a_simu.h
  57. 2 0
      include/configs/mx6_common.h
  58. 121 0
      include/fsl-mc/fsl_dpmng.h
  59. 0 0
      include/fsl-mc/fsl_mc.h
  60. 132 0
      include/fsl-mc/fsl_mc_cmd.h
  61. 26 0
      include/fsl-mc/fsl_mc_sys.h
  62. 11 6
      include/fsl_ddr.h
  63. 1 1
      include/fsl_ddr_dimm_params.h
  64. 1 0
      include/fsl_esdhc.h
  65. 26 0
      include/fsl_sec.h
  66. 40 1
      include/hw_sha.h
  67. 36 0
      lib/Kconfig

+ 3 - 1
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

+ 19 - 4
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.

+ 221 - 10
arch/arm/cpu/armv7/ls102xa/cpu.c

@@ -8,14 +8,214 @@
 #include <asm/arch/clock.h>
 #include <asm/io.h>
 #include <asm/arch/immap_ls102xa.h>
+#include <asm/cache.h>
+#include <asm/system.h>
 #include <tsec.h>
 #include <netdev.h>
 #include <fsl_esdhc.h>
 
 #include "fsl_epu.h"
 
+#define DCSR_RCPM2_BLOCK_OFFSET	0x223000
+#define DCSR_RCPM2_CPMFSMCR0	0x400
+#define DCSR_RCPM2_CPMFSMSR0	0x404
+#define DCSR_RCPM2_CPMFSMCR1	0x414
+#define DCSR_RCPM2_CPMFSMSR1	0x418
+#define CPMFSMSR_FSM_STATE_MASK	0x7f
+
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SYS_DCACHE_OFF
+
+/*
+ * Bit[1] of the descriptor indicates the descriptor type,
+ * and bit[0] indicates whether the descriptor is valid.
+ */
+#define PMD_TYPE_TABLE		0x3
+#define PMD_TYPE_SECT		0x1
+
+/* AttrIndx[2:0] */
+#define PMD_ATTRINDX(t)		((t) << 2)
+
+/* Section */
+#define PMD_SECT_AF		(1 << 10)
+
+#define BLOCK_SIZE_L1		(1UL << 30)
+#define BLOCK_SIZE_L2		(1UL << 21)
+
+/* TTBCR flags */
+#define TTBCR_EAE		(1 << 31)
+#define TTBCR_T0SZ(x)		((x) << 0)
+#define TTBCR_T1SZ(x)		((x) << 16)
+#define TTBCR_USING_TTBR0	(TTBCR_T0SZ(0) | TTBCR_T1SZ(0))
+#define TTBCR_IRGN0_NC		(0 << 8)
+#define TTBCR_IRGN0_WBWA	(1 << 8)
+#define TTBCR_IRGN0_WT		(2 << 8)
+#define TTBCR_IRGN0_WBNWA	(3 << 8)
+#define TTBCR_IRGN0_MASK	(3 << 8)
+#define TTBCR_ORGN0_NC		(0 << 10)
+#define TTBCR_ORGN0_WBWA	(1 << 10)
+#define TTBCR_ORGN0_WT		(2 << 10)
+#define TTBCR_ORGN0_WBNWA	(3 << 10)
+#define TTBCR_ORGN0_MASK	(3 << 10)
+#define TTBCR_SHARED_NON	(0 << 12)
+#define TTBCR_SHARED_OUTER	(2 << 12)
+#define TTBCR_SHARED_INNER	(3 << 12)
+#define TTBCR_EPD0		(0 << 7)
+#define TTBCR			(TTBCR_SHARED_NON | \
+				 TTBCR_ORGN0_NC	| \
+				 TTBCR_IRGN0_NC	| \
+				 TTBCR_USING_TTBR0 | \
+				 TTBCR_EAE)
+
+/*
+ * Memory region attributes for LPAE (defined in pgtable):
+ *
+ * n = AttrIndx[2:0]
+ *
+ *		              n       MAIR
+ *	UNCACHED              000     00000000
+ *	BUFFERABLE            001     01000100
+ *	DEV_WC                001     01000100
+ *	WRITETHROUGH          010     10101010
+ *	WRITEBACK             011     11101110
+ *	DEV_CACHED            011     11101110
+ *	DEV_SHARED            100     00000100
+ *	DEV_NONSHARED         100     00000100
+ *	unused                101
+ *	unused                110
+ *	WRITEALLOC            111     11111111
+ */
+#define MT_MAIR0		0xeeaa4400
+#define MT_MAIR1		0xff000004
+#define MT_STRONLY_ORDER	0
+#define MT_NORMAL_NC		1
+#define MT_DEVICE_MEM		4
+#define MT_NORMAL		7
+
+/* The phy_addr must be aligned to 4KB */
+static inline void set_pgtable(u32 *page_table, u32 index, u32 phy_addr)
+{
+	u32 value = phy_addr | PMD_TYPE_TABLE;
+
+	page_table[2 * index] = value;
+	page_table[2 * index + 1] = 0;
+}
+
+/* The phy_addr must be aligned to 4KB */
+static inline void set_pgsection(u32 *page_table, u32 index, u64 phy_addr,
+				 u32 memory_type)
+{
+	u64 value;
+
+	value = phy_addr | PMD_TYPE_SECT | PMD_SECT_AF;
+	value |= PMD_ATTRINDX(memory_type);
+	page_table[2 * index] = value & 0xFFFFFFFF;
+	page_table[2 * index + 1] = (value >> 32) & 0xFFFFFFFF;
+}
+
+/*
+ * Start MMU after DDR is available, we create MMU table in DRAM.
+ * The base address of TTLB is gd->arch.tlb_addr. We use two
+ * levels of translation tables here to cover 40-bit address space.
+ *
+ * The TTLBs are located at PHY 2G~4G.
+ *
+ * VA mapping:
+ *
+ *  -------  <---- 0GB
+ * |       |
+ * |       |
+ * |-------| <---- 0x24000000
+ * |///////|  ===> 192MB VA map for PCIe1 with offset 0x40_0000_0000
+ * |-------| <---- 0x300000000
+ * |       |
+ * |-------| <---- 0x34000000
+ * |///////|  ===> 192MB VA map for PCIe2 with offset 0x48_0000_0000
+ * |-------| <---- 0x40000000
+ * |       |
+ * |-------| <---- 0x80000000 DDR0 space start
+ * |\\\\\\\|
+ *.|\\\\\\\|  ===> 2GB VA map for 2GB DDR0 Memory space
+ * |\\\\\\\|
+ *  -------  <---- 4GB DDR0 space end
+ */
+static void mmu_setup(void)
+{
+	u32 *level0_table = (u32 *)gd->arch.tlb_addr;
+	u32 *level1_table = (u32 *)(gd->arch.tlb_addr + 0x1000);
+	u64 va_start = 0;
+	u32 reg;
+	int i;
+
+	/* Level 0 Table 2-3 are used to map DDR */
+	set_pgsection(level0_table, 3, 3 * BLOCK_SIZE_L1, MT_NORMAL);
+	set_pgsection(level0_table, 2, 2 * BLOCK_SIZE_L1, MT_NORMAL);
+	/* Level 0 Table 1 is used to map device */
+	set_pgsection(level0_table, 1, 1 * BLOCK_SIZE_L1, MT_DEVICE_MEM);
+	/* Level 0 Table 0 is used to map device including PCIe MEM */
+	set_pgtable(level0_table, 0, (u32)level1_table);
+
+	/* Level 1 has 512 entries */
+	for (i = 0; i < 512; i++) {
+		/* Mapping for PCIe 1 */
+		if (va_start >= CONFIG_SYS_PCIE1_VIRT_ADDR &&
+		    va_start < (CONFIG_SYS_PCIE1_VIRT_ADDR +
+				 CONFIG_SYS_PCIE_MMAP_SIZE))
+			set_pgsection(level1_table, i,
+				      CONFIG_SYS_PCIE1_PHYS_BASE + va_start,
+				      MT_DEVICE_MEM);
+		/* Mapping for PCIe 2 */
+		else if (va_start >= CONFIG_SYS_PCIE2_VIRT_ADDR &&
+			 va_start < (CONFIG_SYS_PCIE2_VIRT_ADDR +
+				     CONFIG_SYS_PCIE_MMAP_SIZE))
+			set_pgsection(level1_table, i,
+				      CONFIG_SYS_PCIE2_PHYS_BASE + va_start,
+				      MT_DEVICE_MEM);
+		else
+			set_pgsection(level1_table, i,
+				      va_start,
+				      MT_DEVICE_MEM);
+		va_start += BLOCK_SIZE_L2;
+	}
+
+	asm volatile("dsb sy;isb");
+	asm volatile("mcr p15, 0, %0, c2, c0, 2" /* Write RT to TTBCR */
+			: : "r" (TTBCR) : "memory");
+	asm volatile("mcrr p15, 0, %0, %1, c2" /* TTBR 0 */
+			: : "r" ((u32)level0_table), "r" (0) : "memory");
+	asm volatile("mcr p15, 0, %0, c10, c2, 0" /* write MAIR 0 */
+			: : "r" (MT_MAIR0) : "memory");
+	asm volatile("mcr p15, 0, %0, c10, c2, 1" /* write MAIR 1 */
+			: : "r" (MT_MAIR1) : "memory");
+
+	/* Set the access control to all-supervisor */
+	asm volatile("mcr p15, 0, %0, c3, c0, 0"
+		     : : "r" (~0));
+
+	/* Enable the mmu */
+	reg = get_cr();
+	set_cr(reg | CR_M);
+}
+
+/*
+ * This function is called from lib/board.c. It recreates MMU
+ * table in main memory. MMU and i/d-cache are enabled here.
+ */
+void enable_caches(void)
+{
+	/* Invalidate all TLB */
+	mmu_page_table_flush(gd->arch.tlb_addr,
+			     gd->arch.tlb_addr +  gd->arch.tlb_size);
+	/* Set up and enable mmu */
+	mmu_setup();
+
+	/* Invalidate & Enable d-cache */
+	invalidate_dcache_all();
+	set_cr(get_cr() | CR_C);
+}
+#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
 int print_cpuinfo(void)
 {
@@ -78,16 +278,6 @@ int print_cpuinfo(void)
 }
 #endif
 
-void enable_caches(void)
-{
-#ifndef CONFIG_SYS_ICACHE_OFF
-	icache_enable();
-#endif
-#ifndef CONFIG_SYS_DCACHE_OFF
-	dcache_enable();
-#endif
-}
-
 #ifdef CONFIG_FSL_ESDHC
 int cpu_mmc_init(bd_t *bis)
 {
@@ -107,6 +297,27 @@ int cpu_eth_init(bd_t *bis)
 int arch_cpu_init(void)
 {
 	void *epu_base = (void *)(CONFIG_SYS_DCSRBAR + EPU_BLOCK_OFFSET);
+	void *rcpm2_base =
+		(void *)(CONFIG_SYS_DCSRBAR + DCSR_RCPM2_BLOCK_OFFSET);
+	u32 state;
+
+	/*
+	 * The RCPM FSM state may not be reset after power-on.
+	 * So, reset them.
+	 */
+	state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR0) &
+		CPMFSMSR_FSM_STATE_MASK;
+	if (state != 0) {
+		out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x80);
+		out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR0, 0x0);
+	}
+
+	state = in_be32(rcpm2_base + DCSR_RCPM2_CPMFSMSR1) &
+		CPMFSMSR_FSM_STATE_MASK;
+	if (state != 0) {
+		out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x80);
+		out_be32(rcpm2_base + DCSR_RCPM2_CPMFSMCR1, 0x0);
+	}
 
 	/*
 	 * After wakeup from deep sleep, Clear EPU registers

+ 6 - 0
arch/arm/cpu/armv8/cache.S

@@ -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

+ 11 - 7
arch/arm/cpu/armv8/cache_v8.c

@@ -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");
 }
 
 /*

+ 5 - 57
arch/arm/cpu/armv8/fsl-lsch3/cpu.c

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

+ 19 - 9
arch/arm/cpu/armv8/fsl-lsch3/fdt.c

@@ -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
 }

+ 132 - 0
arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S

@@ -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
 

+ 8 - 0
arch/arm/cpu/armv8/fsl-lsch3/mp.c

@@ -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");

+ 1 - 0
arch/arm/cpu/armv8/fsl-lsch3/mp.h

@@ -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 */

+ 14 - 2
arch/arm/cpu/armv8/fsl-lsch3/speed.c

@@ -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;
 }
 

+ 38 - 0
arch/arm/include/asm/arch-fsl-lsch3/config.h

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

+ 3 - 0
arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h

@@ -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];

+ 15 - 0
arch/arm/include/asm/arch-ls102xa/config.h

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

+ 38 - 2
arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h

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

+ 57 - 0
arch/arm/include/asm/arch-ls102xa/ls102xa_stream_id.h

@@ -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

+ 2 - 1
arch/arm/include/asm/armv8/mmu.h

@@ -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)

+ 3 - 0
arch/arm/include/asm/global_data.h

@@ -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>

+ 1 - 0
arch/arm/include/asm/system.h

@@ -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);

+ 1 - 1
arch/arm/lib/bootm.c

@@ -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();

+ 15 - 0
board/freescale/common/ls102xa_stream_id.c

@@ -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);
+	}
+}

+ 21 - 0
board/freescale/ls1021aqds/ls1021aqds.c

@@ -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));
 

+ 21 - 0
board/freescale/ls1021atwr/ls1021atwr.c

@@ -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));
 

+ 1 - 0
board/freescale/ls2085a/ddr.c

@@ -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:

+ 25 - 4
board/freescale/ls2085a/ls2085a.c

@@ -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

+ 10 - 8
common/cmd_blob.c

@@ -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,

+ 10 - 0
common/hash.c

@@ -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

+ 25 - 0
doc/README.fsl-trustzone-components

@@ -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.

+ 2 - 2
drivers/crypto/fsl/fsl_blob.c

@@ -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;

+ 137 - 1
drivers/crypto/fsl/fsl_hash.c

@@ -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));
+}

+ 34 - 0
drivers/crypto/fsl/fsl_hash.h

@@ -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

+ 1 - 1
drivers/ddr/fsl/arm_ddr_gen3.c

@@ -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);

+ 119 - 97
drivers/ddr/fsl/ctrl_regs.c

@@ -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))

+ 9 - 9
drivers/ddr/fsl/ddr1_dimm_params.c

@@ -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;
 

+ 6 - 6
drivers/ddr/fsl/ddr2_dimm_params.c

@@ -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;

+ 4 - 4
drivers/ddr/fsl/ddr3_dimm_params.c

@@ -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;

+ 4 - 4
drivers/ddr/fsl/ddr4_dimm_params.c

@@ -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;

+ 35 - 1
drivers/ddr/fsl/fsl_ddr_gen4.c

@@ -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);

+ 16 - 11
drivers/ddr/fsl/lc_common_dimm_params.c

@@ -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;
 	}

+ 18 - 11
drivers/ddr/fsl/main.c

@@ -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++) {

+ 3 - 1
drivers/ddr/fsl/mpc85xx_ddr_gen3.c

@@ -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);
 	}

+ 3 - 3
drivers/ddr/fsl/options.c

@@ -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;

+ 61 - 6
drivers/ddr/fsl/util.c

@@ -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 */

+ 6 - 2
drivers/mmc/fsl_esdhc.c

@@ -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)

+ 1 - 1
drivers/net/Makefile

@@ -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

+ 3 - 1
drivers/net/fsl_mc/Makefile → drivers/net/fsl-mc/Makefile

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

+ 91 - 0
drivers/net/fsl-mc/dpmng.c

@@ -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);
+}

+ 49 - 0
drivers/net/fsl-mc/fsl_dpmng_cmd.h

@@ -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 */

+ 88 - 44
drivers/net/fsl_mc/mc.c → drivers/net/fsl-mc/mc.c

@@ -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;

+ 63 - 0
drivers/net/fsl-mc/mc_sys.c

@@ -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;
+}

+ 466 - 5
drivers/pci/pcie_layerscape.c

@@ -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)
-{
-}

+ 24 - 0
include/configs/ls1021aqds.h

@@ -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

+ 24 - 0
include/configs/ls1021atwr.h

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

+ 9 - 10
include/configs/ls2085a_common.h

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

+ 4 - 0
include/configs/ls2085a_emu.h

@@ -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 */

+ 3 - 0
include/configs/ls2085a_simu.h

@@ -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)

+ 2 - 0
include/configs/mx6_common.h

@@ -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
 

+ 121 - 0
include/fsl-mc/fsl_dpmng.h

@@ -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 */

+ 0 - 0
include/fsl_mc.h → include/fsl-mc/fsl_mc.h


+ 132 - 0
include/fsl-mc/fsl_mc_cmd.h

@@ -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 */

+ 26 - 0
include/fsl-mc/fsl_mc_sys.h

@@ -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 */

+ 11 - 6
include/fsl_ddr.h

@@ -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);

+ 1 - 1
include/fsl_ddr_dimm_params.h

@@ -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);

+ 1 - 0
include/fsl_esdhc.h

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

+ 26 - 0
include/fsl_sec.h

@@ -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
 

+ 40 - 1
include/hw_sha.h

@@ -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

+ 36 - 0
lib/Kconfig

@@ -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