[PATCH 2/2] fsl-ddr: make endianess runtime decision
Sascha Hauer
s.hauer at pengutronix.de
Tue Dec 19 05:18:02 PST 2023
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
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
More information about the barebox
mailing list