driver/ddr/fsl: Fix driver to support empty first slot

CS0 was not allowed to be empty by u-boot driver in the past to simplify
the driver. This may be inconvenient for some debugging. This patch lifts
the restrictions. Controller interleaving still requires CS0 populated.

Signed-off-by: York Sun <yorksun@freescale.com>
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index a59824c..8367c95 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -1116,8 +1116,14 @@
 	int i;
 	unsigned short esdmode4 = 0;	/* Extended SDRAM mode 4 */
 	unsigned short esdmode5;	/* Extended SDRAM mode 5 */
+	int rtt_park = 0;
 
-	esdmode5 = 0x00000500;		/* Data mask enabled */
+	if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) {
+		esdmode5 = 0x00000500;	/* Data mask enable, RTT_PARK CS0 */
+		rtt_park = 1;
+	} else {
+		esdmode5 = 0x00000400;	/* Data mask enabled */
+	}
 
 	ddr->ddr_sdram_mode_9 = (0
 				 | ((esdmode4 & 0xffff) << 16)
@@ -1125,11 +1131,17 @@
 				);
 
 	/* only mode_9 use 0x500, others use 0x400 */
-	esdmode5 = 0x00000400;		/* Data mask enabled */
 
 	debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
 	if (unq_mrs_en) {	/* unique mode registers are supported */
 		for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
+			if (!rtt_park &&
+			    (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) {
+				esdmode5 |= 0x00000500;	/* RTT_PARK */
+				rtt_park = 1;
+			} else {
+				esdmode5 = 0x00000400;
+			}
 			switch (i) {
 			case 1:
 				ddr->ddr_sdram_mode_11 = (0
@@ -1977,31 +1989,41 @@
 			       const dimm_params_t *dimm_params)
 {
 	unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1;
+	int i;
 
-	ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) |
-			((dimm_params->dq_mapping[1] & 0x3F) << 20) |
-			((dimm_params->dq_mapping[2] & 0x3F) << 14) |
-			((dimm_params->dq_mapping[3] & 0x3F) << 8) |
-			((dimm_params->dq_mapping[4] & 0x3F) << 2);
+	for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
+		if (dimm_params[i].n_ranks)
+			break;
+	}
+	if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) {
+		puts("DDR error: no DIMM found!\n");
+		return;
+	}
 
-	ddr->dq_map_1 = ((dimm_params->dq_mapping[5] & 0x3F) << 26) |
-			((dimm_params->dq_mapping[6] & 0x3F) << 20) |
-			((dimm_params->dq_mapping[7] & 0x3F) << 14) |
-			((dimm_params->dq_mapping[10] & 0x3F) << 8) |
-			((dimm_params->dq_mapping[11] & 0x3F) << 2);
+	ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) |
+			((dimm_params[i].dq_mapping[1] & 0x3F) << 20) |
+			((dimm_params[i].dq_mapping[2] & 0x3F) << 14) |
+			((dimm_params[i].dq_mapping[3] & 0x3F) << 8) |
+			((dimm_params[i].dq_mapping[4] & 0x3F) << 2);
 
-	ddr->dq_map_2 = ((dimm_params->dq_mapping[12] & 0x3F) << 26) |
-			((dimm_params->dq_mapping[13] & 0x3F) << 20) |
-			((dimm_params->dq_mapping[14] & 0x3F) << 14) |
-			((dimm_params->dq_mapping[15] & 0x3F) << 8) |
-			((dimm_params->dq_mapping[16] & 0x3F) << 2);
+	ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) |
+			((dimm_params[i].dq_mapping[6] & 0x3F) << 20) |
+			((dimm_params[i].dq_mapping[7] & 0x3F) << 14) |
+			((dimm_params[i].dq_mapping[10] & 0x3F) << 8) |
+			((dimm_params[i].dq_mapping[11] & 0x3F) << 2);
+
+	ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) |
+			((dimm_params[i].dq_mapping[13] & 0x3F) << 20) |
+			((dimm_params[i].dq_mapping[14] & 0x3F) << 14) |
+			((dimm_params[i].dq_mapping[15] & 0x3F) << 8) |
+			((dimm_params[i].dq_mapping[16] & 0x3F) << 2);
 
 	/* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */
