Message ID | 1515724616-25186-1-git-send-email-huan.he@rock-chips.com |
---|---|
State | Changes Requested |
Delegated to: | Philipp Tomsich |
Headers | show |
Series | [U-Boot,1/3] rockchip: add rv1108 sdram driver | expand |
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); > +}
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); >> +} > >
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); +}
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