From 8ec8d58eeb2a43c1d2630d9ef41fac2a7c482082 Mon Sep 17 00:00:00 2001 From: Zhihuan He Date: Mon, 9 Nov 2020 16:42:20 +0800 Subject: [PATCH] drivers: ram: rockchip: add rk3308 sdram driver Change-Id: I96160af2095ba21b440c6d3789349d8cbc4fea75 Signed-off-by: Zhihuan He --- .../include/asm/arch-rockchip/cru_rk3308.h | 473 ++++++++++ .../include/asm/arch-rockchip/grf_rk3308.h | 40 +- .../include/asm/arch-rockchip/pmu_rk3308.h | 71 ++ .../include/asm/arch-rockchip/sdram_rk3308.h | 137 +++ arch/arm/mach-rockchip/rk3308/rk3308.c | 197 +++- .../ram/rockchip/sdram-rk3308-ddr-skew.inc | 59 ++ .../rk3308/sdram-rk3308-ddr2-detect-393.inc | 71 ++ .../rk3308/sdram-rk3308-ddr2-detect-451.inc | 71 ++ .../rk3308/sdram-rk3308-ddr3-detect-393.inc | 71 ++ .../rk3308/sdram-rk3308-ddr3-detect-451.inc | 71 ++ .../rk3308/sdram-rk3308-ddr3-detect-589.inc | 71 ++ .../rk3308/sdram-rk3308-lpddr2-detect-393.inc | 71 ++ .../rk3308/sdram-rk3308-lpddr2-detect-451.inc | 71 ++ drivers/ram/rockchip/sdram_rk3308.c | 880 ++++++++++++++++++ 14 files changed, 2333 insertions(+), 21 deletions(-) create mode 100644 arch/arm/include/asm/arch-rockchip/pmu_rk3308.h create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_rk3308.h create mode 100644 drivers/ram/rockchip/sdram-rk3308-ddr-skew.inc create mode 100644 drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-393.inc create mode 100644 drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-451.inc create mode 100644 drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-393.inc create mode 100644 drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-451.inc create mode 100644 drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-589.inc create mode 100644 drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-393.inc create mode 100644 drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-451.inc create mode 100644 drivers/ram/rockchip/sdram_rk3308.c diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3308.h b/arch/arm/include/asm/arch-rockchip/cru_rk3308.h index 46288468f2..5dda2406d2 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3308.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3308.h @@ -110,6 +110,8 @@ enum { PLL_PD1_SHIFT = 14, PLL_PD_SHIFT = 13, PLL_PD_MASK = 1 << PLL_PD_SHIFT, + PLLPD0_POWER_DOWN = 1, + PLLPD0_NO_POWER_DOWN = 0, PLL_DSMPD_SHIFT = 12, PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, PLL_LOCK_STATUS_SHIFT = 10, @@ -315,4 +317,475 @@ enum { check_member(rk3308_cru, emmc_con[1], 0x494); +enum { /* DPLL_CON0, VPLL0_CON0, VPLL1_CON0 */ + POSTDIV1_SHIFT = 12, + POSTDIV1_MASK = 0x7 << POSTDIV1_SHIFT, + FBDIV_SHIFT = 0, + FBDIV_MASK = 0xfff << FBDIV_SHIFT, + + /* DPLL_CON1, VPLL0_CON1, VPLL1_CON1 */ + PLLPD0_SHIFT = 13, + PLLPD0_MASK = 1 << PLLPD0_SHIFT, + DSMPD_SHIFT = 12, + DSMPD_MASK = 1 << DSMPD_SHIFT, + INTEGER_MODE = 1, + FRACTIONAL_MODE = 0, + PLL_LOCK_SHIFT = 10, + PLL_LOCK_MASK = 0x1 << PLL_LOCK_SHIFT, + POSTDIV2_SHIFT = 6, + POSTDIV2_MASK = 0x7 << POSTDIV2_SHIFT, + REFDIV_SHIFT = 0, + REFDIV_MASK = 0x3f << REFDIV_SHIFT, + + /* VPLL0_CON2, VPLL1_CON2 */ + FRACDIV_SHIFT = 0, + FRACDIV_MASK = 0xffffff << FRACDIV_SHIFT, + + /* CRU_MODE */ + VPLL1_CLK_SEL_SHIFT = 13, + VPLL1_CLK_SEL_MASK = 0x1 << VPLL1_CLK_SEL_SHIFT, + VPLL1_CLK_SEL_WITHOUT_LVL_SHIFT = 1, + + VPLL0_CLK_SEL_SHIFT = 12, + VPLL0_CLK_SEL_MASK = 0x1 << VPLL0_CLK_SEL_SHIFT, + VPLL0_CLK_SEL_WITHOUT_LVL_SHIFT = 1, + + DPLL_CLK_SEL_SHIFT = 11, + DPLL_CLK_SEL_MASK = 0x1 << DPLL_CLK_SEL_SHIFT, + DPLL_CLK_SEL_WITHOUT_LVL_SHIFT = 1, + + APLL_CLK_SEL_SHIFT = 10, + APLL_CLK_SEL_MASK = 0x1 << APLL_CLK_SEL_SHIFT, + APLL_CLK_SEL_WITHOUT_LVL_SHIFT = 1, + + VPLL1_WORK_MODE_SHIFT = 6, + VPLL1_WORK_MODE_MASK = 0x3 << VPLL1_WORK_MODE_SHIFT, + VPLL1_WORK_MODE_XIN_OSC0 = 0, + VPLL1_WORK_MODE_PLL = 1, + VPLL1_WORK_MODE_32K = 2, + + VPLL0_WORK_MODE_SHIFT = 4, + VPLL0_WORK_MODE_MASK = 0x3 << VPLL0_WORK_MODE_SHIFT, + VPLL0_WORK_MODE_XIN_OSC0 = 0, + VPLL0_WORK_MODE_PLL = 1, + VPLL0_WORK_MODE_32K = 2, + + DPLL_WORK_MODE_SHIFT = 2, + DPLL_WORK_MODE_MASK = 0x3 << DPLL_WORK_MODE_SHIFT, + DPLL_WORK_MODE_XIN_OSC0 = 0, + DPLL_WORK_MODE_PLL = 1, + DPLL_WORK_MODE_32K = 2, + + APLL_WORK_MODE_SHIFT = 0, + APLL_WORK_MODE_MASK = 0x3 << APLL_WORK_MODE_SHIFT, + APLL_WORK_MODE_XIN_OSC0 = 0, + APLL_WORK_MODE_PLL = 1, + + /* GLB_RST_CON */ + WDT_GLB_SRST_CTRL_SHIFT = 1, + WDT_GLB_SRST_CTRL = 1, + TSADC_GLB_SRST_CTRL_SHIFT = 0, + TSADC_GLB_SRST_CTRL = 1, + + /* CLKSEL_CON1 */ + DDRPHY4X_PLL_CLK_SEL_SHIFT = 6, + DDRPHY4X_PLL_CLK_SEL_MASK = 0x3 << DDRPHY4X_PLL_CLK_SEL_SHIFT, + DDRPHY4X_PLL_CLK_SEL_DPLL = 0, + DDRPHY4X_DIV_CON_SIHFT = 0, + DDRPHY4X_DIV_CON_MASK = 0x7 << DDRPHY4X_DIV_CON_SIHFT, + DDRPHY4X_DIV_CON = 0, + + /* CLKSEL_CON5 */ + A_H_PCLK_BUS_PLL_SEL_SHIFT = 6, + A_H_PCLK_BUS_PLL_SEL_MASK = 0x3 << A_H_PCLK_BUS_PLL_SEL_SHIFT, + A_H_PCLK_BUS_PLL_SEL_DPLL = 0, + A_H_PCLK_BUS_PLL_SEL_VPLL0 = 1, + A_H_PCLK_BUS_PLL_SEL_VPLL1 = 2, + ACLK_BUS_DIV_CON_SHIFT = 0, + ACLK_BUS_DIV_CON_MASK = 0x1f << ACLK_BUS_DIV_CON_SHIFT, + ACLK_BUS_DIV_CON_7 = 7, + ACLK_BUS_DIV_CON_5 = 5, + ACLK_BUS_DIV_CON_3 = 3, + + /* CLKSEL_CON6 */ + PCLK_BUS_DIV_CON_SHIFT = 8, + PCLK_BUS_DIV_CON_MASK = 0x1f << PCLK_BUS_DIV_CON_SHIFT, + PCLK_BUS_DIV_CON_31 = 31, + PCLK_BUS_DIV_CON_25 = 25, + PCLK_BUS_DIV_CON_15 = 15, + HCLK_BUS_DIV_CON_SHIFT = 0, + HCLK_BUS_DIV_CON_MASK = 0x1f << HCLK_BUS_DIV_CON_SHIFT, + HCLK_BUS_DIV_CON_15 = 15, + HCLK_BUS_DIV_CON_13 = 13, + HCLK_BUS_DIV_CON_11 = 11, + HCLK_BUS_DIV_CON_7 = 7, + + /* CLKSEL_CON7 */ + CLK_CRYPTO_APK_SEL_SHIFT = 14, + CLK_CRYPTO_APK_SEL_MASK = 0x3 << CLK_CRYPTO_APK_SEL_SHIFT, + CLK_CRYPTO_APK_SEL_DPLL = 0, + CLK_CRYPTO_APK_DIV_SHIFT = 8, + CLK_CRYPTO_APK_DIV_MASK = 0x1f << CLK_CRYPTO_APK_DIV_SHIFT, + CLK_CRYPTO_APK_DIV_15 = 15, + CLK_CRYPTO_APK_DIV_13 = 13, + CLK_CRYPTO_APK_DIV_11 = 11, + CLK_CRYPTO_APK_DIV_7 = 7, + CLK_CRYPTO_PLL_SEL_SHIFT = 6, + CLK_CRYPTO_PLL_SEL_MASK = 0x3 << CLK_CRYPTO_PLL_SEL_SHIFT, + CLK_CRYPTO_PLL_SEL_DPLL = 0, + CLK_CRYPTO_DIV_CON_SHIFT = 0, + CLK_CRYPTO_DIV_CON_MASK = 0x1f << CLK_CRYPTO_DIV_CON_SHIFT, + CLK_CRYPTO_DIV_CON_15 = 15, + CLK_CRYPTO_DIV_CON_13 = 13, + CLK_CRYPTO_DIV_CON_11 = 11, + CLK_CRYPTO_DIV_CON_7 = 7, + + /* CLKSEL_CON8 */ + DCLK_VOP_SEL_DCLK_VOP = 0, + DCLK_VOP_DIV_CON_SHIFT = 0, + DCLK_VOP_DIV_CON_MASK = 0xff << DCLK_VOP_DIV_CON_SHIFT, + DCLK_VOP_DIV_CON_15 = 15, + DCLK_VOP_DIV_CON_11 = 11, + + /* CLKSEL_CON10 */ + CLK_UART0_PLL_SEL_SHIFT = 13, + CLK_UART0_PLL_SEL_MASK = 0x7 << CLK_UART0_PLL_SEL_SHIFT, + CLK_UART0_PLL_SEL_XIN_OSC0 = 4, + CLK_UART0_DIV_CON_SHIFT = 0, + CLK_UART0_DIV_CON_MASK = 0x1f << CLK_UART0_DIV_CON_SHIFT, + CLK_UART0_DIV_CON = 0, + CLK_UART0_DIV_CON_15 = 15, + + /* CLKSEL_CON13 */ + CLK_UART1_PLL_SEL_SHIFT = 13, + CLK_UART1_PLL_SEL_MASK = 0x7 << CLK_UART1_PLL_SEL_SHIFT, + CLK_UART1_PLL_SEL_XIN_OSC0 = 4, + CLK_UART1_DIV_CON_SHIFT = 0, + CLK_UART1_DIV_CON_MASK = 0x1f << CLK_UART1_DIV_CON_SHIFT, + CLK_UART1_DIV_CON = 0, + CLK_UART1_DIV_CON_15 = 15, + + /* CLKSEL_CON16 */ + CLK_UART2_PLL_SEL_SHIFT = 13, + CLK_UART2_PLL_SEL_MASK = 0x7 << CLK_UART2_PLL_SEL_SHIFT, + CLK_UART2_PLL_SEL_XIN_OSC0 = 4, + CLK_UART2_DIV_CON_SHIFT = 0, + CLK_UART2_DIV_CON_MASK = 0x1f << CLK_UART2_DIV_CON_SHIFT, + CLK_UART2_DIV_CON = 0, + CLK_UART2_DIV_CON_15 = 15, + + /* CLKSEL_CON19 */ + CLK_UART3_PLL_SEL_SHIFT = 13, + CLK_UART3_PLL_SEL_MASK = 0x7 << CLK_UART3_PLL_SEL_SHIFT, + CLK_UART3_PLL_SEL_XIN_OSC0 = 4, + CLK_UART3_DIV_CON_SHIFT = 0, + CLK_UART3_DIV_CON_MASK = 0x1f << CLK_UART3_DIV_CON_SHIFT, + CLK_UART3_DIV_CON = 0, + CLK_UART3_DIV_CON_15 = 15, + + /* CLKSEL_CON22 */ + CLK_UART4_PLL_SEL_SHIFT = 13, + CLK_UART4_PLL_SEL_MASK = 0x7 << CLK_UART4_PLL_SEL_SHIFT, + CLK_UART4_PLL_SEL_XIN_OSC0 = 4, + CLK_UART4_DIV_CON_SHIFT = 0, + CLK_UART4_DIV_CON_MASK = 0x1f << CLK_UART4_DIV_CON_SHIFT, + CLK_UART4_DIV_CON = 0, + CLK_UART4_DIV_CON_15 = 15, + + /* CLKSEL_CON25 */ + CLK_I2C0_PLL_SEL_SHIFT = 14, + CLK_I2C0_PLL_SEL_MASK = 0x3 << CLK_I2C0_PLL_SEL_SHIFT, + CLK_I2C0_PLL_SEL_DPLL = 0, + CLK_I2C0_DIV_CON_SHIFT = 0, + CLK_I2C0_DIV_CON_MASK = 0x7f << CLK_I2C0_DIV_CON_SHIFT, + CLK_I2C0_DIV_CON_7 = 7, + CLK_I2C0_DIV_CON_5 = 5, + CLK_I2C0_DIV_CON_3 = 3, + + /* CLKSEL_CON26 */ + CLK_I2C1_PLL_SEL_SHIFT = 14, + CLK_I2C1_PLL_SEL_MASK = 0x3 << CLK_I2C1_PLL_SEL_SHIFT, + CLK_I2C1_PLL_SEL_DPLL = 0, + CLK_I2C1_DIV_CON_SHIFT = 0, + CLK_I2C1_DIV_CON_MASK = 0x7f << CLK_I2C1_DIV_CON_SHIFT, + CLK_I2C1_DIV_CON_7 = 7, + CLK_I2C1_DIV_CON_5 = 5, + CLK_I2C1_DIV_CON_3 = 3, + + /* CLKSEL_CON27 */ + CLK_I2C2_PLL_SEL_SHIFT = 14, + CLK_I2C2_PLL_SEL_MASK = 0x3 << CLK_I2C2_PLL_SEL_SHIFT, + CLK_I2C2_PLL_SEL_DPLL = 0, + CLK_I2C2_DIV_CON_SHIFT = 0, + CLK_I2C2_DIV_CON_MASK = 0x7f << CLK_I2C2_DIV_CON_SHIFT, + CLK_I2C2_DIV_CON_7 = 7, + CLK_I2C2_DIV_CON_5 = 5, + CLK_I2C2_DIV_CON_3 = 3, + + /* CLKSEL_CON28 */ + CLK_I2C3_PLL_SEL_SHIFT = 14, + CLK_I2C3_PLL_SEL_MASK = 0x3 << CLK_I2C3_PLL_SEL_SHIFT, + CLK_I2C3_PLL_SEL_DPLL = 0, + CLK_I2C3_DIV_CON_SHIFT = 0, + CLK_I2C3_DIV_CON_MASK = 0x7f << CLK_I2C3_DIV_CON_SHIFT, + CLK_I2C3_DIV_CON_7 = 7, + CLK_I2C3_DIV_CON_5 = 5, + CLK_I2C3_DIV_CON_3 = 3, + + /* CLKSEL_CON29 */ + CLK_PWM_DIV_CON_15 = 15, + CLK_PWM_DIV_CON_11 = 11, + CLK_PWM_DIV_CON_7 = 7, + + /* CLKSEL_CON30 */ + CLK_SPI0_PLL_SEL_SHIFT = 14, + CLK_SPI0_PLL_SEL_MASK = 0x3 << CLK_SPI0_PLL_SEL_SHIFT, + CLK_SPI0_PLL_SEL_DPLL = 0, + CLK_SPI0_DIV_CON_SHIFT = 0, + CLK_SPI0_DIV_CON_MASK = 0x7f << CLK_SPI0_DIV_CON_SHIFT, + CLK_SPI0_DIV_CON_15 = 15, + CLK_SPI0_DIV_CON_11 = 11, + CLK_SPI0_DIV_CON_7 = 7, + + /* CLKSEL_CON31 */ + CLK_SPI1_PLL_SEL_SHIFT = 14, + CLK_SPI1_PLL_SEL_MASK = 0x3 << CLK_SPI1_PLL_SEL_SHIFT, + CLK_SPI1_PLL_SEL_DPLL = 0, + CLK_SPI1_DIV_CON_SHIFT = 0, + CLK_SPI1_DIV_CON_MASK = 0x7f << CLK_SPI1_DIV_CON_SHIFT, + CLK_SPI1_DIV_CON_15 = 15, + CLK_SPI1_DIV_CON_11 = 11, + CLK_SPI1_DIV_CON_7 = 7, + + /* CLKSEL_CON32 */ + CLK_SPI2_PLL_SEL_SHIFT = 14, + CLK_SPI2_PLL_SEL_MASK = 0x3 << CLK_SPI2_PLL_SEL_SHIFT, + CLK_SPI2_PLL_SEL_DPLL = 0, + CLK_SPI2_DIV_CON_SHIFT = 0, + CLK_SPI2_DIV_CON_MASK = 0x7f << CLK_SPI2_DIV_CON_SHIFT, + CLK_SPI2_DIV_CON_15 = 15, + CLK_SPI2_DIV_CON_11 = 11, + CLK_SPI2_DIV_CON_7 = 7, + + /* CLKSEL_CON36 */ + A_H_P_PERI_PLL_SEL_SHIFT = 6, + A_H_P_PERI_PLL_SEL_MASK = 0x3 << A_H_P_PERI_PLL_SEL_SHIFT, + A_H_P_PERI_PLL_SEL_DPLL = 0, + ACLK_PERI_DIV_CON_SHIFT = 0, + ACLK_PERI_DIV_CON_MASK = 0x1f << ACLK_PERI_DIV_CON_SHIFT, + ACLK_PERI_DIV_CON_7 = 7, + ACLK_PERI_DIV_CON_5 = 5, + ACLK_PERI_DIV_CON_3 = 3, + + /* CLKSEL_CON37 */ + PCLK_PERI_DIV_CON_SHIFT = 8, + PCLK_PERI_DIV_CON_MASK = 0x1f << PCLK_PERI_DIV_CON_SHIFT, + PCLK_PERI_DIV_CON_31 = 31, + PCLK_PERI_DIV_CON_27 = 27, + PCLK_PERI_DIV_CON_23 = 23, + PCLK_PERI_DIV_CON_15 = 15, + HCLK_PERI_DIV_CON_SHIFT = 0, + HCLK_PERI_DIV_CON_MASK = 0x1f << HCLK_PERI_DIV_CON_SHIFT, + HCLK_PERI_DIV_CON_15 = 15, + HCLK_PERI_DIV_CON_13 = 13, + HCLK_PERI_DIV_CON_11 = 11, + HCLK_PERI_DIV_CON_7 = 7, + + /* CLKSEL_CON38 */ + CLK_NANDC_SEL50_SHIFT = 15, + CLK_NANDC_SEL50_MASK = 0x1 << CLK_NANDC_SEL50_SHIFT, + CLK_NANDC_SEL50_EVEN = 0, + CLK_NANDC_SEL50_ALWAYS = 1, + CLK_NANDC_PLL_SEL_SHIFT = 6, + CLK_NANDC_PLL_SEL_MASK = 0x3 << CLK_NANDC_PLL_SEL_SHIFT, + CLK_NANDC_PLL_SEL_DPLL = 0, + CLK_NANDC_DIV_CON_SHIFT = 0, + CLK_NANDC_DIV_CON_MASK = 0x1f << CLK_NANDC_DIV_CON_SHIFT, + CLK_NANDC_DIV_CON_15 = 15, + CLK_NANDC_DIV_CON_13 = 13, + CLK_NANDC_DIV_CON_11 = 11, + CLK_NANDC_DIV_CON_7 = 7, + + /* CLKSEL_CON39 */ + CLK_SDMMC_SEL50_SHIFT = 15, + CLK_SDMMC_SEL50_MASK = 0x1 << CLK_SDMMC_SEL50_SHIFT, + CLK_SDMMC_SEL50_EVEN = 0, + CLK_SDMMC_SEL50_ALWAYS = 1, + CLK_SDMMC_PLL_SEL_SHIFT = 8, + CLK_SDMMC_PLL_SEL_MASK = 0x3 << CLK_SDMMC_PLL_SEL_SHIFT, + CLK_SDMMC_PLL_SEL_DPLL = 0, + CLK_SDMMC_DIV_CON_SHIFT = 0, + CLK_SDMMC_DIV_CON_MASK = 0xff << CLK_SDMMC_DIV_CON_SHIFT, + CLK_SDMMC_DIV_CON_31 = 31, + CLK_SDMMC_DIV_CON_27 = 27, + CLK_SDMMC_DIV_CON_23 = 23, + CLK_SDMMC_DIV_CON_15 = 15, + + /* CLKSEL_CON40 */ + CLK_SDIO_SEL50_SHIFT = 15, + CLK_SDIO_SEL50_MASK = 0x1 << CLK_SDIO_SEL50_SHIFT, + CLK_SDIO_SEL50_EVEN = 0, + CLK_SDIO_SEL50_ALWAYS = 1, + CLK_SDIO_PLL_SEL_SHIFT = 8, + CLK_SDIO_PLL_SEL_MASK = 0x3 << CLK_SDIO_PLL_SEL_SHIFT, + CLK_SDIO_PLL_SEL_DPLL = 0, + CLK_SDIO_DIV_CON_SHIFT = 0, + CLK_SDIO_DIV_CON_MASK = 0xff << CLK_SDIO_DIV_CON_SHIFT, + CLK_SDIO_DIV_CON_4 = 4, + CLK_SDIO_DIV_CON_3 = 3, + CLK_SDIO_DIV_CON_2 = 2, + + /* CLKSEL_CON41 */ + CLK_EMMC_SEL50_SHIFT = 15, + CLK_EMMC_SEL50_MASK = 0x1 << CLK_EMMC_SEL50_SHIFT, + CLK_EMMC_SEL50_EVEN = 0, + CLK_EMMC_SEL50_ALWAYS = 1, + CLK_EMMC_PLL_SEL_SHIFT = 8, + CLK_EMMC_PLL_SEL_MASK = 0x3 << CLK_EMMC_PLL_SEL_SHIFT, + CLK_EMMC_PLL_SEL_DPLL = 0, + CLK_EMMC_DIV_CON_SHIFT = 0, + CLK_EMMC_DIV_CON_MASK = 0xff << CLK_EMMC_DIV_CON_SHIFT, + CLK_EMMC_DIV_CON_31 = 31, + CLK_EMMC_DIV_CON_27 = 27, + CLK_EMMC_DIV_CON_23 = 23, + CLK_EMMC_DIV_CON_15 = 15, + + /* CLKSEL_CON42 */ + CLK_SFC_PLL_SEL_SHIFT = 14, + CLK_SFC_PLL_SEL_MASK = 0x3 << CLK_SFC_PLL_SEL_SHIFT, + CLK_SFC_PLL_SEL_DPLL = 0, + CLK_SFC_DIV_CON_SHIFT = 0, + CLK_SFC_DIV_CON_MASK = 0x7f << CLK_SFC_DIV_CON_SHIFT, + CLK_SFC_DIV_CON_65 = 65, + CLK_SFC_DIV_CON_53 = 53, + CLK_SFC_DIV_CON_49 = 49, + CLK_SFC_DIV_CON_31 = 31, + + /* CLKSEL_CON43 */ + RMII_CLK_SEL_SHIFT = 15, + RMII_CLK_SEL_MASK = 0x1 << RMII_CLK_SEL_SHIFT, + RMII_CLK_SEL_100M = 1, + RMII_CLK_SEL_10M = 0, + RMII_EXTCLKSRC_SEL_SHIFT = 14, + RMII_EXTCLKSRC_SEL_MASK = 0x1 << RMII_EXTCLKSRC_SEL_SHIFT, + RMII_EXTCLKSRC_SEL_CLK_MAC = 0, + CLK_MAC_PLL_SEL_SHIFT = 6, + CLK_MAC_PLL_SEL_MASK = 0x3 << CLK_MAC_PLL_SEL_SHIFT, + CLK_MAC_PLL_SEL_DPLL = 0, + CLK_MAC_DIV_CON_SHIFT = 0, + CLK_MAC_DIV_CON_MASK = 0x1f << CLK_MAC_DIV_CON_SHIFT, + CLK_MAC_DIV_CON_31 = 31, + CLK_MAC_DIV_CON_23 = 23, + CLK_MAC_DIV_CON_25 = 25, + + /* CLKSEL_CON44 */ + CLK_WIFI_SEL_SHIFT = 7, + CLK_WIFI_SEL_MASK = 0x1 << CLK_WIFI_SEL_SHIFT, + CLK_WIFI_SEL_CLK_WIFI = 1, + CLK_WIFI_PLL_SEL_SHIFT = 6, + CLK_WIFI_PLL_SEL_MASK = 0x1 << CLK_WIFI_PLL_SEL_SHIFT, + CLK_WIFI_PLL_SEL_DPLL = 0, + CLK_WIFI_DIV_CON_SHIFT = 0, + CLK_WIFI_DIV_CON_MASK = 0x3f << CLK_WIFI_DIV_CON_SHIFT, + CLK_WIFI_DIV_CON_39 = 39, + CLK_WIFI_DIV_CON_29 = 29, + CLK_WIFI_DIV_CON_49 = 49, + CLK_WIFI_DIV_CON_19 = 19, + + /* CLKSEL_CON45 */ + PCLK_AUDIO_DIV_CON_SHIFT = 8, + PCLK_AUDIO_DIV_CON_MASK = 0x1f << PCLK_AUDIO_DIV_CON_SHIFT, + PCLK_AUDIO_DIV_CON_9 = 9, + H_PCLK_AUDIO_PLL_SEL_SHIFT = 6, + H_PCLK_AUDIO_PLL_SEL_MASK = 0x3 << H_PCLK_AUDIO_PLL_SEL_SHIFT, + H_PCLK_AUDIO_PLL_SEL_VPLL0 = 0, + HCLK_AUDIO_DIV_CON_SHIFT = 0, + HCLK_AUDIO_DIV_CON_MASK = 0x1f << HCLK_AUDIO_DIV_CON_SHIFT, + HCLK_AUDIO_DIV_CON_9 = 9, + + /* CLKSEL_CON46 */ + CLK_PDM_SEL_SHIFT = 15, + CLK_PDM_SEL_MASK = 0x1 << CLK_PDM_SEL_SHIFT, + CLK_PDM_SEL_CLK_PDM = 0, + CLK_PDM_PLL_SEL_SHIFT = 8, + CLK_PDM_PLL_SEL_MASK = 0x3 << CLK_PDM_PLL_SEL_SHIFT, + CLK_PDM_PLL_SEL_VPLL0 = 0, + CLK_PDM_DIV_CON_SHIFT = 0, + CLK_PDM_DIV_CON_MASK = 0x7f << CLK_PDM_DIV_CON_SHIFT, + CLK_PDM_DIV_CON_15 = 15, + + /* CLKSEL_CON48 */ + CLK_SPDIFTX_DIV_CON_SHIFT = 0, + CLK_SPDIFTX_DIV_CON_MASK = 0x7f << CLK_SPDIFTX_DIV_CON_SHIFT, + CLK_SPDIFTX_DIV_CON_15 = 15, + + /* CLKSEL_CON52,CLKSEL_CON56,CLKSEL_CON60,CLKSEL_CON64 */ + I2S_8CH_OUT_SEL_SHIFT = 15, + I2S_8CH_OUT_SEL_MASK = 0x1 << I2S_8CH_OUT_SEL_SHIFT, + I2S_8CH_OUT_SEL_TX_RX = 0, + I2S_8CH_TX_RX_SEL_SHIFT = 12, + I2S_8CH_TX_RX_SEL_MASK = 0x1 << I2S_8CH_TX_RX_SEL_SHIFT, + I2S_8CH_TX_RX_SEL_TX = 0, + I2S_8CH_TX_SEL_SHIFT = 10, + I2S_8CH_TX_SEL_MASK = 0x3 << I2S_8CH_TX_SEL_SHIFT, + I2S_8CH_TX_SEL_TX = 0, + I2S_8CH_TX_PLL_SEL_SHIFT = 8, + I2S_8CH_TX_PLL_SEL_MASK = 0x3 << I2S_8CH_TX_PLL_SEL_SHIFT, + I2S_8CH_TX_PLL_SEL_VPLL1 = 1, + I2S_8CH_TX_DIV_CON_SHIFT = 0, + I2S_8CH_TX_DIV_CON_MASK = 0x7f << I2S_8CH_TX_DIV_CON_SHIFT, + I2S_8CH_TX_DIV_CON_17 = 17, + + /* CLKSEL_CON54,CLKSEL_CON58,CLKSEL_CON62,CLKSEL_CON66 */ + I2S_8CH_RX_TX_SEL_SHIFT = 12, + I2S_8CH_RX_TX_SEL_MASK = 0x1 << I2S_8CH_RX_TX_SEL_SHIFT, + I2S_8CH_RX_TX_SEL_RX = 0, + I2S_8CH_RX_SEL_SHIFT = 10, + I2S_8CH_RX_SEL_MASK = 0x3 << I2S_8CH_RX_SEL_SHIFT, + I2S_8CH_RX_SEL_RX = 0, + I2S_8CH_RX_PLL_SEL_SHIFT = 8, + I2S_8CH_RX_PLL_SEL_MASK = 0x3 << I2S_8CH_RX_PLL_SEL_SHIFT, + I2S_8CH_RX_PLL_SEL_VPLL0 = 0, + I2S_8CH_RX_DIV_CON_SHIFT = 0, + I2S_8CH_RX_DIV_CON_MASK = 0x7f << I2S_8CH_RX_DIV_CON_SHIFT, + I2S_8CH_RX_DIV_CON_19 = 19, + + /* SOFTRST_CON1 */ + PRESETN_DDRPHY_REQ_SHIFT = 14, + PRESETN_DDRPHY_REQ_MASK = 0x1 << PRESETN_DDRPHY_REQ_SHIFT, + PRESETN_DDRPHY_REQ_EN = 1, + PRESETN_DDRPHY_REQ_DIS = 0, + + RESETN_DDRPHYDIV_REQ_SHIFT = 13, + RESETN_DDRPHYDIV_REQ_MASK = 0x1 << RESETN_DDRPHYDIV_REQ_SHIFT, + RESETN_DDRPHYDIV_REQ_EN = 1, + RESETN_DDRPHYDIV_REQ_DIS = 0, + + RESETN_DDRPHY_REQ_SHIFT = 12, + RESETN_DDRPHY_REQ_MASK = 0x1 << RESETN_DDRPHY_REQ_SHIFT, + RESETN_DDRPHY_REQ_EN = 1, + RESETN_DDRPHY_REQ_DIS = 0, + + PRESETN_DDRUPCTL_REQ_SHIFT = 6, + PRESETN_DDRUPCTL_REQ_MASK = 0x1 << PRESETN_DDRUPCTL_REQ_SHIFT, + PRESETN_DDRUPCTL_REQ_EN = 1, + PRESETN_DDRUPCTL_REQ_DIS = 0, + + RESETN_DDRUPCTL_REQ_SHIFT = 4, + RESETN_DDRUPCTL_REQ_MASK = 0x1 << RESETN_DDRUPCTL_REQ_SHIFT, + RESETN_DDRUPCTL_REQ_EN = 1, + RESETN_DDRUPCTL_REQ_DIS = 0, + + /* CLKGATE_CON4 */ + CLK_PMU_PVTM_CLK_EN_SHIFT = 4, + CLK_PMU_PVTM_CLK_EN_MASK = 0x1 << CLK_PMU_PVTM_CLK_EN_SHIFT, + CLK_PMU_PVTM_CLK_EN = 0, + + /* SOFTRST_CON5 */ + RESETN_PMU_PVTM_REQ_SHIFT = 1, + RESETN_PMU_PVTM_REQ_MASK = 0x1 << RESETN_PMU_PVTM_REQ_SHIFT, + RESETN_PMU_PVTM_REQ_ACT = 1, + RESETN_PMU_PVTM_REQ_DIS = 0, +}; + #endif diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3308.h b/arch/arm/include/asm/arch-rockchip/grf_rk3308.h index bf241a4bd5..2d0663f4db 100644 --- a/arch/arm/include/asm/arch-rockchip/grf_rk3308.h +++ b/arch/arm/include/asm/arch-rockchip/grf_rk3308.h @@ -154,8 +154,8 @@ struct rk3308_grf { unsigned int host0_status0; unsigned int reserved31[(0x4a0 - 0x48C) / 4 - 1]; unsigned int mac_con0; - unsigned int upctrl_con0; - unsigned int upctrl_status0; + unsigned int upctl_con0; + unsigned int upctl_status0; unsigned int reserved32[(0x500 - 0x4A8) / 4 - 1]; unsigned int os_reg0; unsigned int os_reg1; @@ -195,4 +195,40 @@ struct rk3308_sgrf { }; check_member(rk3308_sgrf, fastboot_en, 0x20); +enum { + /* GPIO1D_IOMUX */ + GPIO1D1_SEL_SHIFT = 2, + GPIO1D1_SEL_MASK = 0x3 << GPIO1D1_SEL_SHIFT, + GPIO1D1_SEL_UART1_TX = 1, + GPIO1D0_SEL_SHIFT = 0, + GPIO1D0_SEL_MASK = 0x3 << GPIO1D0_SEL_SHIFT, + GPIO1D1_SEL_UART1_RX = 1, + /* GPIO4D_IOMUX */ + GPIO4D3_SEL_SHIFT = 6, + GPIO4D3_SEL_MASK = 0x3 << GPIO4D3_SEL_SHIFT, + GPIO4D3_SEL_UART2_TXM1 = 2, + GPIO4D2_SEL_SHIFT = 4, + GPIO4D2_SEL_MASK = 0x3 << GPIO4D2_SEL_SHIFT, + GPIO4D2_SEL_UART2_RXM1 = 2, + /* UPCTL_CON0 */ + CYSYREQ_UPCTL_DDRSTDBY_SHIFT = 5, + CYSYREQ_UPCTL_DDRSTDBY_MASK = 1 << CYSYREQ_UPCTL_DDRSTDBY_SHIFT, + CYSYREQ_UPCTL_DDRSTDBY_EN = 1, + GRF_DDR_16BIT_EN_SHIFT = 0, + GRF_DDR_16BIT_EN_MASK = 1 << GRF_DDR_16BIT_EN_SHIFT, + GRF_DDR_16BIT_EN = 1, + /* SOC_CON5 */ + UART2_MULTI_IOFUNC_SEL_SHIFT = 2, + UART2_MULTI_IOFUNC_SEL_MASK = 0x3 << UART2_MULTI_IOFUNC_SEL_SHIFT, + UART2_MULTI_IOFUNC_SEL_M1 = 1, + /* SOC_CON12 */ + NOC_MSCH_MAIN_PARTIAL_SHIFT = 1, + NOC_MSCH_MAIN_PARTIAL_MASK = 0x1 << NOC_MSCH_MAIN_PARTIAL_SHIFT, + NOC_MSCH_MAIN_PARTIAL_EN = 1, + NOC_MSCH_MAINDDR3_SHIFT = 0, + NOC_MSCH_MAINDDR3_MASK = 0x1 << NOC_MSCH_MAINDDR3_SHIFT, + NOC_MSCH_MAINDDR3_EN = 1, + NOC_MSCH_MAINDDR3_DIS = 0, +}; + #endif diff --git a/arch/arm/include/asm/arch-rockchip/pmu_rk3308.h b/arch/arm/include/asm/arch-rockchip/pmu_rk3308.h new file mode 100644 index 0000000000..6c25ec065c --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/pmu_rk3308.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd + */ + +#ifndef _ASM_ARCH_PMU_RK3308_H +#define _ASM_ARCH_PMU_RK3308_H +struct rk3308_pmu { + u32 reserved0[4]; + u32 wakeup_cfg2_lo; + u32 reserved1; + u32 pwrdn_con_lo; + u32 reserved2; + u32 pwrdn_st; + u32 pwrmode_core_con_lo; + u32 reserved3; + u32 pwrmode_common_con_lo; + u32 pwrmode_common_con_hi; + u32 sft_con_lo; + u32 sft_con_hi; + u32 int_con_lo; + u32 int_con_hi; + u32 int_st; + u32 reserved4[6]; + u32 core_pwr_st; + u32 bus_idle_req_lo; + u32 reserved5; + u32 bus_idle_st; + u32 power_st; + u32 osc_cnt_lo; + u32 osc_cnt_hi; + u32 plllock_cnt_lo; + u32 plllock_cnt_hi; + u32 pllrst_cnt_lo; + u32 pllrst_cnt_hi; + u32 reserved6[2]; + u32 ddrio_pwron_cnt_lo; + u32 ddrio_pwron_cnt_hi; + u32 wakeup_rst_clr_cnt_lo; + u32 wakeup_rst_clr_cnt_hi; + u32 ddr_sref_st; + u32 sys_reg0_lo; + u32 sys_reg0_hi; + u32 sys_reg1_lo; + u32 sys_reg1_hi; + u32 sys_reg2_lo; + u32 sys_reg2_hi; + u32 sys_reg3_lo; + u32 sys_reg3_hi; + u32 scu_pwrdn_cnt_lo; + u32 scu_pwrdn_cnt_hi; + u32 scu_pwrup_cnt_lo; + u32 scu_pwrup_cnt_hi; + u32 timeout_cnt_lo; + u32 timeout_cnt_hi; + u32 cpu0apm_con_lo; + u32 cpu1apm_con_lo; + u32 cpu2apm_con_lo; + u32 cpu3apm_con_lo; + u32 info_tx_con_lo; +}; + +check_member(rk3308_pmu, info_tx_con_lo, 0x00f0); +enum { /* SFT_CON_LO */ + DDR_IO_RET_CFG_SHIFT = 8, + DDR_IO_RET_CFG_MASK = 1 << DDR_IO_RET_CFG_SHIFT, + DDR_IO_RET_CFG = 0, +}; + +#endif + diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rk3308.h b/arch/arm/include/asm/arch-rockchip/sdram_rk3308.h new file mode 100644 index 0000000000..d215bb2f0f --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/sdram_rk3308.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd + */ + +#ifndef _ASM_ARCH_SDRAM_RK3308_H +#define _ASM_ARCH_SDRAM_RK3308_H + +#include +#include +#include +#include +#include +#include + +#define CG_EXIT_TH (250) + +#define PATTERN (0x5aa5f00f) + +struct rk3308_ddr_standby { + u32 con0; + u32 con1; + u32 status0; +}; + +struct rk3308_service_msch { + u32 id_coreid; + u32 id_revisionid; + u32 ddrconf; + u32 ddrtiming; + u32 ddrmode; + u32 readlatency; +}; + +enum { + /* ddr standby */ + IDLE_TH_SHIFT = 16, + /* can not gate msch clk */ + MSCH_GATE_CLK_SHIFT = 7, + MSCH_GATE_CLK_EN = 1, + + DDRPHY4X_GATE_SHIFT = 6, + DDRPHY4X_GATE_EN = 1, + + UPCTL_CORE_CLK_GATE_SHIFT = 5, + UPCTL_CORE_CLK_GATE_EN = 1, + + UPCTL_ACLK_GATE_SHIFT = 4, + UPCTL_ACLK_GATE_EN = 1, + + CTL_IDLR_SHIFT = 1, + CTL_IDLR_EN = 1, + + STDBY_EN_SHIFT = 0, + STDBY_EN = 1, + + CG_EXIT_TH_SHIFT = 16, + + STDBY_STATUS_SHIFT = 0, + STDBY_STATUS_MASK = 0x7f << STDBY_STATUS_SHIFT, + ST_STDBY = 0x10, +}; + +enum { + /* memory scheduler ddrtiming */ + BWRATIO_HALF_BW = 0x80000000, + BWRATIO_HALF_BW_DIS = 0x0, + + PHY_TX_DE_SKEW_SHIFT = 3, + PHY_TX_DE_SKEW_EN = 1, +}; + +struct dram_info { + struct rk3308_cru *cru; + struct rk3308_grf *grf; + struct rk3308_sgrf *sgrf; + struct rk3308_pmu *pmu; + struct ddr_phy *phy; + struct ddr_pctl *pctl; + struct rk3308_ddr_standby *standby; + struct rk3308_service_msch *service_msch; + struct ram_info info; +}; + +struct sdram_params { + u32 idle_pd; + u32 idle_sr; + u32 ddr_2t_en; + u32 stdby_idle; + struct ddr_config ddr_config_t; + struct ddr_timing ddr_timing_t; +}; + +struct rk3308_ddr_skew { + u32 a0_a1_skew[14]; + u32 cs0_dm0_skew[22]; +}; + +struct rk3308_ddr_gd { + struct sdram_head_info_v0 head_info; + struct rk3308_ddr_skew ddr_skew; +}; + +int check_rd_gate(struct dram_info *priv); +void copy_to_reg(u32 *dest, const u32 *src, u32 n); +void enable_low_power(struct dram_info *priv, + struct sdram_params *params_priv); +void ddr_cap_info(size_t size); +void ddr_msch_cfg(struct dram_info *priv, + struct sdram_params *params_priv); +void ddr_msch_cfg_rbc(struct sdram_params *params_priv, + struct dram_info *priv); +void ddr_msch_get_max_col(struct dram_info *priv, + struct ddr_schedule *sch_priv); +void ddr_msch_get_max_row(struct dram_info *priv, + struct ddr_schedule *sch_priv); +void ddr_phy_skew_cfg(struct dram_info *priv); +void ddr_phy_dqs_rx_dll_cfg(struct dram_info *priv, u32 freq); +void enable_ddr_io_ret(struct dram_info *priv); +void modify_data_training(struct dram_info *priv, + struct sdram_params *params_priv); +void move_to_config_state(struct dram_info *priv); +void move_to_access_state(struct dram_info *priv); +void pctl_cfg_grf(struct dram_info *priv, + struct sdram_params *params_priv); +void phy_pctrl_reset_cru(struct dram_info *priv); +void print_dec(u32 n); +void rkdclk_init(struct dram_info *priv, + struct sdram_params *params_priv); +int rv1108_sdram_init(struct dram_info *sdram_priv, + struct sdram_params *params_priv); +void set_bw_grf(struct dram_info *priv); +void set_ds_odt(struct dram_info *priv, + struct sdram_params *params_priv); + +#endif + diff --git a/arch/arm/mach-rockchip/rk3308/rk3308.c b/arch/arm/mach-rockchip/rk3308/rk3308.c index 3cd85005e7..f259fd8f83 100644 --- a/arch/arm/mach-rockchip/rk3308/rk3308.c +++ b/arch/arm/mach-rockchip/rk3308/rk3308.c @@ -1,15 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (c) 2018 Rockchip Electronics Co., Ltd - * - * SPDX-License-Identifier: GPL-2.0+ + * Copyright (C) 2020 Rockchip Electronics Co., Ltd */ + #include +#include #include +#include +#include +#include #include #include #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -41,6 +46,8 @@ struct mm_region *mem_map = rk3308_mem_map; #define GRF_BASE 0xff000000 #define SGRF_BASE 0xff2b0000 +#define CRU_BASE 0xff500000 + enum { @@ -117,6 +124,11 @@ enum { VCCIO3_1V8, }; +enum { + SND_GLB_WDT_RST = BIT(3), + FST_GLB_WDT_RST = BIT(2), +}; + /* * The voltage of VCCIO3(which is the voltage domain of emmc/flash/sfc * interface) can indicated by GPIO0_A4 or io_vsel3. The SOC defaults @@ -153,6 +165,93 @@ int rk_board_init(void) return 0; } +#define SERVICE_CPU_BASE 0xff5c0000 +#define SERVICE_VOICE_BASE 0xff5d0000 +#define SERVICE_LOGIC_BASE 0xff5d8000 +#define SERVICE_PERI_BASE 0xff5e0000 +#define SERVICE_CPU_ADDR (SERVICE_CPU_BASE + 0x80) +#define SERVICE_VOP_ADDR (SERVICE_LOGIC_BASE + 0x100) +#define SERVICE_DMAC0_ADDR (SERVICE_LOGIC_BASE + 0x0) +#define SERVICE_DMAC1_ADDR (SERVICE_LOGIC_BASE + 0x80) +#define SERVICE_CRYPTO_ADDR (SERVICE_LOGIC_BASE + 0x180) +#define SERVICE_VAD_ADDR (SERVICE_VOICE_BASE + 0x80) +#define SERVICE_EMMC_ADDR (SERVICE_PERI_BASE + 0x80) +#define SERVICE_GMAC_ADDR (SERVICE_PERI_BASE + 0x100) +#define SERVICE_NAND_ADDR (SERVICE_PERI_BASE + 0x180) +#define SERVICE_SDIO_ADDR (SERVICE_PERI_BASE + 0x200) +#define SERVICE_SDMMC_ADDR (SERVICE_PERI_BASE + 0x280) +#define SERVICE_SFC_ADDR (SERVICE_PERI_BASE + 0x300) +#define SERVICE_USB_HOST_ADDR (SERVICE_PERI_BASE + 0x380) +#define SERVICE_USB_OTG_ADDR (SERVICE_PERI_BASE + 0x400) + +#define DOS_PRIORITY_OFFSET 0x8 +#define QOS_PRIORITY_P1_P0(p1, p0) ((((p1) & 0x3) << 8) |\ + (((p0) & 0x3) << 0)) + +enum { + IOVSEL4_SHIFT = 4, + IOVSEL4_MASK = BIT(4), + VCCIO4_3V3 = 0, + VCCIO4_1V8, +}; + +int arch_cpu_init(void) +{ +#ifndef CONFIG_TPL_BUILD +#ifdef CONFIG_SPL_BUILD + static struct rk3308_sgrf * const sgrf = (void *)SGRF_BASE; + + /* Set CRYPTO SDMMC EMMC NAND SFC USB master bus to be secure access */ + rk_clrreg(&sgrf->con_secure0, 0x2b83); +#endif +#else /* defined(CONFIG_TPL_BUILD) */ + static struct rk3308_cru * const cru = (void *)CRU_BASE; + static struct rk3308_grf * const grf = (void *)GRF_BASE; + u32 glb_rst_st; + + rk_clrsetreg(&grf->soc_con0, IOVSEL4_MASK, VCCIO4_3V3 << IOVSEL4_SHIFT); + + glb_rst_st = readl(&cru->glb_rst_st); + writel(FST_GLB_WDT_RST | SND_GLB_WDT_RST, &cru->glb_rst_st); + if (glb_rst_st & (FST_GLB_WDT_RST | SND_GLB_WDT_RST)) + writel(BOOT_WATCHDOG, CONFIG_ROCKCHIP_BOOT_MODE_REG); + + writel(WDT_GLB_SRST_CTRL << WDT_GLB_SRST_CTRL_SHIFT | + TSADC_GLB_SRST_CTRL << TSADC_GLB_SRST_CTRL_SHIFT, + &cru->glb_rst_con); + + writel(QOS_PRIORITY_P1_P0(1, 1), + SERVICE_CPU_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(3, 3), + SERVICE_VOP_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_DMAC0_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_DMAC1_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_CRYPTO_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(3, 3), + SERVICE_VAD_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_EMMC_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_GMAC_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_NAND_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_SDIO_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_SDMMC_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_SFC_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_USB_HOST_ADDR + DOS_PRIORITY_OFFSET); + writel(QOS_PRIORITY_P1_P0(2, 2), + SERVICE_USB_OTG_ADDR + DOS_PRIORITY_OFFSET); +#endif + return 0; +} + #ifdef CONFIG_SPL_BUILD int rk_board_init_f(void) { @@ -178,25 +277,85 @@ int rk_board_init_f(void) void board_debug_uart_init(void) { + static struct rk3308_cru * const cru = (void *)CRU_BASE; static struct rk3308_grf * const grf = (void *)GRF_BASE; +#if defined(CONFIG_DEBUG_UART_BASE) +#if (CONFIG_DEBUG_UART_BASE == 0xFF0C0000) + /*select 24M clock to UART2 */ + rk_clrsetreg(&cru->clksel_con[16], + CLK_UART2_PLL_SEL_MASK | CLK_UART2_DIV_CON_MASK, + CLK_UART2_PLL_SEL_XIN_OSC0 << CLK_UART2_PLL_SEL_SHIFT | + CLK_UART2_DIV_CON << CLK_UART2_DIV_CON_SHIFT); + +#if (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) + /* Enable early UART2 channel m0 on the rk3308 */ + rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK, + UART2_IO_SEL_M0 << UART2_IO_SEL_SHIFT); + rk_clrsetreg(&grf->gpio1ch_iomux, GPIO1C7_MASK | GPIO1C6_MASK, + GPIO1C7_UART2_TX_M0 << GPIO1C7_SHIFT | + GPIO1C6_UART2_RX_M0 << GPIO1C6_SHIFT); + +#elif (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) /* Enable early UART2 channel m1 on the rk3308 */ rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK, UART2_IO_SEL_M1 << UART2_IO_SEL_SHIFT); - rk_clrsetreg(&grf->gpio4d_iomux, - GPIO4D3_MASK | GPIO4D2_MASK, - GPIO4D2_UART2_RX_M1 << GPIO4D2_SHIFT | - GPIO4D3_UART2_TX_M1 << GPIO4D3_SHIFT); -} - -#if defined(CONFIG_SPL_BUILD) -int arch_cpu_init(void) -{ - static struct rk3308_sgrf * const sgrf = (void *)SGRF_BASE; - - /* Set CRYPTO SDMMC EMMC NAND SFC USB master bus to be secure access */ - rk_clrreg(&sgrf->con_secure0, 0x2b83); - - return 0; -} + if (readl(BROM_BOOTSOURCE_ID_ADDR) != BROM_BOOTSOURCE_SD) + rk_clrsetreg(&grf->gpio4d_iomux, + GPIO4D3_MASK | GPIO4D2_MASK, + GPIO4D2_UART2_RX_M1 << GPIO4D2_SHIFT | + GPIO4D3_UART2_TX_M1 << GPIO4D3_SHIFT); +#else + #error "Please select M0 or M1 for uart2 !!!" #endif + +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0E0000) + /*select 24M clock to UART4 */ + rk_clrsetreg(&cru->clksel_con[22], + CLK_UART4_PLL_SEL_MASK | CLK_UART4_DIV_CON_MASK, + CLK_UART4_PLL_SEL_XIN_OSC0 << CLK_UART4_PLL_SEL_SHIFT | + CLK_UART4_DIV_CON << CLK_UART4_DIV_CON_SHIFT); + + rk_clrsetreg(&grf->gpio4b_iomux, + GPIO4B1_SEL_MASK | GPIO4B0_SEL_MASK, + GPIO4B1_SEL_UART4_TX << GPIO4B1_SEL_SHIFT | + GPIO4B0_SEL_UART4_RX << GPIO4B0_SEL_SHIFT); +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0A0000) + /*select 24M clock to UART0 */ + rk_clrsetreg(&cru->clksel_con[10], + CLK_UART0_PLL_SEL_MASK | CLK_UART0_DIV_CON_MASK, + CLK_UART0_PLL_SEL_XIN_OSC0 << CLK_UART0_PLL_SEL_SHIFT | + CLK_UART0_DIV_CON << CLK_UART0_DIV_CON_SHIFT); + + rk_clrsetreg(&grf->gpio2a_iomux, + GPIO2A1_SEL_MASK | GPIO2A0_SEL_MASK, + GPIO2A1_SEL_UART0_TX << GPIO2A1_SEL_SHIFT | + GPIO2A0_SEL_UART0_RX << GPIO2A0_SEL_SHIFT); +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0B0000) + /*select 24M clock to UART1 */ + rk_clrsetreg(&cru->clksel_con[13], + CLK_UART1_PLL_SEL_MASK | CLK_UART1_DIV_CON_MASK, + CLK_UART1_PLL_SEL_XIN_OSC0 << CLK_UART1_PLL_SEL_SHIFT | + CLK_UART1_DIV_CON << CLK_UART1_DIV_CON_SHIFT); + + rk_clrsetreg(&grf->gpio1d_iomux, + GPIO1D1_SEL_MASK | GPIO1D0_SEL_MASK, + GPIO1D1_SEL_UART1_TX << GPIO1D1_SEL_SHIFT | + GPIO1D1_SEL_UART1_RX << GPIO1D0_SEL_SHIFT); +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0D0000) + /*select 24M clock to UART3 */ + rk_clrsetreg(&cru->clksel_con[19], + CLK_UART3_PLL_SEL_MASK | CLK_UART3_DIV_CON_MASK, + CLK_UART3_PLL_SEL_XIN_OSC0 << CLK_UART3_PLL_SEL_SHIFT | + CLK_UART3_DIV_CON << CLK_UART3_DIV_CON_SHIFT); + + rk_clrsetreg(&grf->gpio3b_iomux, + GPIO3B5_SEL_MASK | GPIO3B4_SEL_MASK, + GPIO3B5_SEL_UART3_TX << GPIO3B5_SEL_SHIFT | + GPIO3B4_SEL_UART3_RX << GPIO3B4_SEL_SHIFT); +#else + #error "Please select proper uart as debug uart !!!" +#endif +#endif /* defined(CONFIG_DEBUG_UART_BASE) */ +} + diff --git a/drivers/ram/rockchip/sdram-rk3308-ddr-skew.inc b/drivers/ram/rockchip/sdram-rk3308-ddr-skew.inc new file mode 100644 index 0000000000..2f681d833c --- /dev/null +++ b/drivers/ram/rockchip/sdram-rk3308-ddr-skew.inc @@ -0,0 +1,59 @@ +{ + .start_tag = 0x12345678, + .version_info = 0, + .gcpu_gen_freq = 0, + .g_d2_lp2_freq = (451 << 16) | 451, + .g_d3_lp3_freq = (589 << 16) | 0, + .g_d4_lp4_freq = 0x00000000, + .g_uart_info = (2 << 28) | (1 << 24) | 1500000, + .g_sr_pd_idle = (48 << 16) | 10, + .g_ch_info = 0 | 128, + .g_2t_info = 1, + .reserved11 = 0, + .reserved12 = 0, + .reserved13 = 0 +}, +{ + {/*cmd,addr de-skew*/ + 0x22, + 0x22, + 0x21, + 0x21, + 0x21, + 0x10, + 0x21, + 0x21, + 0x13, + 0x23, + 0x10, + 0x99,/*clk*/ + 0x03, + 0x30, + }, + {/*cs0 dq0~7,dm,dqs*/ + 0xaa, + 0xaa, + 0x88, + 0xbb, + 0x88, + 0x88, + 0x99, + 0x88, + 0x88, + 0x7a,/*dqs0 rx tx*/ + 0xa,/*dqsb0 tx*/ + /*cs0 dq8~15,dm,dqs*/ + 0x88, + 0xaa, + 0x99, + 0x68, + 0x89, + 0x88, + 0x99, + 0x87, + 0x89, + 0x56,/*dqs1 rx tx*/ + 0x6,/*dqsb1 tx*/ + }, +} + diff --git a/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-393.inc b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-393.inc new file mode 100644 index 0000000000..2bc4e95da3 --- /dev/null +++ b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-393.inc @@ -0,0 +1,71 @@ +{ + 0, + 0, + 0, + 0, + { + .ddr_type = 0x2, + .chn_cnt = 0x0, + .rank = 0x1, + .cs0_row = 0x0, + .cs1_row = 0x0, + .bank = 0x3, + .col = 0x0, + .dbw = 0x1, + .bw = 0x1 + }, + { + .freq = 393, + { + 0x000000C4, + 0x000000C8, + 0x000001F4, + 0x00000013, + 0x80000013, + 0x00000002, + 0x00000081, + 0x00010006, + 0x00000003, + 0x00000000, + 0x00000006, + 0x00000005, + 0x00000012, + 0x00000018, + 0x00000006, + 0x00000004, + 0x00000003, + 0x00000006, + 0x00000003, + 0x000000C8, + 0x00000002, + 0x00000008, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000001, + 0x00000001, + 0x00000003, + 0x00000005, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000003, + 0x00000000, + 0x00000169 + }, + { + { + 0x00001A63, + 0x00000000, + 0x00000000, + 0x00000000 + }, + 0x00000004, + 0x00000060 + }, + {0x1028B14C}, + 0x00000018, + {0x000004A2}, + 0x00000015 + } +} diff --git a/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-451.inc b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-451.inc new file mode 100644 index 0000000000..69394482c3 --- /dev/null +++ b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr2-detect-451.inc @@ -0,0 +1,71 @@ +{ + 0, + 0, + 0, + 0, + { + .ddr_type = 0x2, + .chn_cnt = 0x0, + .rank = 0x1, + .cs0_row = 0x0, + .cs1_row = 0x0, + .bank = 0x3, + .col = 0x0, + .dbw = 0x1, + .bw = 0x1 + }, + { + .freq = 451, + { + 0x000000E1, + 0x000000C8, + 0x000001F4, + 0x00000016, + 0x80000013, + 0x00000002, + 0x00000094, + 0x00010007, + 0x00000003, + 0x00000000, + 0x00000007, + 0x00000006, + 0x00000015, + 0x0000001C, + 0x00000007, + 0x00000005, + 0x00000004, + 0x00000007, + 0x00000004, + 0x000000C8, + 0x00000003, + 0x0000000A, + 0x00000000, + 0x00000000, + 0x00000001, + 0x00000001, + 0x00000001, + 0x00000003, + 0x00000006, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000003, + 0x00000000, + 0x00000227 + }, + { + { + 0x00001C73, + 0x00000000, + 0x00000000, + 0x00000000 + }, + 0x00000004, + 0x00000070 + }, + {0x1428D1CE}, + 0x00000019, + {0x000004F2}, + 0x00000015 + } +} diff --git a/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-393.inc b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-393.inc new file mode 100644 index 0000000000..052750db17 --- /dev/null +++ b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-393.inc @@ -0,0 +1,71 @@ +{ + 0, + 0, + 0, + 0, + { + .ddr_type = 0x3, + .chn_cnt = 0x0, + .rank = 0x1, + .cs0_row = 0x0, + .cs1_row = 0x0, + .bank = 0x3, + .col = 0x0, + .dbw = 0x1, + .bw = 0x1 + }, + { + .freq = 393, + { + 0x000000C4, + 0x000000C8, + 0x000001F4, + 0x00000013, + 0x80000013, + 0x00000004, + 0x00000076, + 0x00000006, + 0x00000003, + 0x00000000, + 0x00000006, + 0x00000005, + 0x0000000F, + 0x00000015, + 0x00000006, + 0x00000004, + 0x00000004, + 0x00000006, + 0x00000004, + 0x00000200, + 0x00000003, + 0x0000000A, + 0x00000040, + 0x00002710, + 0x00000001, + 0x00000005, + 0x00000005, + 0x00000003, + 0x0000000C, + 0x00000028, + 0x00000100, + 0x00000000, + 0x00000004, + 0x00000000, + 0x00000169 + }, + { + { + 0x00000420, + 0x00000000, + 0x00000000, + 0x00000000 + }, + 0x00000004, + 0x00000060 + }, + {0x1028B18A}, + 0x00000018, + {0x000004A2}, + 0x00000015 + } +} diff --git a/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-451.inc b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-451.inc new file mode 100644 index 0000000000..81dd8dc63d --- /dev/null +++ b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-451.inc @@ -0,0 +1,71 @@ +{ + 0, + 0, + 0, + 0, + { + .ddr_type = 0x3, + .chn_cnt = 0x0, + .rank = 0x1, + .cs0_row = 0x0, + .cs1_row = 0x0, + .bank = 0x3, + .col = 0x0, + .dbw = 0x1, + .bw = 0x1 + }, + { + .freq = 451, + { + 0x000000E1, + 0x000000C8, + 0x000001F4, + 0x00000016, + 0x80000013, + 0x00000004, + 0x00000088, + 0x00000008, + 0x00000004, + 0x00000000, + 0x00000008, + 0x00000006, + 0x00000011, + 0x00000019, + 0x00000008, + 0x00000004, + 0x00000004, + 0x00000007, + 0x00000004, + 0x00000200, + 0x00000004, + 0x0000000B, + 0x00000040, + 0x00002710, + 0x00000001, + 0x00000005, + 0x00000005, + 0x00000004, + 0x0000000C, + 0x0000002E, + 0x00000100, + 0x00000000, + 0x00000005, + 0x00000000, + 0x000001A2 + }, + { + { + 0x00000640, + 0x00000000, + 0x00000008, + 0x00000000 + }, + 0x00000004, + 0x00000080 + }, + {0x1448E20C}, + 0x0000001B, + {0x000004B2}, + 0x00000015 + } +} diff --git a/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-589.inc b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-589.inc new file mode 100644 index 0000000000..1f7722c7dc --- /dev/null +++ b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-ddr3-detect-589.inc @@ -0,0 +1,71 @@ +{ + 0, + 0, + 0, + 0, + { + .ddr_type = 0x3, + .chn_cnt = 0x0, + .rank = 0x1, + .cs0_row = 0x0, + .cs1_row = 0x0, + .bank = 0x3, + .col = 0x0, + .dbw = 0x1, + .bw = 0x1 + }, + { + .freq = 589, + { + 0x00000126, + 0x000000C8, + 0x000001F4, + 0x0000001D, + 0x80000013, + 0x00000004, + 0x000000B1, + 0x0000000A, + 0x00000005, + 0x00000000, + 0x0000000A, + 0x00000007, + 0x00000017, + 0x00000021, + 0x0000000A, + 0x00000005, + 0x00000005, + 0x00000009, + 0x00000005, + 0x00000200, + 0x00000005, + 0x0000000F, + 0x00000040, + 0x00002710, + 0x00000001, + 0x00000006, + 0x00000006, + 0x00000004, + 0x0000000C, + 0x0000003B, + 0x00000100, + 0x00000000, + 0x00000005, + 0x00000000, + 0x00000227 + }, + { + { + 0x00000860, + 0x00000000, + 0x00000010, + 0x00000000 + }, + 0x00000004, + 0x000000A0 + }, + {0x18492290}, + 0x0000001E, + {0x000004F2}, + 0x00000015 + } +} diff --git a/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-393.inc b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-393.inc new file mode 100644 index 0000000000..a7142b7c7e --- /dev/null +++ b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-393.inc @@ -0,0 +1,71 @@ +{ + 0, + 0, + 0, + 0, + { + .ddr_type = 0x5, + .chn_cnt = 0x0, + .rank = 0x1, + .cs0_row = 0x0, + .cs1_row = 0x0, + .bank = 0x3, + .col = 0x0, + .dbw = 0x1, + .bw = 0x1 + }, + { + .freq = 393, + { + 0x000000C4, + 0x000000C8, + 0x000001F4, + 0x00000013, + 0x80000013, + 0x00000005, + 0x00000053, + 0x0002000B, + 0x00000009, + 0x00000000, + 0x00000007, + 0x00000004, + 0x00000011, + 0x0000001C, + 0x0000000A, + 0x00000004, + 0x00000003, + 0x00000006, + 0x00000003, + 0x00000057, + 0x00000003, + 0x00000000, + 0x00000024, + 0x00000000, + 0x00000002, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000000, + 0x00000000, + 0x0000008E, + 0x00000002, + 0x00000006, + 0x000001F4, + 0xFFFF2634 + }, + { + { + 0x00000000, + 0x00000082, + 0x00000005, + 0x00000001 + }, + 0x00000000, + 0x00000070 + }, + {0x106502CE}, + 0x0000001C, + {0x00000000}, + 0xFFF8355C + } +} diff --git a/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-451.inc b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-451.inc new file mode 100644 index 0000000000..f8bae8c40b --- /dev/null +++ b/drivers/ram/rockchip/sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-451.inc @@ -0,0 +1,71 @@ +{ + 0, + 0, + 0, + 0, + { + .ddr_type = 0x5, + .chn_cnt = 0x0, + .rank = 0x1, + .cs0_row = 0x0, + .cs1_row = 0x0, + .bank = 0x3, + .col = 0x0, + .dbw = 0x1, + .bw = 0x1 + }, + { + .freq = 451, + { + 0x000000E1, + 0x000000C8, + 0xFF2B0000, + 0x00000016, + 0x80000013, + 0x00000005, + 0x0000005F, + 0x0002000D, + 0x00000009, + 0x00000000, + 0x00000007, + 0x00000004, + 0x00000013, + 0x00000020, + 0x0000000B, + 0x00000005, + 0x00000004, + 0x00000007, + 0x00000004, + 0x00000064, + 0x00000004, + 0x00000000, + 0x00000029, + 0x00000000, + 0x00000002, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000000, + 0x00000000, + 0x000000A3, + 0x00000002, + 0x00000007, + 0x000001F4, + 0xFFFF2634 + }, + { + { + 0x00000000, + 0x000000A2, + 0x00000005, + 0x00000001 + }, + 0x00000000, + 0x00000070 + }, + {0x10652350}, + 0x0000001D, + {0x00000000}, + 0xFFF8355C + } +} diff --git a/drivers/ram/rockchip/sdram_rk3308.c b/drivers/ram/rockchip/sdram_rk3308.c new file mode 100644 index 0000000000..49c56ae78b --- /dev/null +++ b/drivers/ram/rockchip/sdram_rk3308.c @@ -0,0 +1,880 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Rockchip Electronics Co., Ltd + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define CRU_BASE 0xff500000 +#define GRF_BASE 0xff000000 +#define SGRF_BASE 0xff2b0000 +#define DDR_PHY_BASE 0xff530000 +#define DDR_PCTL_BASE 0xff010000 +#define DDR_STANDBY_BASE 0xff030000 +#define PMU_BASS_ADDR 0xff520000 +#define SERVICE_MSCH_BASE 0xff5c8000 + +struct rk3308_ddr_gd ddr_gd = { +#include "sdram-rk3308-ddr-skew.inc" +}; + +struct sdram_params sdram_configs[] = { +#if (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 3) + #include "sdram_inc/rk3308/sdram-rk3308-ddr3-detect-589.inc" +#elif (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 2) + #include "sdram_inc/rk3308/sdram-rk3308-ddr2-detect-451.inc" +#elif (CONFIG_ROCKCHIP_TPL_INIT_DRAM_TYPE == 5) + #include "sdram_inc/rk3308/sdram-rk3308-lpddr2-detect-451.inc" +#endif +}; + +#define DDR3_DDR2_ODT_DISABLE_FREQ (666) + +#define DDR2_TRFC_256MBIT (75) +#define DDR2_TRFC_512MBIT (105) +#define DDR2_TRFC_1GBIT (128) +#define DDR2_TRFC_2GBIT (195) +#define DDR2_TRFC_4GBIT (328) + +#define DDR3_TRFC_512MBIT (90) +#define DDR3_TRFC_1GBIT (110) +#define DDR3_TRFC_2GBIT (160) +#define DDR3_TRFC_4GBIT (300) +#define DDR3_TRFC_8GBIT (350) + +#define LPDDR2_TRFC_8GBIT (210) /*ns*/ +#define LPDDR2_TRFC_4GBIT (130) /*ns*/ +#define LPDDR2_TREC_512MBIT (90) /*ns*/ + +void enable_ddr_io_ret(struct dram_info *priv) +{ + rk_clrsetreg(&priv->pmu->sft_con_lo, DDR_IO_RET_CFG_MASK, + DDR_IO_RET_CFG << DDR_IO_RET_CFG_SHIFT); + + rk_clrsetreg(&priv->grf->upctl_con0, GRF_DDR_16BIT_EN_MASK, + GRF_DDR_16BIT_EN << GRF_DDR_16BIT_EN_SHIFT); +} + +void pll_set(u32 pll_type, struct dram_info *priv, + struct rockchip_pll_rate_table *pll_priv) +{ + /* pll power down */ + rk_clrsetreg(&priv->cru->pll[pll_type].con1, PLLPD0_MASK, + PLLPD0_POWER_DOWN << PLLPD0_SHIFT); + rk_clrsetreg(&priv->cru->pll[pll_type].con1, + DSMPD_MASK, pll_priv->dsmpd << DSMPD_SHIFT); + + /* set pll freq */ + rk_clrsetreg(&priv->cru->pll[pll_type].con0, + FBDIV_MASK | POSTDIV1_MASK, + pll_priv->fbdiv << FBDIV_SHIFT | + pll_priv->postdiv1 << POSTDIV1_SHIFT); + rk_clrsetreg(&priv->cru->pll[pll_type].con1, + POSTDIV2_MASK | REFDIV_MASK, + pll_priv->postdiv2 << POSTDIV2_SHIFT | + pll_priv->refdiv << REFDIV_SHIFT); + writel(pll_priv->frac << FRACDIV_SHIFT, + &priv->cru->pll[pll_type].con2); + /* pll power up */ + rk_clrsetreg(&priv->cru->pll[pll_type].con1, PLLPD0_MASK, + PLLPD0_NO_POWER_DOWN << PLLPD0_SHIFT); + + /* wait until pll lock */ + while (!(readl(&priv->cru->pll[pll_type].con1) & + (1u << PLL_LOCK_SHIFT))) + udelay(1); +} + +void rkdclk_init(struct dram_info *priv, + struct sdram_params *params_priv) +{ + u32 ddr_pll_sel; + u32 ddr_phy_div_con; + u32 uart_div[5] = {15, 15, 15, 15, 15}; + struct rockchip_pll_rate_table rk3308_pll_div; + + /* DPLL VPLL0 VPLL1 mode in 24MHz*/ + rk_clrsetreg(&priv->cru->mode, VPLL1_WORK_MODE_MASK, + VPLL1_WORK_MODE_XIN_OSC0 << VPLL1_WORK_MODE_SHIFT); + rk_clrsetreg(&priv->cru->mode, VPLL0_WORK_MODE_MASK, + VPLL0_WORK_MODE_XIN_OSC0 << VPLL0_WORK_MODE_SHIFT); + rk_clrsetreg(&priv->cru->mode, DPLL_WORK_MODE_MASK, + DPLL_WORK_MODE_XIN_OSC0 << DPLL_WORK_MODE_SHIFT); + + /* set PLL without level shift */ + rk_clrsetreg(&priv->cru->mode, VPLL1_CLK_SEL_MASK, + VPLL1_CLK_SEL_WITHOUT_LVL_SHIFT << VPLL1_CLK_SEL_SHIFT); + rk_clrsetreg(&priv->cru->mode, VPLL0_CLK_SEL_MASK, + VPLL0_CLK_SEL_WITHOUT_LVL_SHIFT << VPLL0_CLK_SEL_SHIFT); + rk_clrsetreg(&priv->cru->mode, DPLL_CLK_SEL_MASK, + DPLL_CLK_SEL_WITHOUT_LVL_SHIFT << DPLL_CLK_SEL_SHIFT); + + /* set vpll1 in 903.168MHz vco = 1.806GHz */ + rk3308_pll_div.refdiv = 2; + rk3308_pll_div.fbdiv = 150; + rk3308_pll_div.postdiv1 = 2; + rk3308_pll_div.postdiv2 = 1; + rk3308_pll_div.frac = 0x872B02; + rk3308_pll_div.dsmpd = 0; + pll_set(VPLL1, priv, &rk3308_pll_div); + + if (params_priv->ddr_timing_t.freq == 393) { + /* set vpll0 in 786.432MHz vco = 3.146GHz */ + rk3308_pll_div.refdiv = 2; + rk3308_pll_div.fbdiv = 262; + rk3308_pll_div.postdiv1 = 4; + rk3308_pll_div.postdiv2 = 1; + rk3308_pll_div.frac = 0x24DD2F; + rk3308_pll_div.dsmpd = 0; + } else { + /* set vpll0 in 1179.648MHz, vco = 2.359GHz*/ + rk3308_pll_div.refdiv = 2; + rk3308_pll_div.fbdiv = 196; + rk3308_pll_div.postdiv1 = 2; + rk3308_pll_div.postdiv2 = 1; + rk3308_pll_div.frac = 0x9BA5E3; + rk3308_pll_div.dsmpd = 0; + } + pll_set(VPLL0, priv, &rk3308_pll_div); + + if (params_priv->ddr_timing_t.freq == 800) { + ddr_pll_sel = 0; + ddr_phy_div_con = 0; + } else if (params_priv->ddr_timing_t.freq == 589) { + ddr_pll_sel = 1; + ddr_phy_div_con = 0; + } else if (params_priv->ddr_timing_t.freq == 451) { + ddr_pll_sel = 2; + ddr_phy_div_con = 0; + } else if (params_priv->ddr_timing_t.freq == 393) { + ddr_pll_sel = 1; + ddr_phy_div_con = 0; + } else if (params_priv->ddr_timing_t.freq == 294) { + ddr_pll_sel = 1; + ddr_phy_div_con = 1; + } else if (params_priv->ddr_timing_t.freq == 225) { + ddr_pll_sel = 2; + ddr_phy_div_con = 1; + } else { + printascii("err\n"); + while (1) + ; + } + + /* dpll default set in 1300MHz */ + if (params_priv->ddr_timing_t.freq == 800) { + /* set dpll in 1584 MHz ,vco=3.168G*/ + rk3308_pll_div.refdiv = 1; + rk3308_pll_div.fbdiv = 132; + rk3308_pll_div.postdiv1 = 2; + rk3308_pll_div.postdiv2 = 1; + rk3308_pll_div.frac = 0; + rk3308_pll_div.dsmpd = 1; + } else { + /* 1300000000,vco = 1.3GHz */ + rk3308_pll_div.refdiv = 6; + rk3308_pll_div.fbdiv = 325; + rk3308_pll_div.postdiv1 = 1; + rk3308_pll_div.postdiv2 = 1; + rk3308_pll_div.frac = 0; + rk3308_pll_div.dsmpd = 1; + } + + pll_set(DPLL, priv, &rk3308_pll_div); + + /* set ddrphy freq */ + rk_clrsetreg(&priv->cru->clksel_con[1], + DDRPHY4X_PLL_CLK_SEL_MASK | DDRPHY4X_DIV_CON_MASK, + ddr_pll_sel << DDRPHY4X_PLL_CLK_SEL_SHIFT | + ddr_phy_div_con << DDRPHY4X_DIV_CON_SIHFT); + + /* set aclk_bus 216.7MHz */ + rk_clrsetreg(&priv->cru->clksel_con[5], + A_H_PCLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK, + A_H_PCLK_BUS_PLL_SEL_DPLL << A_H_PCLK_BUS_PLL_SEL_SHIFT | + ACLK_BUS_DIV_CON_5 << ACLK_BUS_DIV_CON_SHIFT); + /* set pclk_bus 50MHz,hclk_bus 92.857MHz */ + rk_clrsetreg(&priv->cru->clksel_con[6], + PCLK_BUS_DIV_CON_MASK | HCLK_BUS_DIV_CON_MASK, + PCLK_BUS_DIV_CON_25 << PCLK_BUS_DIV_CON_SHIFT | + HCLK_BUS_DIV_CON_13 << HCLK_BUS_DIV_CON_SHIFT); + /* set crypto 92.857MHz,crypto_apk 92.857MHz */ + rk_clrsetreg(&priv->cru->clksel_con[7], + CLK_CRYPTO_APK_SEL_MASK | CLK_CRYPTO_APK_DIV_MASK | + CLK_CRYPTO_PLL_SEL_MASK | CLK_CRYPTO_DIV_CON_MASK, + CLK_CRYPTO_APK_SEL_DPLL << CLK_CRYPTO_APK_SEL_SHIFT | + CLK_CRYPTO_APK_DIV_13 << CLK_CRYPTO_APK_DIV_SHIFT | + CLK_CRYPTO_PLL_SEL_DPLL << CLK_CRYPTO_PLL_SEL_SHIFT | + CLK_CRYPTO_DIV_CON_13 << CLK_CRYPTO_DIV_CON_SHIFT); + /* set aclk_peri 216.7MHz */ + rk_clrsetreg(&priv->cru->clksel_con[36], + A_H_P_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK, + A_H_P_PERI_PLL_SEL_DPLL << A_H_P_PERI_PLL_SEL_SHIFT | + ACLK_PERI_DIV_CON_5 << ACLK_PERI_DIV_CON_SHIFT); + /* set hclk_peri 92.857MHz,pclk_peri 46.428MHz */ + rk_clrsetreg(&priv->cru->clksel_con[37], + PCLK_PERI_DIV_CON_MASK | HCLK_PERI_DIV_CON_MASK, + PCLK_PERI_DIV_CON_27 << PCLK_PERI_DIV_CON_SHIFT | + HCLK_PERI_DIV_CON_13 << HCLK_PERI_DIV_CON_SHIFT); + /* set NANDC 92.857MHz */ + rk_clrsetreg(&priv->cru->clksel_con[38], + CLK_NANDC_PLL_SEL_MASK | + CLK_NANDC_DIV_CON_MASK, + CLK_NANDC_PLL_SEL_DPLL << CLK_NANDC_PLL_SEL_SHIFT | + CLK_NANDC_DIV_CON_13 << CLK_NANDC_DIV_CON_SHIFT); + /* set SDMMC 46.4/(internal freq_div 2)=23.2MHz */ + rk_clrsetreg(&priv->cru->clksel_con[39], + CLK_SDMMC_PLL_SEL_MASK | + CLK_SDMMC_DIV_CON_MASK, + CLK_SDMMC_PLL_SEL_DPLL << CLK_SDMMC_PLL_SEL_SHIFT | + CLK_SDMMC_DIV_CON_27 << CLK_SDMMC_DIV_CON_SHIFT); + /* set emmc 46.4/(internal freq_div 2)=23.2MHz */ + rk_clrsetreg(&priv->cru->clksel_con[41], + CLK_EMMC_PLL_SEL_MASK | + CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_DPLL << CLK_EMMC_PLL_SEL_SHIFT | + CLK_EMMC_DIV_CON_27 << CLK_EMMC_DIV_CON_SHIFT); + /* set SFC 24.07/(internal freq_div 2)=12.0MHz */ + rk_clrsetreg(&priv->cru->clksel_con[42], + CLK_SFC_PLL_SEL_MASK | CLK_SFC_DIV_CON_MASK, + CLK_SFC_PLL_SEL_DPLL << CLK_SFC_PLL_SEL_SHIFT | + CLK_SFC_DIV_CON_53 << CLK_SFC_DIV_CON_SHIFT); +#if defined(CONFIG_DPLL_FREQ_1200MHZ) + /*vco=1.2GHz*/ + rk3308_pll_div.refdiv = 2; + rk3308_pll_div.fbdiv = 100; + rk3308_pll_div.postdiv1 = 1; + rk3308_pll_div.postdiv2 = 1; + rk3308_pll_div.frac = 0; + + /* set dpll in 1200 MHz */ + pll_set(DPLL, priv, &rk3308_pll_div); + + /* set aclk_bus 200MHz */ + rk_clrsetreg(&priv->cru->clksel_con[5], + A_H_PCLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK, + A_H_PCLK_BUS_PLL_SEL_DPLL << A_H_PCLK_BUS_PLL_SEL_SHIFT | + ACLK_BUS_DIV_CON_5 << ACLK_BUS_DIV_CON_SHIFT); + /* set pclk_bus 46.15MHz,hclk_bus 100MHz */ + rk_clrsetreg(&priv->cru->clksel_con[6], + PCLK_BUS_DIV_CON_MASK | HCLK_BUS_DIV_CON_MASK, + PCLK_BUS_DIV_CON_25 << PCLK_BUS_DIV_CON_SHIFT | + HCLK_BUS_DIV_CON_11 << HCLK_BUS_DIV_CON_SHIFT); + /* set crypto,crypto_apk 100MHz */ + rk_clrsetreg(&priv->cru->clksel_con[7], + CLK_CRYPTO_APK_SEL_MASK | CLK_CRYPTO_APK_DIV_MASK | + CLK_CRYPTO_PLL_SEL_MASK | CLK_CRYPTO_DIV_CON_MASK, + CLK_CRYPTO_APK_SEL_DPLL << CLK_CRYPTO_APK_SEL_SHIFT | + CLK_CRYPTO_APK_DIV_11 << CLK_CRYPTO_APK_DIV_SHIFT | + CLK_CRYPTO_PLL_SEL_DPLL << CLK_CRYPTO_PLL_SEL_SHIFT | + CLK_CRYPTO_DIV_CON_11 << CLK_CRYPTO_DIV_CON_SHIFT); + /* set aclk_peri 200MHz */ + rk_clrsetreg(&priv->cru->clksel_con[36], + A_H_P_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK, + A_H_P_PERI_PLL_SEL_DPLL << A_H_P_PERI_PLL_SEL_SHIFT | + ACLK_PERI_DIV_CON_5 << ACLK_PERI_DIV_CON_SHIFT); + /* set hclk_peri 100MHz,pclk_peri 50MHz */ + rk_clrsetreg(&priv->cru->clksel_con[37], + PCLK_PERI_DIV_CON_MASK | HCLK_PERI_DIV_CON_MASK, + PCLK_PERI_DIV_CON_23 << PCLK_PERI_DIV_CON_SHIFT | + HCLK_PERI_DIV_CON_11 << HCLK_PERI_DIV_CON_SHIFT); + /* set NANDC 100MHz */ + rk_clrsetreg(&priv->cru->clksel_con[38], + CLK_NANDC_PLL_SEL_MASK | + CLK_NANDC_DIV_CON_MASK, + CLK_NANDC_PLL_SEL_DPLL << CLK_NANDC_PLL_SEL_SHIFT | + CLK_NANDC_DIV_CON_11 << CLK_NANDC_DIV_CON_SHIFT); + /* set SDMMC 50MHz */ + rk_clrsetreg(&priv->cru->clksel_con[39], + CLK_SDMMC_PLL_SEL_MASK | + CLK_SDMMC_DIV_CON_MASK, + CLK_SDMMC_PLL_SEL_DPLL << CLK_SDMMC_PLL_SEL_SHIFT | + CLK_SDMMC_DIV_CON_23 << CLK_SDMMC_DIV_CON_SHIFT); + /* set emmc 50MHz */ + rk_clrsetreg(&priv->cru->clksel_con[41], + CLK_EMMC_PLL_SEL_MASK | + CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_DPLL << CLK_EMMC_PLL_SEL_SHIFT | + CLK_EMMC_DIV_CON_23 << CLK_EMMC_DIV_CON_SHIFT); + /* set SFC 24MHz */ + rk_clrsetreg(&priv->cru->clksel_con[42], + CLK_SFC_PLL_SEL_MASK | CLK_SFC_DIV_CON_MASK, + CLK_SFC_PLL_SEL_DPLL << CLK_SFC_PLL_SEL_SHIFT | + CLK_SFC_DIV_CON_49 << CLK_SFC_DIV_CON_SHIFT); + +#elif defined(CONFIG_DPLL_FREQ_748MHZ) + /*vco=1.5GHz*/ + rk3308_pll_div.refdiv = 6; + rk3308_pll_div.fbdiv = 374; + rk3308_pll_div.postdiv1 = 2; + rk3308_pll_div.postdiv2 = 1; + rk3308_pll_div.frac = 0; + + /* set dpll in 748 MHz */ + pll_set(DPLL, priv, &rk3308_pll_div); + + /* set aclk_bus 187MHz */ + rk_clrsetreg(&priv->cru->clksel_con[5], + A_H_PCLK_BUS_PLL_SEL_MASK | ACLK_BUS_DIV_CON_MASK, + A_H_PCLK_BUS_PLL_SEL_DPLL << A_H_PCLK_BUS_PLL_SEL_SHIFT | + ACLK_BUS_DIV_CON_3 << ACLK_BUS_DIV_CON_SHIFT); + /* set pclk_bus 46.75MHz,hclk_bus 93.5MHz */ + rk_clrsetreg(&priv->cru->clksel_con[6], + PCLK_BUS_DIV_CON_MASK | HCLK_BUS_DIV_CON_MASK, + PCLK_BUS_DIV_CON_15 << PCLK_BUS_DIV_CON_SHIFT | + HCLK_BUS_DIV_CON_7 << HCLK_BUS_DIV_CON_SHIFT); + /* set crypto,crypto_apk 93.5MHz */ + rk_clrsetreg(&priv->cru->clksel_con[7], + CLK_CRYPTO_APK_SEL_MASK | CLK_CRYPTO_APK_DIV_MASK | + CLK_CRYPTO_PLL_SEL_MASK | CLK_CRYPTO_DIV_CON_MASK, + CLK_CRYPTO_APK_SEL_DPLL << CLK_CRYPTO_APK_SEL_SHIFT | + CLK_CRYPTO_APK_DIV_7 << CLK_CRYPTO_APK_DIV_SHIFT | + CLK_CRYPTO_PLL_SEL_DPLL << CLK_CRYPTO_PLL_SEL_SHIFT | + CLK_CRYPTO_DIV_CON_7 << CLK_CRYPTO_DIV_CON_SHIFT); + /* set aclk_peri 187MHz */ + rk_clrsetreg(&priv->cru->clksel_con[36], + A_H_P_PERI_PLL_SEL_MASK | ACLK_PERI_DIV_CON_MASK, + A_H_P_PERI_PLL_SEL_DPLL << A_H_P_PERI_PLL_SEL_SHIFT | + ACLK_PERI_DIV_CON_3 << ACLK_PERI_DIV_CON_SHIFT); + /* set hclk_peri 93.5MHz,pclk_peri 46.75MHz */ + rk_clrsetreg(&priv->cru->clksel_con[37], + PCLK_PERI_DIV_CON_MASK | HCLK_PERI_DIV_CON_MASK, + PCLK_PERI_DIV_CON_15 << PCLK_PERI_DIV_CON_SHIFT | + HCLK_PERI_DIV_CON_7 << HCLK_PERI_DIV_CON_SHIFT); + /* set NANDC 93.5MHz */ + rk_clrsetreg(&priv->cru->clksel_con[38], + CLK_NANDC_PLL_SEL_MASK | + CLK_NANDC_DIV_CON_MASK, + CLK_NANDC_SEL50_ALWAYS << CLK_NANDC_SEL50_SHIFT | + CLK_NANDC_PLL_SEL_DPLL << CLK_NANDC_PLL_SEL_SHIFT | + CLK_NANDC_DIV_CON_7 << CLK_NANDC_DIV_CON_SHIFT); + /* set NANDC 46.75MHz */ + rk_clrsetreg(&priv->cru->clksel_con[39], + CLK_SDMMC_PLL_SEL_MASK | + CLK_SDMMC_DIV_CON_MASK, + CLK_SDMMC_PLL_SEL_DPLL << CLK_SDMMC_PLL_SEL_SHIFT | + CLK_SDMMC_DIV_CON_15 << CLK_SDMMC_DIV_CON_SHIFT); + /* set emmc 46.75MHz */ + rk_clrsetreg(&priv->cru->clksel_con[41], + CLK_EMMC_PLL_SEL_MASK | + CLK_EMMC_DIV_CON_MASK, + CLK_EMMC_PLL_SEL_DPLL << CLK_EMMC_PLL_SEL_SHIFT | + CLK_EMMC_DIV_CON_15 << CLK_EMMC_DIV_CON_SHIFT); + /* set SFC 23.375MHz */ + rk_clrsetreg(&priv->cru->clksel_con[42], + CLK_SFC_PLL_SEL_MASK | CLK_SFC_DIV_CON_MASK, + CLK_SFC_PLL_SEL_DPLL << CLK_SFC_PLL_SEL_SHIFT | + CLK_SFC_DIV_CON_31 << CLK_SFC_DIV_CON_SHIFT); + +#endif + /* set spdif tx lower than 100Mhz */ + rk_clrsetreg(&priv->cru->clksel_con[48], + CLK_SPDIFTX_DIV_CON_MASK, + CLK_SPDIFTX_DIV_CON_15 << CLK_SPDIFTX_DIV_CON_SHIFT); + + if (UART_INFO_ID(ddr_gd.head_info.g_uart_info) < 5) + uart_div[UART_INFO_ID(ddr_gd.head_info.g_uart_info)] = 0; + + /* set uart0~4 lower than 100Mhz */ + rk_clrsetreg(&priv->cru->clksel_con[10], + CLK_UART0_DIV_CON_MASK, + uart_div[0] << CLK_UART0_DIV_CON_SHIFT); + rk_clrsetreg(&priv->cru->clksel_con[13], + CLK_UART1_DIV_CON_MASK, + uart_div[1] << CLK_UART1_DIV_CON_SHIFT); + rk_clrsetreg(&priv->cru->clksel_con[16], + CLK_UART2_DIV_CON_MASK, + uart_div[2] << CLK_UART2_DIV_CON_SHIFT); + rk_clrsetreg(&priv->cru->clksel_con[19], + CLK_UART3_DIV_CON_MASK, + uart_div[3] << CLK_UART3_DIV_CON_SHIFT); + rk_clrsetreg(&priv->cru->clksel_con[22], + CLK_UART4_DIV_CON_MASK, + uart_div[4] << CLK_UART4_DIV_CON_SHIFT); + + /* pll clk in pll out */ + rk_clrsetreg(&priv->cru->mode, VPLL1_WORK_MODE_MASK, + VPLL1_WORK_MODE_PLL << VPLL1_WORK_MODE_SHIFT); + rk_clrsetreg(&priv->cru->mode, VPLL0_WORK_MODE_MASK, + VPLL0_WORK_MODE_PLL << VPLL0_WORK_MODE_SHIFT); + rk_clrsetreg(&priv->cru->mode, DPLL_WORK_MODE_MASK, + DPLL_WORK_MODE_PLL << DPLL_WORK_MODE_SHIFT); +} + +void phy_pctrl_reset_cru(struct dram_info *priv) +{ + rk_clrsetreg(&priv->cru->softrst_con[1], + PRESETN_DDRPHY_REQ_MASK | RESETN_DDRPHYDIV_REQ_MASK | + RESETN_DDRPHY_REQ_MASK | PRESETN_DDRUPCTL_REQ_MASK | + RESETN_DDRUPCTL_REQ_MASK, + PRESETN_DDRPHY_REQ_EN << PRESETN_DDRPHY_REQ_SHIFT | + RESETN_DDRPHYDIV_REQ_EN << RESETN_DDRPHYDIV_REQ_SHIFT | + RESETN_DDRPHY_REQ_EN << RESETN_DDRPHY_REQ_SHIFT | + PRESETN_DDRUPCTL_REQ_EN << PRESETN_DDRUPCTL_REQ_SHIFT | + RESETN_DDRUPCTL_REQ_EN << RESETN_DDRUPCTL_REQ_SHIFT); + udelay(10); + + rk_clrsetreg(&priv->cru->softrst_con[1], + PRESETN_DDRPHY_REQ_MASK | RESETN_DDRPHYDIV_REQ_MASK | + RESETN_DDRPHY_REQ_MASK, + PRESETN_DDRPHY_REQ_DIS << PRESETN_DDRPHY_REQ_SHIFT | + RESETN_DDRPHYDIV_REQ_DIS << RESETN_DDRPHYDIV_REQ_SHIFT | + RESETN_DDRPHY_REQ_DIS << RESETN_DDRPHY_REQ_SHIFT); + udelay(10); + + rk_clrsetreg(&priv->cru->softrst_con[1], + PRESETN_DDRUPCTL_REQ_MASK | RESETN_DDRUPCTL_REQ_MASK, + PRESETN_DDRUPCTL_REQ_DIS << PRESETN_DDRUPCTL_REQ_SHIFT | + RESETN_DDRUPCTL_REQ_DIS << RESETN_DDRUPCTL_REQ_SHIFT); + udelay(10); +} + +void pctl_cfg_grf(struct dram_info *priv, + struct sdram_params *params_priv) +{ + if (params_priv->ddr_config_t.ddr_type == DDR3 || + params_priv->ddr_config_t.ddr_type == DDR2) + rk_clrsetreg(&priv->grf->soc_con12, NOC_MSCH_MAINDDR3_MASK, + NOC_MSCH_MAINDDR3_EN << NOC_MSCH_MAINDDR3_SHIFT); + else + rk_clrsetreg(&priv->grf->soc_con12, NOC_MSCH_MAINDDR3_MASK, + NOC_MSCH_MAINDDR3_DIS << NOC_MSCH_MAINDDR3_SHIFT); +} + +void ddr_msch_cfg(struct dram_info *priv, + struct sdram_params *params_priv) +{ + writel(BWRATIO_HALF_BW | params_priv->ddr_timing_t.noc_timing.d32, + &priv->service_msch->ddrtiming); + writel(params_priv->ddr_timing_t.readlatency, + &priv->service_msch->readlatency); +} + +void ddr_msch_cfg_rbc(struct sdram_params *params_priv, + struct dram_info *priv) +{ + int i = 0; + + if (params_priv->ddr_config_t.bank == 3) { + /* bank = 8 */ + if (params_priv->ddr_config_t.col == 10) + i = 1; + else if (params_priv->ddr_config_t.col == 11) + i = 2; + else + goto msch_err; + + } else if (params_priv->ddr_config_t.bank == 2) { + /* bank = 4 */ + i = 0; + } else { + goto msch_err; + } + + writel(i, &priv->service_msch->ddrconf); + return; + +msch_err: + printascii("msch_err\n"); + while (1) + ; +} + +void ddr_phy_skew_cfg(struct dram_info *priv) +{ + copy_to_reg(&priv->phy->phy_reg_ca_skew[0], + &ddr_gd.ddr_skew.a0_a1_skew[0], 14 * 4); + copy_to_reg(&priv->phy->phy_reg_skew_cs0data[0], + &ddr_gd.ddr_skew.cs0_dm0_skew[0], 22 * 4); + + writel(PHY_TX_DE_SKEW_EN << PHY_TX_DE_SKEW_SHIFT, + &priv->phy->phy_reg2); +} + +void set_ds_odt(struct dram_info *priv, + struct sdram_params *params_priv) +{ + /* set phy drive resistance */ + writel(PHY_RON_RTT_56OHM, &priv->phy->phy_reg11); + clrsetbits_le32(&priv->phy->phy_reg12, CMD_PRCOMP_MASK, + PHY_RON_RTT_56OHM << CMD_PRCOMP_SHIFT); + + writel(PHY_RON_RTT_45OHM, &priv->phy->phy_reg16); + writel(PHY_RON_RTT_45OHM, &priv->phy->phy_reg18); + writel(PHY_RON_RTT_56OHM, &priv->phy->phy_reg20); + writel(PHY_RON_RTT_56OHM, &priv->phy->phy_reg2f); + writel(PHY_RON_RTT_56OHM, &priv->phy->phy_reg30); + writel(PHY_RON_RTT_56OHM, &priv->phy->phy_reg3f); + if (params_priv->ddr_config_t.ddr_type == LPDDR2) { + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg21); + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg2e); + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg31); + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg3e); + } else { + if (params_priv->ddr_timing_t.freq > + DDR3_DDR2_ODT_DISABLE_FREQ) { + /*set phy odt*/ + writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg21); + writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg2e); + writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg31); + writel(PHY_RON_RTT_225OHM, &priv->phy->phy_reg3e); + } else { + /*disable phy odt*/ + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg21); + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg2e); + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg31); + writel(PHY_RON_RTT_DISABLE, &priv->phy->phy_reg3e); + } + } +} + +void ddr_phy_dqs_rx_dll_cfg(struct dram_info *priv, u32 freq) +{ + if (freq > 736) { + /* 22.5 degree delay */ + writel(LEFT_CHN_A_READ_DQS_22_5_DELAY, &priv->phy->phy_reg28); + writel(RIGHT_CHN_A_READ_DQS_22_5_DELAY, &priv->phy->phy_reg38); + } else if (freq > 441) { + /* 45 degree delay */ + writel(LEFT_CHN_A_READ_DQS_45_DELAY, &priv->phy->phy_reg28); + writel(RIGHT_CHN_A_READ_DQS_45_DELAY, &priv->phy->phy_reg38); + } +} + +void ddr_msch_get_max_col(struct dram_info *priv, + struct ddr_schedule *sch_priv) +{ + writel(2, &priv->service_msch->ddrconf); + sch_priv->col = 11; + sch_priv->bank = 3; +} + +void ddr_msch_get_max_row(struct dram_info *priv, + struct ddr_schedule *sch_priv) +{ + writel(1, &priv->service_msch->ddrconf); + sch_priv->row = 15; + sch_priv->col = 10; + sch_priv->bank = 3; +} + +void enable_ddr_standby(struct dram_info *priv, + struct sdram_params *params_priv) +{ + rk_clrsetreg(&priv->grf->upctl_con0, CYSYREQ_UPCTL_DDRSTDBY_MASK, + CYSYREQ_UPCTL_DDRSTDBY_EN << + CYSYREQ_UPCTL_DDRSTDBY_SHIFT); + + /* CG_EXIT_TH is equal phy dll lock time when we gate phy 4x clk */ + writel(CG_EXIT_TH << CG_EXIT_TH_SHIFT, &priv->standby->con1); + + if (params_priv->stdby_idle == 128) { + if (params_priv->ddr_timing_t.freq == 451) + params_priv->stdby_idle = 105; + else if (params_priv->ddr_timing_t.freq == 393) + params_priv->stdby_idle = 10; + } + writel(params_priv->stdby_idle << IDLE_TH_SHIFT | + DDRPHY4X_GATE_EN << DDRPHY4X_GATE_SHIFT | + UPCTL_CORE_CLK_GATE_EN << UPCTL_CORE_CLK_GATE_SHIFT | + UPCTL_ACLK_GATE_EN << UPCTL_ACLK_GATE_SHIFT | + CTL_IDLR_EN << CTL_IDLR_SHIFT | + STDBY_EN << STDBY_EN_SHIFT, &priv->standby->con0); + + while (1) { + if ((readl(&priv->standby->status0) & + STDBY_STATUS_MASK) == ST_STDBY) { + break; + } + } +} + +void ddr_set_atags(void) +{ + struct tag_serial t_serial; + + memset(&t_serial, 0, sizeof(struct tag_serial)); +#ifdef CONFIG_DRAM_INIT_BUILD + u32 uart_info; + + t_serial.version = 0; + uart_info = ddr_gd.head_info.g_uart_info; + if (UART_INFO_ID(uart_info) >= MAX_UART_NUMBER_) { + t_serial.enable = 0; + } else { + t_serial.enable = 1; + t_serial.baudrate = UART_INFO_BAUD(uart_info); + t_serial.m_mode = UART_INFO_IOMUX(uart_info); + t_serial.id = UART_INFO_ID(uart_info); + if (UART_INFO_ID(uart_info) == 0) + t_serial.addr = UART0_BASE; + else if (UART_INFO_ID(uart_info) == 1) + t_serial.addr = UART1_BASE; + else if (UART_INFO_ID(uart_info) == 2) + t_serial.addr = UART2_BASE; + else if (UART_INFO_ID(uart_info) == 3) + t_serial.addr = UART3_BASE; + else + t_serial.addr = UART4_BASE; + } +#else + /* set serial data to &t_serial */ +#if defined(CONFIG_DEBUG_UART_BASE) + t_serial.version = 0; + t_serial.enable = 1; + t_serial.addr = CONFIG_DEBUG_UART_BASE; + t_serial.baudrate = CONFIG_BAUDRATE; + +#if (CONFIG_DEBUG_UART_BASE == 0xFF0A0000) + /* uart0 as debug uart */ + t_serial.m_mode = SERIAL_M_MODE_M0; + t_serial.id = 0; +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0B0000) + /* uart1 as debug uart */ + t_serial.m_mode = SERIAL_M_MODE_M0; + t_serial.id = 1; +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0C0000) +#if (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 0) + t_serial.m_mode = SERIAL_M_MODE_M0; +#elif (CONFIG_ROCKCHIP_UART_MUX_SEL_M == 1) + /* uart2 m1 as debug uart */ + t_serial.m_mode = SERIAL_M_MODE_M1; +#else + #error "Please select M0 or M1 for uart2 !!!" +#endif + t_serial.id = 2; +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0D0000) + /* uart3 as debug uart */ + t_serial.m_mode = SERIAL_M_MODE_M0; + t_serial.id = 3; +#elif (CONFIG_DEBUG_UART_BASE == 0xFF0E0000) + /* uart4 as debug uart */ + t_serial.m_mode = SERIAL_M_MODE_M0; + t_serial.id = 4; +#else + #error "Please select proper uart as debug uart !!!" +#endif + +#endif /* defined(CONFIG_DEBUG_UART_BASE) */ +#endif /* CONFIG_DRAM_INIT_BUILD */ + + /* First pre-loader must call it before atags_set_tag() */ + atags_destroy(); + atags_set_tag(ATAG_SERIAL, &t_serial); +} + +static void modify_sdram_params(struct dram_info *priv, + struct sdram_params *params_priv) +{ + u32 tmp = 0; + u32 bw = 1; + u32 nMHz = params_priv->ddr_timing_t.freq; + + size_t size = 1llu << (bw + + params_priv->ddr_config_t.col + + params_priv->ddr_config_t.cs0_row + + params_priv->ddr_config_t.bank); + + move_to_config_state(priv); + switch (params_priv->ddr_config_t.ddr_type) { + case DDR2: + if (size <= 0x4000000) + tmp = DDR2_TRFC_512MBIT; + else if (size <= 0x8000000) + tmp = DDR2_TRFC_1GBIT; + else if (size <= 0x10000000) + tmp = DDR2_TRFC_2GBIT; + else + tmp = DDR2_TRFC_4GBIT; + + priv->pctl->trfc = (tmp * nMHz + 999) / 1000; + tmp = (((tmp + 10) * nMHz + 999) / 1000); + if (tmp < 200) + tmp = 200; + priv->pctl->texsr = tmp & 0x3FF; + break; + case DDR3: + if (size <= 0x4000000) + tmp = DDR3_TRFC_512MBIT; + else if (size <= 0x8000000) + tmp = DDR3_TRFC_1GBIT; + else if (size <= 0x10000000) + tmp = DDR3_TRFC_2GBIT; + else if (size <= 0x20000000) + tmp = DDR3_TRFC_4GBIT; + else + tmp = DDR3_TRFC_8GBIT; + priv->pctl->trfc = (tmp * nMHz + 999) / 1000; + break; + case LPDDR2: + if (size <= 0x4000000) + tmp = LPDDR2_TREC_512MBIT; + else if (size <= 0x20000000) + tmp = LPDDR2_TRFC_4GBIT; + else + tmp = LPDDR2_TRFC_8GBIT; + + priv->pctl->trfc = (tmp * nMHz + 999) / 1000; + tmp = (((tmp + 10) * nMHz + 999) / 1000); + if (tmp < 2) + tmp = 2; + priv->pctl->texsr = tmp & 0x3FF; + break; + } + move_to_access_state(priv); +} + +int check_rd_gate(struct dram_info *priv) +{ + u32 max_val = 0; + u32 min_val = 0xff; + u32 gate[2]; + + gate[0] = readl(&priv->phy->phy_regfb); + gate[1] = readl(&priv->phy->phy_regfc); + max_val = max(gate[0], gate[1]); + min_val = min(gate[0], gate[1]); + + if (max_val > 0x80 || min_val < 0x20) + return -1; + else + return 0; +} + +static u32 dram_test(u32 i, u32 dqs) +{ + for (phys_addr_t j = 4 * dqs; j < 0x2000; j += 8) + writel(PATTERN + i, j); + + for (phys_addr_t j = 4 * dqs; j < 0x2000; j += 8) + if ((PATTERN + i) != readl(j)) + return 1; + + return 0; +} + +/** + * modify_data_training() - Setting DQS gating calibration bypass, + * scanning data training range and then select center one. + */ +#define PHY_REG3C(n) (0x10 * (n)) + +void modify_data_training(struct dram_info *priv, + struct sdram_params *params_priv) +{ + u32 value = 0; + u32 i = 0, dqs = 0; + u32 max_value = 0, min_value = 0; + + writel(readl(&priv->phy->phy_regfb), &priv->phy->phy_reg2c); + writel(readl(&priv->phy->phy_regfc), &priv->phy->phy_reg3c); + + /* DQS gating calibration bypass */ + setbits_le32(&priv->phy->phy_reg2, BIT(1)); + + /* rk3308 only support DQS0, DQS1 */ + for (dqs = 0; dqs < 2; dqs++) { + value = readl(&priv->phy->phy_regfb + dqs); + i = 0; + while (dram_test(i, dqs) == 0) { + i++; + writel(value + i, + &priv->phy->phy_reg2c + PHY_REG3C(dqs)); + } + max_value = value + i - 1; + + i = 1; + writel(value - i, &priv->phy->phy_reg2c + PHY_REG3C(dqs)); + while (dram_test(i, dqs) == 0) { + i++; + writel(value - i, + &priv->phy->phy_reg2c + PHY_REG3C(dqs)); + } + min_value = value - i + 1; + + /* select center one as gate training result */ + writel((max_value + min_value + 1) / 2, + &priv->phy->phy_reg2c + PHY_REG3C(dqs)); + } + printascii("REG2C: 0x"); + printhex8(readl(&priv->phy->phy_reg2c)); + printascii(", 0x"); + printhex8(readl(&priv->phy->phy_reg3c)); + printascii("\n"); +} + +void enable_low_power(struct dram_info *priv, + struct sdram_params *params_priv) +{ + move_to_config_state(priv); + + if (params_priv->idle_pd == 48 && params_priv->idle_sr == 10) { + if (params_priv->ddr_timing_t.freq == 451) { + params_priv->idle_sr = 28; + params_priv->idle_pd = 7; + } else if (params_priv->ddr_timing_t.freq == 393) { + params_priv->idle_sr = 31; + params_priv->idle_pd = 15; + } + } + clrsetbits_le32(&priv->pctl->mcfg, PD_IDLE_MASK, + params_priv->idle_pd << PD_IDLE_SHIFT); + clrsetbits_le32(&priv->pctl->mcfg1, + SR_IDLE_MASK | HW_EXIT_IDLE_EN_MASK, + params_priv->idle_sr | HW_EXIT_IDLE_EN); + + /* uPCTL in low_power status because of auto self-refresh */ + writel(GO_STATE, &priv->pctl->sctl); +} + +int get_uart_config(void) +{ + return ddr_gd.head_info.g_uart_info; +} + +int sdram_init(void) +{ + struct dram_info sdram_priv; + struct sdram_params *params = sdram_configs; + + sdram_priv.cru = (void *)CRU_BASE; + sdram_priv.grf = (void *)GRF_BASE; + sdram_priv.sgrf = (void *)SGRF_BASE; + sdram_priv.phy = (void *)DDR_PHY_BASE; + sdram_priv.pctl = (void *)DDR_PCTL_BASE; + sdram_priv.standby = (void *)DDR_STANDBY_BASE; + sdram_priv.pmu = (void *)PMU_BASS_ADDR; + sdram_priv.service_msch = (void *)SERVICE_MSCH_BASE; + params->idle_pd = PD_INFO(ddr_gd.head_info.g_sr_pd_idle); + params->idle_sr = SR_INFO(ddr_gd.head_info.g_sr_pd_idle); + params->ddr_2t_en = DDR_2T_INFO(ddr_gd.head_info.g_2t_info); + params->stdby_idle = STANDBY_IDLE(ddr_gd.head_info.g_ch_info); + + rv1108_sdram_init(&sdram_priv, params); + + modify_sdram_params(&sdram_priv, params); + + if (params->idle_pd != 0 && params->idle_sr != 0) + enable_ddr_standby(&sdram_priv, params); + ddr_set_atags(); + printascii("OUT\n"); + + return 0; +}