[U-Boot] [PATCH 1/3] driver/ddr: Change Freescale ARM DDR driver to support both big and little endian

York Sun yorksun at freescale.com
Mon Feb 10 22:59:42 CET 2014


Initially it was believed the DDR controller on Freescale ARM would have
big endian. But some platform will have little endian.

Signed-off-by: York Sun <yorksun at freescale.com>
---
 README                         |    6 +++
 drivers/ddr/fsl/arm_ddr_gen3.c |  103 ++++++++++++++++++++--------------------
 drivers/ddr/fsl/ctrl_regs.c    |    4 +-
 drivers/ddr/fsl/util.c         |   12 ++---
 include/fsl_ddr.h              |    9 ++++
 5 files changed, 75 insertions(+), 59 deletions(-)

diff --git a/README b/README
index fe48ccd..b1b760a 100644
--- a/README
+++ b/README
@@ -487,6 +487,12 @@ The following options need to be configured:
 		PBI commands can be used to configure SoC before it starts the execution.
 		Please refer doc/README.pblimage for more details
 
+		CONFIG_SYS_FSL_DDR_BE
+		Defines the DDR controller register space as Big Endian
+
+		CONFIG_SYS_FSL_DDR_LE
+		Defines the DDR controller register space as Little Endian
+
 - Intel Monahans options:
 		CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
 
diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c
index bf11390..d4ed9ae 100644
--- a/drivers/ddr/fsl/arm_ddr_gen3.c
+++ b/drivers/ddr/fsl/arm_ddr_gen3.c
@@ -11,6 +11,7 @@
 #include <fsl_ddr_sdram.h>
 #include <asm/processor.h>
 #include <fsl_immap.h>
+#include <fsl_ddr.h>
 
 #if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
 #error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
@@ -63,54 +64,54 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 		goto step2;
 
 	if (regs->ddr_eor)
-		out_be32(&ddr->eor, regs->ddr_eor);
+		ddr_out32(&ddr->eor, regs->ddr_eor);
 	for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
 		if (i == 0) {
-			out_be32(&ddr->cs0_bnds, regs->cs[i].bnds);
-			out_be32(&ddr->cs0_config, regs->cs[i].config);
-			out_be32(&ddr->cs0_config_2, regs->cs[i].config_2);
+			ddr_out32(&ddr->cs0_bnds, regs->cs[i].bnds);
+			ddr_out32(&ddr->cs0_config, regs->cs[i].config);
+			ddr_out32(&ddr->cs0_config_2, regs->cs[i].config_2);
 
 		} else if (i == 1) {
-			out_be32(&ddr->cs1_bnds, regs->cs[i].bnds);
-			out_be32(&ddr->cs1_config, regs->cs[i].config);
-			out_be32(&ddr->cs1_config_2, regs->cs[i].config_2);
+			ddr_out32(&ddr->cs1_bnds, regs->cs[i].bnds);
+			ddr_out32(&ddr->cs1_config, regs->cs[i].config);
+			ddr_out32(&ddr->cs1_config_2, regs->cs[i].config_2);
 
 		} else if (i == 2) {
-			out_be32(&ddr->cs2_bnds, regs->cs[i].bnds);
-			out_be32(&ddr->cs2_config, regs->cs[i].config);
-			out_be32(&ddr->cs2_config_2, regs->cs[i].config_2);
+			ddr_out32(&ddr->cs2_bnds, regs->cs[i].bnds);
+			ddr_out32(&ddr->cs2_config, regs->cs[i].config);
+			ddr_out32(&ddr->cs2_config_2, regs->cs[i].config_2);
 
 		} else if (i == 3) {
-			out_be32(&ddr->cs3_bnds, regs->cs[i].bnds);
-			out_be32(&ddr->cs3_config, regs->cs[i].config);
-			out_be32(&ddr->cs3_config_2, regs->cs[i].config_2);
+			ddr_out32(&ddr->cs3_bnds, regs->cs[i].bnds);
+			ddr_out32(&ddr->cs3_config, regs->cs[i].config);
+			ddr_out32(&ddr->cs3_config_2, regs->cs[i].config_2);
 		}
 	}
 
