[U-Boot] [PATCH] imx: ventana: base SPL MMDC calibration on width and size not board

Tim Harvey tharvey at gateworks.com
Thu Aug 21 08:31:11 CEST 2014


The IMX6 MMDC calibration registers depend on propagation delay and capacitive
loading between the SoC's MMDC and the DDR3 chips. On the Ventana boards the
board layout varies little in trace-lengths such that propagation delays are
irrelevant thus we can simply things by using calibration values obtained
from various board layouts based on a common SoC and DDR chip configuration.

This eliminates board-model from being needed allowing more flexibility. These
values were tested on a large sample size of Gateworks Ventana boards ranging
in layout, and memory configuration over the entire temperature range supported.

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
 board/gateworks/gw_ventana/gw_ventana_spl.c | 189 ++++++++++++++++------------
 1 file changed, 109 insertions(+), 80 deletions(-)

diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c
index e943879..9fc253b 100644
--- a/board/gateworks/gw_ventana/gw_ventana_spl.c
+++ b/board/gateworks/gw_ventana/gw_ventana_spl.c
@@ -201,55 +201,79 @@ static struct mx6_ddr3_cfg mt41k128m16jt_125 = {
 	.trasmin = 3500,
 };
 
-/* GW54xx specific calibration */
-static struct mx6_mmdc_calibration gw54xxq_mmdc_calib = {
+/* MT41K256M16HA-125 */
+static struct mx6_ddr3_cfg mt41k256m16ha_125 = {
+	.mem_speed = 1600,
+	.density = 4,
+	.width = 16,
+	.banks = 8,
+	.rowaddr = 15,
+	.coladdr = 10,
+	.pagesz = 2,
+	.trcd = 1375,
+	.trcmin = 4875,
+	.trasmin = 3500,
+};
+
+/*
+ * calibration - these are the various CPU/DDR3 combinations we support
+ */
+
+static struct mx6_mmdc_calibration mx6dq_128x32_mmdc_calib = {
 	/* write leveling calibration determine */
-	.p0_mpwldectrl0 = 0x00190018,
-	.p0_mpwldectrl1 = 0x0021001D,
-	.p1_mpwldectrl0 = 0x00160027,
-	.p1_mpwldectrl1 = 0x0012001E,
+	.p0_mpwldectrl0 = 0x00190017,
+	.p0_mpwldectrl1 = 0x00140026,
 	/* Read DQS Gating calibration */
-	.p0_mpdgctrl0 = 0x43370346,
-	.p0_mpdgctrl1 = 0x032A0321,
-	.p1_mpdgctrl0 = 0x433A034D,
-	.p1_mpdgctrl1 = 0x032F0235,
+	.p0_mpdgctrl0 = 0x43380347,
+	.p0_mpdgctrl1 = 0x433C034D,
 	/* Read Calibration: DQS delay relative to DQ read access */
 	.p0_mprddlctl = 0x3C313539,
-	.p1_mprddlctl = 0x37333140,
 	/* Write Calibration: DQ/DM delay relative to DQS write access */
-	.p0_mpwrdlctl = 0x37393C38,
-	.p1_mpwrdlctl = 0x42334538,
+	.p0_mpwrdlctl = 0x36393C39,
+};
+
+static struct mx6_mmdc_calibration mx6sdl_128x32_mmdc_calib = {
+	/* write leveling calibration determine */
+	.p0_mpwldectrl0 = 0x003C003C,
+	.p0_mpwldectrl1 = 0x001F002A,
+	/* Read DQS Gating calibration */
+	.p0_mpdgctrl0 = 0x42410244,
+	.p0_mpdgctrl1 = 0x4234023A,
+	/* Read Calibration: DQS delay relative to DQ read access */
+	.p0_mprddlctl = 0x484A4C4B,
+	/* Write Calibration: DQ/DM delay relative to DQS write access */
+	.p0_mpwrdlctl = 0x33342B32,
 };
 
-/* GW53xx specific calibration */
-static struct mx6_mmdc_calibration gw53xxq_mmdc_calib = {
+static struct mx6_mmdc_calibration mx6dq_128x64_mmdc_calib = {
 	/* write leveling calibration determine */
-	.p0_mpwldectrl0 = 0x00160013,
-	.p0_mpwldectrl1 = 0x00090024,
-	.p1_mpwldectrl0 = 0x001F0018,
-	.p1_mpwldectrl1 = 0x000C001C,
+	.p0_mpwldectrl0 = 0x00190017,
+	.p0_mpwldectrl1 = 0x00140026,
+	.p1_mpwldectrl0 = 0x0021001C,
+	.p1_mpwldectrl1 = 0x0011001D,
 	/* Read DQS Gating calibration */
-	.p0_mpdgctrl0 = 0x433A034C,
-	.p0_mpdgctrl1 = 0x0336032F,
-	.p1_mpdgctrl0 = 0x4343034A,
-	.p1_mpdgctrl1 = 0x03370222,
+	.p0_mpdgctrl0 = 0x43380347,
+	.p0_mpdgctrl1 = 0x433C034D,
+	.p1_mpdgctrl0 = 0x032C0324,
+	.p1_mpdgctrl1 = 0x03310232,
 	/* Read Calibration: DQS delay relative to DQ read access */
-	.p0_mprddlctl = 0x3F343638,
-	.p1_mprddlctl = 0x38373442,
+	.p0_mprddlctl = 0x3C313539,
+	.p1_mprddlctl = 0x37343141,
 	/* Write Calibration: DQ/DM delay relative to DQS write access */
-	.p0_mpwrdlctl = 0x343A3E39,
-	.p1_mpwrdlctl = 0x44344239,
+	.p0_mpwrdlctl = 0x36393C39,
+	.p1_mpwrdlctl = 0x42344438,
 };
-static struct mx6_mmdc_calibration gw53xxdl_mmdc_calib = {
+
+static struct mx6_mmdc_calibration mx6sdl_128x64_mmdc_calib = {
 	/* write leveling calibration determine */
 	.p0_mpwldectrl0 = 0x003C003C,
-	.p0_mpwldectrl1 = 0x00330038,
-	.p1_mpwldectrl0 = 0x001F002A,
+	.p0_mpwldectrl1 = 0x001F002A,
+	.p1_mpwldectrl0 = 0x00330038,
 	.p1_mpwldectrl1 = 0x0022003F,
 	/* Read DQS Gating calibration */
 	.p0_mpdgctrl0 = 0x42410244,
-	.p0_mpdgctrl1 = 0x022D022D,
-	.p1_mpdgctrl0 = 0x4234023A,
+	.p0_mpdgctrl1 = 0x4234023A,
+	.p1_mpdgctrl0 = 0x022D022D,
 	.p1_mpdgctrl1 = 0x021C0228,
 	/* Read Calibration: DQS delay relative to DQ read access */
 	.p0_mprddlctl = 0x484A4C4B,
@@ -259,51 +283,42 @@ static struct mx6_mmdc_calibration gw53xxdl_mmdc_calib = {
 	.p1_mpwrdlctl = 0x3933332B,
 };
 
-/* GW52xx specific calibration */
-static struct mx6_mmdc_calibration gw52xxdl_mmdc_calib = {
-	/* write leveling calibration determine */
-	.p0_mpwldectrl0 = 0x0040003F,
-	.p0_mpwldectrl1 = 0x00370037,
-	/* Read DQS Gating calibration */
-	.p0_mpdgctrl0 = 0x42420244,
-	.p0_mpdgctrl1 = 0x022F022F,
-	/* Read Calibration: DQS delay relative to DQ read access */
-	.p0_mprddlctl = 0x49464B4A,
-	/* Write Calibration: DQ/DM delay relative to DQS write access */
-	.p0_mpwrdlctl = 0x32362C32,
-};
-
-/* GW51xx specific calibration */
-static struct mx6_mmdc_calibration gw51xxq_mmdc_calib = {
+static struct mx6_mmdc_calibration mx6dq_256x32_mmdc_calib = {
 	/* write leveling calibration determine */
-	.p0_mpwldectrl0 = 0x00150016,
-	.p0_mpwldectrl1 = 0x001F0017,
+	.p0_mpwldectrl0 = 0x001E001A,
+	.p0_mpwldectrl1 = 0x0026001F,
 	/* Read DQS Gating calibration */
-	.p0_mpdgctrl0 = 0x433D034D,
-	.p0_mpdgctrl1 = 0x033D032F,
+	.p0_mpdgctrl0 = 0x43370349,
+	.p0_mpdgctrl1 = 0x032D0327,
 	/* Read Calibration: DQS delay relative to DQ read access */
-	.p0_mprddlctl = 0x3F313639,
+	.p0_mprddlctl = 0x3D303639,
 	/* Write Calibration: DQ/DM delay relative to DQS write access */
-	.p0_mpwrdlctl = 0x33393F36,
+	.p0_mpwrdlctl = 0x32363934,
 };
 
-static struct mx6_mmdc_calibration gw51xxdl_mmdc_calib = {
+static struct mx6_mmdc_calibration mx6dq_256x64_mmdc_calib = {
 	/* write leveling calibration determine */
-	.p0_mpwldectrl0 = 0x003D003F,
-	.p0_mpwldectrl1 = 0x002F0038,
+	.p0_mpwldectrl0 = 0X00220021,
+	.p0_mpwldectrl1 = 0X00200030,
+	.p1_mpwldectrl0 = 0X002D0027,
+	.p1_mpwldectrl1 = 0X00150026,
 	/* Read DQS Gating calibration */
-	.p0_mpdgctrl0 = 0x423A023A,
-	.p0_mpdgctrl1 = 0x022A0228,
+	.p0_mpdgctrl0 = 0x43330342,
+	.p0_mpdgctrl1 = 0x0339034A,
+	.p1_mpdgctrl0 = 0x032F0325,
+	.p1_mpdgctrl1 = 0x032F022E,
 	/* Read Calibration: DQS delay relative to DQ read access */
-	.p0_mprddlctl = 0x48494C4C,
+	.p0_mprddlctl = 0X3A2E3437,
+	.p1_mprddlctl = 0X35312F3F,
 	/* Write Calibration: DQ/DM delay relative to DQS write access */
-	.p0_mpwrdlctl = 0x34352D31,
+	.p0_mpwrdlctl = 0X33363B37,
+	.p1_mpwrdlctl = 0X40304239,
 };
 
-static void spl_dram_init(int width, int size, int board_model)
+static void spl_dram_init(int width, int size_mb, int board_model)
 {
-	struct mx6_ddr3_cfg *mem = &mt41k128m16jt_125;
-	struct mx6_mmdc_calibration *calib;
+	struct mx6_ddr3_cfg *mem = NULL;
+	struct mx6_mmdc_calibration *calib = NULL;
 	struct mx6_ddr_sysinfo sysinfo = {
 		/* width of data bus:0=16,1=32,2=64 */
 		.dsize = width/32,
@@ -329,29 +344,43 @@ static void spl_dram_init(int width, int size, int board_model)
 	/*
 	 * MMDC Calibration requires the following data:
 	 *   mx6_mmdc_calibration - board-specific calibration (routing delays)
+	 *      these calibration values depend on board routing, SoC, and DDR
 	 *   mx6_ddr_sysinfo - board-specific memory architecture (width/cs/etc)
 	 *   mx6_ddr_cfg - chip specific timing/layout details
 	 */
-	switch (board_model) {
-	default:
-	case GW51xx:
+	if (width == 32 && size_mb == 512) {
+		mem = &mt41k128m16jt_125;
 		if (is_cpu_type(MXC_CPU_MX6Q))
-			calib = &gw51xxq_mmdc_calib;
+			calib = &mx6dq_128x32_mmdc_calib;
 		else
-			calib = &gw51xxdl_mmdc_calib;
-		break;
-	case GW52xx:
-		calib = &gw52xxdl_mmdc_calib;
-		break;
-	case GW53xx:
+			calib = &mx6sdl_128x32_mmdc_calib;
+		debug("2gB density\n");
+	} else if (width == 64 && size_mb == 1024) {
+		mem = &mt41k128m16jt_125;
 		if (is_cpu_type(MXC_CPU_MX6Q))
-			calib = &gw53xxq_mmdc_calib;
+			calib = &mx6dq_128x64_mmdc_calib;
 		else
-			calib = &gw53xxdl_mmdc_calib;
-		break;
-	case GW54xx:
-		calib = &gw54xxq_mmdc_calib;
-		break;
+			calib = &mx6sdl_128x64_mmdc_calib;
+		debug("2gB density\n");
+	} else if (width == 32 && size_mb == 1024) {
+		mem = &mt41k256m16ha_125;
+		if (is_cpu_type(MXC_CPU_MX6Q))
+			calib = &mx6dq_256x32_mmdc_calib;
+		debug("4gB density\n");
+	} else if (width == 64 && size_mb == 2048) {
+		mem = &mt41k256m16ha_125;
+		if (is_cpu_type(MXC_CPU_MX6Q))
+			calib = &mx6dq_256x64_mmdc_calib;
+		debug("4gB density\n");
+	}
+
+	if (!mem) {
+		puts("Error: Invalid Memory Configuration\n");
+		hang();
+	}
+	if (!calib) {
+		puts("Error: Invalid Board Calibration Configuration\n");
+		hang();
 	}
 
 	if (is_cpu_type(MXC_CPU_MX6Q))
-- 
1.8.3.2



More information about the U-Boot mailing list