[U-Boot] [PATCH 1/3] rockchip: add rv1108 sdram driver
Kever Yang
kever.yang at rock-chips.com
Fri Jan 12 03:34:08 UTC 2018
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 at 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 at 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 at 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 at 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);
> +}
More information about the U-Boot
mailing list