diff options
Diffstat (limited to 'drivers/clk/rockchip/clk_rk3308.c')
-rw-r--r-- | drivers/clk/rockchip/clk_rk3308.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/clk/rockchip/clk_rk3308.c b/drivers/clk/rockchip/clk_rk3308.c index d27673c454..d0a3f65446 100644 --- a/drivers/clk/rockchip/clk_rk3308.c +++ b/drivers/clk/rockchip/clk_rk3308.c @@ -451,6 +451,58 @@ static ulong rk3308_pwm_set_clk(struct clk *clk, uint hz) return rk3308_pwm_get_clk(clk); } +static ulong rk3308_uart_get_clk(struct clk *clk) +{ + struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3308_cru *cru = priv->cru; + u32 div, pll_sel, con, con_id, parent; + + switch (clk->id) { + case SCLK_UART0: + con_id = 10; + break; + case SCLK_UART1: + con_id = 13; + break; + case SCLK_UART2: + con_id = 16; + break; + case SCLK_UART3: + con_id = 19; + break; + case SCLK_UART4: + con_id = 22; + break; + default: + printf("do not support this uart interface\n"); + return -EINVAL; + } + + con = readl(&cru->clksel_con[con_id]); + pll_sel = (con & CLK_UART_PLL_SEL_MASK) >> CLK_UART_PLL_SEL_SHIFT; + div = (con & CLK_UART_DIV_CON_MASK) >> CLK_UART_DIV_CON_SHIFT; + + switch (pll_sel) { + case CLK_UART_PLL_SEL_DPLL: + parent = priv->dpll_hz; + break; + case CLK_UART_PLL_SEL_VPLL0: + parent = priv->vpll0_hz; + break; + case CLK_UART_PLL_SEL_VPLL1: + parent = priv->vpll0_hz; + break; + case CLK_UART_PLL_SEL_24M: + parent = OSC_HZ; + break; + default: + printf("do not support this uart pll sel\n"); + return -EINVAL; + } + + return DIV_TO_RATE(parent, div); +} + static ulong rk3308_vop_get_clk(struct clk *clk) { struct rk3308_clk_priv *priv = dev_get_priv(clk->dev); @@ -813,6 +865,13 @@ static ulong rk3308_clk_get_rate(struct clk *clk) case SCLK_EMMC_SAMPLE: rate = rk3308_mmc_get_clk(clk); break; + case SCLK_UART0: + case SCLK_UART1: + case SCLK_UART2: + case SCLK_UART3: + case SCLK_UART4: + rate = rk3308_uart_get_clk(clk); + break; case SCLK_I2C0: case SCLK_I2C1: case SCLK_I2C2: |