ARMv8/ls2085a_emu: Enable DP-DDR as standalone memory block

DP-DDR is used for DPAA, separated from main memory pool for general
use. It has 32-bit bus width and use a standard DDR4 DIMM (64-bit).

Signed-off-by: York Sun <yorksun@freescale.com>
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h
index b17410a..f632c82 100644
--- a/arch/arm/include/asm/arch-fsl-lsch3/config.h
+++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h
@@ -16,6 +16,7 @@
 #define CONFIG_SYS_IMMR				0x01000000
 #define CONFIG_SYS_FSL_DDR_ADDR			(CONFIG_SYS_IMMR + 0x00080000)
 #define CONFIG_SYS_FSL_DDR2_ADDR		(CONFIG_SYS_IMMR + 0x00090000)
+#define CONFIG_SYS_FSL_DDR3_ADDR		0x08210000
 #define CONFIG_SYS_FSL_GUTS_ADDR		(CONFIG_SYS_IMMR + 0x00E00000)
 #define CONFIG_SYS_FSL_PMU_ADDR			(CONFIG_SYS_IMMR + 0x00E30000)
 #define CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR	(CONFIG_SYS_IMMR + 0x00300000)
@@ -60,7 +61,7 @@
 #ifdef CONFIG_LS2085A
 #define CONFIG_MAX_CPUS				16
 #define CONFIG_SYS_FSL_IFC_BANK_COUNT		8
-#define CONFIG_NUM_DDR_CONTROLLERS		2
+#define CONFIG_NUM_DDR_CONTROLLERS		3
 #define CONFIG_SYS_FSL_CLUSTER_CLOCKS		{ 1, 1, 4, 4 }
 #else
 #error SoC not defined
diff --git a/board/freescale/ls2085a/ddr.c b/board/freescale/ls2085a/ddr.c
index 257bc16..b4a3fc9 100644
--- a/board/freescale/ls2085a/ddr.c
+++ b/board/freescale/ls2085a/ddr.c
@@ -30,9 +30,9 @@
 	 * to  pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
 	 */
 	if (popts->registered_dimm_en)
-		pbsp = rdimms[0];
+		pbsp = rdimms[ctrl_num];
 	else
-		pbsp = udimms[0];
+		pbsp = udimms[ctrl_num];
 
 
 	/* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
@@ -72,6 +72,12 @@
 		pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
 		pbsp->wrlvl_ctl_3);
 
+	if (ctrl_num == CONFIG_DP_DDR_CTRL) {
+		/* force DDR bus width to 32 bits */
+		popts->data_bus_width = 1;
+		popts->otf_burst_chop_en = 0;
+		popts->burst_length = DDR_BL8;
+	}
 	/*
 	 * Factors to consider for half-strength driver enable:
 	 *	- number of DIMMs installed
@@ -163,6 +169,10 @@
 
 void dram_init_banksize(void)
 {
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+	phys_size_t dp_ddr_size;
+#endif
+
 	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
 	if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
 		gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
@@ -172,4 +182,24 @@
 	} else {
 		gd->bd->bi_dram[0].size = gd->ram_size;
 	}
+
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+	/* initialize DP-DDR here */
+	puts("DP-DDR:  ");
+	/*
+	 * DDR controller use 0 as the base address for binding.
+	 * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
+	 */
+	dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
+					  CONFIG_DP_DDR_CTRL,
+					  CONFIG_DP_DDR_NUM_CTRLS,
+					  CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
+					  NULL, NULL, NULL);
+	if (dp_ddr_size) {
+		gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
+		gd->bd->bi_dram[2].size = dp_ddr_size;
+	} else {
+		puts("Not detected");
+	}
+#endif
 }
diff --git a/board/freescale/ls2085a/ddr.h b/board/freescale/ls2085a/ddr.h
index 77f6aaf..9958a68 100644
--- a/board/freescale/ls2085a/ddr.h
+++ b/board/freescale/ls2085a/ddr.h
@@ -33,6 +33,18 @@
 	{}
 };
 
