From bfdd732b80a56e31d3bbe59de76a6a91b0f5b9e4 Mon Sep 17 00:00:00 2001 From: huang lin Date: Thu, 25 Sep 2014 16:33:38 +0800 Subject: rockchip: support pwm regulator BUG=None TEST=Boot Veyron Pinky and test the VDD_LOG Original-Change-Id: Ie2eef918e04ba0e13879e915b0b0bef44aef550e Original-Signed-off-by: huang lin Original-Reviewed-on: https://chromium-review.googlesource.com/219753 Original-Reviewed-by: Julius Werner Original-Commit-Queue: Julius Werner Change-Id: I444b47564d90b3480b351fdd8460e5b94e71927c (cherry picked from commit 4491d9c4037161fd8c4cc40856167bf73182fda6) Signed-off-by: Aaron Durbin Reviewed-on: http://review.coreboot.org/9240 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/soc/rockchip/rk3288/clock.c | 95 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 6 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 2449674f20..59a32db5b2 100644 --- a/src/soc/rockchip/rk3288/clock.c +++ b/src/soc/rockchip/rk3288/clock.c @@ -109,6 +109,32 @@ static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 4); /* m0 core axi clock div: clk = clk_src / (div_con + 1) */ #define M0_DIV_MSK (0xF) +/*******************CLKSEL1 BITS***************************/ +/* pd bus clk pll sel: codec or general */ +#define PD_BUS_SEL_PLL_MSK (1 << 15) +#define PD_BUS_SEL_CPLL (0 << 15) +#define PD_BUS_SEL_GPLL (1 << 15) + +/* pd bus pclk div: + * pclk = pd_bus_aclk /(div + 1) + */ +#define PD_BUS_PCLK_DIV_SHIFT (12) +#define PD_BUS_PCLK_DIV_MSK (0x7 << 12) + +/* pd bus hclk div: + * aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 + */ +#define PD_BUS_HCLK_DIV_SHIFT (8) +#define PD_BUS_HCLK_DIV_MSK (0x3 << 8) + +/* pd bus aclk div: + * pd_bus_aclk = pd_bus_src_clk /(div0 * div1) + */ +#define PD_BUS_ACLK_DIV0_SHIFT (3) +#define PD_BUS_ACLK_DIV0_MASK (0x1f << 3) +#define PD_BUS_ACLK_DIV1_SHIFT (0) +#define PD_BUS_ACLK_DIV1_MASK (0x7 << 0) + /*******************CLKSEL10 BITS***************************/ /* peripheral bus clk pll sel: codec or general */ #define PERI_SEL_PLL_MSK (1 << 15) @@ -133,6 +159,7 @@ static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 4); */ #define PERI_ACLK_DIV_SHIFT (0x0) #define PERI_ACLK_DIV_MSK (0x1F) +#define PERI_ACLK_DIV_SHIFT (0) /*******************CLKSEL37 BITS***************************/ #define L2_DIV_MSK (0x7) @@ -186,8 +213,28 @@ static int rkclk_set_pll(u32 *pll_con, const struct pll_div *pll_div_cfg) return 0; } +/* + TODO: + it should be replaced by lib.h function + 'unsigned long log2(unsigned long x)' +*/ +static unsigned int log2(unsigned int value) +{ + unsigned int div = 0; + + while (value != 1) { + div++; + value = ALIGN_UP(value, 2) / 2; + } + return div; +} + void rkclk_init(void) { + u32 aclk_div; + u32 hclk_div; + u32 pclk_div; + /* pll enter slow-mode */ writel(RK_CLRSETBITS(APLL_MODE_MSK, APLL_MODE_SLOW) | RK_CLRSETBITS(GPLL_MODE_MSK, GPLL_MODE_SLOW) @@ -231,16 +278,52 @@ void rkclk_init(void) | RK_CLRSETBITS(PCLK_DBG_DIV_MSK, (3 << PCLK_DBG_DIV_SHIFT)), &cru_ptr->cru_clksel_con[37]); + /* + * pd_bus clock pll source selection and + * set up dependent divisors for PCLK/HCLK and ACLK clocks. + */ + aclk_div = GPLL_HZ / PD_BUS_ACLK_HZ - 1; + assert((aclk_div + 1) * PD_BUS_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f); + hclk_div = PD_BUS_ACLK_HZ / PD_BUS_HCLK_HZ - 1; + assert((hclk_div + 1) * PD_BUS_HCLK_HZ == + PD_BUS_ACLK_HZ && (hclk_div < 0x4) && (hclk_div != 0x2)); + + pclk_div = PD_BUS_ACLK_HZ / PD_BUS_PCLK_HZ - 1; + assert((pclk_div + 1) * PD_BUS_PCLK_HZ == + PD_BUS_ACLK_HZ && pclk_div < 0x7); + + writel(RK_SETBITS(PD_BUS_SEL_GPLL) + | RK_CLRSETBITS(PD_BUS_PCLK_DIV_MSK, + pclk_div << PD_BUS_PCLK_DIV_SHIFT) + | RK_CLRSETBITS(PD_BUS_HCLK_DIV_MSK, + hclk_div << PD_BUS_HCLK_DIV_SHIFT) + | RK_CLRSETBITS(PD_BUS_ACLK_DIV0_MASK, + aclk_div << PD_BUS_ACLK_DIV0_SHIFT) + | RK_CLRSETBITS(PD_BUS_ACLK_DIV1_MASK, 0 << 0), + &cru_ptr->cru_clksel_con[1]); + /* * peri clock pll source selection and * set up dependent divisors for PCLK/HCLK and ACLK clocks. - * peri clock select gpll, gpll clk = 594MHz - * aclk = 148.5MHz, hclk = 148.5Mhz, pclk = 74.25MHz */ - writel(RK_SETBITS(PERI_SEL_PLL_MSK) - | RK_CLRSETBITS(PERI_PCLK_DIV_MSK, 1 << PERI_PCLK_DIV_SHIFT) - | RK_CLRSETBITS(PERI_HCLK_DIV_MSK, 0 << PERI_HCLK_DIV_SHIFT) - | RK_CLRSETBITS(PERI_ACLK_DIV_MSK, 3 << 0), + aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1; + assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f); + + hclk_div = log2(PERI_ACLK_HZ / PERI_HCLK_HZ); + assert((1 << hclk_div) * PERI_HCLK_HZ == + PERI_ACLK_HZ && (hclk_div < 0x4)); + + pclk_div = log2(PERI_ACLK_HZ / PERI_PCLK_HZ); + assert((1 << pclk_div) * PERI_PCLK_HZ == + PERI_ACLK_HZ && (pclk_div < 0x4)); + + writel(RK_SETBITS(PERI_SEL_GPLL) + | RK_CLRSETBITS(PERI_PCLK_DIV_MSK, + pclk_div << PERI_PCLK_DIV_SHIFT) + | RK_CLRSETBITS(PERI_HCLK_DIV_MSK, + hclk_div << PERI_HCLK_DIV_SHIFT) + | RK_CLRSETBITS(PERI_ACLK_DIV_MSK, + aclk_div << PERI_ACLK_DIV_SHIFT), &cru_ptr->cru_clksel_con[10]); /* PLL enter normal-mode */ -- cgit v1.2.3