-	out_be32(&ddr->timing_cfg_3, regs->timing_cfg_3);
-	out_be32(&ddr->timing_cfg_0, regs->timing_cfg_0);
-	out_be32(&ddr->timing_cfg_1, regs->timing_cfg_1);
-	out_be32(&ddr->timing_cfg_2, regs->timing_cfg_2);
-	out_be32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
-	out_be32(&ddr->sdram_mode, regs->ddr_sdram_mode);
-	out_be32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
-	out_be32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
-	out_be32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
-	out_be32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
-	out_be32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
-	out_be32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
-	out_be32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
-	out_be32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
-	out_be32(&ddr->sdram_interval, regs->ddr_sdram_interval);
-	out_be32(&ddr->sdram_data_init, regs->ddr_data_init);
-	out_be32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
-	out_be32(&ddr->init_addr, regs->ddr_init_addr);
-	out_be32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
-
-	out_be32(&ddr->timing_cfg_4, regs->timing_cfg_4);
-	out_be32(&ddr->timing_cfg_5, regs->timing_cfg_5);
-	out_be32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
-	out_be32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
+	ddr_out32(&ddr->timing_cfg_3, regs->timing_cfg_3);
+	ddr_out32(&ddr->timing_cfg_0, regs->timing_cfg_0);
+	ddr_out32(&ddr->timing_cfg_1, regs->timing_cfg_1);
+	ddr_out32(&ddr->timing_cfg_2, regs->timing_cfg_2);
+	ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
+	ddr_out32(&ddr->sdram_mode, regs->ddr_sdram_mode);
+	ddr_out32(&ddr->sdram_mode_2, regs->ddr_sdram_mode_2);
+	ddr_out32(&ddr->sdram_mode_3, regs->ddr_sdram_mode_3);
+	ddr_out32(&ddr->sdram_mode_4, regs->ddr_sdram_mode_4);
+	ddr_out32(&ddr->sdram_mode_5, regs->ddr_sdram_mode_5);
+	ddr_out32(&ddr->sdram_mode_6, regs->ddr_sdram_mode_6);
+	ddr_out32(&ddr->sdram_mode_7, regs->ddr_sdram_mode_7);
+	ddr_out32(&ddr->sdram_mode_8, regs->ddr_sdram_mode_8);
+	ddr_out32(&ddr->sdram_md_cntl, regs->ddr_sdram_md_cntl);
+	ddr_out32(&ddr->sdram_interval, regs->ddr_sdram_interval);
+	ddr_out32(&ddr->sdram_data_init, regs->ddr_data_init);
+	ddr_out32(&ddr->sdram_clk_cntl, regs->ddr_sdram_clk_cntl);
+	ddr_out32(&ddr->init_addr, regs->ddr_init_addr);
+	ddr_out32(&ddr->init_ext_addr, regs->ddr_init_ext_addr);
+
+	ddr_out32(&ddr->timing_cfg_4, regs->timing_cfg_4);
+	ddr_out32(&ddr->timing_cfg_5, regs->timing_cfg_5);
+	ddr_out32(&ddr->ddr_zq_cntl, regs->ddr_zq_cntl);
+	ddr_out32(&ddr->ddr_wrlvl_cntl, regs->ddr_wrlvl_cntl);
 #ifndef CONFIG_SYS_FSL_DDR_EMU
 	/*
 	 * Skip these two registers if running on emulator
@@ -118,23 +119,23 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
 	 */
 
 	if (regs->ddr_wrlvl_cntl_2)
-		out_be32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
+		ddr_out32(&ddr->ddr_wrlvl_cntl_2, regs->ddr_wrlvl_cntl_2);
 	if (regs->ddr_wrlvl_cntl_3)
-		out_be32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
+		ddr_out32(&ddr->ddr_wrlvl_cntl_3, regs->ddr_wrlvl_cntl_3);
 #endif
 
-	out_be32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
-	out_be32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
-	out_be32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
-	out_be32(&ddr->ddr_cdr1, regs->ddr_cdr1);
-	out_be32(&ddr->ddr_cdr2, regs->ddr_cdr2);
-	out_be32(&ddr->err_disable, regs->err_disable);
-	out_be32(&ddr->err_int_en, regs->err_int_en);
+	ddr_out32(&ddr->ddr_sr_cntr, regs->ddr_sr_cntr);
+	ddr_out32(&ddr->ddr_sdram_rcw_1, regs->ddr_sdram_rcw_1);
+	ddr_out32(&ddr->ddr_sdram_rcw_2, regs->ddr_sdram_rcw_2);
+	ddr_out32(&ddr->ddr_cdr1, regs->ddr_cdr1);
+	ddr_out32(&ddr->ddr_cdr2, regs->ddr_cdr2);
+	ddr_out32(&ddr->err_disable, regs->err_disable);
+	ddr_out32(&ddr->err_int_en, regs->err_int_en);
 	for (i = 0; i < 32; i++) {
 		if (regs->debug[i]) {
 			debug("Write to debug_%d as %08x\n", i + 1,
 			      regs->debug[i]);
-			out_be32(&ddr->debug[i], regs->debug[i]);
+			ddr_out32(&ddr->debug[i], regs->debug[i]);
 		}
 	}
 
