
It is going to be useful in more than one place.
Signed-off-by: Siarhei Siamashka siarhei.siamashka@gmail.com --- arch/arm/cpu/armv7/sunxi/dram.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 18a5c3b..49d1770 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -115,23 +115,31 @@ static void mctl_enable_dll0(u32 phase) udelay(22); }
+/* Get the number of DDR byte lanes */ +static u32 mctl_get_number_of_lanes(void) +{ + struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; + switch (readl(&dram->dcr) & DRAM_DCR_BUS_WIDTH_MASK) { + case DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT): + return 4; + case DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_16BIT): + return 2; + default: + return 1; + } +} + /* * Note: This differs from pm/standby in that it checks the bus width */ static void mctl_enable_dllx(u32 phase) { struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE; - u32 i, n, bus_width; - - bus_width = readl(&dram->dcr); + u32 i, number_of_lanes;
- if ((bus_width & DRAM_DCR_BUS_WIDTH_MASK) == - DRAM_DCR_BUS_WIDTH(DRAM_DCR_BUS_WIDTH_32BIT)) - n = DRAM_DCR_NR_DLLCR_32BIT; - else - n = DRAM_DCR_NR_DLLCR_16BIT; + number_of_lanes = mctl_get_number_of_lanes();
- for (i = 1; i < n; i++) { + for (i = 1; i <= number_of_lanes; i++) { clrsetbits_le32(&dram->dllcr[i], 0xf << 14, (phase & 0xf) << 14); clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET, @@ -140,12 +148,12 @@ static void mctl_enable_dllx(u32 phase) } udelay(2);
- for (i = 1; i < n; i++) + for (i = 1; i <= number_of_lanes; i++) clrbits_le32(&dram->dllcr[i], DRAM_DLLCR_NRESET | DRAM_DLLCR_DISABLE); udelay(22);
- for (i = 1; i < n; i++) + for (i = 1; i <= number_of_lanes; i++) clrsetbits_le32(&dram->dllcr[i], DRAM_DLLCR_DISABLE, DRAM_DLLCR_NRESET); udelay(22);