From 4e5b1bd0dff216b00d7ce9a5201dfe173805a06c Mon Sep 17 00:00:00 2001 From: York Sun Date: Mon, 10 Feb 2014 13:59:42 -0800 Subject: [PATCH] driver/ddr: Change Freescale ARM DDR driver to support both big and little endian 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 --- README | 6 ++ drivers/ddr/fsl/arm_ddr_gen3.c | 101 +++++++++++++++++---------------- drivers/ddr/fsl/ctrl_regs.c | 4 +- drivers/ddr/fsl/util.c | 12 ++-- include/fsl_ddr.h | 9 +++ 5 files changed, 74 insertions(+), 58 deletions(-) diff --git a/README b/README index 6668631bcc..413d682829 100644 --- a/README +++ b/README @@ -486,6 +486,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 bf113908fd..d4ed9aec2a 100644 --- a/drivers/ddr/fsl/arm_ddr_gen3.c +++ b/drivers/ddr/fsl/arm_ddr_gen3.c @@ -11,6 +11,7 @@ #include #include #include +#include #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); + 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); - 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_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 6bf22cfbd6..5acbc737ba 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 0658261d8d..450a488712 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 e03f9db5f2..72c0b2e94e 100644 --- a/include/fsl_ddr.h +++ b/include/fsl_ddr.h @@ -14,6 +14,14 @@ #include +#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,