mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
clk: rockchip: Add adaptive frequency scaling for pll_rk3066
Change-Id: I9c3422a45f86e8b95be0ad069ac70d5490eb5161 Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
This commit is contained in:
@@ -39,6 +39,8 @@ struct rockchip_clk_pll {
|
||||
u8 flags;
|
||||
const struct rockchip_pll_rate_table *rate_table;
|
||||
unsigned int rate_count;
|
||||
int sel;
|
||||
unsigned long scaling;
|
||||
spinlock_t *lock;
|
||||
|
||||
struct rockchip_clk_provider *ctx;
|
||||
@@ -71,6 +73,23 @@ struct rockchip_clk_pll {
|
||||
|
||||
static struct rockchip_pll_rate_table auto_table;
|
||||
|
||||
int rockchip_pll_clk_adaptive_scaling(struct clk *clk, int sel)
|
||||
{
|
||||
struct clk *parent = clk_get_parent(clk);
|
||||
struct rockchip_clk_pll *pll;
|
||||
|
||||
if (IS_ERR_OR_NULL(parent))
|
||||
return -EINVAL;
|
||||
|
||||
pll = to_rockchip_clk_pll(__clk_get_hw(parent));
|
||||
if (!pll)
|
||||
return -EINVAL;
|
||||
|
||||
pll->sel = sel;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct rockchip_pll_rate_table *rk_pll_rate_table_get(void)
|
||||
{
|
||||
return &auto_table;
|
||||
@@ -247,9 +266,16 @@ static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pll->rate_count; i++) {
|
||||
if (rate == rate_table[i].rate)
|
||||
if (rate == rate_table[i].rate) {
|
||||
if (i < pll->sel) {
|
||||
pll->scaling = rate;
|
||||
return &rate_table[pll->sel];
|
||||
}
|
||||
pll->scaling = 0;
|
||||
return &rate_table[i];
|
||||
}
|
||||
}
|
||||
pll->scaling = 0;
|
||||
|
||||
if (pll->type == pll_rk3066)
|
||||
return rockchip_rk3066_pll_clk_set_by_auto(pll, 24 * MHZ, rate);
|
||||
@@ -597,6 +623,9 @@ static unsigned long rockchip_rk3066_pll_recalc_rate(struct clk_hw *hw,
|
||||
return prate;
|
||||
}
|
||||
|
||||
if (pll->sel && pll->scaling)
|
||||
return pll->scaling;
|
||||
|
||||
rockchip_rk3066_pll_get_params(pll, &cur);
|
||||
|
||||
rate64 *= cur.nf;
|
||||
@@ -670,9 +699,18 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
const struct rockchip_pll_rate_table *rate;
|
||||
unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate);
|
||||
struct regmap *grf = pll->ctx->grf;
|
||||
int ret;
|
||||
|
||||
pr_debug("%s: changing %s to %lu with a parent rate of %lu\n",
|
||||
__func__, clk_hw_get_name(hw), drate, prate);
|
||||
if (IS_ERR(grf)) {
|
||||
pr_debug("%s: grf regmap not available, aborting rate change\n",
|
||||
__func__);
|
||||
return PTR_ERR(grf);
|
||||
}
|
||||
|
||||
pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n",
|
||||
__func__, clk_hw_get_name(hw), old_rate, drate, prate);
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = rockchip_get_pll_settings(pll, drate);
|
||||
@@ -682,7 +720,11 @@ static int rockchip_rk3066_pll_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return rockchip_rk3066_pll_set_params(pll, rate);
|
||||
ret = rockchip_rk3066_pll_set_params(pll, rate);
|
||||
if (ret)
|
||||
pll->scaling = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rockchip_rk3066_pll_enable(struct clk_hw *hw)
|
||||
|
||||
@@ -995,6 +995,7 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates);
|
||||
void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
|
||||
int rockchip_pll_clk_adaptive_scaling(struct clk *clk, int sel);
|
||||
void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
|
||||
unsigned int reg, void (*cb)(void));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user