summaryrefslogtreecommitdiffstats
path: root/src/soc/rockchip/rk3288/clock.c
diff options
context:
space:
mode:
authorJinkun Hong <jinkun.hong@rock-chips.com>2014-08-28 09:37:22 -0700
committerPatrick Georgi <pgeorgi@google.com>2015-03-24 15:25:23 +0100
commitc33ce3554ddc73635084e6e71b5e4f7dae021926 (patch)
treec727bcdeb697d2dde1ba983a1af08a07083c4b2f /src/soc/rockchip/rk3288/clock.c
parentd5fb66e060954f8505cfceed371aace9c8285fe7 (diff)
downloadcoreboot-c33ce3554ddc73635084e6e71b5e4f7dae021926.tar.gz
coreboot-c33ce3554ddc73635084e6e71b5e4f7dae021926.tar.bz2
coreboot-c33ce3554ddc73635084e6e71b5e4f7dae021926.zip
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 <pgeorgi@chromium.org> Original-Commit-Id: 52838c68fe6963285c974af5dc5837e819efc321 Original-Change-Id: I6ddfe30b8585002b45060fe998c9238cbb611c05 Original-Signed-off-by: jinkun.hong <jinkun.hong@rock-chips.com> Original-Reviewed-on: https://chromium-review.googlesource.com/209465 Original-Reviewed-by: Julius Werner <jwerner@chromium.org> Original-Commit-Queue: Julius Werner <jwerner@chromium.org> Reviewed-on: http://review.coreboot.org/8865 Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/soc/rockchip/rk3288/clock.c')
-rwxr-xr-xsrc/soc/rockchip/rk3288/clock.c77
1 files changed, 68 insertions, 9 deletions
diff --git a/src/soc/rockchip/rk3288/clock.c b/src/soc/rockchip/rk3288/clock.c
index 757d1803871a..b194b4c10e0a 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;