Please split this into multiple patches; e.g.:
-       the CRU changes are not SDRAM related
-       same goes for the GRF changes for GPIOs

The DRAM driver header file is essentially the same that was added in 
sdram_rk322x.h
with the key difference that 'dfitphywrdatalat’ is exposed in the structure 
here and added
into ‘reserved7’ in what we already have in the tree… and the *_timing 
structure differs,
but is semantically covered (i.e. all the fields are there, but the structure 
is split into
multiple sub-structures) by what we have in the tree.

The sdram_rv1108.c implementation just duplicates large amounts of common code
again (e.g. this is the 5th instance of move_to_access_state that I see in our 
drivers)
and even skips over using common code that has already been factored out (e.g.
rockchip_sdram_size is reimplemented).

The PHY operations (e.g. phy_dll_bypass_set) appear to be closely related to the
PHY in the rk322x: e.g. even the register-writes for the DLL bypass are to the 
same
registers with the key difference being that the RV1108 has a 16bit-wide bus 
only.
That said, I prefer the way the PHY registers are documented in the header file
and enums in this implementation (compared to how a number of constants are
open-coded in the rk322x driver)…

Looks like this is a good opportunity to make some progress on the long-overdue
refactoring of our DRAM drivers by merging much of the code here with the one
in the rk322x-implementation and moving the common code out of both drivers.

Regards,
Philipp. 

