device/dram/ddr3: improve XMP support

- Fix offsets for supported CAS latencies
- Add support for reading CWL and CMD rate from the profile

Change-Id: Ie4f545ed1df92c146be02f56fea0ca9037478649
Signed-off-by: Dan Elkouby <streetwalkermc@gmail.com>
Reviewed-on: https://review.coreboot.org/25663
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c
index 67f3009..535b48a 100644
--- a/src/device/dram/ddr3.c
+++ b/src/device/dram/ddr3.c
@@ -295,6 +295,11 @@
 	dimm->tRTP = spd[27] * mtb;
 	/* Minimum Four Activate Window Delay Time (tFAWmin) */
 	dimm->tFAW = (((spd[28] & 0x0f) << 8) + spd[29]) * mtb;
+	/* Minimum CAS Write Latency Time (tCWLmin)
+	 * - not present in standard SPD */
+	dimm->tCWL = 0;
+	/* System CMD Rate Mode - not present in standard SPD */
+	dimm->tCMD = 0;
 
 	printram("  FTB timings        :");
 	/* FTB is introduced in SPD revision 1.1 */
@@ -484,7 +489,7 @@
 	/* SDRAM Minimum Cycle Time (tCKmin) */
 	dimm->tCK = xmp[1] * mtb;
 	/* CAS Latencies Supported */
-	dimm->cas_supported = (xmp[9] << 8) + xmp[8];
+	dimm->cas_supported = ((xmp[4] << 8) + xmp[3]) & 0x7fff;
 	/* Minimum CAS Latency Time (tAAmin) */
 	dimm->tAA = xmp[2] * mtb;
 	/* Minimum Write Recovery Time (tWRmin) */
@@ -507,6 +512,10 @@
 	dimm->tRTP = xmp[16] * mtb;
 	/* Minimum Four Activate Window Delay Time (tFAWmin) */
 	dimm->tFAW = (((xmp[18] & 0x0f) << 8) + xmp[19]) * mtb;
+	/* Minimum CAS Write Latency Time (tCWLmin) */
+	dimm->tCWL = xmp[5] * mtb;
+	/* System CMD Rate Mode */
+	dimm->tCMD = xmp[23] * mtb;
 
 	return ret;
 }
@@ -568,6 +577,12 @@
 	print_ns("  tWTRmin           : ", dimm->tWTR);
 	print_ns("  tRTPmin           : ", dimm->tRTP);
 	print_ns("  tFAWmin           : ", dimm->tFAW);
+	/* Those values are only relevant if an XMP profile sets them */
+	if (dimm->tCWL)
+		print_ns("  tCWLmin           : ", dimm->tCWL);
+	if (dimm->tCMD)
+		printk(BIOS_INFO, "  tCMDmin           : %3u\n",
+		       DIV_ROUND_UP(dimm->tCMD, 256));
 }
 
 /*==============================================================================
diff --git a/src/include/device/dram/ddr3.h b/src/include/device/dram/ddr3.h
index 0756095..9a24661 100644
--- a/src/include/device/dram/ddr3.h
+++ b/src/include/device/dram/ddr3.h
@@ -162,6 +162,8 @@
 	u32 tWTR;
 	u32 tRTP;
 	u32 tFAW;
+	u32 tCWL;
+	u16 tCMD;
 
 	u8 reference_card;
 	/* XMP: Module voltage in mV */