Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- arch/arm/boards/ls1021aiot/lowlevel.c | 2 +- arch/arm/boards/ls1046ardb/lowlevel.c | 2 +- arch/arm/boards/tqmls1046a/lowlevel.c | 2 +- drivers/ddr/fsl/arm_ddr_gen3.c | 7 ++- drivers/ddr/fsl/fsl_ddr_gen4.c | 7 ++- drivers/ddr/fsl/main.c | 13 ++++-- include/soc/fsl/fsl_ddr_sdram.h | 65 ++++++++++++++++++++------- 7 files changed, 74 insertions(+), 24 deletions(-) diff --git a/arch/arm/boards/ls1021aiot/lowlevel.c b/arch/arm/boards/ls1021aiot/lowlevel.c index f255c425b7..6bba528635 100644 --- a/arch/arm/boards/ls1021aiot/lowlevel.c +++ b/arch/arm/boards/ls1021aiot/lowlevel.c @@ -91,7 +91,7 @@ static noinline __noreturn void ls1021aiot_r_entry(void) udelay(500); putc_ll('>'); - fsl_ddr_set_memctl_regs(&ddrc[0], 0); + fsl_ddr_set_memctl_regs(&ddrc[0], 0, false); ls1021a_errata_post_ddr(); diff --git a/arch/arm/boards/ls1046ardb/lowlevel.c b/arch/arm/boards/ls1046ardb/lowlevel.c index e7544df86a..408e6017f6 100644 --- a/arch/arm/boards/ls1046ardb/lowlevel.c +++ b/arch/arm/boards/ls1046ardb/lowlevel.c @@ -209,7 +209,7 @@ static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize) goto err; } - memsize = fsl_ddr_sdram(&ls1046a_info); + memsize = fsl_ddr_sdram(&ls1046a_info, false); ls1046a_errata_post_ddr(); diff --git a/arch/arm/boards/tqmls1046a/lowlevel.c b/arch/arm/boards/tqmls1046a/lowlevel.c index dc64762433..6a5ad1f83a 100644 --- a/arch/arm/boards/tqmls1046a/lowlevel.c +++ b/arch/arm/boards/tqmls1046a/lowlevel.c @@ -108,7 +108,7 @@ static noinline __noreturn void tqmls1046a_r_entry(void) udelay(500); putc_ll('>'); - fsl_ddr_set_memctl_regs(&ddrc[0], 0); + fsl_ddr_set_memctl_regs(&ddrc[0], 0, false); ls1046a_errata_post_ddr(); diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c index a8b96f1261..1cbdb1446f 100644 --- a/drivers/ddr/fsl/arm_ddr_gen3.c +++ b/drivers/ddr/fsl/arm_ddr_gen3.c @@ -21,7 +21,7 @@ * Dividing the initialization to two steps to deassert DDR reset signal * to comply with JEDEC specs for RDIMMs. */ -void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step) +void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step, bool little_endian) { struct ccsr_ddr __iomem *ddr = c->base; const fsl_ddr_cfg_regs_t *regs = &c->fsl_ddr_config_reg; @@ -30,6 +30,11 @@ void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step) u32 total_gb_size_per_controller; int timeout; + if (little_endian) + ddr_endianess = DDR_ENDIANESS_LE; + else + ddr_endianess = DDR_ENDIANESS_BE; + if (step == 2) goto step2; diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index 147ff9916d..19aa4f22a9 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -36,7 +36,7 @@ static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits) * Dividing the initialization to two steps to deassert DDR reset signal * to comply with JEDEC specs for RDIMMs. */ -void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step) +void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step, bool little_endian) { struct ccsr_ddr __iomem *ddr = c->base; const fsl_ddr_cfg_regs_t *regs = &c->fsl_ddr_config_reg; @@ -53,6 +53,11 @@ void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step) u32 cs0_bnds, cs1_bnds, cs2_bnds, cs3_bnds, cs0_config; mod_bnds = regs->cs[0].config & CTLR_INTLV_MASK; + if (little_endian) + ddr_endianess = DDR_ENDIANESS_LE; + else + ddr_endianess = DDR_ENDIANESS_BE; + if (step == 2) goto step2; diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index c05f6d52fb..27303fec7e 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -13,6 +13,8 @@ #include <linux/log2.h> #include "fsl_ddr.h" +enum ddr_endianess ddr_endianess; + /* * ASSUMPTIONS: * - Same number of CONFIG_DIMM_SLOTS_PER_CTLR on each controller @@ -378,12 +380,17 @@ static unsigned long long fsl_ddr_compute(struct fsl_ddr_info *pinfo) return total_mem; } -phys_size_t fsl_ddr_sdram(struct fsl_ddr_info *pinfo) +phys_size_t fsl_ddr_sdram(struct fsl_ddr_info *pinfo, bool little_endian) { unsigned int i; unsigned long long total_memory; int deassert_reset = 0; + if (little_endian) + ddr_endianess = DDR_ENDIANESS_LE; + else + ddr_endianess = DDR_ENDIANESS_BE; + total_memory = fsl_ddr_compute(pinfo); /* setup 3-way interleaving before enabling DDRC */ @@ -428,14 +435,14 @@ phys_size_t fsl_ddr_sdram(struct fsl_ddr_info *pinfo) * The following call with step = 1 returns before enabling * the controller. It has to finish with step = 2 later. */ - fsl_ddr_set_memctl_regs(c, deassert_reset ? 1 : 0); + fsl_ddr_set_memctl_regs(c, deassert_reset ? 1 : 0, little_endian); } if (deassert_reset) { for (i = 0; i < pinfo->num_ctrls; i++) { struct fsl_ddr_controller *c = &pinfo->c[i]; /* Call with step = 2 to continue initialization */ - fsl_ddr_set_memctl_regs(c, 2); + fsl_ddr_set_memctl_regs(c, 2, little_endian); } } diff --git a/include/soc/fsl/fsl_ddr_sdram.h b/include/soc/fsl/fsl_ddr_sdram.h index 23f0816599..c20bc027fe 100644 --- a/include/soc/fsl/fsl_ddr_sdram.h +++ b/include/soc/fsl/fsl_ddr_sdram.h @@ -449,21 +449,54 @@ struct fsl_ddr_info { unsigned long long mem_base; }; -phys_size_t fsl_ddr_sdram(struct fsl_ddr_info *pinfo); -void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step); - -#ifdef CONFIG_SYS_FSL_DDR_LE -#define ddr_in32(a) in_le32(a) -#define ddr_out32(a, v) out_le32(a, v) -#define ddr_setbits32(a, v) setbits_le32(a, v) -#define ddr_clrbits32(a, v) clrbits_le32(a, v) -#define ddr_clrsetbits32(a, clear, set) clrsetbits_le32(a, clear, set) -#else -#define ddr_in32(a) in_be32(a) -#define ddr_out32(a, v) out_be32(a, v) -#define ddr_setbits32(a, v) setbits_be32(a, v) -#define ddr_clrbits32(a, v) clrbits_be32(a, v) -#define ddr_clrsetbits32(a, clear, set) clrsetbits_be32(a, clear, set) -#endif +phys_size_t fsl_ddr_sdram(struct fsl_ddr_info *pinfo, bool little_endian); +void fsl_ddr_set_memctl_regs(struct fsl_ddr_controller *c, int step, bool little_endian); + +enum ddr_endianess { + DDR_ENDIANESS_LE, + DDR_ENDIANESS_BE, +}; + +extern enum ddr_endianess ddr_endianess; + +static inline u32 ddr_in32(void __iomem *reg) +{ + if (ddr_endianess == DDR_ENDIANESS_LE) + return in_le32(reg); + else + return in_be32(reg); +} + +static inline void ddr_out32(void __iomem *reg, u32 val) +{ + if (ddr_endianess == DDR_ENDIANESS_LE) + out_le32(reg, val); + else + out_be32(reg, val); +} + +static inline void ddr_setbits32(void __iomem *reg, u32 set) +{ + if (ddr_endianess == DDR_ENDIANESS_LE) + setbits_le32(reg, set); + else + setbits_be32(reg, set); +} + +static inline void ddr_clrbits32(void __iomem *reg, u32 clr) +{ + if (ddr_endianess == DDR_ENDIANESS_LE) + clrbits_le32(reg, clr); + else + clrbits_be32(reg, clr); +} + +static inline void ddr_clrsetbits32(void __iomem *reg, u32 clr, u32 set) +{ + if (ddr_endianess == DDR_ENDIANESS_LE) + clrsetbits_le32(reg, clr, set); + else + clrsetbits_be32(reg, clr, set); +} #endif -- 2.39.2