mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-19 13:41:31 +02:00
clk: rockchip: rk3308: Add support for SCLK_RTC32K clock
Add support to get and set the SCLK_RTC32K clock rate. Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> [jonas@kwiboo.se: Update commit message] Signed-off-by: Jonas Karlman <jonas@kwiboo.se> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
This commit is contained in:
parent
314992516f
commit
d3e35e71ec
@ -147,6 +147,20 @@ enum {
|
|||||||
CORE_DIV_CON_SHIFT = 0,
|
CORE_DIV_CON_SHIFT = 0,
|
||||||
CORE_DIV_CON_MASK = 0x0f << CORE_DIV_CON_SHIFT,
|
CORE_DIV_CON_MASK = 0x0f << CORE_DIV_CON_SHIFT,
|
||||||
|
|
||||||
|
/* CRU_CLK_SEL2_CON */
|
||||||
|
CLK_RTC32K_SEL_SHIFT = 8,
|
||||||
|
CLK_RTC32K_SEL_MASK = 3 << CLK_RTC32K_SEL_SHIFT,
|
||||||
|
CLK_RTC32K_IO = 0,
|
||||||
|
CLK_RTC32K_PVTM,
|
||||||
|
CLK_RTC32K_FRAC_DIV,
|
||||||
|
CLK_RTC32K_DIV,
|
||||||
|
|
||||||
|
/* CRU_CLK_SEL3_CON */
|
||||||
|
CLK_RTC32K_FRAC_NUMERATOR_SHIFT = 16,
|
||||||
|
CLK_RTC32K_FRAC_NUMERATOR_MASK = 0xffff << 16,
|
||||||
|
CLK_RTC32K_FRAC_DENOMINATOR_SHIFT = 0,
|
||||||
|
CLK_RTC32K_FRAC_DENOMINATOR_MASK = 0xffff,
|
||||||
|
|
||||||
/* CRU_CLK_SEL5_CON */
|
/* CRU_CLK_SEL5_CON */
|
||||||
BUS_PLL_SEL_SHIFT = 6,
|
BUS_PLL_SEL_SHIFT = 6,
|
||||||
BUS_PLL_SEL_MASK = 0x3 << BUS_PLL_SEL_SHIFT,
|
BUS_PLL_SEL_MASK = 0x3 << BUS_PLL_SEL_SHIFT,
|
||||||
|
@ -65,6 +65,57 @@ static struct rockchip_pll_clock rk3308_pll_clks[] = {
|
|||||||
RK3308_MODE_CON, 6, 10, 0, NULL),
|
RK3308_MODE_CON, 6, 10, 0, NULL),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* rational_best_approximation(31415, 10000,
|
||||||
|
* (1 << 8) - 1, (1 << 5) - 1, &n, &d);
|
||||||
|
*
|
||||||
|
* you may look at given_numerator as a fixed point number,
|
||||||
|
* with the fractional part size described in given_denominator.
|
||||||
|
*
|
||||||
|
* for theoretical background, see:
|
||||||
|
* http://en.wikipedia.org/wiki/Continued_fraction
|
||||||
|
*/
|
||||||
|
static void rational_best_approximation(unsigned long given_numerator,
|
||||||
|
unsigned long given_denominator,
|
||||||
|
unsigned long max_numerator,
|
||||||
|
unsigned long max_denominator,
|
||||||
|
unsigned long *best_numerator,
|
||||||
|
unsigned long *best_denominator)
|
||||||
|
{
|
||||||
|
unsigned long n, d, n0, d0, n1, d1;
|
||||||
|
|
||||||
|
n = given_numerator;
|
||||||
|
d = given_denominator;
|
||||||
|
n0 = 0;
|
||||||
|
d1 = 0;
|
||||||
|
n1 = 1;
|
||||||
|
d0 = 1;
|
||||||
|
for (;;) {
|
||||||
|
unsigned long t, a;
|
||||||
|
|
||||||
|
if (n1 > max_numerator || d1 > max_denominator) {
|
||||||
|
n1 = n0;
|
||||||
|
d1 = d0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (d == 0)
|
||||||
|
break;
|
||||||
|
t = d;
|
||||||
|
a = n / d;
|
||||||
|
d = n % d;
|
||||||
|
n = t;
|
||||||
|
t = n0 + a * n1;
|
||||||
|
n0 = n1;
|
||||||
|
n1 = t;
|
||||||
|
t = d0 + a * d1;
|
||||||
|
d0 = d1;
|
||||||
|
d1 = t;
|
||||||
|
}
|
||||||
|
*best_numerator = n1;
|
||||||
|
*best_denominator = d1;
|
||||||
|
}
|
||||||
|
|
||||||
static ulong rk3308_armclk_set_clk(struct rk3308_clk_priv *priv, ulong hz)
|
static ulong rk3308_armclk_set_clk(struct rk3308_clk_priv *priv, ulong hz)
|
||||||
{
|
{
|
||||||
struct rk3308_cru *cru = priv->cru;
|
struct rk3308_cru *cru = priv->cru;
|
||||||
@ -832,6 +883,44 @@ static ulong rk3308_crypto_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
|
|||||||
return rk3308_crypto_get_clk(priv, clk_id);
|
return rk3308_crypto_get_clk(priv, clk_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ulong rk3308_rtc32k_get_clk(struct rk3308_clk_priv *priv, ulong clk_id)
|
||||||
|
{
|
||||||
|
struct rk3308_cru *cru = priv->cru;
|
||||||
|
unsigned long m, n;
|
||||||
|
u32 con, fracdiv;
|
||||||
|
|
||||||
|
con = readl(&cru->clksel_con[2]);
|
||||||
|
if ((con & CLK_RTC32K_SEL_MASK) >> CLK_RTC32K_SEL_SHIFT !=
|
||||||
|
CLK_RTC32K_FRAC_DIV)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fracdiv = readl(&cru->clksel_con[3]);
|
||||||
|
m = fracdiv & CLK_RTC32K_FRAC_NUMERATOR_MASK;
|
||||||
|
m >>= CLK_RTC32K_FRAC_NUMERATOR_SHIFT;
|
||||||
|
n = fracdiv & CLK_RTC32K_FRAC_DENOMINATOR_MASK;
|
||||||
|
n >>= CLK_RTC32K_FRAC_DENOMINATOR_SHIFT;
|
||||||
|
|
||||||
|
return OSC_HZ * m / n;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ulong rk3308_rtc32k_set_clk(struct rk3308_clk_priv *priv, ulong clk_id,
|
||||||
|
ulong hz)
|
||||||
|
{
|
||||||
|
struct rk3308_cru *cru = priv->cru;
|
||||||
|
unsigned long m, n, val;
|
||||||
|
|
||||||
|
rational_best_approximation(hz, OSC_HZ,
|
||||||
|
GENMASK(16 - 1, 0),
|
||||||
|
GENMASK(16 - 1, 0),
|
||||||
|
&m, &n);
|
||||||
|
val = m << CLK_RTC32K_FRAC_NUMERATOR_SHIFT | n;
|
||||||
|
writel(val, &cru->clksel_con[3]);
|
||||||
|
rk_clrsetreg(&cru->clksel_con[2], CLK_RTC32K_SEL_MASK,
|
||||||
|
CLK_RTC32K_FRAC_DIV << CLK_RTC32K_SEL_SHIFT);
|
||||||
|
|
||||||
|
return rk3308_rtc32k_get_clk(priv, clk_id);
|
||||||
|
}
|
||||||
|
|
||||||
static ulong rk3308_clk_get_rate(struct clk *clk)
|
static ulong rk3308_clk_get_rate(struct clk *clk)
|
||||||
{
|
{
|
||||||
struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
|
struct rk3308_clk_priv *priv = dev_get_priv(clk->dev);
|
||||||
@ -912,6 +1001,9 @@ static ulong rk3308_clk_get_rate(struct clk *clk)
|
|||||||
case SCLK_CRYPTO_APK:
|
case SCLK_CRYPTO_APK:
|
||||||
rate = rk3308_crypto_get_clk(priv, clk->id);
|
rate = rk3308_crypto_get_clk(priv, clk->id);
|
||||||
break;
|
break;
|
||||||
|
case SCLK_RTC32K:
|
||||||
|
rate = rk3308_rtc32k_get_clk(priv, clk->id);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -990,6 +1082,9 @@ static ulong rk3308_clk_set_rate(struct clk *clk, ulong rate)
|
|||||||
case SCLK_CRYPTO_APK:
|
case SCLK_CRYPTO_APK:
|
||||||
ret = rk3308_crypto_set_clk(priv, clk->id, rate);
|
ret = rk3308_crypto_set_clk(priv, clk->id, rate);
|
||||||
break;
|
break;
|
||||||
|
case SCLK_RTC32K:
|
||||||
|
ret = rk3308_rtc32k_set_clk(priv, clk->id, rate);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user