+/* DP-DDR DIMM */
+static const struct board_specific_parameters udimm2[] = {
+	/*
+	 * memory controller 2
+	 *   num|  hi| rank|  clk| wrlvl |   wrlvl   |  wrlvl
+	 * ranks| mhz| GB  |adjst| start |   ctl2    |  ctl3
+	 */
+	{2,  2140, 0, 4,     4, 0x0, 0x0},
+	{1,  2140, 0, 4,     4, 0x0, 0x0},
+	{}
+};
+
 static const struct board_specific_parameters rdimm0[] = {
 	/*
 	 * memory controller 0
@@ -45,12 +57,29 @@
 	{}
 };
 
+/* DP-DDR DIMM */
+static const struct board_specific_parameters rdimm2[] = {
+	/*
+	 * memory controller 2
+	 *   num|  hi| rank|  clk| wrlvl |   wrlvl   |  wrlvl
+	 * ranks| mhz| GB  |adjst| start |   ctl2    |  ctl3
+	 */
+	{4,  2140, 0, 5,     4, 0x0, 0x0},
+	{2,  2140, 0, 5,     4, 0x0, 0x0},
+	{1,  2140, 0, 4,     4, 0x0, 0x0},
+	{}
+};
+
 static const struct board_specific_parameters *udimms[] = {
 	udimm0,
+	udimm0,
+	udimm2,
 };
 
 static const struct board_specific_parameters *rdimms[] = {
 	rdimm0,
+	rdimm0,
+	rdimm2,
 };
 
 
diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c
index d19f692..c2a726b 100644
--- a/board/freescale/ls2085a/ls2085a.c
+++ b/board/freescale/ls2085a/ls2085a.c
@@ -35,9 +35,20 @@
 	return 0;
 }
 
+void detail_board_ddr_info(void)
+{
+	puts("\nDDR    ");
+	print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
+	print_ddr_info(0);
+	if (gd->bd->bi_dram[2].size) {
+		puts("\nDP-DDR ");
+		print_size(gd->bd->bi_dram[2].size, "");
+		print_ddr_info(CONFIG_DP_DDR_CTRL);
+	}
+}
+
 int dram_init(void)
 {
-	printf("DRAM:  ");
 	gd->ram_size = initdram(0);
 
 	return 0;
diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h
index 6355e4a..5ac7623 100644
--- a/include/configs/ls2085a_common.h
+++ b/include/configs/ls2085a_common.h
@@ -54,6 +54,18 @@
 #define CONFIG_SYS_FSL_DDR_SDRAM_BASE_PHY	0
 #define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_DDR_SDRAM_BASE
 #define CONFIG_SYS_DDR_BLOCK2_BASE	0x8080000000ULL
+#define CONFIG_SYS_FSL_DDR_MAIN_NUM_CTRLS	2
+
+#define CONFIG_SYS_FSL_OTHER_DDR_NUM_CTRLS
+#define CONFIG_SYS_DP_DDR_BASE		0x6000000000ULL
+/*
+ * DDR controller use 0 as the base address for binding.
+ * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
+ */
+#define CONFIG_SYS_DP_DDR_BASE_PHY	0
+#define CONFIG_DP_DDR_CTRL		2
+#define CONFIG_DP_DDR_NUM_CTRLS		1
+#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR	1
 
 /* Generic Timer Definitions */
 #define COUNTER_FREQUENCY		12000000	/* 12MHz */
@@ -236,7 +248,7 @@
 #define CONFIG_SYS_CLK_FREQ	133333333
 
 
-#define CONFIG_NR_DRAM_BANKS		2
+#define CONFIG_NR_DRAM_BANKS		3
 
 #define CONFIG_SYS_HZ			1000
 
diff --git a/include/configs/ls2085a_emu.h b/include/configs/ls2085a_emu.h
index a5cea63..487cd99 100644
--- a/include/configs/ls2085a_emu.h
+++ b/include/configs/ls2085a_emu.h
@@ -13,6 +13,7 @@
 #define CONFIG_SYS_FSL_DDR_EMU		/* Support emulator */
 #define SPD_EEPROM_ADDRESS1	0x51
 #define SPD_EEPROM_ADDRESS2	0x52
+#define SPD_EEPROM_ADDRESS3	0x53
 #define SPD_EEPROM_ADDRESS	SPD_EEPROM_ADDRESS1
 #define CONFIG_SYS_SPD_BUS_NUM	1	/* SPD on I2C bus 1 */