All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/4] drivers/ddr/fsl: Update DDR driver for DDR4
@ 2015-03-19 16:30 York Sun
  2015-03-19 16:30 ` [U-Boot] [PATCH 2/4] driver/ddr/fsl: Fix driver to support empty first slot York Sun
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: York Sun @ 2015-03-19 16:30 UTC (permalink / raw)
  To: u-boot

Add/update registers for DDR4, including DQ mappings. Allow raw timing
method used for all controllers. Update mode_9 register to 0x500 for
improved stability. Check DDR controller version number individually
in case a SoC has multiple DDR controllers of different versions.
Increase read-write turnaround for DDR4 high speeds.

Signed-off-by: York Sun <yorksun@freescale.com>
---
 drivers/ddr/fsl/ctrl_regs.c   |   17 ++++++++++----
 drivers/ddr/fsl/interactive.c |   51 ++++++++++++++++++++++++++++++++++++++++-
 drivers/ddr/fsl/main.c        |    2 +-
 drivers/ddr/fsl/util.c        |   28 +++++++++++++++++++---
 include/fsl_ddr.h             |    4 +---
 5 files changed, 89 insertions(+), 13 deletions(-)

diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 690e73d..9ccddef 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -313,7 +313,10 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
 #ifdef CONFIG_SYS_FSL_DDR4
 	/* tXP=max(4nCK, 6ns) */
 	int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
-	trwt_mclk = 2;
+	unsigned int data_rate = get_ddr_freq(ctrl_num);
+
+	/* for faster clock, need more time for data setup */
+	trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2;
 	twrt_mclk = 1;
 	act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
 	pre_pd_exit_mclk = act_pd_exit_mclk;
@@ -338,7 +341,7 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
 	 */
 	txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
 
-	ip_rev = fsl_ddr_get_version();
+	ip_rev = fsl_ddr_get_version(ctrl_num);
 	if (ip_rev >= 0x40700) {
 		/*
 		 * MRS_CYC = max(tMRD, tMOD)
@@ -544,7 +547,7 @@ static void set_timing_cfg_1(const unsigned int ctrl_num,
 	 * we need set extend bit for it at
 	 * TIMING_CFG_3[EXT_CASLAT]
 	 */
-	if (fsl_ddr_get_version() <= 0x40400)
+	if (fsl_ddr_get_version(ctrl_num) <= 0x40400)
 		caslat_ctrl = 2 * cas_latency - 1;
 	else
 		caslat_ctrl = (cas_latency - 1) << 1;
@@ -1114,12 +1117,16 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
 	unsigned short esdmode4 = 0;	/* Extended SDRAM mode 4 */
 	unsigned short esdmode5;	/* Extended SDRAM mode 5 */
 
-	esdmode5 = 0x00000400;		/* Data mask enabled */
+	esdmode5 = 0x00000500;		/* Data mask enabled */
 
 	ddr->ddr_sdram_mode_9 = (0
 				 | ((esdmode4 & 0xffff) << 16)
 				 | ((esdmode5 & 0xffff) << 0)
 				);
+
+	/* 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++) {
@@ -2349,7 +2356,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
 	set_ddr_cdr1(ddr, popts);
 	set_ddr_cdr2(ddr, popts);
 	set_ddr_sdram_cfg(ddr, popts, common_dimm);
-	ip_rev = fsl_ddr_get_version();
+	ip_rev = fsl_ddr_get_version(ctrl_num);
 	if (ip_rev > 0x40400)
 		unq_mrs_en = 1;
 
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 32ba6d8..57d14e8 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -205,6 +205,8 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 
 #define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \
 	sizeof((dimm_params_t *)0)->x, 0}
+#define DIMM_PARM_HEX(x) {#x, offsetof(dimm_params_t, x), \
+	sizeof((dimm_params_t *)0)->x, 1}
 
 static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 				   unsigned int ctrl_num,
@@ -220,6 +222,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 		DIMM_PARM(primary_sdram_width),
 		DIMM_PARM(ec_sdram_width),
 		DIMM_PARM(registered_dimm),
+		DIMM_PARM(mirrored_dimm),
 		DIMM_PARM(device_width),
 
 		DIMM_PARM(n_row_addr),
@@ -274,7 +277,27 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
 		DIMM_PARM(tdqsq_max_ps),
 		DIMM_PARM(tqhs_ps),
 #endif
-
+#ifdef CONFIG_SYS_FSL_DDR4
+		DIMM_PARM_HEX(dq_mapping[0]),
+		DIMM_PARM_HEX(dq_mapping[1]),
+		DIMM_PARM_HEX(dq_mapping[2]),
+		DIMM_PARM_HEX(dq_mapping[3]),
+		DIMM_PARM_HEX(dq_mapping[4]),
+		DIMM_PARM_HEX(dq_mapping[5]),
+		DIMM_PARM_HEX(dq_mapping[6]),
+		DIMM_PARM_HEX(dq_mapping[7]),
+		DIMM_PARM_HEX(dq_mapping[8]),
+		DIMM_PARM_HEX(dq_mapping[9]),
+		DIMM_PARM_HEX(dq_mapping[10]),
+		DIMM_PARM_HEX(dq_mapping[11]),
+		DIMM_PARM_HEX(dq_mapping[12]),
+		DIMM_PARM_HEX(dq_mapping[13]),
+		DIMM_PARM_HEX(dq_mapping[14]),
+		DIMM_PARM_HEX(dq_mapping[15]),
+		DIMM_PARM_HEX(dq_mapping[16]),
+		DIMM_PARM_HEX(dq_mapping[17]),
+		DIMM_PARM(dq_mapping_ors),
+#endif
 		DIMM_PARM(rank_density),
 		DIMM_PARM(capacity),
 		DIMM_PARM(base_address),
@@ -296,6 +319,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
 		DIMM_PARM(primary_sdram_width),
 		DIMM_PARM(ec_sdram_width),
 		DIMM_PARM(registered_dimm),
+		DIMM_PARM(mirrored_dimm),
 		DIMM_PARM(device_width),
 
 		DIMM_PARM(n_row_addr),
@@ -314,6 +338,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
 		DIMM_PARM(tckmax_ps),
 
 		DIMM_PARM(caslat_x),
+		DIMM_PARM_HEX(caslat_x),
 		DIMM_PARM(taa_ps),
 		DIMM_PARM(caslat_x_minus_1),
 		DIMM_PARM(caslat_x_minus_2),
@@ -322,6 +347,9 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
 		DIMM_PARM(trcd_ps),
 		DIMM_PARM(trp_ps),
 		DIMM_PARM(tras_ps),
+#if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
+		DIMM_PARM(tfaw_ps),
+#endif
 #ifdef CONFIG_SYS_FSL_DDR4
 		DIMM_PARM(trfc1_ps),
 		DIMM_PARM(trfc2_ps),
@@ -347,6 +375,27 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
 		DIMM_PARM(tdqsq_max_ps),
 		DIMM_PARM(tqhs_ps),
 #endif
+#ifdef CONFIG_SYS_FSL_DDR4
+		DIMM_PARM_HEX(dq_mapping[0]),
+		DIMM_PARM_HEX(dq_mapping[1]),
+		DIMM_PARM_HEX(dq_mapping[2]),
+		DIMM_PARM_HEX(dq_mapping[3]),
+		DIMM_PARM_HEX(dq_mapping[4]),
+		DIMM_PARM_HEX(dq_mapping[5]),
+		DIMM_PARM_HEX(dq_mapping[6]),
+		DIMM_PARM_HEX(dq_mapping[7]),
+		DIMM_PARM_HEX(dq_mapping[8]),
+		DIMM_PARM_HEX(dq_mapping[9]),
+		DIMM_PARM_HEX(dq_mapping[10]),
+		DIMM_PARM_HEX(dq_mapping[11]),
+		DIMM_PARM_HEX(dq_mapping[12]),
+		DIMM_PARM_HEX(dq_mapping[13]),
+		DIMM_PARM_HEX(dq_mapping[14]),
+		DIMM_PARM_HEX(dq_mapping[15]),
+		DIMM_PARM_HEX(dq_mapping[16]),
+		DIMM_PARM_HEX(dq_mapping[17]),
+		DIMM_PARM(dq_mapping_ors),
+#endif
 	};
 	static const unsigned int n_opts = ARRAY_SIZE(options);
 
diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c
index b72b242..fa22383 100644
--- a/drivers/ddr/fsl/main.c
+++ b/drivers/ddr/fsl/main.c
@@ -453,7 +453,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
 				retval = compute_dimm_parameters(
 							i, spd, pdimm, j);
 #ifdef CONFIG_SYS_DDR_RAW_TIMING
-				if (!i && !j && retval) {
+				if (!j && retval) {
 					printf("SPD error on controller %d! "
 					"Trying fallback to raw timing "
 					"calculation\n", i);
diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c
index 664081b..ce55aea 100644
--- a/drivers/ddr/fsl/util.c
+++ b/drivers/ddr/fsl/util.c
@@ -23,12 +23,34 @@
 
 #define ULL_8FS 0xFFFFFFFFULL
 
-u32 fsl_ddr_get_version(void)
+u32 fsl_ddr_get_version(unsigned int ctrl_num)
 {
 	struct ccsr_ddr __iomem *ddr;
 	u32 ver_major_minor_errata;
 
-	ddr = (void *)_DDR_ADDR;
+	switch (ctrl_num) {
+	case 0:
+		ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+		break;
+#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+	case 1:
+		ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+		break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+	case 2:
+		ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+		break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+	case 3:
+		ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+		break;
+#endif
+	default:
+		printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
+		return 0;
+	}
 	ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
 	ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
 
@@ -212,7 +234,7 @@ void print_ddr_info(unsigned int start_ctrl)
 
 	/* Calculate CAS latency based on timing cfg values */
 	cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
-	if (fsl_ddr_get_version() <= 0x40400)
+	if (fsl_ddr_get_version(0) <= 0x40400)
 		cas_lat += 1;
 	else
 		cas_lat += 2;
diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h
index feccef9..4099a74 100644
--- a/include/fsl_ddr.h
+++ b/include/fsl_ddr.h
@@ -34,9 +34,7 @@
 #define ddr_clrsetbits32(a, clear, set)	clrsetbits_be32(a, clear, set)
 #endif
 
-#define _DDR_ADDR CONFIG_SYS_FSL_DDR_ADDR
-
-u32 fsl_ddr_get_version(void);
+u32 fsl_ddr_get_version(unsigned int ctrl_num);
 
 #if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
 /*
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-04-23 23:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-19 16:30 [U-Boot] [PATCH 1/4] drivers/ddr/fsl: Update DDR driver for DDR4 York Sun
2015-03-19 16:30 ` [U-Boot] [PATCH 2/4] driver/ddr/fsl: Fix driver to support empty first slot York Sun
2015-03-19 16:30 ` [U-Boot] [PATCH 3/4] driver/ddr/fsl: Add built-in memory test for DDR4 driver York Sun
2015-03-19 16:30 ` [U-Boot] [PATCH 4/4] driver/ddr/fsl: Add workaround for DDR erratum A008511 York Sun
2015-04-23 23:38 ` [U-Boot] [PATCH 1/4] drivers/ddr/fsl: Update DDR driver for DDR4 York Sun

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.