Signed-off-by: Mikhail Kalashnikov
From: iuncuim
>
> The H616 SoC has support for several types of DRAM: DDR3, LPDDR3,
> DDR4 and LPDDR4.
> At the moment, the driver only supports DDR3 memory.
> Let's extend the driver to support the LPDDR3 memory. All "magic"
> values obtained from the boot0.
> ---
> .../include/asm/arch-sunxi/dram_sun50i_h616.h | 1 +
> arch/arm/mach-sunxi/Kconfig | 10 +-
> arch/arm/mach-sunxi/dram_sun50i_h616.c| 215 --
> arch/arm/mach-sunxi/dram_timings/Makefile | 1 +
> .../arm/mach-sunxi/dram_timings/h616_lpddr3.c | 95
> 5 files changed, 255 insertions(+), 67 deletions(-)
> create mode 100644 arch/arm/mach-sunxi/dram_timings/h616_lpddr3.c
>
> diff --git a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> index 6db869c098..bf4188fa89 100644
> --- a/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> +++ b/arch/arm/include/asm/arch-sunxi/dram_sun50i_h616.h
> @@ -148,6 +148,7 @@ check_member(sunxi_mctl_ctl_reg, unk_0x4240, 0x4240);
> struct dram_para {
> u32 clk;
> enum sunxi_dram_type type;
> + u8 phy_init[27];
> u8 cols;
> u8 rows;
> u8 ranks;
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 3ad37ef6ba..5ce82a955c 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -487,6 +487,14 @@ config SUNXI_DRAM_H6_DDR3_1333
> This option is the DDR3 timing used by the boot0 on H6 TV boxes
> which use a DDR3-1333 timing.
>
> +config SUNXI_DRAM_H616_LPDDR3
> + bool "LPDDR3 DRAM chips on the H616 DRAM controller"
> + select SUNXI_DRAM_LPDDR3
> + depends on DRAM_SUN50I_H616
> + ---help---
> + This option is the LPDDR3 timing used by the stock boot0 by
> + Allwinner.
> +
> config SUNXI_DRAM_H616_DDR3_1333
> bool "DDR3-1333 boot0 timings on the H616 DRAM controller"
> select SUNXI_DRAM_DDR3
> @@ -1083,4 +1091,4 @@ config CHIP_DIP_SCAN
> select W1_GPIO
> select W1_EEPROM
> select W1_EEPROM_DS24XXX
> - select CMD_EXTENSION
> \ No newline at end of file
> + select CMD_EXTENSION
> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> index 1f9416d6ea..d34b218ee5 100644
> --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c
> +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c
> @@ -227,13 +227,6 @@ static void mctl_set_addrmap(struct dram_para *para)
> mctl_ctl->addrmap[8] = 0x3F3F;
> }
>
> -static const u8 phy_init[] = {
> - 0x07, 0x0b, 0x02, 0x16, 0x0d, 0x0e, 0x14, 0x19,
> - 0x0a, 0x15, 0x03, 0x13, 0x04, 0x0c, 0x10, 0x06,
> - 0x0f, 0x11, 0x1a, 0x01, 0x12, 0x17, 0x00, 0x08,
> - 0x09, 0x05, 0x18
> -};
> -
> static void mctl_phy_configure_odt(struct dram_para *para)
> {
> unsigned int val;
> @@ -263,19 +256,31 @@ static void mctl_phy_configure_odt(struct dram_para
> *para)
> writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x34c);
>
> val = para->dx_odt & 0x1f;
> - writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x380);
> + if (para->type == SUNXI_DRAM_TYPE_LPDDR3)
> + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x380);
> + else
> + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x380);
> writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x384);
>
> val = (para->dx_odt >> 8) & 0x1f;
> - writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c0);
> + if (para->type == SUNXI_DRAM_TYPE_LPDDR3)
> + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x3c0);
> + else
> + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c0);
> writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x3c4);
>
> val = (para->dx_odt >> 16) & 0x1f;
> - writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x400);
> + if (para->type == SUNXI_DRAM_TYPE_LPDDR3)
> + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x400);
> + else
> + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x400);
> writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x404);
>
> val = (para->dx_odt >> 24) & 0x1f;
> - writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x440);
> + if (para->type == SUNXI_DRAM_TYPE_LPDDR3)
> + writel_relaxed(0, SUNXI_DRAM_PHY0_BASE + 0x440);
> + else
> + writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x440);
> writel_relaxed(val, SUNXI_DRAM_PHY0_BASE + 0x444);
>
> dmb();
> @@ -793,31 +798,47 @@ static void
> mctl_phy_ca_bit_delay_compensation(struct dram_para *para)
> writel(val, SUNXI_DRAM_PHY0_BASE + 0x7e0);
> writel(val, SUNXI_DRAM_PHY0_BASE + 0x7f4);
>
> - /* following configuration is DDR3 specific */
> - val = (para->tpr10 >> 7) & 0x1e;
> - if (para->tpr2 & 1) {
> - writel(val, SUNXI_DRAM_PHY0_BASE + 0x794);
> -