X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fclk%2Fclk_rk3288.c;h=2a85e93a6cc3f534ac165e17343de18344c43619;hb=75cc93fad73897896511f08c1529233484ff063c;hp=ad7c34f445b30a644e4c2e9cc9f39cd4880239b0;hpb=830a6081706e3f07bdd2a0fd7de131516d2a92a9;p=u-boot diff --git a/drivers/clk/clk_rk3288.c b/drivers/clk/clk_rk3288.c index ad7c34f445..2a85e93a6c 100644 --- a/drivers/clk/clk_rk3288.c +++ b/drivers/clk/clk_rk3288.c @@ -59,6 +59,16 @@ enum { /* PLL CON3 */ PLL_RESET_SHIFT = 5, + /* CLKSEL0 */ + CORE_SEL_PLL_MASK = 1, + CORE_SEL_PLL_SHIFT = 15, + A17_DIV_MASK = 0x1f, + A17_DIV_SHIFT = 8, + MP_DIV_MASK = 0xf, + MP_DIV_SHIFT = 4, + M0_DIV_MASK = 0xf, + M0_DIV_SHIFT = 0, + /* CLKSEL1: pd bus clk pll sel: codec or general */ PD_BUS_SEL_PLL_MASK = 15, PD_BUS_SEL_CPLL = 0, @@ -83,8 +93,13 @@ enum { * peripheral bus pclk div: * aclk_bus: pclk_bus = 1:1 or 2:1 or 4:1 or 8:1 */ + PERI_SEL_PLL_MASK = 1, + PERI_SEL_PLL_SHIFT = 15, + PERI_SEL_CPLL = 0, + PERI_SEL_GPLL, + PERI_PCLK_DIV_SHIFT = 12, - PERI_PCLK_DIV_MASK = 7, + PERI_PCLK_DIV_MASK = 3, /* peripheral bus hclk div: aclk_bus: hclk_bus = 1:1 or 2:1 or 4:1 */ PERI_HCLK_DIV_SHIFT = 8, @@ -160,13 +175,13 @@ static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id, uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000; uint output_hz = vco_hz / div->no; - debug("PLL at %p: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", - pll, div->nf, div->nr, div->no, vco_hz, output_hz); + debug("PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", + (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz); assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ && output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ && (div->no == 1 || !(div->no % 2))); - /* enter rest */ + /* enter reset */ rk_setreg(&pll->con3, 1 << PLL_RESET_SHIFT); rk_clrsetreg(&pll->con0, @@ -177,7 +192,7 @@ static int rkclk_set_pll(struct rk3288_cru *cru, enum rk_clk_id clk_id, udelay(10); - /* return form rest */ + /* return from reset */ rk_clrreg(&pll->con3, 1 << PLL_RESET_SHIFT); return 0; @@ -199,7 +214,6 @@ static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf, }; int cfg; - debug("%s: cru=%p, grf=%p, hz=%u\n", __func__, cru, grf, hz); switch (hz) { case 300000000: cfg = 0; @@ -214,7 +228,7 @@ static int rkclk_configure_ddr(struct rk3288_cru *cru, struct rk3288_grf *grf, cfg = 3; break; default: - debug("Unsupported SDRAM frequency, add to clock.c!"); + debug("Unsupported SDRAM frequency"); return -EINVAL; } @@ -420,6 +434,7 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) PERI_PCLK_DIV_MASK << PERI_PCLK_DIV_SHIFT | PERI_HCLK_DIV_MASK << PERI_HCLK_DIV_SHIFT | PERI_ACLK_DIV_MASK << PERI_ACLK_DIV_SHIFT, + PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT | pclk_div << PERI_PCLK_DIV_SHIFT | hclk_div << PERI_HCLK_DIV_SHIFT | aclk_div << PERI_ACLK_DIV_SHIFT); @@ -433,6 +448,52 @@ static void rkclk_init(struct rk3288_cru *cru, struct rk3288_grf *grf) } #endif +void rkclk_configure_cpu(struct rk3288_cru *cru, struct rk3288_grf *grf) +{ + /* pll enter slow-mode */ + rk_clrsetreg(&cru->cru_mode_con, + APLL_MODE_MASK << APLL_MODE_SHIFT, + APLL_MODE_SLOW << APLL_MODE_SHIFT); + + rkclk_set_pll(cru, CLK_ARM, &apll_init_cfg); + + /* waiting for pll lock */ + while (!(readl(&grf->soc_status[1]) & SOCSTS_APLL_LOCK)) + udelay(1); + + /* + * core clock pll source selection and + * set up dependent divisors for MPAXI/M0AXI and ARM clocks. + * core clock select apll, apll clk = 1800MHz + * arm clk = 1800MHz, mpclk = 450MHz, m0clk = 900MHz + */ + rk_clrsetreg(&cru->cru_clksel_con[0], + CORE_SEL_PLL_MASK << CORE_SEL_PLL_SHIFT | + A17_DIV_MASK << A17_DIV_SHIFT | + MP_DIV_MASK << MP_DIV_SHIFT | + M0_DIV_MASK << M0_DIV_SHIFT, + 0 << A17_DIV_SHIFT | + 3 << MP_DIV_SHIFT | + 1 << M0_DIV_SHIFT); + + /* + * set up dependent divisors for L2RAM/ATCLK and PCLK clocks. + * l2ramclk = 900MHz, atclk = 450MHz, pclk_dbg = 450MHz + */ + rk_clrsetreg(&cru->cru_clksel_con[37], + CLK_L2RAM_DIV_MASK << CLK_L2RAM_DIV_SHIFT | + ATCLK_CORE_DIV_CON_MASK << ATCLK_CORE_DIV_CON_SHIFT | + PCLK_CORE_DBG_DIV_MASK >> PCLK_CORE_DBG_DIV_SHIFT, + 1 << CLK_L2RAM_DIV_SHIFT | + 3 << ATCLK_CORE_DIV_CON_SHIFT | + 3 << PCLK_CORE_DBG_DIV_SHIFT); + + /* PLL enter normal-mode */ + rk_clrsetreg(&cru->cru_mode_con, + APLL_MODE_MASK << APLL_MODE_SHIFT, + APLL_MODE_NORMAL << APLL_MODE_SHIFT); +} + /* Get pll rate by id */ static uint32_t rkclk_pll_get_rate(struct rk3288_cru *cru, enum rk_clk_id clk_id) @@ -787,7 +848,7 @@ static const char *const clk_name[CLK_COUNT] = { "dpll", "cpll", "gpll", - "mpll", + "npll", }; static int rk3288_clk_bind(struct udevice *dev)