From c33ce3554ddc73635084e6e71b5e4f7dae021926 Mon Sep 17 00:00:00 2001 From: Jinkun Hong Date: Thu, 28 Aug 2014 09:37:22 -0700 Subject: rk3288: add ddr driver Supports DDR3 and LPDDR3.Supports dual channel.ddr max freq is 533mhz. ddr timing config file in src\mainboard\google\veyron\sdram_inf Remove dpll init in rk clk_init(), add rkclk_configure_ddr(unsigned int hz). BUG=chrome-os-partner:29778 TEST=Build coreboot Change-Id: I429eb0b8c365c6285fb6cfef008b41776cc9c2d9 Signed-off-by: Patrick Georgi Original-Commit-Id: 52838c68fe6963285c974af5dc5837e819efc321 Original-Change-Id: I6ddfe30b8585002b45060fe998c9238cbb611c05 Original-Signed-off-by: jinkun.hong Original-Reviewed-on: https://chromium-review.googlesource.com/209465 Original-Reviewed-by: Julius Werner Original-Commit-Queue: Julius Werner Reviewed-on: http://review.coreboot.org/8865 Reviewed-by: Stefan Reinauer Tested-by: build bot (Jenkins) --- src/soc/rockchip/rk3288/clock.c | 77 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 9 deletions(-) (limited to 'src/soc/rockchip/rk3288/clock.c') diff --git a/src/soc/rockchip/rk3288/clock.c b/src/soc/rockchip/rk3288/clock.c index 757d180387..b194b4c10e 100755 --- a/src/soc/rockchip/rk3288/clock.c +++ b/src/soc/rockchip/rk3288/clock.c @@ -70,11 +70,10 @@ static struct rk3288_cru_reg * const cru_ptr = (void *)CRU_BASE; (_nr * _no) == hz,\ #hz "Hz cannot be hit with PLL divisors in " __FILE__); -/* apll = 816MHz, gpll = 594MHz, cpll = 384MHz, dpll = 300MHz */ +/* apll = 816MHz, gpll = 594MHz, cpll = 384MHz */ static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 2); static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 4); static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 4); -static const struct pll_div dpll_init_cfg = PLL_DIVISORS(DPLL_HZ, 1, 4); /*******************PLL CON0 BITS***************************/ #define PLL_OD_MSK (0x0F) @@ -191,23 +190,21 @@ void rkclk_init(void) /* pll enter slow-mode */ writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_SLOW) | RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_SLOW) - | RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_SLOW) - | RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_SLOW), + | RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_SLOW), &cru_ptr->cru_mode_con); /* init pll */ rkclk_set_pll(&cru_ptr->cru_apll_con[0], &apll_init_cfg); rkclk_set_pll(&cru_ptr->cru_gpll_con[0], &gpll_init_cfg); rkclk_set_pll(&cru_ptr->cru_cpll_con[0], &cpll_init_cfg); - rkclk_set_pll(&cru_ptr->cru_dpll_con[0], &dpll_init_cfg); /* waiting for pll lock */ while (1) { if ((readl(&rk3288_grf->soc_status[1]) & (SOCSTS_APLL_LOCK | SOCSTS_CPLL_LOCK - | SOCSTS_DPLL_LOCK | SOCSTS_GPLL_LOCK)) + | SOCSTS_GPLL_LOCK)) == (SOCSTS_APLL_LOCK | SOCSTS_CPLL_LOCK - | SOCSTS_GPLL_LOCK | SOCSTS_DPLL_LOCK)) + | SOCSTS_GPLL_LOCK)) break; udelay(1); } @@ -248,12 +245,74 @@ void rkclk_init(void) /* PLL enter normal-mode */ writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_NORM) | RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_NORM) - | RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_NORM) - | RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_NORM), + | RK_CLRSETBITS(CPLL_MODE_MSK, CPLL_MODE_NORM), &cru_ptr->cru_mode_con); } +void rkclk_configure_ddr(unsigned int hz) +{ + struct pll_div dpll_cfg; + + if (hz <= 150000000) { + dpll_cfg.nr = 3; + dpll_cfg.no = 8; + } else if (hz <= 540000000) { + dpll_cfg.nr = 6; + dpll_cfg.no = 4; + } else { + dpll_cfg.nr = 1; + dpll_cfg.no = 1; + } + + dpll_cfg.nf = (hz / 1000 * dpll_cfg.nr * dpll_cfg.no) / 24000; + assert(dpll_cfg.nf < 4096 + && hz == dpll_cfg.nf * 24000 / (dpll_cfg.nr * dpll_cfg.no) + * 1000); + /* pll enter slow-mode */ + writel(RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_SLOW), + &cru_ptr->cru_mode_con); + + rkclk_set_pll(&cru_ptr->cru_dpll_con[0], &dpll_cfg); + + /* waiting for pll lock */ + while (1) { + if (readl(&rk3288_grf->soc_status[1]) & SOCSTS_DPLL_LOCK) + break; + udelay(1); + } + + /* PLL enter normal-mode */ + writel(RK_CLRSETBITS(DPLL_MODE_MSK, DPLL_MODE_NORM), + &cru_ptr->cru_mode_con); +} + +void rkclk_ddr_reset(u32 ch, u32 ctl, u32 phy) +{ + u32 phy_ctl_srstn_shift = 4 + 5 * ch; + u32 ctl_psrstn_shift = 3 + 5 * ch; + u32 ctl_srstn_shift = 2 + 5 * ch; + u32 phy_psrstn_shift = 1 + 5 * ch; + u32 phy_srstn_shift = 5 * ch; + + writel(RK_CLRSETBITS(1 << phy_ctl_srstn_shift, + phy << phy_ctl_srstn_shift) + | RK_CLRSETBITS(1 << ctl_psrstn_shift, ctl << ctl_psrstn_shift) + | RK_CLRSETBITS(1 << ctl_srstn_shift, ctl << ctl_srstn_shift) + | RK_CLRSETBITS(1 << phy_psrstn_shift, phy << phy_psrstn_shift) + | RK_CLRSETBITS(1 << phy_srstn_shift, phy << phy_srstn_shift), + &cru_ptr->cru_softrst_con[10]); +} + +void rkclk_ddr_phy_ctl_reset(u32 ch, u32 n) +{ + u32 phy_ctl_srstn_shift = 4 + 5 * ch; + + writel(RK_CLRSETBITS(1 << phy_ctl_srstn_shift, + n << phy_ctl_srstn_shift), + &cru_ptr->cru_softrst_con[10]); +} + void rkclk_configure_spi(unsigned int bus, unsigned int hz) { int src_clk_div = GPLL_HZ / hz; -- cgit v1.2.3