powerpc/mpc8xxx: Add x4 DDR device support

On selected platforms, x4 DDR devices can be supported. Using x4 devices may
lower the performance, but generally they are available for higher density.

Tested on MT36JSF2G72PZ-1G9E1 RDIMM.

Signed-off-by: York Sun <yorksun@freescale.com>
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
index b5e4070..bf5a6f2 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ctrl_regs.c
@@ -681,6 +681,7 @@
 	unsigned int odt_cfg = 0;	/* ODT configuration */
 	unsigned int num_pr;		/* Number of posted refreshes */
 	unsigned int slow = 0;		/* DDR will be run less than 1250 */
+	unsigned int x4_en = 0;		/* x4 DRAM enable */
 	unsigned int obc_cfg;		/* On-The-Fly Burst Chop Cfg */
 	unsigned int ap_en;		/* Address Parity Enable */
 	unsigned int d_init;		/* DRAM data initialization */
@@ -725,6 +726,8 @@
 		ap_en = 0;
 	}
 
+	x4_en = popts->x4_en ? 1 : 0;
+
 #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
 	/* Use the DDR controller to auto initialize memory. */
 	d_init = popts->ECC_init_using_memctl;
@@ -747,6 +750,7 @@
 		| ((odt_cfg & 0x3) << 21)
 		| ((num_pr & 0xf) << 12)
 		| ((slow & 1) << 11)
+		| (x4_en << 10)
 		| (qd_en << 9)
 		| (unq_mrs_en << 8)
 		| ((obc_cfg & 0x1) << 6)
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c
index 3e7c269..b67158c 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/ddr3_dimm_params.c
@@ -129,6 +129,7 @@
 		pdimm->ec_sdram_width = 0;
 	pdimm->data_width = pdimm->primary_sdram_width
 			  + pdimm->ec_sdram_width;
+	pdimm->device_width = 1 << ((spd->organization & 0x7) + 2);
 
 	/* These are the types defined by the JEDEC DDR3 SPD spec */
 	pdimm->mirrored_dimm = 0;
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c
index 1ed6c77..260fce5 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/interactive.c
@@ -205,6 +205,7 @@
 		DIMM_PARM(primary_sdram_width),
 		DIMM_PARM(ec_sdram_width),
 		DIMM_PARM(registered_dimm),
+		DIMM_PARM(device_width),
 
 		DIMM_PARM(n_row_addr),
 		DIMM_PARM(n_col_addr),
@@ -263,6 +264,7 @@
 		DIMM_PARM(primary_sdram_width),
 		DIMM_PARM(ec_sdram_width),
 		DIMM_PARM(registered_dimm),
+		DIMM_PARM(device_width),
 
 		DIMM_PARM(n_row_addr),
 		DIMM_PARM(n_col_addr),
@@ -443,6 +445,7 @@
 		CTRL_OPTIONS(twoT_en),
 		CTRL_OPTIONS(threeT_en),
 		CTRL_OPTIONS(ap_en),
+		CTRL_OPTIONS(x4_en),
 		CTRL_OPTIONS(bstopre),
 		CTRL_OPTIONS(wrlvl_override),
 		CTRL_OPTIONS(wrlvl_sample),
@@ -687,6 +690,7 @@
 		CTRL_OPTIONS(threeT_en),
 		CTRL_OPTIONS(registered_dimm_en),
 		CTRL_OPTIONS(ap_en),
+		CTRL_OPTIONS(x4_en),
 		CTRL_OPTIONS(bstopre),
 		CTRL_OPTIONS(wrlvl_override),
 		CTRL_OPTIONS(wrlvl_sample),
diff --git a/arch/powerpc/cpu/mpc8xxx/ddr/options.c b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
index 26369e0..30cdca4 100644
--- a/arch/powerpc/cpu/mpc8xxx/ddr/options.c
+++ b/arch/powerpc/cpu/mpc8xxx/ddr/options.c
@@ -700,6 +700,8 @@
 	}
 #endif
 
+	popts->x4_en = (pdimm[0].device_width == 4) ? 1 : 0;
+
 	/* Choose burst length. */
 #if defined(CONFIG_FSL_DDR3)
 #if defined(CONFIG_E500MC)