> On 12 Jan 2018, at 04:34, Kever Yang <[email protected]> wrote:
> 
> 
> 
> On 01/12/2018 10:36 AM, zhihuan he wrote:
>> add rv1108 sdram driver so we can set up sdram in SPL
> 
> More detail about this driver, eg. support dram type, capacity and so on.
>> 
>> Signed-off-by: zhihuan he <[email protected]>
> Please use Full Name here.
> 
> Please move sdram driver into driver/ram/rockchip/ folder.
> 
> Thanks,
> - Kever
>> 
>> ---
>> 
>>  arch/arm/include/asm/arch-rockchip/cru_rv1108.h   | 152 +++--
>>  arch/arm/include/asm/arch-rockchip/grf_rv1108.h   | 137 +++--
>>  arch/arm/include/asm/arch-rockchip/sdram_rv1108.h | 581 +++++++++++++++++++
>>  arch/arm/mach-rockchip/rv1108/Makefile            |   1 +
>>  arch/arm/mach-rockchip/rv1108/sdram_rv1108.c      | 643 
>> ++++++++++++++++++++++
>>  5 files changed, 1427 insertions(+), 87 deletions(-)
>>  create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rv1108.h
>>  create mode 100644 arch/arm/mach-rockchip/rv1108/sdram_rv1108.c
>> 
>> diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h 
>> b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
>> index ad2dc96..b2ac6a9 100644
>> --- a/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
>> +++ b/arch/arm/include/asm/arch-rockchip/cru_rv1108.h
>> @@ -56,61 +56,129 @@ struct pll_div {
>>    enum {
>>      /* PLL CON0 */
>> -    FBDIV_MASK              = 0xfff,
>> -    FBDIV_SHIFT             = 0,
>> +    FBDIV_MASK                      = 0xfff,
>> +    FBDIV_SHIFT                     = 0,
>>      /* PLL CON1 */
>> -    POSTDIV2_SHIFT          = 12,
>> -    POSTDIV2_MASK           = 7 << POSTDIV2_SHIFT,
>> -    POSTDIV1_SHIFT          = 8,
>> -    POSTDIV1_MASK           = 7 << POSTDIV1_SHIFT,
>> -    REFDIV_MASK             = 0x3f,
>> -    REFDIV_SHIFT            = 0,
>> +    POSTDIV2_SHIFT                  = 12,
>> +    POSTDIV2_MASK                   = 7 << POSTDIV2_SHIFT,
>> +    POSTDIV1_SHIFT                  = 8,
>> +    POSTDIV1_MASK                   = 7 << POSTDIV1_SHIFT,
>> +    REFDIV_MASK                     = 0x3f,
>> +    REFDIV_SHIFT                    = 0,
>>      /* PLL CON2 */
>> -    LOCK_STA_SHIFT          = 31,
>> -    LOCK_STA_MASK           = 1 << LOCK_STA_SHIFT,
>> -    FRACDIV_MASK            = 0xffffff,
>> -    FRACDIV_SHIFT           = 0,
>> +    LOCK_STA_SHIFT                  = 31,
>> +    LOCK_STA_MASK                   = 1 << LOCK_STA_SHIFT,
>> +    FRACDIV_MASK                    = 0xffffff,
>> +    FRACDIV_SHIFT                   = 0,
>>      /* PLL CON3 */
>> -    WORK_MODE_SHIFT         = 8,
>> -    WORK_MODE_MASK          = 1 << WORK_MODE_SHIFT,
>> -    WORK_MODE_SLOW          = 0,
>> -    WORK_MODE_NORMAL        = 1,
>> -    DSMPD_SHIFT             = 3,
>> -    DSMPD_MASK              = 1 << DSMPD_SHIFT,
>> +    WORK_MODE_SHIFT                 = 8,
>> +    WORK_MODE_MASK                  = 1 << WORK_MODE_SHIFT,
>> +    WORK_MODE_SLOW                  = 0,
>> +    WORK_MODE_NORMAL                = 1,
>> +    DSMPD_SHIFT                     = 3,
>> +    DSMPD_MASK                      = 1 << DSMPD_SHIFT,
>> +    INTEGER_MODE                    = 1,
>> +    GLOBAL_POWER_DOWN_SHIFT         = 0,
>> +    GLOBAL_POWER_DOWN_MASK          = 1 << GLOBAL_POWER_DOWN_SHIFT,
>> +    GLOBAL_POWER_DOWN               = 1,
>> +    GLOBAL_POWER_UP                 = 0,
>>      /* CLKSEL0_CON */
>> -    CORE_PLL_SEL_SHIFT      = 8,
>> -    CORE_PLL_SEL_MASK       = 3 << CORE_PLL_SEL_SHIFT,
>> -    CORE_PLL_SEL_APLL       = 0,
>> -    CORE_PLL_SEL_GPLL       = 1,
>> -    CORE_PLL_SEL_DPLL       = 2,
>> -    CORE_CLK_DIV_SHIFT      = 0,
>> -    CORE_CLK_DIV_MASK       = 0x1f << CORE_CLK_DIV_SHIFT,
>> +    CORE_PLL_SEL_SHIFT              = 8,
>> +    CORE_PLL_SEL_MASK               = 3 << CORE_PLL_SEL_SHIFT,
>> +    CORE_PLL_SEL_APLL               = 0,
>> +    CORE_PLL_SEL_GPLL               = 1,
>> +    CORE_PLL_SEL_DPLL               = 2,
>> +    CORE_CLK_DIV_SHIFT              = 0,
>> +    CORE_CLK_DIV_MASK               = 0x1f << CORE_CLK_DIV_SHIFT,
>> +
>> +    /* CLKSEL_CON1 */
>> +    PCLK_DBG_DIV_CON_SHIFT          = 4,
>> +    PCLK_DBG_DIV_CON_MASK           = 0xf << PCLK_DBG_DIV_CON_SHIFT,
>> +    ACLK_CORE_DIV_CON_SHIFT         = 0,
>> +    ACLK_CORE_DIV_CON_MASK          = 7 << ACLK_CORE_DIV_CON_SHIFT,
>> +
>> +    /* CLKSEL_CON2 */
>> +    ACLK_BUS_PLL_SEL_SHIFT          = 8,
>> +    ACLK_BUS_PLL_SEL_MASK           = 3 << ACLK_BUS_PLL_SEL_SHIFT,
>> +    ACLK_BUS_PLL_SEL_GPLL           = 0,
>> +    ACLK_BUS_PLL_SEL_APLL           = 1,
>> +    ACLK_BUS_PLL_SEL_DPLL           = 2,
>> +    ACLK_BUS_DIV_CON_SHIFT          = 0,
>> +    ACLK_BUS_DIV_CON_MASK           = 0x1f << ACLK_BUS_DIV_CON_SHIFT,
>> +
>> +    /* CLKSEL_CON3 */
>> +    PCLK_BUS_DIV_CON_SHIFT          = 8,
>> +    PCLK_BUS_DIV_CON_MASK           = 0x1f << PCLK_BUS_DIV_CON_SHIFT,
>> +    HCLK_BUS_DIV_CON_SHIFT          = 0,
>> +    HCLK_BUS_DIV_CON_MASK           = 0x1f,
>> +
>> +    /* CLKSEL_CON4 */
>> +    CLK_DDR_PLL_SEL_SHIFT           = 8,
>> +    CLK_DDR_PLL_SEL_MASK            = 0x3 << CLK_DDR_PLL_SEL_SHIFT,
>> +    CLK_DDR_DIV_CON_SHIFT           = 0,
>> +    CLK_DDR_DIV_CON_MASK            = 0x3 << CLK_DDR_DIV_CON_SHIFT,
>>      /* CLKSEL_CON22 */
>> -    CLK_SARADC_DIV_CON_SHIFT= 0,
>> -    CLK_SARADC_DIV_CON_MASK = GENMASK(9, 0),
>> -    CLK_SARADC_DIV_CON_WIDTH= 10,
>> +    CLK_SARADC_DIV_CON_SHIFT        = 0,
>> +    CLK_SARADC_DIV_CON_MASK         = GENMASK(9, 0),
>> +    CLK_SARADC_DIV_CON_WIDTH        = 10,
>> +
>> +    /* CLKSEL_CON23 */
>> +    ACLK_PERI_PLL_SEL_SHIFT         = 15,
>> +    ACLK_PERI_PLL_SEL_MASK          = 1 << ACLK_PERI_PLL_SEL_SHIFT,
>> +    ACLK_PERI_PLL_SEL_GPLL          = 0,
>> +    ACLK_PERI_PLL_SEL_DPLL          = 1,
>> +    PCLK_PERI_DIV_CON_SHIFT         = 10,
>> +    PCLK_PERI_DIV_CON_MASK          = 0x1f << PCLK_PERI_DIV_CON_SHIFT,
>> +    HCLK_PERI_DIV_CON_SHIFT         = 5,
>> +    HCLK_PERI_DIV_CON_MASK          = 0x1f << HCLK_PERI_DIV_CON_SHIFT,
>> +    ACLK_PERI_DIV_CON_SHIFT         = 0,
>> +    ACLK_PERI_DIV_CON_MASK          = 0x1f,
>>      /* CLKSEL24_CON */
>> -    MAC_PLL_SEL_SHIFT       = 12,
>> -    MAC_PLL_SEL_MASK        = 1 << MAC_PLL_SEL_SHIFT,
>> -    MAC_PLL_SEL_APLL        = 0,
>> -    MAC_PLL_SEL_GPLL        = 1,
>> -    RMII_EXTCLK_SEL_SHIFT   = 8,
>> -    RMII_EXTCLK_SEL_MASK    = 1 << RMII_EXTCLK_SEL_SHIFT,
>> -    MAC_CLK_DIV_MASK        = 0x1f,
>> -    MAC_CLK_DIV_SHIFT       = 0,
>> +    MAC_PLL_SEL_SHIFT               = 12,
>> +    MAC_PLL_SEL_MASK                = 1 << MAC_PLL_SEL_SHIFT,
>> +    MAC_PLL_SEL_APLL                = 0,
>> +    MAC_PLL_SEL_GPLL                = 1,
>> +    RMII_EXTCLK_SEL_SHIFT           = 8,
>> +    RMII_EXTCLK_SEL_MASK            = 1 << RMII_EXTCLK_SEL_SHIFT,
>> +    MAC_CLK_DIV_MASK                = 0x1f,
>> +    MAC_CLK_DIV_SHIFT               = 0,
>>      /* CLKSEL27_CON */
>> -    SFC_PLL_SEL_SHIFT       = 7,
>> -    SFC_PLL_SEL_MASK        = 1 << SFC_PLL_SEL_SHIFT,
>> -    SFC_PLL_SEL_DPLL        = 0,
>> -    SFC_PLL_SEL_GPLL        = 1,
>> -    SFC_CLK_DIV_SHIFT       = 0,
>> -    SFC_CLK_DIV_MASK        = 0x3f << SFC_CLK_DIV_SHIFT,
>> +    SFC_PLL_SEL_SHIFT               = 7,
>> +    SFC_PLL_SEL_MASK                = 1 << SFC_PLL_SEL_SHIFT,
>> +    SFC_PLL_SEL_DPLL                = 0,
>> +    SFC_PLL_SEL_GPLL                = 1,
>> +    SFC_CLK_DIV_SHIFT               = 0,
>> +    SFC_CLK_DIV_MASK                = 0x3f << SFC_CLK_DIV_SHIFT,
>> +
>> +    /* SOFTRST1_CON*/
>> +    DDRPHY_SRSTN_CLKDIV_REQ_SHIFT   = 0,
>> +    DDRPHY_SRSTN_CLKDIV_REQ         = 1,
>> +    DDRPHY_SRSTN_CLKDIV_DIS         = 0,
>> +    DDRPHY_SRSTN_CLKDIV_REQ_MASK    = 1 << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT,
>> +    DDRPHY_SRSTN_REQ_SHIFT          = 1,
>> +    DDRPHY_SRSTN_REQ                = 1,
>> +    DDRPHY_SRSTN_DIS                = 0,
>> +    DDRPHY_SRSTN_REQ_MASK           = 1 << DDRPHY_SRSTN_REQ_SHIFT,
>> +    DDRPHY_PSRSTN_REQ_SHIFT         = 2,
>> +    DDRPHY_PSRSTN_REQ               = 1,
>> +    DDRPHY_PSRSTN_DIS               = 0,
>> +    DDRPHY_PSRSTN_REQ_MASK          = 1 << DDRPHY_PSRSTN_REQ_SHIFT,
>> +
>> +    /* SOFTRST2_CON*/
>> +    DDRUPCTL_PSRSTN_REQ_SHIFT       = 0,
>> +    DDRUPCTL_PSRSTN_REQ             = 1,
>> +    DDRUPCTL_PSRSTN_DIS             = 0,
>> +    DDRUPCTL_PSRSTN_REQ_MASK        = 1 << DDRUPCTL_PSRSTN_REQ_SHIFT,
>> +    DDRUPCTL_NSRSTN_REQ_SHIFT       = 1,
>> +    DDRUPCTL_NSRSTN_REQ             = 1,
>> +    DDRUPCTL_NSRSTN_DIS             = 0,
>> +    DDRUPCTL_NSRSTN_REQ_MASK        = 1 << DDRUPCTL_NSRSTN_REQ_SHIFT,
>>  };
>>  #endif
>> diff --git a/arch/arm/include/asm/arch-rockchip/grf_rv1108.h 
>> b/arch/arm/include/asm/arch-rockchip/grf_rv1108.h
>> index c816a5b..88a9291 100644
>> --- a/arch/arm/include/asm/arch-rockchip/grf_rv1108.h
>> +++ b/arch/arm/include/asm/arch-rockchip/grf_rv1108.h
>> @@ -1,7 +1,7 @@
>>  /*
>>   * (C) Copyright 2016 Rockchip Electronics Co., Ltd
>> - *
>> - * SPDX-License-Identifier:     GPL-2.0+
>> + * Author: zhihuan he <[email protected]>
>> + * SPDX-License-Identifier: GPL-2.0+
>>   */
>>  #ifndef _ASM_ARCH_GRF_RV1108_H
>>  #define _ASM_ARCH_GRF_RV1108_H
>> @@ -108,6 +108,44 @@ struct rv1108_grf {
>>  };
>>  check_member(rv1108_grf, chip_id, 0xf90);
>>  +struct rv1108_pmu_grf {
>> +    u32 gpioa_iomux;
>> +    u32 gpiob_iomux;
>> +    u32 gpioc_iomux;
>> +    u32 reserved1;
>> +    u32 gpioa_p;
>> +    u32 gpiob_p;
>> +    u32 gpioc_p;
>> +    u32 reserved2;
>> +    u32 gpioa_e;
>> +    u32 gpiob_e;
>> +    u32 gpioc_e;
>> +    u32 reserved3;
>> +    u32 gpioa_smt;
>> +    u32 gpiob_smt;
>> +    u32 gpioc_smt;
>> +    u32 reserved4;
>> +    u32 pmugrf_gpio0a_sr;
>> +    u32 pmugrf_gpio0b_sr;
>> +    u32 pmugrf_gpio0c_sr;
>> +    u32 reserved5[(0x100 - 0x4c) / 4];
>> +    u32 pmugrf_soc_con[4];
>> +    u32 reserved6[(0x180 - 0x110) / 4];
>> +    u32 pmu_grf_pmugrf_dll_con[2];
>> +    u32 reserved7[2];
>> +    u32 pmu_grf_pmugrf_dll_status[2];
>> +    u32 reserved8[(0x200 - 0x198) / 4];
>> +    u32 pmu_grf_pmugrf_os_reg[4];
>> +    u32 reserved9[(0x300 - 0x210) / 4];
>> +    u32 pmu_grf_pmugrf_fast_boot_addr;
>> +    u32 reserved10[(0x380 - 0x304) / 4];
>> +    u32 pmu_grf_pmugrf_a7_jtag_mask;
>> +    u32 reserved11[(0x388 - 0x384) / 4];
>> +    u32 pmu_grf_pmugrf_ceva_jtag_mask;
>> +};
>> +
>> +check_member(rv1108_pmu_grf, pmu_grf_pmugrf_ceva_jtag_mask, 0x388);
>> +
>>  /* GRF_GPIO1B_IOMUX */
>>  enum {
>>      GPIO1B7_SHIFT           = 14,
>> @@ -211,7 +249,7 @@ enum {
>>      GPIO1C1_I2S_SDI_M0,
>>      GPIO1C1_PWM4,
>>  -   GPIO1C0_SHIFT           = 0,
>> +    GPIO1C0_SHIFT           = 0,
>>      GPIO1C0_MASK            = 3,
>>      GPIO1C0_GPIO            = 0,
>>      GPIO1C0_LCDC_D11,
>> @@ -285,48 +323,48 @@ enum {
>>      GPIO2A6_FLASH_D6,
>>      GPIO2A6_EMMC_D6,
>>  -   GPIO2A5_SHIFT           = 10,
>> -    GPIO2A5_MASK            = 3 << GPIO2A5_SHIFT,
>> -    GPIO2A5_GPIO            = 0,
>> +    GPIO2A5_SHIFT           = 10,
>> +    GPIO2A5_MASK            = 3 << GPIO2A5_SHIFT,
>> +    GPIO2A5_GPIO            = 0,
>>      GPIO2A5_FLASH_D5,
>>      GPIO2A5_EMMC_D5,
>>  -   GPIO2A4_SHIFT           = 8,
>> -    GPIO2A4_MASK            = 3 << GPIO2A4_SHIFT,
>> -    GPIO2A4_GPIO            = 0,
>> +    GPIO2A4_SHIFT           = 8,
>> +    GPIO2A4_MASK            = 3 << GPIO2A4_SHIFT,
>> +    GPIO2A4_GPIO            = 0,
>>      GPIO2A4_FLASH_D4,
>>      GPIO2A4_EMMC_D4,
>>  -   GPIO2A3_SHIFT           = 6,
>> -    GPIO2A3_MASK            = 3 << GPIO2A3_SHIFT,
>> -    GPIO2A3_GPIO            = 0,
>> +    GPIO2A3_SHIFT           = 6,
>> +    GPIO2A3_MASK            = 3 << GPIO2A3_SHIFT,
>> +    GPIO2A3_GPIO            = 0,
>>      GPIO2A3_FLASH_D3,
>>      GPIO2A3_EMMC_D3,
>>      GPIO2A3_SFC_HOLD_IO3,
>>  -   GPIO2A2_SHIFT           = 4,
>> -    GPIO2A2_MASK            = 3 << GPIO2A2_SHIFT,
>> -    GPIO2A2_GPIO            = 0,
>> +    GPIO2A2_SHIFT           = 4,
>> +    GPIO2A2_MASK            = 3 << GPIO2A2_SHIFT,
>> +    GPIO2A2_GPIO            = 0,
>>      GPIO2A2_FLASH_D2,
>>      GPIO2A2_EMMC_D2,
>>      GPIO2A2_SFC_WP_IO2,
>>  -   GPIO2A1_SHIFT           = 2,
>> -    GPIO2A1_MASK            = 3 << GPIO2A1_SHIFT,
>> -    GPIO2A1_GPIO            = 0,
>> +    GPIO2A1_SHIFT           = 2,
>> +    GPIO2A1_MASK            = 3 << GPIO2A1_SHIFT,
>> +    GPIO2A1_GPIO            = 0,
>>      GPIO2A1_FLASH_D1,
>>      GPIO2A1_EMMC_D1,
>>      GPIO2A1_SFC_SO_IO1,
>>  -   GPIO2A0_SHIFT           = 0,
>> -    GPIO2A0_MASK            = 3 << GPIO2A0_SHIFT,
>> -    GPIO2A0_GPIO            = 0,
>> +    GPIO2A0_SHIFT           = 0,
>> +    GPIO2A0_MASK            = 3 << GPIO2A0_SHIFT,
>> +    GPIO2A0_GPIO            = 0,
>>      GPIO2A0_FLASH_D0,
>>      GPIO2A0_EMMC_D0,
>>      GPIO2A0_SFC_SI_IO0,
>>  };
>>  -/* GRF_GPIO2D_IOMUX */
>> +/* GRF_GPIO2B_IOMUX */
>>  enum {
>>      GPIO2B7_SHIFT           = 14,
>>      GPIO2B7_MASK            = 3 << GPIO2B7_SHIFT,
>> @@ -334,41 +372,41 @@ enum {
>>      GPIO2B7_FLASH_CS1,
>>      GPIO2B7_SFC_CLK,
>>  -   GPIO2B6_SHIFT           = 12,
>> -    GPIO2B6_MASK            = 1 << GPIO2B6_SHIFT,
>> -    GPIO2B6_GPIO            = 0,
>> +    GPIO2B6_SHIFT           = 12,
>> +    GPIO2B6_MASK            = 1 << GPIO2B6_SHIFT,
>> +    GPIO2B6_GPIO            = 0,
>>      GPIO2B6_EMMC_CLKO,
>>  -   GPIO2B5_SHIFT           = 10,
>> -    GPIO2B5_MASK            = 1 << GPIO2B5_SHIFT,
>> -    GPIO2B5_GPIO            = 0,
>> +    GPIO2B5_SHIFT           = 10,
>> +    GPIO2B5_MASK            = 1 << GPIO2B5_SHIFT,
>> +    GPIO2B5_GPIO            = 0,
>>      GPIO2B5_FLASH_CS0,
>>  -   GPIO2B4_SHIFT           = 8,
>> -    GPIO2B4_MASK            = 3 << GPIO2B4_SHIFT,
>> -    GPIO2B4_GPIO            = 0,
>> +    GPIO2B4_SHIFT           = 8,
>> +    GPIO2B4_MASK            = 3 << GPIO2B4_SHIFT,
>> +    GPIO2B4_GPIO            = 0,
>>      GPIO2B4_FLASH_RDY,
>>      GPIO2B4_EMMC_CMD,
>>      GPIO2B4_SFC_CSN0,
>>  -   GPIO2B3_SHIFT           = 6,
>> -    GPIO2B3_MASK            = 1 << GPIO2B3_SHIFT,
>> -    GPIO2B3_GPIO            = 0,
>> +    GPIO2B3_SHIFT           = 6,
>> +    GPIO2B3_MASK            = 1 << GPIO2B3_SHIFT,
>> +    GPIO2B3_GPIO            = 0,
>>      GPIO2B3_FLASH_RDN,
>>  -   GPIO2B2_SHIFT           = 4,
>> -    GPIO2B2_MASK            = 1 << GPIO2B2_SHIFT,
>> -    GPIO2B2_GPIO            = 0,
>> +    GPIO2B2_SHIFT           = 4,
>> +    GPIO2B2_MASK            = 1 << GPIO2B2_SHIFT,
>> +    GPIO2B2_GPIO            = 0,
>>      GPIO2B2_FLASH_WRN,
>>  -   GPIO2B1_SHIFT           = 2,
>> -    GPIO2B1_MASK            = 1 << GPIO2B1_SHIFT,
>> -    GPIO2B1_GPIO            = 0,
>> +    GPIO2B1_SHIFT           = 2,
>> +    GPIO2B1_MASK            = 1 << GPIO2B1_SHIFT,
>> +    GPIO2B1_GPIO            = 0,
>>      GPIO2B1_FLASH_CLE,
>>  -   GPIO2B0_SHIFT           = 0,
>> -    GPIO2B0_MASK            = 1 << GPIO2B0_SHIFT,
>> -    GPIO2B0_GPIO            = 0,
>> +    GPIO2B0_SHIFT           = 0,
>> +    GPIO2B0_MASK            = 1 << GPIO2B0_SHIFT,
>> +    GPIO2B0_GPIO            = 0,
>>      GPIO2B0_FLASH_ALE,
>>  };
>>  @@ -427,12 +465,12 @@ enum {
>>      GPIO3A7_GPIO            = 0,
>>      GPIO3A6_SHIFT           = 12,
>> -    GPIO3A6_MASK            = 1 << GPIO3A6_SHIFT,
>> +    GPIO3A6_MASK            = 3 << GPIO3A6_SHIFT,
>>      GPIO3A6_GPIO            = 0,
>>      GPIO3A6_UART1_SOUT,
>>      GPIO3A5_SHIFT           = 10,
>> -    GPIO3A5_MASK            = 1 << GPIO3A5_SHIFT,
>> +    GPIO3A5_MASK            = 3 << GPIO3A5_SHIFT,
>>      GPIO3A5_GPIO            = 0,
>>      GPIO3A5_UART1_SIN,
>>  @@ -506,4 +544,13 @@ enum {
>>      GPIO3C0_GPIO            = 0,
>>      GPIO3C0_SDMMC_D3,
>>  };
>> +
>> +enum {
>> +    /* GRF_SOC_CON0 */
>> +    GRF_CON_MSCH_MAINDDR3                   = 1 << 4,
>> +    GRF_CON_MSCH_MAINPARTIALPOP             = 1 << 5,
>> +    GRF_CON_MSCH_MAINPARTIALPOP_MASK        = 1 << 5,
>> +    GRF_CON_MSCH_MAINPARTIALPOP_32BIT       = 0 << 5,
>> +};
>> +
>>  #endif
>> diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rv1108.h 
>> b/arch/arm/include/asm/arch-rockchip/sdram_rv1108.h
>> new file mode 100644
>> index 0000000..de881a1
>> --- /dev/null
>> +++ b/arch/arm/include/asm/arch-rockchip/sdram_rv1108.h
>> @@ -0,0 +1,581 @@
>> +/*
>> + * Copyright (C) 2017 Rockchip Electronics Co., Ltd
>> + * Author: zhihuan he <[email protected]>
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +#ifndef _ASM_ARCH_SDRAM_RV1108_H
>> +#define _ASM_ARCH_SDRAM_RV1108_H
>> +
>> +#include <common.h>
>> +
>> +#define SR_IDLE             3
>> +#define PD_IDLE             64
>> +#define SDRAM_ADDR  0x60000000
>> +#define SDRAM_END_ADDR      0x80000000
>> +#define PATTERN             (0x5aa5f00f)
>> +
>> +struct rv1108_ddr_pctl {
>> +    u32 scfg;
>> +    u32 sctl;
>> +    u32 stat;
>> +    u32 intrstat;
>> +    u32 reserved0[(0x40 - 0x10) / 4];
>> +    u32 mcmd;
>> +    u32 powctl;
>> +    u32 powstat;
>> +    u32 cmdtstat;
>> +    u32 cmdtstaten;
>> +    u32 reserved1[(0x60 - 0x54) / 4];
>> +    u32 mrrcfg0;
>> +    u32 mrrstat0;
>> +    u32 mrrstat1;
>> +    u32 reserved2[(0x7c - 0x6c) / 4];
>> +    u32 mcfg1;
>> +    u32 mcfg;
>> +    u32 ppcfg;
>> +    u32 mstat;
>> +    u32 lpddr2zqcfg;
>> +    u32 reserved3;
>> +    u32 dtupdes;
>> +    u32 dtuna;
>> +    u32 dtune;
>> +    u32 dtuprd0;
>> +    u32 dtuprd1;
>> +    u32 dtuprd2;
>> +    u32 dtuprd3;
>> +    u32 dtuawdt;
>> +    u32 reserved4[(0xc0 - 0xb4) / 4];
>> +    u32 togcnt1u;
>> +    u32 tinit;
>> +    u32 trsth;
>> +    u32 togcnt100n;
>> +    u32 trefi;
>> +    u32 tmrd;
>> +    u32 trfc;
>> +    u32 trp;
>> +    u32 trtw;
>> +    u32 tal;
>> +    u32 tcl;
>> +    u32 tcwl;
>> +    u32 tras;
>> +    u32 trc;
>> +    u32 trcd;
>> +    u32 trrd;
>> +    u32 trtp;
>> +    u32 twr;
>> +    u32 twtr;
>> +    u32 texsr;
>> +    u32 txp;
>> +    u32 txpdll;
>> +    u32 tzqcs;
>> +    u32 tzqcsi;
>> +    u32 tdqs;
>> +    u32 tcksre;
>> +    u32 tcksrx;
>> +    u32 tcke;
>> +    u32 tmod;
>> +    u32 trstl;
>> +    u32 tzqcl;
>> +    u32 tmrr;
>> +    u32 tckesr;
>> +    u32 tdpd;
>> +    u32 trefi_mem_ddr3;
>> +    u32 reserved5[(0x180 - 0x14c) / 4];
>> +    u32 ecccfg;
>> +    u32 ecctst;
>> +    u32 eccclr;
>> +    u32 ecclog;
>> +    u32 reserved6[(0x200 - 0x190) / 4];
>> +    u32 dtuwactl;
>> +    u32 dturactl;
>> +    u32 dtucfg;
>> +    u32 dtuectl;
>> +    u32 dtuwd0;
>> +    u32 dtuwd1;
>> +    u32 dtuwd2;
>> +    u32 dtuwd3;
>> +    u32 dtuwdm;
>> +    u32 dturd0;
>> +    u32 dturd1;
>> +    u32 dturd2;
>> +    u32 dturd3;
>> +    u32 dtulfsrwd;
>> +    u32 dtulfsrrd;
>> +    u32 dtueaf;
>> +    u32 dfitctrldelay;
>> +    u32 dfiodtcfg;
>> +    u32 dfiodtcfg1;
>> +    u32 dfiodtrankmap;
>> +    u32 dfitphywrdata;
>> +    u32 dfitphywrlat;
>> +    u32 dfitphywrdatalat;
>> +    u32 reserved7;
>> +    u32 dfitrddataen;
>> +    u32 dfitphyrdlat;
>> +    u32 reserved8[(0x270 - 0x268) / 4];
>> +    u32 dfitphyupdtype0;
>> +    u32 dfitphyupdtype1;
>> +    u32 dfitphyupdtype2;
>> +    u32 dfitphyupdtype3;
>> +    u32 dfitctrlupdmin;
>> +    u32 dfitctrlupdmax;
>> +    u32 dfitctrlupddly;
>> +    u32 reserved9;
>> +    u32 dfiupdcfg;
>> +    u32 dfitrefmski;
>> +    u32 dfitctrlupdi;
>> +    u32 reserved10[(0x2ac - 0x29c) / 4];
>> +    u32 dfitrcfg0;
>> +    u32 dfitrstat0;
>> +    u32 dfitrwrlvlen;
>> +    u32 dfitrrdlvlen;
>> +    u32 dfitrrdlvlgateen;
>> +    u32 dfiststat0;
>> +    u32 dfistcfg0;
>> +    u32 dfistcfg1;
>> +    u32 reserved11;
>> +    u32 dfitdramclken;
>> +    u32 dfitdramclkdis;
>> +    u32 dfistcfg2;
>> +    u32 dfistparclr;
>> +    u32 dfistparlog;
>> +    u32 reserved12[(0x2f0 - 0x2e4) / 4];
>> +    u32 dfilpcfg0;
>> +    u32 reserved13[(0x300 - 0x2f4) / 4];
>> +    u32 dfitrwrlvlresp0;
>> +    u32 dfitrwrlvlresp1;
>> +    u32 dfitrwrlvlresp2;
>> +    u32 dfitrrdlvlresp0;
>> +    u32 dfitrrdlvlresp1;
>> +    u32 dfitrrdlvlresp2;
>> +    u32 dfitrwrlvldelay0;
>> +    u32 dfitrwrlvldelay1;
>> +    u32 dfitrwrlvldelay2;
>> +    u32 dfitrrdlvldelay0;
>> +    u32 dfitrrdlvldelay1;
>> +    u32 dfitrrdlvldelay2;
>> +    u32 dfitrrdlvlgatedelay0;
>> +    u32 dfitrrdlvlgatedelay1;
>> +    u32 dfitrrdlvlgatedelay2;
>> +    u32 dfitrcmd;
>> +    u32 reserved14[(0x3f8 - 0x340) / 4];
>> +    u32 ipvr;
>> +    u32 iptr;
>> +};
>> +
>> +check_member(rv1108_ddr_pctl, iptr, 0x03fc);
>> +
>> +struct rv1108_ddr_phy {
>> +    u32 phy_reg0;
>> +    u32 phy_reg1;
>> +    u32 phy_reg2;
>> +    u32 phy_reg3;
>> +    u32 reserved0;
>> +    u32 phy_reg5;
>> +    u32 phy_reg6;
>> +    u32 reserveds1[(0x24 - 0x1c) / 4];
>> +    u32 phy_reg9;
>> +    u32 reserveds2[(0x2c - 0x28) / 4];
>> +    u32 phy_regb;
>> +    u32 phy_regc;
>> +    u32 reserveds3[(0x44 - 0x34) / 4];
>> +    u32 phy_reg11;
>> +    u32 phy_reg12;
>> +    u32 phy_reg13;
>> +    u32 phy_reg14;
>> +    u32 reserved4;
>> +    u32 phy_reg16;
>> +    u32 phy_reg17;
>> +    u32 phy_reg18;
>> +    u32 reserveds5[(0x80 - 0x64) / 4];
>> +    u32 phy_reg20;
>> +    u32 phy_reg21;
>> +    u32 reserveds6[(0x98 - 0x88) / 4];
>> +    u32 phy_reg26;
>> +    u32 phy_reg27;
>> +    u32 phy_reg28;
>> +    u32 reserveds7[(0xac - 0xa4) / 4];
>> +    u32 phy_reg2b;
>> +    u32 reserveds8[(0xb8 - 0xb0) / 4];
>> +    u32 phy_reg2e;
>> +    u32 phy_reg2f;
>> +    u32 phy_reg30;
>> +    u32 phy_reg31;
>> +    u32 reserveds9[(0xd8 - 0xc8) / 4];
>> +    u32 phy_reg36;
>> +    u32 phy_reg37;
>> +    u32 phy_reg38;
>> +    u32 reserveds10[(0xec - 0xe4) / 4];
>> +    u32 phy_reg3b;
>> +    u32 reserveds11[(0xf8 - 0xf0) / 4];
>> +    u32 phy_reg3e;
>> +    u32 phy_reg3f;
>> +    u32 reserveds12[(0x1c0 - 0x100) / 4];
>> +    u32 phy_reg_skew_cs0data[(0x218 - 0x1c0) / 4];
>> +    u32 reserveds13[(0x28c - 0x218) / 4];
>> +    u32 phy_vref;
>> +    u32 phy_regdll;/*dll bypass switch reg,0x290*/
>> +    u32 reserveds14[(0x2c0 - 0x294) / 4];
>> +    u32 phy_reg_ca_skew[(0x2f8 - 0x2c0) / 4];
>> +    u32 reserveds15[(0x300 - 0x2f8) / 4];
>> +    u32 phy_reg_skew_cs1data[(0x358 - 0x300) / 4];
>> +    u32 reserveds16[(0x3c0 - 0x358) / 4];
>> +    u32 phy_regf0;
>> +    u32 phy_regf1;
>> +    u32 reserveds17[(0x3e8 - 0x3c8) / 4];
>> +    u32 phy_regfa;
>> +    u32 phy_regfb;
>> +    u32 phy_regfc;
>> +    u32 reserved18;
>> +    u32 reserved19;
>> +    u32 phy_regff;
>> +};
>> +
>> +check_member(rv1108_ddr_phy, phy_regff, 0x03fc);
>> +
>> +struct rv1108_ddr_timing {
>> +    u32 freq;
>> +    struct rv1108_pctl_timing {
>> +            u32 togcnt1u;
>> +            u32 tinit;
>> +            u32 trsth;
>> +            u32 togcnt100n;
>> +            u32 trefi;
>> +            u32 tmrd;
>> +            u32 trfc;
>> +            u32 trp;
>> +            u32 trtw;
>> +            u32 tal;
>> +            u32 tcl;
>> +            u32 tcwl;
>> +            u32 tras;
>> +            u32 trc;
>> +            u32 trcd;
>> +            u32 trrd;
>> +            u32 trtp;
>> +            u32 twr;
>> +            u32 twtr;
>> +            u32 texsr;
>> +            u32 txp;
>> +            u32 txpdll;
>> +            u32 tzqcs;
>> +            u32 tzqcsi;
>> +            u32 tdqs;
>> +            u32 tcksre;
>> +            u32 tcksrx;
>> +            u32 tcke;
>> +            u32 tmod;
>> +            u32 trstl;
>> +            u32 tzqcl;
>> +            u32 tmrr;
>> +            u32 tckesr;
>> +            u32 tdpd;
>> +            u32 trefi_mem_ddr3;
>> +    } pctl_timing;
>> +    struct rv1108_phy_timing {
>> +            u32 mr[4];
>> +            u32 bl;
>> +            u32 cl_al;
>> +    } phy_timing;
>> +    u32 noc_timing;
>> +    u32 readlatency;
>> +    u32 activate;
>> +    u32 devtodev;
>> +};
>> +
>> +struct rv1108_service_msch {
>> +    u32 id_coreid;
>> +    u32 id_revisionid;
>> +    u32 ddrconf;
>> +    u32 ddrtiming;
>> +    u32 ddrmode;
>> +    u32 readlatency;
>> +    u32 activate;
>> +    u32 devtodev;
>> +};
>> +
>> +struct rv1108_ddr_config {
>> +    /*
>> +     * 000: lpddr
>> +     * 001: ddr
>> +     * 010: ddr2
>> +     * 011: ddr3
>> +     * 100: lpddr2-s2
>> +     * 101: lpddr2-s4
>> +     * 110: lpddr3
>> +     */
>> +    u32 ddr_type;
>> +    u32 chn_cnt;
>> +    u32 rank;
>> +    u32 cs0_row;
>> +    u32 cs1_row;
>> +
>> +    /* 2: 4bank, 3: 8bank */
>> +    u32 bank;
>> +    u32 col;
>> +    /* die buswidth, 2:32bit, 1:16bit, 0:8bit */
>> +    u32 dbw;
>> +    /* bw(0: 8bit, 1: 16bit, 2: 32bit) */
>> +    u32 bw;
>> +};
>> +
>> +/* rv1108 sdram initial */
>> +void rv1108_sdram_init(void);
>> +
>> +/* get ddr size on board */
>> +size_t sdram_size(void);
>> +
>> +enum {
>> +    PHY_LOW_SPEED_MHZ               = 400,
>> +    /* PHY_REG0 */
>> +    CHN_ENABLE_SHIFT                = 4,
>> +    DQ_16BIT_EN_MASK                = 3 << 4,
>> +    DQ_16BIT_EN                     = 3 << 4,
>> +    DQ_32BIT_EN_MASK                = 0xf << 4,
>> +    DQ_32BIT_EN                     = 0xf << 4,
>> +    RESET_DIGITAL_CORE_SHIFT        = 3,
>> +    RESET_DIGITAL_CORE_MASK         = 1 << RESET_DIGITAL_CORE_SHIFT,
>> +    RESET_DIGITAL_CORE_ACT          = 0,
>> +    RESET_DIGITAL_CORE_DIS          = 1,
>> +    RESET_ANALOG_LOGIC_SHIFT        = 2,
>> +    RESET_ANALOG_LOGIC_MASK         = 1 << RESET_ANALOG_LOGIC_SHIFT,
>> +    RESET_ANALOG_LOGIC_ACT          = 0,
>> +    RESET_ANALOG_LOGIC_DIS          = 1,
>> +
>> +    /* PHY_REG1 */
>> +    MEMORY_SELECT_DDR3              = 0,
>> +    PHY_BL_8                        = 1 << 2,
>> +
>> +    /* PHY_REG2 */
>> +    DQS_GATE_TRAINING_SEL_CS0       = 1 << 5,
>> +    DQS_GATE_TRAINING_ACT           = 1,
>> +    DQS_GATE_TRAINING_DIS           = 0,
>> +
>> +    /* PHY_REG12 */
>> +    CMD_PRCOMP_SHIFT                = 3,
>> +    CMD_PRCOMP_MASK                 = 0x1f << CMD_PRCOMP_SHIFT,
>> +
>> +    /* DDRPHY_REG13 */
>> +    CMD_DLL_BYPASS_SHIFT            = 4,
>> +    CMD_DLL_BYPASS                  = 1,
>> +    CMD_DLL_BYPASS_MASK             = 1,
>> +    CMD_DLL_BYPASS_DISABLE          = 0,
>> +
>> +    /* DDRPHY_REG14 */
>> +    CK_DLL_BYPASS_SHIFT             = 3,
>> +    CK_DLL_BYPASS                   = 1,
>> +    CK_DLL_BYPASS_DISABLE           = 0,
>> +
>> +    /* DDRPHY_REG26 */
>> +    LEFT_CHN_A_DQ_DLL_SHIFT         = 4,
>> +    LEFT_CHN_A_DQ_DLL_BYPASS        = 1,
>> +    LEFT_CHN_A_DQ_DLL_BYPASS_MASK   = 1,
>> +    LEFT_CHN_A_DQ_DLL_BYPASS_DIS    = 0,
>> +
>> +    /* DDRPHY_REG27 */
>> +    LEFT_CHN_A_DQS_DLL_SHIFT        = 3,
>> +    LEFT_CHN_A_DQS_DLL_BYPASS       = 1,
>> +    LEFT_CHN_A_DQS_DLL_BYPASS_DIS   = 0,
>> +
>> +    /* DDRPHY_REG28 */
>> +    LEFT_CHN_A_READ_DQS_45_DELAY    = 2,
>> +
>> +    /* DDRPHY_REG36 */
>> +    RIGHT_CHN_A_DQ_DLL_SHIFT        = 4,
>> +    RIGHT_CHN_A_DQ_DLL_BYPASS       = 1,
>> +    RIGHT_CHN_A_DQ_DLL_BYPASS_MASK  = 1,
>> +    RIGHT_CHN_A_DQ_DLL_BYPASS_DIS   = 0,
>> +
>> +    /* DDRPHY_REG37 */
>> +    RIGHT_CHN_A_DQS_DLL_SHIFT       = 3,
>> +    RIGHT_CHN_A_DQS_DLL_BYPASS      = 1,
>> +    RIGHT_CHN_A_DQS_DLL_BYPASS_DIS  = 0,
>> +
>> +    /* DDRPHY_REG38 */
>> +    RIGHT_CHN_A_READ_DQS_45_DELAY   = 2,
>> +
>> +    /* PHY_REGDLL */
>> +    RIGHT_CHN_A_TX_DQ_BYPASS_SHIFT  = 2,
>> +    RIGHT_CHN_A_TX_DQ_BYPASS_SET    = 1,
>> +    RIGHT_CHN_A_TX_DQ_BYPASS_DIS    = 0,
>> +    LEFT_CHN_A_TX_DQ_BYPASS_SHIFT   = 1,
>> +    LEFT_CHN_A_TX_DQ_BYPASS_SET     = 1,
>> +    LEFT_CHN_A_TX_DQ_BYPASS_DIS     = 0,
>> +    CMD_CK_DLL_BYPASS_SHIFT         = 0,
>> +    CMD_CK_DLL_BYPASS_SET           = 1,
>> +    CMD_CK_DLL_BYPASS_DIS           = 0,
>> +
>> +    /* PHY_REGFF */
>> +    CHN_A_TRAINING_DONE_MASK        = 3,
>> +    CHN_A_HIGH_8BIT_TRAINING_DONE   = 1 << 1,
>> +    CHN_A_LOW_8BIT_TRAINING_DONE    = 1,
>> +};
>> +
>> +/*PCTL*/
>> +enum {
>> +    /* PCTL_SCTL */
>> +    INIT_STATE                              = 0,
>> +    CFG_STATE                               = 1,
>> +    GO_STATE                                = 2,
>> +    SLEEP_STATE                             = 3,
>> +    WAKEUP_STATE                            = 4,
>> +
>> +    /* PCTL_STAT*/
>> +    PCTL_CTL_STAT_MASK                      = 0x7,
>> +    INIT_MEM                                = 0,
>> +    CONFIG                                  = 1,
>> +    CONFIG_REQ                              = 2,
>> +    ACCESS                                  = 3,
>> +    ACCESS_REQ                              = 4,
>> +    LOW_POWER                               = 5,
>> +    LOW_POWER_ENTRY_REQ                     = 6,
>> +    LOW_POWER_EXIT_REQ                      = 7,
>> +
>> +    /* PCTL_MCMD */
>> +    START_CMD                               = 0x80000000,
>> +    RANK_SEL_SHIFT                          = 20,
>> +    RANK_SEL_CS0                            = 1,
>> +    RANK_SEL_CS1                            = 2,
>> +    RANK_SEL_CS0_CS1                        = 3,
>> +    BANK_ADDR_SHIFT                         = 17,
>> +    BANK_ADDR_MASK                          = 0x7,
>> +    CMD_ADDR_SHIFT                          = 4,
>> +    CMD_ADDR_MASK                           = 0x1fff,
>> +    DDR3_DLL_RESET                          = 1 << 8,
>> +    DESELECT_CMD                            = 0x0,
>> +    PREA_CMD                                = 0x1,
>> +    REF_CMD                                 = 0x2,
>> +    MRS_CMD                                 = 0x3,
>> +    ZQCS_CMD                                = 0x4,
>> +    ZQCL_CMD                                = 0x5,
>> +    RSTL_CMD                                = 0x6,
>> +    MPR_CMD                                 = 0x8,
>> +    DFICTRLUPD_CMD                          = 0xa,
>> +    MR0                                     = 0x0,
>> +    MR1                                     = 0x1,
>> +    MR2                                     = 0x2,
>> +    MR3                                     = 0x3,
>> +
>> +    /* PCTL_POWCTL */
>> +    POWER_UP_START                          = 1,
>> +    POWER_UP_START_MASK                     = 1,
>> +
>> +    /* PCTL_POWSTAT */
>> +    POWER_UP_DONE                           = 1,
>> +
>> +    /*PCTL_PPCFG*/
>> +    PPMEM_EN_MASK                           = 1,
>> +    PPMEM_EN                                = 1,
>> +    PPMEM_DIS                               = 0,
>> +    /* PCTL_TREFI */
>> +    UPD_REF                                 = 0x80000000,
>> +
>> +    /* PCTL_DFISTCFG0 */
>> +    DFI_DATA_BYTE_DISABLE_EN_SHIFT          = 2,
>> +    DFI_DATA_BYTE_DISABLE_EN                = 1,
>> +    DFI_FREQ_RATIO_EN_SHIFT                 = 1,
>> +    DFI_FREQ_RATIO_EN                       = 1,
>> +    DFI_INIT_START_SHIFT                    = 0,
>> +    DFI_INIT_START_EN                       = 1,
>> +
>> +    /* PCTL_DFISTCFG1 */
>> +    DFI_DRAM_CLK_DISABLE_EN_DPD_SHIFT       = 1,
>> +    DFI_DRAM_CLK_DISABLE_EN_DPD             = 1,
>> +    DFI_DRAM_CLK_DISABLE_EN_SHIFT           = 0,
>> +    DFI_DRAM_CLK_DISABLE_EN                 = 1,
>> +
>> +    /* PCTL_DFISTCFG2 */
>> +    PARITY_EN_SHIFT                         = 1,
>> +    PARITY_EN                               = 1,
>> +    PARITY_INTR_EN_SHIFT                    = 0,
>> +    PARITY_INTR_EN                          = 1,
>> +
>> +    /* PCTL_DFILPCFG0 */
>> +    DFI_LP_EN_SR_SHIFT                      = 8,
>> +    DFI_LP_EN_SR                            = 1,
>> +    DFI_LP_WAKEUP_SR_SHIFT                  = 12,
>> +    DFI_LP_WAKEUP_SR_32_CYCLES              = 1,
>> +    DFI_TLP_RESP_SHIFT                      = 16,
>> +    DFI_TLP_RESP                            = 5,
>> +
>> +    /* PCTL_DFITPHYUPDTYPE0 */
>> +    TPHYUPD_TYPE0                           = 1,
>> +
>> +    /* PCTL_DFITPHYRDLAT */
>> +    TPHY_RDLAT                              = 0xd,
>> +
>> +    /* PCTL_DFITPHYWRDATA */
>> +    TPHY_WRDATA                             = 0x0,
>> +
>> +    /* PCTL_DFIUPDCFG */
>> +    DFI_PHYUPD_DISABLE                      = 0 << 1,
>> +    DFI_CTRLUPD_DISABLE                     = 0,
>> +
>> +    /* PCTL_DFIODTCFG */
>> +    RANK0_ODT_WRITE_SEL_SHIFT               = 3,
>> +    RANK0_ODT_WRITE_SEL                     = 1,
>> +    RANK1_ODT_WRITE_SEL_SHIFT               = 11,
>> +    RANK1_ODT_WRITE_SEL                     = 1,
>> +
>> +    /* PCTL_DFIODTCFG1 */
>> +    ODT_LEN_BL8_W_SHIFT                     = 16,
>> +    ODT_LEN_BL8_W                           = 7,
>> +
>> +    /* PCTL_MCFG */
>> +    MDDR_LPDDR23_CLOCK_STOP_IDLE_DIS        = 0 << 24,
>> +    DDR3_EN                                 = 1 << 5,
>> +    MEM_BL_8                                = 1,
>> +    TFAW_CFG_5_TDDR                         = 1 << 18,
>> +    PD_EXIT_SLOW_EXIT_MODE                  = 0 << 17,
>> +    PD_TYPE_ACT_PD                          = 1 << 16,
>> +    PD_IDLE_DISABLE                         = 0 << 8,
>> +    PD_IDLE_MASK                            = 0xff << 8,
>> +    PD_IDLE_SHIFT                           = 8,
>> +
>> +    /* PCTL_MCFG1 */
>> +    SR_IDLE_MASK                            = 0xff,
>> +    HW_EXIT_IDLE_EN_SHIFT                   = 31,
>> +    HW_EXIT_IDLE_EN_MASK                    = 1 << HW_EXIT_IDLE_EN_SHIFT,
>> +    HW_EXIT_IDLE_EN                         = 1 << HW_EXIT_IDLE_EN_SHIFT,
>> +
>> +    /* PCTL_SCFG */
>> +    HW_LOW_POWER_EN                         = 1,
>> +};
>> +
>> +enum {
>> +    /*memory scheduler ddrtiming*/
>> +    BWRATIO_HALF_BW                         = 0x80000000,
>> +    BWRATIO_HALF_BW_DIS                     = 0x0,
>> +};
>> +
>> +enum {
>> +    /* PHY_DDR3_RON_RTT */
>> +    PHY_RON_RTT_DISABLE                     = 0,
>> +    PHY_RON_RTT_451OHM                      = 1,
>> +    PHY_RON_RTT_225OHM                      = 2,
>> +    PHY_RON_RTT_150OHM                      = 3,
>> +    PHY_RON_RTT_112OHM                      = 4,
>> +    PHY_RON_RTT_90OHM                       = 5,
>> +    PHY_RON_RTT_75OHM                       = 6,
>> +    PHY_RON_RTT_64OHM                       = 7,
>> +
>> +    PHY_RON_RTT_56OHM                       = 16,
>> +    PHY_RON_RTT_50OHM                       = 17,
>> +    PHY_RON_RTT_45OHM                       = 18,
>> +    PHY_RON_RTT_41OHM                       = 19,
>> +    PHY_RON_RTT_37OHM                       = 20,
>> +    PHY_RON_RTT_34OHM                       = 21,
>> +    PHY_RON_RTT_33OHM                       = 22,
>> +    PHY_RON_RTT_30OHM                       = 23,
>> +
>> +    PHY_RON_RTT_28OHM                       = 24,
>> +    PHY_RON_RTT_26OHM                       = 25,
>> +    PHY_RON_RTT_25OHM                       = 26,
>> +    PHY_RON_RTT_23OHM                       = 27,
>> +    PHY_RON_RTT_22OHM                       = 28,
>> +    PHY_RON_RTT_21OHM                       = 29,
>> +    PHY_RON_RTT_20OHM                       = 30,
>> +    PHY_RON_RTT_19OHM                       = 31,
>> +};
>> +
>> +#endif
>> diff --git a/arch/arm/mach-rockchip/rv1108/Makefile 
>> b/arch/arm/mach-rockchip/rv1108/Makefile
>> index 9035a1a..c4e8a16 100644
>> --- a/arch/arm/mach-rockchip/rv1108/Makefile
>> +++ b/arch/arm/mach-rockchip/rv1108/Makefile
>> @@ -7,5 +7,6 @@
>>  ifndef CONFIG_SPL_BUILD
>>  obj-y += syscon_rv1108.o
>>  endif
>> +obj-y += sdram_rv1108.o
>>  obj-y += rv1108.o
>>  obj-y += clk_rv1108.o
>> diff --git a/arch/arm/mach-rockchip/rv1108/sdram_rv1108.c 
>> b/arch/arm/mach-rockchip/rv1108/sdram_rv1108.c
>> new file mode 100644
>> index 0000000..fcb6e2c
>> --- /dev/null
>> +++ b/arch/arm/mach-rockchip/rv1108/sdram_rv1108.c
>> @@ -0,0 +1,643 @@
>> +/*
>> + * Copyright (C) 2017 Rockchip Electronics Co., Ltd
>> + * Author: zhihuan he <[email protected]>
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +#include <common.h>
>> +#include <linux/io.h>
>> +#include <linux/types.h>
>> +#include <asm/arch/cru_rv1108.h>
>> +#include <asm/arch/grf_rv1108.h>
>> +#include <asm/arch/hardware.h>
>> +#include <asm/arch/sdram_rv1108.h>
>> +#include <asm/arch/timer.h>
>> +#include <ram.h>
>> +#include <asm/arch/sdram_common.h>
>> +
>> +/*
>> + * we can not fit the code to access the device tree in SPL
>> + * (due to 6K SRAM size limits), so these are hard-coded
>> + */
>> +
>> +#define DDR_CONF_PERFORMANCE                (1)
>> +#define DDRPHY_BUFFEREN_CORE_EN(n)  (((0x1 << 2) << 16) | (n << 2))
>> +
>> +#define CRU_BASE            0x20200000
>> +#define GRF_BASE            0x10300000
>> +#define DDR_PHY_BASE                0x20210000
>> +#define DDR_PCTL_BASE               0x202b0000
>> +#define SERVICE_MSCH_BASE   0x31070000
>> +#define PMU_GRF_BASE                0x20060000
>> +/* PMU */
>> +#define PMU_BASS_ADDR                       0x20010000
>> +#define PMU_SFT_CON                 (PMU_BASS_ADDR + 0x1c)
>> +#define DDR_IO_RET_EN(n)            (n << 11)
>> +
>> +struct rv1108_sdram_priv {
>> +    struct rv1108_cru *cru;
>> +    struct rv1108_grf *grf;
>> +    struct rv1108_ddr_phy *phy;
>> +    struct rv1108_ddr_pctl *pctl;
>> +    struct rv1108_ddr_timing *timing;
>> +    struct rv1108_service_msch *service_msch;
>> +    /* ddr die config */
>> +    struct rv1108_ddr_config ddr_config;
>> +};
>> +
>> +/* use integer mode, 1200MHz dpll setting,600MHz ddr
>> + * refdiv, fbdiv, postdiv1, postdiv2
>> + */
>> +const struct pll_div dpll_init_cfg = {
>> +    1,
>> +    133,
>> +    4,
>> +    1,
>> +    0
>> +};
>> +
>> +const struct rv1108_ddr_timing ddr_timing = {
>> +    0x190,
>> +    {0xc8,
>> +    0xc8,
>> +    0x1f4,
>> +    0x14,
>> +    0x4e,
>> +    0x4,
>> +    0x78,
>> +    0x6,
>> +    0x3,
>> +    0x0,
>> +    0x6,
>> +    0x5,
>> +    0xf,
>> +    0x15,
>> +    0x6,
>> +    0x4,
>> +    0x4,
>> +    0x6,
>> +    0x4,
>> +    0x200,
>> +    0x3,
>> +    0xa,
>> +    0x40,
>> +    0x2710,
>> +    0x1,
>> +    0x5,
>> +    0x5,
>> +    0x3,
>> +    0xc,
>> +    0x28,
>> +    0x100,
>> +    0x0,
>> +    0x4,
>> +    0x0,
>> +    0x618},
>> +    {{0x420,
>> +    0x40,
>> +    0x0,
>> +    0x0},
>> +    0x01,
>> +    0x60},
>> +    0x9028b18a,
>> +    0x18,
>> +    0x4a4,
>> +    0x15
>> +};
>> +
>> +void get_ddr_config(struct rv1108_ddr_config *config)
>> +{
>> +    /* rv1108 up to 1 memory ranks,support for x8,x16 DDR3,
>> +     * total memory data path width of 16 bits.
>> +     */
>> +    /* DDR config */
>> +    config->ddr_type = 3;
>> +    config->chn_cnt = 0;
>> +    config->rank = 1;
>> +    config->cs1_row = 0;
>> +
>> +    /* 8bank */
>> +    config->bank = 3;
>> +
>> +    /* ddr3 always set to 1,16 bit */
>> +    config->dbw = 1;
>> +    /* 16 bit bw */
>> +    config->bw = 1;
>> +}
>> +
>> +static void rkdclk_init(struct rv1108_sdram_priv *priv)
>> +{
>> +    struct rv1108_pll *pll = &priv->cru->pll[1];
>> +
>> +    rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
>> +                 WORK_MODE_SLOW << WORK_MODE_SHIFT);
>> +    rk_clrsetreg(&pll->con3, GLOBAL_POWER_DOWN_MASK,
>> +                 GLOBAL_POWER_DOWN << GLOBAL_POWER_DOWN_SHIFT);
>> +    rk_clrsetreg(&pll->con3, DSMPD_MASK, INTEGER_MODE << DSMPD_SHIFT);
>> +    rk_clrsetreg(&pll->con0, FBDIV_MASK,
>> +                 dpll_init_cfg.fbdiv << FBDIV_SHIFT);
>> +    rk_clrsetreg(&pll->con1, POSTDIV2_MASK | POSTDIV1_MASK | REFDIV_MASK,
>> +                 dpll_init_cfg.postdiv2 << POSTDIV2_SHIFT |
>> +                 dpll_init_cfg.postdiv1 << POSTDIV1_SHIFT |
>> +                 dpll_init_cfg.refdiv << REFDIV_SHIFT);
>> +    rk_clrsetreg(&pll->con3, GLOBAL_POWER_DOWN_MASK,
>> +                 GLOBAL_POWER_UP << GLOBAL_POWER_DOWN_SHIFT);
>> +    while (!(readl(&pll->con2) & (1u << LOCK_STA_SHIFT)))
>> +            rockchip_udelay(1);
>> +
>> +    rk_clrsetreg(&priv->cru->clksel_con[4], CLK_DDR_PLL_SEL_MASK |
>> +                 CLK_DDR_DIV_CON_MASK, 0 << CLK_DDR_PLL_SEL_SHIFT |
>> +                 0 << CLK_DDR_DIV_CON_SHIFT);
>> +    rk_clrsetreg(&pll->con3, WORK_MODE_MASK,
>> +                 WORK_MODE_NORMAL << WORK_MODE_SHIFT);
>> +}
>> +
>> +static void copy_to_reg(u32 *dest, const u32 *src, u32 n)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < n / sizeof(u32); i++) {
>> +            writel(*src, dest);
>> +            src++;
>> +            dest++;
>> +    }
>> +}
>> +
>> +void phy_pctrl_reset(struct rv1108_sdram_priv *priv)
>> +{
>> +    struct rv1108_ddr_phy *ddr_phy = priv->phy;
>> +
>> +    rk_clrsetreg(&priv->cru->softrst_con[2], DDRUPCTL_PSRSTN_REQ_MASK |
>> +                 DDRUPCTL_NSRSTN_REQ_MASK,
>> +                 DDRUPCTL_PSRSTN_REQ << DDRUPCTL_PSRSTN_REQ_SHIFT |
>> +                 DDRUPCTL_NSRSTN_REQ << DDRUPCTL_NSRSTN_REQ_SHIFT);
>> +    rk_clrsetreg(&priv->cru->softrst_con[1],
>> +                 DDRPHY_SRSTN_CLKDIV_REQ_MASK | DDRPHY_SRSTN_REQ_MASK |
>> +                 DDRPHY_PSRSTN_REQ_MASK,
>> +                 DDRPHY_SRSTN_CLKDIV_REQ << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT |
>> +                 DDRPHY_SRSTN_REQ << DDRPHY_SRSTN_REQ_SHIFT |
>> +                 DDRPHY_PSRSTN_REQ << DDRPHY_PSRSTN_REQ_SHIFT);
>> +
>> +    rockchip_udelay(10);
>> +
>> +    rk_clrsetreg(&priv->cru->softrst_con[1],
>> +                 DDRPHY_SRSTN_CLKDIV_REQ_MASK | DDRPHY_SRSTN_REQ_MASK |
>> +                 DDRPHY_PSRSTN_REQ_MASK,
>> +                 DDRPHY_SRSTN_CLKDIV_DIS << DDRPHY_SRSTN_CLKDIV_REQ_SHIFT |
>> +                 DDRPHY_PSRSTN_DIS << DDRPHY_PSRSTN_REQ_SHIFT |
>> +                 DDRPHY_SRSTN_DIS << DDRPHY_SRSTN_REQ_SHIFT);
>> +    rockchip_udelay(10);
>> +
>> +    rk_clrsetreg(&priv->cru->softrst_con[2], DDRUPCTL_PSRSTN_REQ_MASK |
>> +                 DDRUPCTL_NSRSTN_REQ_MASK,
>> +                 DDRUPCTL_PSRSTN_DIS << DDRUPCTL_PSRSTN_REQ_SHIFT |
>> +                 DDRUPCTL_NSRSTN_DIS << DDRUPCTL_NSRSTN_REQ_SHIFT);
>> +    rockchip_udelay(10);
>> +
>> +    clrsetbits_le32(&ddr_phy->phy_reg0,
>> +                    RESET_DIGITAL_CORE_MASK | RESET_ANALOG_LOGIC_MASK,
>> +                    RESET_DIGITAL_CORE_ACT << RESET_DIGITAL_CORE_SHIFT |
>> +                    RESET_ANALOG_LOGIC_ACT << RESET_ANALOG_LOGIC_SHIFT);
>> +    rockchip_udelay(1);
>> +    clrsetbits_le32(&ddr_phy->phy_reg0,
>> +                    RESET_ANALOG_LOGIC_MASK,
>> +                    RESET_ANALOG_LOGIC_DIS << RESET_ANALOG_LOGIC_SHIFT);
>> +    rockchip_udelay(5);
>> +    clrsetbits_le32(&ddr_phy->phy_reg0,
>> +                    RESET_DIGITAL_CORE_MASK,
>> +                    RESET_DIGITAL_CORE_DIS << RESET_DIGITAL_CORE_SHIFT);
>> +    rockchip_udelay(1);
>> +}
>> +
>> +void phy_dll_bypass_set(struct rv1108_sdram_priv *priv, unsigned int freq)
>> +{
>> +    struct rv1108_ddr_phy *ddr_phy = priv->phy;
>> +
>> +    clrsetbits_le32(&ddr_phy->phy_reg13, CMD_DLL_BYPASS_MASK <<
>> +                    CMD_DLL_BYPASS_SHIFT, CMD_DLL_BYPASS <<
>> +                    CMD_DLL_BYPASS_SHIFT);
>> +
>> +    writel(CK_DLL_BYPASS_DISABLE << CK_DLL_BYPASS_SHIFT,
>> +           &ddr_phy->phy_reg14);
>> +
>> +    clrsetbits_le32(&ddr_phy->phy_reg26, LEFT_CHN_A_DQ_DLL_BYPASS_MASK <<
>> +                    LEFT_CHN_A_DQ_DLL_SHIFT, LEFT_CHN_A_DQ_DLL_BYPASS <<
>> +                    LEFT_CHN_A_DQ_DLL_SHIFT);
>> +    writel(LEFT_CHN_A_DQS_DLL_BYPASS_DIS <<
>> +           LEFT_CHN_A_DQS_DLL_SHIFT, &ddr_phy->phy_reg27);
>> +
>> +    clrsetbits_le32(&ddr_phy->phy_reg36, RIGHT_CHN_A_DQ_DLL_BYPASS_MASK <<
>> +                    RIGHT_CHN_A_DQ_DLL_SHIFT, RIGHT_CHN_A_DQ_DLL_BYPASS <<
>> +                    RIGHT_CHN_A_DQ_DLL_SHIFT);
>> +    writel(RIGHT_CHN_A_DQS_DLL_BYPASS_DIS <<
>> +           RIGHT_CHN_A_DQS_DLL_SHIFT, &ddr_phy->phy_reg37);
>> +
>> +    if (freq <= PHY_LOW_SPEED_MHZ) {
>> +            writel(RIGHT_CHN_A_TX_DQ_BYPASS_SET <<
>> +                   RIGHT_CHN_A_TX_DQ_BYPASS_SHIFT |
>> +                   LEFT_CHN_A_TX_DQ_BYPASS_SET <<
>> +                   LEFT_CHN_A_TX_DQ_BYPASS_SHIFT |
>> +                   CMD_CK_DLL_BYPASS_SET << CMD_CK_DLL_BYPASS_SHIFT,
>> +                   &ddr_phy->phy_regdll);
>> +    } else {
>> +            writel(RIGHT_CHN_A_TX_DQ_BYPASS_DIS <<
>> +                   RIGHT_CHN_A_TX_DQ_BYPASS_SHIFT |
>> +                   LEFT_CHN_A_TX_DQ_BYPASS_DIS <<
>> +                   LEFT_CHN_A_TX_DQ_BYPASS_SHIFT |
>> +                   CMD_CK_DLL_BYPASS_DIS << CMD_CK_DLL_BYPASS_SHIFT,
>> +                            &ddr_phy->phy_regdll);
>> +    }
>> +
>> +    /* 45 degree delay */
>> +    writel(LEFT_CHN_A_READ_DQS_45_DELAY, &ddr_phy->phy_reg28);
>> +    writel(RIGHT_CHN_A_READ_DQS_45_DELAY, &ddr_phy->phy_reg38);
>> +}
>> +
>> +static void send_command(struct rv1108_ddr_pctl *pctl,
>> +                     u32 rank, u32 cmd, u32 arg)
>> +{
>> +    writel((START_CMD | (rank << RANK_SEL_SHIFT) | arg | cmd),
>> +           &pctl->mcmd);
>> +    while (readl(&pctl->mcmd) & START_CMD)
>> +            ;
>> +}
>> +
>> +static void memory_init(struct rv1108_sdram_priv *priv)
>> +{
>> +    struct rv1108_ddr_pctl *pctl = priv->pctl;
>> +
>> +    send_command(pctl, RANK_SEL_CS0_CS1, DESELECT_CMD, 0);
>> +    rockchip_udelay(1);
>> +    send_command(pctl, RANK_SEL_CS0_CS1, PREA_CMD, 0);
>> +
>> +    send_command(pctl, RANK_SEL_CS0_CS1, DESELECT_CMD, 0);
>> +    rockchip_udelay(1);
>> +    send_command(pctl, RANK_SEL_CS0_CS1, MRS_CMD,
>> +                 (MR2 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
>> +                 (ddr_timing.phy_timing.mr[2] & CMD_ADDR_MASK) <<
>> +                 CMD_ADDR_SHIFT);
>> +
>> +    send_command(pctl, RANK_SEL_CS0_CS1, MRS_CMD,
>> +                 (MR3 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
>> +                 (ddr_timing.phy_timing.mr[3] & CMD_ADDR_MASK) <<
>> +                 CMD_ADDR_SHIFT);
>> +
>> +    send_command(pctl, RANK_SEL_CS0_CS1, MRS_CMD,
>> +                 (MR1 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
>> +                 (ddr_timing.phy_timing.mr[1] & CMD_ADDR_MASK) <<
>> +                 CMD_ADDR_SHIFT);
>> +
>> +    send_command(pctl, RANK_SEL_CS0_CS1, MRS_CMD,
>> +                 (MR0 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
>> +                 (ddr_timing.phy_timing.mr[0] & CMD_ADDR_MASK) <<
>> +                 CMD_ADDR_SHIFT | DDR3_DLL_RESET);
>> +
>> +    send_command(pctl, RANK_SEL_CS0_CS1, ZQCL_CMD, 0);
>> +}
>> +
>> +static void set_bw(struct rv1108_sdram_priv *priv)
>> +{
>> +    if (readl(&priv->ddr_config.bw) == 1) {
>> +            clrsetbits_le32(&priv->pctl->ppcfg, PPMEM_EN_MASK, PPMEM_EN);
>> +            clrsetbits_le32(&priv->phy->phy_reg0, DQ_16BIT_EN_MASK,
>> +                            DQ_16BIT_EN);
>> +            rk_clrsetreg(&priv->grf->soc_con0,
>> +                         GRF_CON_MSCH_MAINPARTIALPOP_MASK,
>> +                         GRF_CON_MSCH_MAINPARTIALPOP);
>> +            clrsetbits_le32(&priv->service_msch->ddrtiming,
>> +                            BWRATIO_HALF_BW, BWRATIO_HALF_BW);
>> +    }
>> +}
>> +
>> +static void move_to_config_state(struct rv1108_sdram_priv *priv)
>> +{
>> +    unsigned int state;
>> +
>> +    while (1) {
>> +            state = readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK;
>> +            switch (state) {
>> +            case LOW_POWER:
>> +                    writel(WAKEUP_STATE, &priv->pctl->sctl);
>> +                    while ((readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK)
>> +                            != ACCESS)
>> +                            ;
>> +                    /*
>> +                     * If at low power state, need wakeup first, and then
>> +                     * enter the config, so fallthrough
>> +                     */
>> +            case ACCESS:
>> +            case INIT_MEM:
>> +                    writel(CFG_STATE, &priv->pctl->sctl);
>> +                    while ((readl(&priv->pctl->stat) & PCTL_CTL_STAT_MASK)
>> +                            != CONFIG)
>> +                            ;
>> +                    break;
>> +            case CONFIG:
>> +                    return;
>> +            default:
>> +                    break;
>> +            }
>> +    }
>> +}
>> +
>> +static void move_to_access_state(struct rv1108_sdram_priv *priv)
>> +{
>> +    unsigned int state;
>> +    struct rv1108_ddr_pctl *pctl = priv->pctl;
>> +
>> +    while (1) {
>> +            state = readl(&pctl->stat) & PCTL_CTL_STAT_MASK;
>> +            switch (state) {
>> +            case LOW_POWER:
>> +                    writel(WAKEUP_STATE, &pctl->sctl);
>> +                    while ((readl(&pctl->stat) & PCTL_CTL_STAT_MASK) !=
>> +                           ACCESS)
>> +                            ;
>> +                    break;
>> +            case INIT_MEM:
>> +                    writel(CFG_STATE, &pctl->sctl);
>> +                    while ((readl(&pctl->stat) & PCTL_CTL_STAT_MASK) !=
>> +                           CONFIG)
>> +                            ;
>> +                    /* fallthrough */
>> +            case CONFIG:
>> +                    writel(GO_STATE, &pctl->sctl);
>> +                    while ((readl(&pctl->stat) & PCTL_CTL_STAT_MASK) !=
>> +                           ACCESS)
>> +                            ;
>> +                    break;
>> +            case ACCESS:
>> +                    return;
>> +            default:
>> +                    break;
>> +            }
>> +    }
>> +}
>> +
>> +static void pctl_cfg(struct rv1108_sdram_priv *priv)
>> +{
>> +    struct rv1108_ddr_pctl *pctl = priv->pctl;
>> +    u32 reg;
>> +
>> +    /* DFI config */
>> +    writel(DFI_DATA_BYTE_DISABLE_EN << DFI_DATA_BYTE_DISABLE_EN_SHIFT |
>> +           DFI_INIT_START_EN << DFI_INIT_START_SHIFT, &pctl->dfistcfg0);
>> +    writel(DFI_DRAM_CLK_DISABLE_EN_DPD <<
>> +           DFI_DRAM_CLK_DISABLE_EN_DPD_SHIFT |
>> +           DFI_DRAM_CLK_DISABLE_EN << DFI_DRAM_CLK_DISABLE_EN_SHIFT,
>> +           &pctl->dfistcfg1);
>> +    writel(PARITY_EN << PARITY_EN_SHIFT |
>> +           PARITY_INTR_EN << PARITY_INTR_EN_SHIFT, &pctl->dfistcfg2);
>> +    writel(DFI_LP_EN_SR << DFI_LP_EN_SR_SHIFT |
>> +           DFI_LP_WAKEUP_SR_32_CYCLES << DFI_LP_WAKEUP_SR_SHIFT |
>> +           DFI_TLP_RESP << DFI_TLP_RESP_SHIFT,
>> +           &pctl->dfilpcfg0);
>> +
>> +    writel(TPHYUPD_TYPE0, &pctl->dfitphyupdtype0);
>> +    writel(TPHY_RDLAT, &pctl->dfitphyrdlat);
>> +    writel(TPHY_WRDATA, &pctl->dfitphywrdata);
>> +
>> +    writel(DFI_PHYUPD_DISABLE | DFI_CTRLUPD_DISABLE, &pctl->dfiupdcfg);
>> +
>> +    copy_to_reg(&pctl->togcnt1u, &ddr_timing.pctl_timing.togcnt1u,
>> +                sizeof(struct rv1108_pctl_timing));
>> +
>> +    writel((RANK0_ODT_WRITE_SEL << RANK0_ODT_WRITE_SEL_SHIFT |
>> +           RANK1_ODT_WRITE_SEL << RANK1_ODT_WRITE_SEL_SHIFT),
>> +           &pctl->dfiodtcfg);
>> +
>> +    writel(ODT_LEN_BL8_W << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
>> +
>> +    reg = readl(&pctl->tcl);
>> +    writel((reg - 1) / 2 - 1, &pctl->dfitrddataen);
>> +    reg = readl(&pctl->tcwl);
>> +    writel((reg - 1) / 2 - 1, &pctl->dfitphywrlat);
>> +
>> +    writel(ddr_timing.pctl_timing.trsth, &pctl->trsth);
>> +    writel(MDDR_LPDDR23_CLOCK_STOP_IDLE_DIS | DDR3_EN | MEM_BL_8 |
>> +           TFAW_CFG_5_TDDR | PD_EXIT_SLOW_EXIT_MODE |
>> +           PD_TYPE_ACT_PD | PD_IDLE_DISABLE, &pctl->mcfg);
>> +
>> +    writel(RK_SETBITS(GRF_CON_MSCH_MAINDDR3 | GRF_CON_MSCH_MAINPARTIALPOP),
>> +           &priv->grf->soc_con0);
>> +    setbits_le32(&pctl->scfg, HW_LOW_POWER_EN);
>> +}
>> +
>> +static void phy_cfg(struct rv1108_sdram_priv *priv)
>> +{
>> +    struct rv1108_ddr_phy *ddr_phy = priv->phy;
>> +    struct rv1108_service_msch *msch = priv->service_msch;
>> +
>> +    writel((readl(&msch->ddrtiming) & BWRATIO_HALF_BW) |
>> +           ddr_timing.noc_timing,
>> +           &msch->ddrtiming);
>> +    writel(ddr_timing.readlatency, &msch->readlatency);
>> +    writel(ddr_timing.activate, &msch->activate);
>> +    writel(ddr_timing.devtodev, &msch->devtodev);
>> +
>> +    writel(MEMORY_SELECT_DDR3 | PHY_BL_8, &ddr_phy->phy_reg1);
>> +
>> +    writel(ddr_timing.phy_timing.cl_al, &ddr_phy->phy_regb);
>> +    writel(ddr_timing.pctl_timing.tcwl, &ddr_phy->phy_regc);
>> +
>> +    writel(PHY_RON_RTT_34OHM, &ddr_phy->phy_reg11);
>> +    clrsetbits_le32(&ddr_phy->phy_reg12, CMD_PRCOMP_MASK,
>> +                    PHY_RON_RTT_34OHM << CMD_PRCOMP_SHIFT);
>> +    writel(PHY_RON_RTT_45OHM, &ddr_phy->phy_reg16);
>> +    writel(PHY_RON_RTT_45OHM, &ddr_phy->phy_reg18);
>> +    writel(PHY_RON_RTT_34OHM, &ddr_phy->phy_reg20);
>> +    writel(PHY_RON_RTT_34OHM, &ddr_phy->phy_reg2f);
>> +    writel(PHY_RON_RTT_34OHM, &ddr_phy->phy_reg30);
>> +    writel(PHY_RON_RTT_34OHM, &ddr_phy->phy_reg3f);
>> +    writel(PHY_RON_RTT_225OHM, &ddr_phy->phy_reg21);
>> +    writel(PHY_RON_RTT_225OHM, &ddr_phy->phy_reg2e);
>> +    writel(PHY_RON_RTT_225OHM, &ddr_phy->phy_reg31);
>> +    writel(PHY_RON_RTT_225OHM, &ddr_phy->phy_reg3e);
>> +}
>> +
>> +void dram_cfg_rbc(struct rv1108_sdram_priv *priv)
>> +{
>> +    int i = 0;
>> +    struct rv1108_ddr_config config = priv->ddr_config;
>> +    struct rv1108_service_msch *msch = priv->service_msch;
>> +
>> +    move_to_config_state(priv);
>> +
>> +    if (config.col == 10)
>> +            i = 2;
>> +    else
>> +            i = 3;
>> +
>> +    writel(i, &msch->ddrconf);
>> +    move_to_access_state(priv);
>> +}
>> +
>> +void enable_low_power(struct rv1108_sdram_priv *priv)
>> +{
>> +    move_to_config_state(priv);
>> +
>> +    clrsetbits_le32(&priv->pctl->mcfg, PD_IDLE_MASK,
>> +                    PD_IDLE << PD_IDLE_SHIFT);
>> +    clrsetbits_le32(&priv->pctl->mcfg1, SR_IDLE_MASK | HW_EXIT_IDLE_EN_MASK,
>> +                    SR_IDLE | HW_EXIT_IDLE_EN);
>> +
>> +    /* uPCTL in low_power status because of auto self-refreh */
>> +    writel(GO_STATE, &priv->pctl->sctl);
>> +}
>> +
>> +static void data_training(struct rv1108_sdram_priv *priv)
>> +{
>> +    struct rv1108_ddr_phy *ddr_phy = priv->phy;
>> +    struct rv1108_ddr_pctl *pctl = priv->pctl;
>> +    u32 value;
>> +
>> +    /* disable auto refresh */
>> +    value = readl(&pctl->trefi);
>> +    writel(UPD_REF, &pctl->trefi);
>> +
>> +    writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_DIS,
>> +           &ddr_phy->phy_reg2);
>> +    writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_ACT,
>> +           &ddr_phy->phy_reg2);
>> +    rockchip_udelay(30);
>> +    writel(DQS_GATE_TRAINING_SEL_CS0 | DQS_GATE_TRAINING_DIS,
>> +           &ddr_phy->phy_reg2);
>> +
>> +    send_command(pctl, RANK_SEL_CS0_CS1, PREA_CMD, 0);
>> +
>> +    while ((readl(&ddr_phy->phy_regff) & CHN_A_TRAINING_DONE_MASK) ==
>> +           (CHN_A_HIGH_8BIT_TRAINING_DONE | CHN_A_LOW_8BIT_TRAINING_DONE))
>> +            ;
>> +
>> +    writel(value | UPD_REF, &pctl->trefi);
>> +}
>> +
>> +static u32 rv1108_sdram_detect(struct rv1108_sdram_priv *priv,
>> +                           struct rv1108_ddr_config *config)
>> +{
>> +    u32 row, col;
>> +    u32 test_addr;
>> +    struct rv1108_service_msch *msch = priv->service_msch;
>> +
>> +    move_to_config_state(priv);
>> +    writel(1, &msch->ddrconf);
>> +    move_to_access_state(priv);
>> +
>> +    /* detect col */
>> +    for (col = 11; col >= 10; col--) {
>> +            writel(0, SDRAM_ADDR);
>> +            test_addr = SDRAM_ADDR + (1u << (col +
>> +                            config->bw - 1u));
>> +            writel(PATTERN, test_addr);
>> +            if ((readl(test_addr) == PATTERN) &&
>> +                (readl(SDRAM_ADDR) == 0))
>> +                    break;
>> +    }
>> +    if (col <= 8)
>> +            goto cap_err;
>> +    config->col = col;
>> +
>> +    /* detect row */
>> +    col = 11;
>> +    for (row = 16; row >= 12; row--) {
>> +            writel(0, SDRAM_ADDR);
>> +            test_addr = SDRAM_ADDR + (1u << (row +
>> +                            config->bank + col + config->bw - 1u));
>> +            writel(PATTERN, test_addr);
>> +            if ((readl(test_addr) == PATTERN) &&
>> +                (readl(SDRAM_ADDR) == 0))
>> +                    break;
>> +    }
>> +    if (row <= 11)
>> +            goto cap_err;
>> +    config->cs0_row = row;
>> +    return 0;
>> +cap_err:
>> +    return 1;
>> +}
>> +
>> +static void sdram_all_config(struct rv1108_sdram_priv *priv)
>> +{
>> +    u32 os_reg = 0;
>> +    u32 cs1_row = 0;
>> +    struct rv1108_ddr_config config = priv->ddr_config;
>> +
>> +    if (config.rank > 1)
>> +            cs1_row = config.cs1_row - 13;
>> +
>> +    os_reg = config.ddr_type << SYS_REG_DDRTYPE_SHIFT |
>> +             config.chn_cnt << SYS_REG_NUM_CH_SHIFT |
>> +             (config.rank - 1) << SYS_REG_RANK_SHIFT(0) |
>> +             (config.col - 9) << SYS_REG_COL_SHIFT(0) |
>> +             (config.bank == 3 ? 0 : 1) << SYS_REG_BK_SHIFT(0) |
>> +             (config.cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(0) |
>> +             cs1_row << SYS_REG_CS1_ROW_SHIFT(0) |
>> +             config.bw << SYS_REG_BW_SHIFT(0) |
>> +             config.dbw << SYS_REG_DBW_SHIFT(0);
>> +
>> +    writel(os_reg, &priv->grf->os_reg2);
>> +}
>> +
>> +size_t sdram_size(void)
>> +{
>> +    u32 size, os_reg, cs0_row, cs1_row, col, bank, rank, bw;
>> +    struct rv1108_grf *grf = (void *)GRF_BASE;
>> +
>> +    os_reg = readl(&grf->os_reg2);
>> +
>> +    cs0_row = 13 + ((os_reg >> SYS_REG_CS0_ROW_SHIFT(0)) &
>> +                    SYS_REG_CS0_ROW_MASK);
>> +    cs1_row = 13 + ((os_reg >> SYS_REG_CS1_ROW_SHIFT(0)) &
>> +                    SYS_REG_CS1_ROW_MASK);
>> +    col = 9 + ((os_reg >> SYS_REG_COL_SHIFT(0)) & SYS_REG_COL_MASK);
>> +    bank = 3 - ((os_reg >> SYS_REG_BK_SHIFT(0)) & SYS_REG_BK_MASK);
>> +    rank = 1 + ((os_reg >> SYS_REG_RANK_SHIFT(0)) & SYS_REG_RANK_MASK);
>> +    bw = 2 - ((os_reg >> SYS_REG_BW_SHIFT(0)) & SYS_REG_BW_MASK);
>> +
>> +    size = 1 << (cs0_row + col + bank + bw);
>> +
>> +    if (rank > 1)
>> +            size += size >> (cs0_row - cs1_row);
>> +
>> +    return size;
>> +}
>> +
>> +void rv1108_sdram_init(void)
>> +{
>> +    struct rv1108_sdram_priv sdram_priv;
>> +    struct rv1108_pmu_grf * const pmu_grf = (void *)PMU_GRF_BASE;
>> +
>> +    sdram_priv.cru = (void *)CRU_BASE;
>> +    sdram_priv.grf = (void *)GRF_BASE;
>> +    sdram_priv.phy = (void *)DDR_PHY_BASE;
>> +    sdram_priv.pctl = (void *)DDR_PCTL_BASE;
>> +    sdram_priv.service_msch = (void *)SERVICE_MSCH_BASE;
>> +
>> +    /* pmu enable ddr io retention */
>> +    writel(DDR_IO_RET_EN(1), PMU_SFT_CON);
>> +    pmu_grf->pmugrf_soc_con[0] = DDRPHY_BUFFEREN_CORE_EN(1);
>> +
>> +    get_ddr_config(&sdram_priv.ddr_config);
>> +    rkdclk_init(&sdram_priv);
>> +    phy_pctrl_reset(&sdram_priv);
>> +    phy_dll_bypass_set(&sdram_priv, ddr_timing.freq);
>> +    pctl_cfg(&sdram_priv);
>> +    phy_cfg(&sdram_priv);
>> +
>> +    rk_clrsetreg(&sdram_priv.pctl->powctl, POWER_UP_START_MASK,
>> +                 POWER_UP_START);
>> +    while (!(readl(&sdram_priv.pctl->powstat) & POWER_UP_DONE))
>> +            ;
>> +
>> +    memory_init(&sdram_priv);
>> +    move_to_config_state(&sdram_priv);
>> +    set_bw(&sdram_priv);
>> +    data_training(&sdram_priv);
>> +    move_to_access_state(&sdram_priv);
>> +    if (rv1108_sdram_detect(&sdram_priv, &sdram_priv.ddr_config)) {
>> +            while (1)
>> +                    ;
>> +    }
>> +    dram_cfg_rbc(&sdram_priv);
>> +    sdram_all_config(&sdram_priv);
>> +    enable_low_power(&sdram_priv);
>> +}
> 
> 

_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to