[U-Boot,1/3] rockchip: add rv1108 sdram driver

Message ID 1515724616-25186-1-git-send-email-huan.he@rock-chips.com
State New
Delegated to: Philipp Tomsich
Headers show
Series
  • [U-Boot,1/3] rockchip: add rv1108 sdram driver
Related show

Commit Message

huan.he@rock-chips.com Jan. 12, 2018, 2:36 a.m.
add rv1108 sdram driver so we can set up sdram in SPL

Signed-off-by: zhihuan he <huan.he@rock-chips.com>

---

 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

Comments

Kever Yang Jan. 12, 2018, 3:34 a.m. | #1
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 <huan.he@rock-chips.com>
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 <huan.he@rock-chips.com>
> + * 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 <huan.he@rock-chips.com>
> + * 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 <huan.he@rock-chips.com>
> + * 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);
> +}
Dr. Philipp Tomsich Jan. 12, 2018, 10:56 a.m. | #2
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 <kever.yang@rock-chips.com> 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 <huan.he@rock-chips.com>
> 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 <huan.he@rock-chips.com>
>> + * 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 <huan.he@rock-chips.com>
>> + * 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 <huan.he@rock-chips.com>
>> + * 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);
>> +}
> 
>

Patch

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 <huan.he@rock-chips.com>
+ * 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 <huan.he@rock-chips.com>
+ * 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 <huan.he@rock-chips.com>
+ * 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);
+}