@@ -155,7 +156,7 @@ step2:
 	/* Set, but do not enable the memory */
 	temp_sdram_cfg = regs->ddr_sdram_cfg;
 	temp_sdram_cfg &= ~(SDRAM_CFG_MEM_EN);
-	out_be32(&ddr->sdram_cfg, temp_sdram_cfg);
+	ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg);
 
 	/*
 	 * 500 painful micro-seconds must elapse between
@@ -167,8 +168,8 @@ step2:
 	asm volatile("dsb sy;isb");
 
 	/* Let the controller go */
-	temp_sdram_cfg = in_be32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
-	out_be32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
+	temp_sdram_cfg = ddr_in32(&ddr->sdram_cfg) & ~SDRAM_CFG_BI;
+	ddr_out32(&ddr->sdram_cfg, temp_sdram_cfg | SDRAM_CFG_MEM_EN);
 	asm volatile("dsb sy;isb");
 
 	total_gb_size_per_controller = 0;
@@ -202,7 +203,7 @@ step2:
 	debug("Need to wait up to %d * 10ms\n", timeout);
 
 	/* Poll DDR_SDRAM_CFG_2[D_INIT] bit until auto-data init is done.  */
-	while ((in_be32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
+	while ((ddr_in32(&ddr->sdram_cfg_2) & SDRAM_CFG2_D_INIT) &&
 		(timeout >= 0)) {
 		udelay(10000);		/* throttle polling rate */
 		timeout--;
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 6bf22cf..5acbc73 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -25,8 +25,8 @@ static u32 fsl_ddr_get_version(void)
 	u32 ver_major_minor_errata;
 
 	ddr = (void *)_DDR_ADDR;
-	ver_major_minor_errata = (in_be32(&ddr->ip_rev1) & 0xFFFF) << 8;
-	ver_major_minor_errata |= (in_be32(&ddr->ip_rev2) & 0xFF00) >> 8;
+	ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
+	ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
 
 	return ver_major_minor_errata;
 }
diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c
index 0658261..450a488 100644
--- a/drivers/ddr/fsl/util.c
+++ b/drivers/ddr/fsl/util.c
@@ -146,21 +146,21 @@ void board_add_ram_info(int use_default)
 	u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
 #endif
 #if (CONFIG_NUM_DDR_CONTROLLERS > 1)
-	uint32_t cs0_config = in_be32(&ddr->cs0_config);
+	uint32_t cs0_config = ddr_in32(&ddr->cs0_config);
 #endif
-	uint32_t sdram_cfg = in_be32(&ddr->sdram_cfg);
+	uint32_t sdram_cfg = ddr_in32(&ddr->sdram_cfg);
 	int cas_lat;
 
 #if CONFIG_NUM_DDR_CONTROLLERS >= 2
 	if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
 		ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR;
-		sdram_cfg = in_be32(&ddr->sdram_cfg);
+		sdram_cfg = ddr_in32(&ddr->sdram_cfg);
 	}
 #endif
 #if CONFIG_NUM_DDR_CONTROLLERS >= 3
 	if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
 		ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR;
-		sdram_cfg = in_be32(&ddr->sdram_cfg);
+		sdram_cfg = ddr_in32(&ddr->sdram_cfg);
 	}
 #endif
 	puts(" (DDR");
@@ -188,8 +188,8 @@ void board_add_ram_info(int use_default)
 		puts(", 64-bit");
 
 	/* Calculate CAS latency based on timing cfg values */
-	cas_lat = ((in_be32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1;
-	if ((in_be32(&ddr->timing_cfg_3) >> 12) & 1)
+	cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf) + 1;
+	if ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 1)
 		cas_lat += (8 << 1);
 	printf(", CL=%d", cas_lat >> 1);
 	if (cas_lat & 0x1)
diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h
index e03f9db..72c0b2e 100644
--- a/include/fsl_ddr.h
+++ b/include/fsl_ddr.h
@@ -14,6 +14,14 @@
 
 #include <common_timing_params.h>
 
+#ifdef CONFIG_SYS_FSL_DDR_LE
+#define ddr_in32(a)	in_le32(a)
+#define ddr_out32(a, v)	out_le32(a, v)
+#else
+#define ddr_in32(a)	in_be32(a)
+#define ddr_out32(a, v)	out_be32(a, v)
+#endif
+
 #if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
 /*
  * Bind the main DDR setup driver's generic names
@@ -93,6 +101,7 @@ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
 
 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 unsigned int check_fsl_memctl_config_regs(const fsl_ddr_cfg_regs_t *ddr);
+void board_add_ram_info(int use_default);
 
 /* processor specific function */
 void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
-- 
1.7.9.5




More information about the U-Boot mailing list