-	ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) |
-			((dimm_params->dq_mapping[8] & 0x3F) << 20) |
+	ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) |
+			((dimm_params[i].dq_mapping[8] & 0x3F) << 20) |
 			(acc_ecc_en ? 0 :
-			 (dimm_params->dq_mapping[9] & 0x3F) << 14) |
-			dimm_params->dq_mapping_ors;
+			 (dimm_params[i].dq_mapping[9] & 0x3F) << 14) |
+			dimm_params[i].dq_mapping_ors;
 
 	debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0);
 	debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1);
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index bbfb4ee..42834ca 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -135,7 +135,8 @@
 
 	if (spd->mem_type) {
 		if (spd->mem_type != SPD_MEMTYPE_DDR4) {
-			printf("DIMM %u: is not a DDR4 SPD.\n", dimm_number);
+			printf("Ctrl %u DIMM %u: is not a DDR4 SPD.\n",
+			       ctrl_num, dimm_number);
 			return 1;
 		}
 	} else {
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 57d14e8..d23e6e5 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -512,7 +512,7 @@
 		CTRL_OPTIONS_CS(3, odt_rd_cfg),
 		CTRL_OPTIONS_CS(3, odt_wr_cfg),
 #endif
-#if defined(CONFIG_SYS_FSL_DDR3)
+#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
 		CTRL_OPTIONS_CS(0, odt_rtt_norm),
 		CTRL_OPTIONS_CS(0, odt_rtt_wr),
 #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
@@ -802,7 +802,7 @@
 		CTRL_OPTIONS_CS(3, odt_rd_cfg),
 		CTRL_OPTIONS_CS(3, odt_wr_cfg),
 #endif
-#if defined(CONFIG_SYS_FSL_DDR3)
+#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
 		CTRL_OPTIONS_CS(0, odt_rtt_norm),
 		CTRL_OPTIONS_CS(0, odt_rtt_wr),
 #if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
@@ -844,6 +844,7 @@
 		CTRL_OPTIONS(twot_en),
 		CTRL_OPTIONS(threet_en),
 		CTRL_OPTIONS(registered_dimm_en),
+		CTRL_OPTIONS(mirrored_dimm),
 		CTRL_OPTIONS(ap_en),
 		CTRL_OPTIONS(x4_en),
 		CTRL_OPTIONS(bstopre),
diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c
index b295344..b12eeb9 100644
--- a/drivers/ddr/fsl/lc_common_dimm_params.c
+++ b/drivers/ddr/fsl/lc_common_dimm_params.c
@@ -22,7 +22,7 @@
 	unsigned int common_caslat;
 	unsigned int caslat_actual;
 	unsigned int retry = 16;
-	unsigned int tmp;
+	unsigned int tmp = ~0;
 	const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
 #ifdef CONFIG_SYS_FSL_DDR3
 	const unsigned int taamax = 20000;
@@ -31,8 +31,7 @@
 #endif
 
 	/* compute the common CAS latency supported between slots */
-	tmp = dimm_params[0].caslat_x;
-	for (i = 1; i < number_of_dimms; i++) {
+	for (i = 0; i < number_of_dimms; i++) {
 		if (dimm_params[i].n_ranks)
 			tmp &= dimm_params[i].caslat_x;
 	}
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index 5beb11b..3b30fa2 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -728,7 +728,12 @@
 
 	/* Choose ddr controller address mirror mode */
 #if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
-	popts->mirrored_dimm = pdimm[0].mirrored_dimm;
+	for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
+		if (pdimm[i].n_ranks) {
+			popts->mirrored_dimm = pdimm[i].mirrored_dimm;
+			break;
+		}
+	}
 #endif
 
 	/* Global Timing Parameters. */