mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
clk: s7d: Fix known issue [1/1]
PD#SWPL-163050 Problem: 1 PLL driver adds rstn features 2 Add ACLKM clock 3 Adapts to pll_v4_ops Solution: Fixed Verify: s7d_bm209 Change-Id: Ide5199539d388d9ee415ecf65f3c162b2e4c881c Signed-off-by: Chuan Liu <chuan.liu@amlogic.com>
This commit is contained in:
+467
-9
@@ -225,10 +225,6 @@ static unsigned int __pll_params_with_frac(unsigned long rate,
|
||||
else
|
||||
frac_max = (1 << (pll->frac.width - 2));
|
||||
|
||||
/* Bail out if we are already over the requested rate */
|
||||
if (rate < parent_rate * m / n)
|
||||
return 0;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST)
|
||||
val = DIV_ROUND_CLOSEST_ULL(val * frac_max, parent_rate);
|
||||
else
|
||||
@@ -635,10 +631,14 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
|
||||
return 0;
|
||||
|
||||
/* Make sure the pll is in reset */
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
|
||||
/* Enable the pll */
|
||||
meson_parm_write(clk->map, &pll->en, 1);
|
||||
|
||||
/*
|
||||
* Make the PLL more stable, if not,
|
||||
* It will probably lock failed (GP0 PLL)
|
||||
@@ -648,7 +648,10 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
|
||||
#endif
|
||||
|
||||
/* Take the pll out reset */
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
|
||||
if (meson_clk_pll_wait_lock(hw))
|
||||
return -EIO;
|
||||
@@ -665,7 +668,10 @@ static void meson_clk_pll_disable(struct clk_hw *hw)
|
||||
return;
|
||||
|
||||
/* Put the pll is in reset */
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
|
||||
/* Disable the pll */
|
||||
meson_parm_write(clk->map, &pll->en, 0);
|
||||
@@ -1036,13 +1042,465 @@ const struct clk_ops meson_clk_pll_v3_ops = {
|
||||
.disable = meson_clk_pll_disable
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_pll_v3_ops);
|
||||
#endif
|
||||
|
||||
static unsigned long meson_clk_pll_params_to_rate(struct meson_clk_pll_data *pll,
|
||||
unsigned long prate,
|
||||
u32 m, u32 n, u32 frac, u32 od)
|
||||
{
|
||||
u64 vco_rate, frac_rate;
|
||||
u32 frac_precision;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_POWER_OF_TWO)
|
||||
n = (u32)BIT(n);
|
||||
|
||||
if (unlikely(!n))
|
||||
return 0;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_FIXED_EN0P5)
|
||||
prate = prate >> 1;
|
||||
|
||||
prate = DIV_ROUND_UP_ULL(prate, n);
|
||||
vco_rate = (u64)prate * m;
|
||||
|
||||
if (frac) {
|
||||
if (pll->flags & CLK_MESON_PLL_FIXED_FRAC_WEIGHT_PRECISION)
|
||||
frac_precision = FIXED_FRAC_WEIGHT_PRECISION;
|
||||
else
|
||||
frac_precision = (u32)BIT(pll->frac.width);
|
||||
|
||||
frac_rate = (u64)prate * frac;
|
||||
vco_rate += DIV_ROUND_UP_ULL(frac_rate, frac_precision);
|
||||
}
|
||||
|
||||
return vco_rate >> od;
|
||||
}
|
||||
|
||||
static unsigned long meson_clk_pll_v4_recalc_rate(struct clk_hw *hw, unsigned long prate)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
unsigned int m, n, frac, od;
|
||||
|
||||
n = meson_parm_read(clk->map, &pll->n);
|
||||
m = meson_parm_read(clk->map, &pll->m);
|
||||
od = meson_parm_read(clk->map, &pll->od);
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&pll->frac))
|
||||
frac = meson_parm_read(clk->map, &pll->frac);
|
||||
else
|
||||
frac = 0;
|
||||
|
||||
return meson_clk_pll_params_to_rate(pll, prate, m, n, frac, od);
|
||||
}
|
||||
|
||||
static unsigned int meson_clk_pll_v4_get_range_m(unsigned long long rate,
|
||||
unsigned long parent_rate,
|
||||
unsigned int n,
|
||||
struct meson_clk_pll_data *pll)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_POWER_OF_TWO)
|
||||
val = rate << n;
|
||||
else
|
||||
val = rate * n;
|
||||
if (__pll_round_closest_mult(pll))
|
||||
return DIV_ROUND_CLOSEST_ULL(val, parent_rate);
|
||||
|
||||
return div_u64(val, parent_rate);
|
||||
}
|
||||
|
||||
static int meson_clk_pll_get_range_value(struct meson_clk_pll_data *pll,
|
||||
unsigned long rate,
|
||||
unsigned long prate,
|
||||
unsigned int *m,
|
||||
unsigned int *n,
|
||||
unsigned int *od)
|
||||
{
|
||||
u64 vco_rate;
|
||||
u32 idx;
|
||||
unsigned int t_m;
|
||||
unsigned long now, best = 0;
|
||||
unsigned long t_prate = prate;
|
||||
u32 od_max = BIT(pll->od.width) - 1;
|
||||
|
||||
/* limit od max value for hw limit */
|
||||
if (unlikely(!!pll->od_max))
|
||||
od_max = pll->od_max;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_FIXED_N) {
|
||||
*n = pll->fixed_n;
|
||||
} else {
|
||||
if (pll->flags & CLK_MESON_PLL_POWER_OF_TWO)
|
||||
*n = 0;
|
||||
else
|
||||
*n = 1;
|
||||
}
|
||||
|
||||
for (idx = 0; idx <= od_max; idx++) {
|
||||
vco_rate = (u64)rate << idx;
|
||||
if (pll->flags & CLK_MESON_PLL_FIXED_EN0P5)
|
||||
t_prate = prate >> 1;
|
||||
t_m = meson_clk_pll_v4_get_range_m(vco_rate, t_prate, *n, pll);
|
||||
if (t_m > pll->range->max)
|
||||
break;
|
||||
if (t_m < pll->range->min)
|
||||
continue;
|
||||
|
||||
now = meson_clk_pll_params_to_rate(pll, prate, t_m, *n, 0, idx);
|
||||
if (meson_clk_pll_is_better(rate, best, now, pll)) {
|
||||
best = now;
|
||||
*m = t_m;
|
||||
*od = idx;
|
||||
if (now == rate)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_clk_pll_get_table_value(struct meson_clk_pll_data *pll,
|
||||
unsigned long rate,
|
||||
unsigned long prate,
|
||||
unsigned int *m,
|
||||
unsigned int *n,
|
||||
unsigned int *od)
|
||||
{
|
||||
u32 idx;
|
||||
unsigned int t_m, t_n, t_od;
|
||||
unsigned long now, best = 0;
|
||||
|
||||
for (idx = 0; pll->table[idx].m; idx++) {
|
||||
t_m = pll->table[idx].m;
|
||||
t_n = pll->table[idx].n;
|
||||
t_od = pll->table[idx].od;
|
||||
|
||||
now = meson_clk_pll_params_to_rate(pll, prate, t_m, t_n, 0, t_od);
|
||||
if (meson_clk_pll_is_better(rate, best, now, pll)) {
|
||||
best = now;
|
||||
*m = t_m;
|
||||
*n = t_n;
|
||||
*od = t_od;
|
||||
if (now == rate)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_clk_pll_get_params_table(struct meson_clk_pll_data *pll,
|
||||
unsigned long rate,
|
||||
unsigned long prate,
|
||||
unsigned int *m,
|
||||
unsigned int *n,
|
||||
unsigned int *od)
|
||||
{
|
||||
if (pll->range)
|
||||
return meson_clk_pll_get_range_value(pll, rate, prate, m, n, od);
|
||||
else if (pll->table)
|
||||
return meson_clk_pll_get_table_value(pll, rate, prate, m, n, od);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static unsigned int meson_clk_pll_get_param_frac(struct meson_clk_pll_data *pll,
|
||||
unsigned long rate,
|
||||
unsigned long prate,
|
||||
unsigned int m,
|
||||
unsigned int n,
|
||||
unsigned int od)
|
||||
{
|
||||
unsigned int frac_max;
|
||||
u64 vco_rate = (u64)rate << od;
|
||||
u64 frac;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_FIXED_EN0P5)
|
||||
prate = prate >> 1;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_POWER_OF_TWO) {
|
||||
frac = vco_rate << n;
|
||||
if (vco_rate < (((u64)prate >> n) * m))
|
||||
return 0;
|
||||
} else {
|
||||
frac = vco_rate * n;
|
||||
/* Bail out if we are already over the requested rate */
|
||||
if (vco_rate < (div_u64((u64)prate * m, n)))
|
||||
return 0;
|
||||
}
|
||||
if (pll->flags & CLK_MESON_PLL_FIXED_FRAC_WEIGHT_PRECISION)
|
||||
frac_max = FIXED_FRAC_WEIGHT_PRECISION;
|
||||
else
|
||||
frac_max = 1 << pll->frac.width;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_ROUND_CLOSEST)
|
||||
frac = DIV_ROUND_CLOSEST_ULL(frac * frac_max, prate);
|
||||
else
|
||||
frac = div_u64(frac * frac_max, prate);
|
||||
|
||||
frac -= (u64)m * frac_max;
|
||||
return min_t(unsigned int, frac, frac_max);
|
||||
}
|
||||
|
||||
static int meson_clk_pll_v4_get_params(struct meson_clk_pll_data *pll,
|
||||
unsigned long rate,
|
||||
unsigned long prate,
|
||||
unsigned int *best_m,
|
||||
unsigned int *best_n,
|
||||
unsigned int *best_od,
|
||||
unsigned int *best_frac)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = meson_clk_pll_get_params_table(pll, rate, prate, best_m, best_n, best_od);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&pll->frac))
|
||||
*best_frac = meson_clk_pll_get_param_frac(pll, rate, prate,
|
||||
*best_m, *best_n, *best_od);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_clk_pll_v4_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
struct pll_rate_range *pll_range = &pll->pll_range;
|
||||
unsigned long rate = req->rate;
|
||||
|
||||
if (pll->flags & CLK_MESON_PLL_READ_ONLY) {
|
||||
req->rate = clk_hw_get_rate(hw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rate = clamp(rate, pll_range->min_rate, pll_range->max_rate);
|
||||
rate = clamp(rate, req->min_rate, req->max_rate);
|
||||
req->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool meson_clk_pll_od_or_frac_correct(struct clk_regmap *clk,
|
||||
struct meson_clk_pll_data *pll,
|
||||
unsigned int m, unsigned int n)
|
||||
{
|
||||
return meson_parm_read(clk->map, &pll->m) == m &&
|
||||
meson_parm_read(clk->map, &pll->n) == n &&
|
||||
meson_parm_read(clk->map, &pll->en);
|
||||
}
|
||||
|
||||
static int meson_clk_pll_v4_init(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
struct pll_rate_range *rate_range = &pll->pll_range;
|
||||
|
||||
if (rate_range->max_rate == 0)
|
||||
rate_range->max_rate = ULONG_MAX;
|
||||
|
||||
//if (!pll->range && !pll->table)
|
||||
// return -EINVAL;
|
||||
/*
|
||||
* Do not init pll
|
||||
* 1. it will gate pll which is needed in RTOS
|
||||
* 2. it will gate sys pll who is feeding CPU
|
||||
*/
|
||||
if (pll->flags & CLK_MESON_PLL_IGNORE_INIT) {
|
||||
pr_warn("ignore %s clock init\n", clk_hw_get_name(hw));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pll->init_count) {
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN) {
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
regmap_multi_reg_write(clk->map, pll->init_regs,
|
||||
pll->init_count);
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
} else {
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
regmap_multi_reg_write(clk->map, pll->init_regs,
|
||||
pll->init_count);
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_clk_pll_v4_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
|
||||
/* do nothing if the PLL is already enabled */
|
||||
if (clk_hw_is_enabled(hw))
|
||||
return 0;
|
||||
|
||||
/* Make sure the pll is in reset */
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
|
||||
/* Enable the pll */
|
||||
meson_parm_write(clk->map, &pll->en, 1);
|
||||
|
||||
/* Make sure the pll is in lock reset */
|
||||
if (MESON_PARM_APPLICABLE(&pll->l_rst)) {
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->l_rst, 0);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->l_rst, 1);
|
||||
}
|
||||
|
||||
/* Make sure the pll force lock is clear */
|
||||
if (MESON_PARM_APPLICABLE(&pll->fl))
|
||||
meson_parm_write(clk->map, &pll->fl, 0);
|
||||
|
||||
/*
|
||||
* Make the PLL more stable, if not,
|
||||
* It will probably lock failed (GP0 PLL)
|
||||
*/
|
||||
udelay(50);
|
||||
|
||||
/* Take the pll out reset */
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
|
||||
/* Take the pll out lock reset */
|
||||
if (MESON_PARM_APPLICABLE(&pll->l_rst)) {
|
||||
udelay(20);
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->l_rst, 1);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->l_rst, 0);
|
||||
}
|
||||
|
||||
if (meson_clk_pll_wait_lock(hw))
|
||||
return -EIO;
|
||||
|
||||
/* Make sure the pll force lock is set */
|
||||
if (MESON_PARM_APPLICABLE(&pll->fl))
|
||||
meson_parm_write(clk->map, &pll->fl, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void meson_clk_pll_v4_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
|
||||
if (bypass_clk_disable)
|
||||
return;
|
||||
|
||||
/* Put the pll is in reset */
|
||||
if (pll->flags & CLK_MESON_PLL_RSTN)
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->rst, 1);
|
||||
|
||||
/* Disable the pll */
|
||||
meson_parm_write(clk->map, &pll->en, 0);
|
||||
}
|
||||
|
||||
static int meson_clk_pll_v4_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
unsigned int m, n, od, frac;
|
||||
unsigned int enabled;
|
||||
unsigned long old_rate, vco_rate;
|
||||
int ret = 0;
|
||||
|
||||
if (prate == 0 || rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
old_rate = clk_hw_get_rate(hw);
|
||||
|
||||
/* calculate M, N, OD*/
|
||||
ret = meson_clk_pll_v4_get_params(pll, rate, prate, &m, &n, &od, &frac);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* only frac correct, only write frac register only */
|
||||
if (meson_clk_pll_od_or_frac_correct(clk, pll, m, n)) {
|
||||
if (unlikely(!!frac) && frac != meson_parm_read(clk->map, &pll->frac))
|
||||
/* Clear frac bits and Update frac value */
|
||||
meson_parm_write(clk->map, &pll->frac, frac);
|
||||
if (unlikely(!!od) && od != meson_parm_read(clk->map, &pll->od))
|
||||
/* Clear od bits and Update od value */
|
||||
meson_parm_write(clk->map, &pll->od, od);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enabled = meson_parm_read(clk->map, &pll->en);
|
||||
if (enabled)
|
||||
meson_clk_pll_v4_disable(hw);
|
||||
|
||||
if (MESON_PARM_APPLICABLE(&pll->th)) {
|
||||
vco_rate = meson_clk_pll_params_to_rate(pll, prate, m, n, frac, 0);
|
||||
if (vco_rate >= MESON_PLL_THRESHOLD_RATE)
|
||||
meson_parm_write(clk->map, &pll->th, 1);
|
||||
else
|
||||
meson_parm_write(clk->map, &pll->th, 0);
|
||||
}
|
||||
|
||||
meson_parm_write(clk->map, &pll->n, n);
|
||||
meson_parm_write(clk->map, &pll->m, m);
|
||||
meson_parm_write(clk->map, &pll->od, od);
|
||||
if (MESON_PARM_APPLICABLE(&pll->frac))
|
||||
meson_parm_write(clk->map, &pll->frac, frac);
|
||||
|
||||
/* If the pll is stopped, bail out now */
|
||||
if (!enabled)
|
||||
return 0;
|
||||
|
||||
ret = meson_clk_pll_v4_enable(hw);
|
||||
if (ret) {
|
||||
pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
|
||||
__func__, old_rate);
|
||||
/*
|
||||
* FIXME: Do we really need/want this HACK ?
|
||||
* It looks unsafe. what happens if the clock gets into a
|
||||
* broken state and we can't lock back on the old_rate ? Looks
|
||||
* like an infinite recursion is possible
|
||||
*/
|
||||
meson_clk_pll_v4_set_rate(hw, old_rate, prate);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct clk_ops meson_clk_pll_v4_ops = {
|
||||
/* walk the init regs each time when set a new rate,
|
||||
* init callback is not useful for v3 ops
|
||||
*/
|
||||
.init = meson_clk_pll_v4_init,
|
||||
.recalc_rate = meson_clk_pll_v4_recalc_rate,
|
||||
.determine_rate = meson_clk_pll_v4_determine_rate,
|
||||
.set_rate = meson_clk_pll_v4_set_rate,
|
||||
.is_enabled = meson_clk_pll_is_enabled,
|
||||
.enable = meson_clk_pll_v4_enable,
|
||||
.disable = meson_clk_pll_v4_disable
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_pll_v4_ops);
|
||||
|
||||
const struct clk_ops meson_clk_pll_ro_ops = {
|
||||
.recalc_rate = meson_clk_pll_recalc_rate,
|
||||
.init = meson_clk_pll_v4_init,
|
||||
.recalc_rate = meson_clk_pll_v4_recalc_rate,
|
||||
.is_enabled = meson_clk_pll_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_pll_ro_ops);
|
||||
#endif
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic PLL driver");
|
||||
MODULE_AUTHOR("Carlo Caione <carlo@endlessm.com>");
|
||||
|
||||
@@ -16,6 +16,11 @@ struct pll_mult_range {
|
||||
unsigned int max;
|
||||
};
|
||||
|
||||
struct pll_rate_range {
|
||||
unsigned long min_rate;
|
||||
unsigned long max_rate;
|
||||
};
|
||||
|
||||
#if defined CONFIG_AMLOGIC_MODIFY && defined CONFIG_ARM
|
||||
struct pll_params_table {
|
||||
u16 m;
|
||||
@@ -35,6 +40,7 @@ struct pll_params_table {
|
||||
struct pll_params_table {
|
||||
unsigned int m;
|
||||
unsigned int n;
|
||||
u16 od;
|
||||
const struct reg_sequence *regs;
|
||||
unsigned int regs_count;
|
||||
};
|
||||
@@ -43,9 +49,17 @@ struct pll_params_table {
|
||||
{ \
|
||||
.m = (_m), \
|
||||
.n = (_n), \
|
||||
.od = (0), \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PLL_PARAMS_v4(_m, _n, _od) \
|
||||
{ \
|
||||
.m = (_m), \
|
||||
.n = (_n), \
|
||||
.od = (_od), \
|
||||
}
|
||||
|
||||
#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0)
|
||||
#define CLK_MESON_PLL_IGNORE_INIT BIT(1)
|
||||
#define CLK_MESON_PLL_FIXED_FRAC_WEIGHT_PRECISION BIT(2)
|
||||
@@ -54,10 +68,12 @@ struct pll_params_table {
|
||||
#define CLK_MESON_PLL_FIXED_EN0P5 BIT(5)
|
||||
/*
|
||||
* when PLL set the same rate, Do nothing in clk_set_rate,
|
||||
* enable callback relock it, OD should not be cleared in ARM64,
|
||||
* v3 enable callback relock it, OD should not be cleared in ARM64,
|
||||
* and retain it.
|
||||
*/
|
||||
#define CLK_MESON_PLL_RETAIN_OD BIT(6)
|
||||
#define CLK_MESON_PLL_READ_ONLY BIT(7)
|
||||
#define CLK_MESON_PLL_RSTN BIT(8)
|
||||
|
||||
struct meson_clk_pll_data {
|
||||
struct parm en;
|
||||
@@ -66,6 +82,7 @@ struct meson_clk_pll_data {
|
||||
struct parm frac;
|
||||
struct parm l;
|
||||
struct parm rst;
|
||||
struct parm l_rst;
|
||||
struct parm th; /* threshold */
|
||||
struct parm fl; /* force lock */
|
||||
/* for 32bit dco overflow */
|
||||
@@ -77,8 +94,10 @@ struct meson_clk_pll_data {
|
||||
unsigned int init_count;
|
||||
const struct pll_params_table *table;
|
||||
const struct pll_mult_range *range;
|
||||
struct pll_rate_range pll_range;
|
||||
unsigned long od_max;
|
||||
unsigned int smc_id;
|
||||
u8 flags;
|
||||
u16 flags;
|
||||
u8 secid_disable;
|
||||
u8 secid;
|
||||
u8 fixed_n;
|
||||
@@ -89,5 +108,6 @@ extern const struct clk_ops meson_clk_pll_ops;
|
||||
extern const struct clk_ops meson_clk_pcie_pll_ops;
|
||||
extern const struct clk_ops meson_secure_pll_v2_ops;
|
||||
extern const struct clk_ops meson_clk_pll_v3_ops;
|
||||
extern const struct clk_ops meson_clk_pll_v4_ops;
|
||||
|
||||
#endif /* __MESON_CLK_PLL_H */
|
||||
|
||||
+36
-280
@@ -273,13 +273,13 @@ static struct clk_fixed_factor _name = { \
|
||||
}, \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
#define __MESON_CLK_PLL(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_l_rst_reg, _l_rst_shift, _l_rst_width, \
|
||||
_init_reg, _init_reg_cnt, _range, _table, \
|
||||
_smcid, _secid, _secid_dis, _dflags, \
|
||||
_ops, _pname, _pdata, _phw, _iflags, \
|
||||
@@ -292,6 +292,7 @@ static struct clk_regmap _name = { \
|
||||
MEMBER_REG_PARM(n, _n_reg, _n_shift, _n_width), \
|
||||
MEMBER_REG_PARM(l, _l_reg, _l_shift, _l_width), \
|
||||
MEMBER_REG_PARM(rst, _r_reg, _r_shift, _r_width), \
|
||||
MEMBER_REG_PARM(l_rst, _l_rst_reg, _l_rst_shift, _l_rst_width),\
|
||||
MEMBER_REG_PARM(od, _od_reg, _od_shift, _od_width), \
|
||||
.range = _range, \
|
||||
.table = _table, \
|
||||
@@ -312,67 +313,6 @@ static struct clk_regmap _name = { \
|
||||
.flags = _iflags, \
|
||||
}, \
|
||||
}
|
||||
#else
|
||||
#define __MESON_CLK_PLL(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_init_reg, _init_reg_cnt, _range, _table, \
|
||||
_smcid, _secid, _secid_dis, _dflags, \
|
||||
_ops, _pname, _pdata, _phw, _iflags, \
|
||||
_od_name, _od_reg, _od_shift, _od_width, \
|
||||
_od_table, _od_smcid, _od_secid, _od_dflags, \
|
||||
_od_ops, _od_iflags) \
|
||||
static struct clk_regmap _name = { \
|
||||
.data = &(struct meson_clk_pll_data){ \
|
||||
MEMBER_REG_PARM(en, _en_reg, _en_shift, _en_width), \
|
||||
MEMBER_REG_PARM(m, _m_reg, _m_shift, _m_width), \
|
||||
MEMBER_REG_PARM(frac, _f_reg, _f_shift, _f_width), \
|
||||
MEMBER_REG_PARM(n, _n_reg, _n_shift, _n_width), \
|
||||
MEMBER_REG_PARM(l, _l_reg, _l_shift, _l_width), \
|
||||
MEMBER_REG_PARM(rst, _r_reg, _r_shift, _r_width), \
|
||||
MEMBER_REG_PARM(od, _od_reg, _od_shift, _od_width), \
|
||||
.range = _range, \
|
||||
.table = _table, \
|
||||
.init_regs = _init_reg, \
|
||||
.init_count = _init_reg_cnt, \
|
||||
.smc_id = _smcid, \
|
||||
.secid = _secid, \
|
||||
.secid_disable = _secid_dis, \
|
||||
.flags = _dflags, \
|
||||
}, \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.name = # _name, \
|
||||
.ops = _ops, \
|
||||
.parent_names = _pname, \
|
||||
.parent_data = _pdata, \
|
||||
.parent_hws = _phw, \
|
||||
.num_parents = 1, \
|
||||
.flags = _iflags, \
|
||||
}, \
|
||||
}; \
|
||||
static struct clk_regmap _od_name = { \
|
||||
.data = &(struct clk_regmap_div_data){ \
|
||||
.offset = _od_reg, \
|
||||
.shift = _od_shift, \
|
||||
.width = _od_width, \
|
||||
.table = _od_table, \
|
||||
.smc_id = _od_smcid, \
|
||||
.secid = _od_secid, \
|
||||
.flags = _od_dflags, \
|
||||
}, \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.name = # _od_name, \
|
||||
.ops = _od_ops, \
|
||||
.parent_hws = (const struct clk_hw *[]) { \
|
||||
&_name.hw }, \
|
||||
.num_parents = 1, \
|
||||
.flags = _od_iflags, \
|
||||
}, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MESON_CLK_MUX_RW(_name, _reg, _mask, _shift, _table, _dflags, \
|
||||
_pdata, _iflags) \
|
||||
@@ -456,13 +396,13 @@ static struct clk_regmap _od_name = { \
|
||||
&meson_clk_dualdiv_ops, NULL, NULL, \
|
||||
(const struct clk_hw *[]) { _phw }, _iflags)
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
#define MESON_CLK_PLL_RW(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_l_rst_reg, _l_rst_shift, _l_rst_width, \
|
||||
_init_reg, _range, _table, \
|
||||
_dflags, _pdata, _iflags, \
|
||||
_od_reg, _od_shift, _od_width) \
|
||||
@@ -472,125 +412,12 @@ static struct clk_regmap _od_name = { \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_l_rst_reg, _l_rst_shift, _l_rst_width, \
|
||||
_init_reg, ARRAY_SIZE(_init_reg), _range, _table,\
|
||||
0, 0, 0, _dflags, &meson_clk_pll_v3_ops, \
|
||||
0, 0, 0, _dflags, &meson_clk_pll_v4_ops, \
|
||||
NULL, _pdata, NULL, _iflags, \
|
||||
_od_reg, _od_shift, _od_width)
|
||||
|
||||
#define MESON_CLK_PLL_RO(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_dflags, _pdata, _iflags, \
|
||||
_od_reg, _od_shift, _od_width) \
|
||||
__MESON_CLK_PLL(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
NULL, 0, NULL, NULL, \
|
||||
0, 0, 0, _dflags, &meson_clk_pll_ro_ops, \
|
||||
NULL, _pdata, NULL, _iflags, \
|
||||
_od_reg, _od_shift, _od_width)
|
||||
|
||||
#define MESON_CLK_PLL_SEC(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_range, _table, \
|
||||
_smcid, _secid, _secid_dis, _dflags, \
|
||||
_pdata, _iflags, \
|
||||
_od_reg, _od_shift, _od_width) \
|
||||
__MESON_CLK_PLL(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
NULL, 0, _range, _table, \
|
||||
_smcid, _secid, _secid_dis, _dflags, \
|
||||
&meson_secure_pll_v2_ops, \
|
||||
NULL, _pdata, NULL, _iflags, \
|
||||
_od_reg, _od_shift, _od_width)
|
||||
#else
|
||||
#define MESON_CLK_PLL_RW(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_init_reg, _range, _table, \
|
||||
_dflags, _pdata, _iflags, \
|
||||
_od_reg, _od_shift, _od_width, _od_table, \
|
||||
_od_dflags) \
|
||||
__MESON_CLK_PLL(_name ## _dco, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_init_reg, ARRAY_SIZE(_init_reg), _range, _table,\
|
||||
0, 0, 0, _dflags, \
|
||||
&meson_clk_pll_v3_ops, \
|
||||
NULL, _pdata, NULL, _iflags, \
|
||||
_name, _od_reg, _od_shift, _od_width, \
|
||||
_od_table, 0, 0, _od_dflags, \
|
||||
&clk_regmap_divider_ops, CLK_SET_RATE_PARENT)
|
||||
|
||||
#define MESON_CLK_PLL_RO(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_dflags, _pdata, _iflags, \
|
||||
_od_reg, _od_shift, _od_width, _od_table, \
|
||||
_od_dflags) \
|
||||
__MESON_CLK_PLL(_name ## _dco, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
NULL, 0, NULL, NULL, \
|
||||
0, 0, 0, _dflags, \
|
||||
&meson_clk_pll_ro_ops, \
|
||||
NULL, _pdata, NULL, _iflags, \
|
||||
_name, _od_reg, _od_shift, _od_width, \
|
||||
_od_table, 0, 0, _od_dflags, \
|
||||
&clk_regmap_divider_ro_ops, CLK_SET_RATE_PARENT)
|
||||
|
||||
#define MESON_CLK_PLL_SEC(_name, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
_range, _table, \
|
||||
_smcid, _secid, _secid_dis, _dflags, \
|
||||
_pdata, _iflags, \
|
||||
_od_reg, _od_shift, _od_width, _od_table, \
|
||||
_od_smcid, _od_secid, _od_dflags) \
|
||||
__MESON_CLK_PLL(_name ## _dco, _en_reg, _en_shift, _en_width, \
|
||||
_m_reg, _m_shift, _m_width, \
|
||||
_f_reg, _f_shift, _f_width, \
|
||||
_n_reg, _n_shift, _n_width, \
|
||||
_l_reg, _l_shift, _l_width, \
|
||||
_r_reg, _r_shift, _r_width, \
|
||||
NULL, 0, _range, _table, \
|
||||
_smcid, _secid, _secid_dis, _dflags, \
|
||||
&meson_secure_pll_v2_ops, \
|
||||
NULL, _pdata, NULL, _iflags, \
|
||||
_name, _od_reg, _od_shift, _od_width, \
|
||||
_od_table, _od_smcid, _od_secid, _od_dflags, \
|
||||
&clk_regmap_secure_v2_divider_ops, CLK_SET_RATE_PARENT)
|
||||
#endif
|
||||
|
||||
#define __MESON_CLK_COMPOSITE(_m_name, _m_reg, _m_mask, _m_shift, \
|
||||
_m_table, _m_dflags, _m_ops, _pname, \
|
||||
_pdata, _phw, _pnub, _m_iflags, \
|
||||
@@ -665,23 +492,6 @@ static struct clk_regmap _g_name = { \
|
||||
_cname, _g_reg, _g_bit, _g_dflags, \
|
||||
&clk_regmap_gate_ops, _g_iflags)
|
||||
|
||||
#define MESON_CLK_COMPOSITE_RO(_cname, _m_reg, _m_mask, _m_shift, \
|
||||
_m_table, _m_dflags, _m_pdata, _m_iflags,\
|
||||
_d_reg, _d_shift, _d_width, _d_table, \
|
||||
_d_dflags, _d_iflags, \
|
||||
_g_reg, _g_bit, _g_dflags, _g_iflags) \
|
||||
__MESON_CLK_COMPOSITE(_cname ## _sel, _m_reg, _m_mask, _m_shift,\
|
||||
_m_table, CLK_MUX_READ_ONLY | (_m_dflags),\
|
||||
&clk_regmap_mux_ro_ops, \
|
||||
NULL, _m_pdata, NULL, \
|
||||
ARRAY_SIZE(_m_pdata), _m_iflags, \
|
||||
_cname ## _div, \
|
||||
_d_reg, _d_shift, _d_width, _d_table, \
|
||||
CLK_DIVIDER_READ_ONLY | (_d_dflags), \
|
||||
&clk_regmap_divider_ro_ops, _d_iflags, \
|
||||
_cname, _g_reg, _g_bit, _g_dflags, \
|
||||
&clk_regmap_gate_ro_ops, _g_iflags)
|
||||
|
||||
static const struct clk_parent_data fclk_parent = {
|
||||
.fw_name = "fixed_pll",
|
||||
};
|
||||
@@ -706,29 +516,18 @@ MESON_CLK_GATE_RO(fclk_div2p5, ANACTRL_FIXPLL_CTRL0, 25, 0, &fclk_div2p5_div.hw,
|
||||
MESON_CLK_FIXED_FACTOR_FCLK(fclk_clk50m_div, 1, 40);
|
||||
MESON_CLK_GATE_RO(fclk_clk50m, ANACTRL_FIXPLL_CTRL1, 31, 0, &fclk_clk50m_div.hw, 0);
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
static const struct pll_params_table gp0_pll_table[] = {
|
||||
PLL_PARAMS(128, 0, 0), /* DCO = 1536M OD = 0 PLL = 1536M */
|
||||
PLL_PARAMS(192, 0, 1), /* DCO = 2304M OD = 1 PLL = 1152M */
|
||||
PLL_PARAMS_v4(128, 0, 0), /* DCO = 1536M OD = 0 PLL = 1536M */
|
||||
PLL_PARAMS_v4(192, 0, 1), /* DCO = 2304M OD = 1 PLL = 1152M */
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
#else
|
||||
static const struct pll_params_table gp0_pll_table[] = {
|
||||
PLL_PARAMS(128, 0), /* DCO = 1536M */
|
||||
PLL_PARAMS(192, 0), /* DCO = 2304M */
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct reg_sequence gp0_init_regs[] = {
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL0, .def = 0x000100ea },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL1, .def = 0x1148cd00 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL0, .def = 0x00010000 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL1, .def = 0x11480000 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL2, .def = 0x1219b010 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x00008010 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL4, .def = 0x1f01110f },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL1, .def = 0x1948cd00, .delay_us = 20 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL0, .def = 0x200100ea, .delay_us = 20 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x20008010 },
|
||||
{ .reg = ANACTRL_GP0PLL_CTRL4, .def = 0x1f01110f }
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gp0_pll_parent = {
|
||||
@@ -737,44 +536,30 @@ static const struct clk_parent_data gp0_pll_parent = {
|
||||
|
||||
MESON_CLK_PLL_RW(gp0_pll, ANACTRL_GP0PLL_CTRL1, 27, 1, /* en */
|
||||
ANACTRL_GP0PLL_CTRL0, 0, 9, /* m */
|
||||
ANACTRL_GP0PLL_CTRL1, 0, 19, /* frac */
|
||||
ANACTRL_GP0PLL_CTRL1, 0, 17, /* frac */
|
||||
ANACTRL_GP0PLL_CTRL0, 12, 3, /* n */
|
||||
ANACTRL_GP0PLL_CTRL0, 31, 1, /* lock */
|
||||
ANACTRL_GP0PLL_CTRL0, 29, 1, /* rst */
|
||||
ANACTRL_GP0PLL_CTRL3, 29, 1, /* l_rst */
|
||||
gp0_init_regs, NULL, gp0_pll_table, /* init_regs, range, table */
|
||||
CLK_MESON_PLL_POWER_OF_TWO | CLK_MESON_PLL_FIXED_EN0P5, /* dflags */
|
||||
CLK_MESON_PLL_POWER_OF_TWO | CLK_MESON_PLL_FIXED_EN0P5 |
|
||||
CLK_MESON_PLL_IGNORE_INIT | CLK_MESON_PLL_RSTN, /* dflags */
|
||||
&gp0_pll_parent, 0, /* pdata, iflags */
|
||||
ANACTRL_GP0PLL_CTRL0, 20, 3 /* od */
|
||||
#ifdef CONFIG_ARM
|
||||
);
|
||||
#else
|
||||
, NULL, CLK_DIVIDER_POWER_OF_TWO); /* od_table, od_dflags */
|
||||
#endif
|
||||
ANACTRL_GP0PLL_CTRL0, 20, 3); /* od */
|
||||
|
||||
#ifdef CONFIG_ARM
|
||||
static const struct pll_params_table hifi_pll_table[] = {
|
||||
PLL_PARAMS(150, 0, 0), /* DCO = 1800M OD = 0 PLL = 1800M */
|
||||
PLL_PARAMS(150, 0, 2), /* DCO = 1800M OD = 4 PLL = 450M */
|
||||
PLL_PARAMS(163, 0, 2), /* DCO = 1944M OD = 4 PLL = 486M */
|
||||
PLL_PARAMS_v4(150, 0, 0), /* DCO = 1800M OD = 0 PLL = 1800M */
|
||||
PLL_PARAMS_v4(150, 0, 2), /* DCO = 1800M OD = 4 PLL = 450M */
|
||||
PLL_PARAMS_v4(163, 0, 2), /* DCO = 1944M OD = 4 PLL = 486M */
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
#else
|
||||
static const struct pll_params_table hifi_pll_table[] = {
|
||||
PLL_PARAMS(150, 0), /* DCO = 1800M */
|
||||
PLL_PARAMS(163, 0), /* DCO = 1944M */
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct reg_sequence hifi0_init_regs[] = {
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL0, .def = 0x000100ea },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL1, .def = 0x11489c40 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL0, .def = 0x00010000 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL1, .def = 0x11480000 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL2, .def = 0x1219b010 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL3, .def = 0x00008010 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL4, .def = 0x1f01110f },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL1, .def = 0x19489c40, .delay_us = 20 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL0, .def = 0x200100ea, .delay_us = 20 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL3, .def = 0x20008010 }
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL3, .def = 0x20008010 },
|
||||
{ .reg = ANACTRL_HIFI0PLL_CTRL4, .def = 0x1f01110f }
|
||||
};
|
||||
|
||||
static const struct clk_parent_data hifi0_pll_parent = {
|
||||
@@ -783,31 +568,24 @@ static const struct clk_parent_data hifi0_pll_parent = {
|
||||
|
||||
MESON_CLK_PLL_RW(hifi_pll, ANACTRL_HIFI0PLL_CTRL1, 27, 1, /* en */
|
||||
ANACTRL_HIFI0PLL_CTRL0, 0, 9, /* m */
|
||||
ANACTRL_HIFI0PLL_CTRL1, 0, 19, /* frac */
|
||||
ANACTRL_HIFI0PLL_CTRL1, 0, 17, /* frac */
|
||||
ANACTRL_HIFI0PLL_CTRL0, 12, 3, /* n */
|
||||
ANACTRL_HIFI0PLL_CTRL0, 31, 1, /* lock */
|
||||
ANACTRL_HIFI0PLL_CTRL0, 29, 1, /* rst */
|
||||
ANACTRL_HIFI0PLL_CTRL3, 29, 1, /* l_rst */
|
||||
hifi0_init_regs, NULL, hifi_pll_table, /* init_regs, range, table */
|
||||
CLK_MESON_PLL_POWER_OF_TWO | CLK_MESON_PLL_FIXED_EN0P5 |
|
||||
CLK_MESON_PLL_FIXED_FRAC_WEIGHT_PRECISION, /* dflags */
|
||||
CLK_MESON_PLL_FIXED_FRAC_WEIGHT_PRECISION |
|
||||
CLK_MESON_PLL_RSTN, /* dflags */
|
||||
&hifi0_pll_parent, 0, /* pdata, iflags */
|
||||
ANACTRL_HIFI0PLL_CTRL0, 20, 3 /* od */
|
||||
#ifdef CONFIG_ARM
|
||||
);
|
||||
#else
|
||||
, NULL, /* od_table */
|
||||
CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST); /* od_dflags */
|
||||
#endif
|
||||
ANACTRL_HIFI0PLL_CTRL0, 20, 3); /* od */
|
||||
|
||||
static const struct reg_sequence hifi1_init_regs[] = {
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL0, .def = 0x000100ea },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL1, .def = 0x11489c40 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL0, .def = 0x00010000 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL1, .def = 0x11480000 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL2, .def = 0x1219b010 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL3, .def = 0x00008010 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL4, .def = 0x1f01110f },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL1, .def = 0x19489c40, .delay_us = 20 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL0, .def = 0x200100ea, .delay_us = 20 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL3, .def = 0x20008010 }
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL3, .def = 0x20008010 },
|
||||
{ .reg = ANACTRL_HIFI1PLL_CTRL4, .def = 0x1f01110f }
|
||||
};
|
||||
|
||||
static const struct clk_parent_data hifi1_pll_parent = {
|
||||
@@ -816,21 +594,17 @@ static const struct clk_parent_data hifi1_pll_parent = {
|
||||
|
||||
MESON_CLK_PLL_RW(hifi1_pll, ANACTRL_HIFI1PLL_CTRL1, 27, 1, /* en */
|
||||
ANACTRL_HIFI1PLL_CTRL0, 0, 9, /* m */
|
||||
ANACTRL_HIFI1PLL_CTRL1, 0, 19, /* frac */
|
||||
ANACTRL_HIFI1PLL_CTRL1, 0, 17, /* frac */
|
||||
ANACTRL_HIFI1PLL_CTRL0, 12, 3, /* n */
|
||||
ANACTRL_HIFI1PLL_CTRL0, 31, 1, /* lock */
|
||||
ANACTRL_HIFI1PLL_CTRL0, 29, 1, /* rst */
|
||||
ANACTRL_HIFI1PLL_CTRL3, 29, 1, /* l_rst */
|
||||
hifi1_init_regs, NULL, hifi_pll_table, /* init_regs, range, table */
|
||||
CLK_MESON_PLL_POWER_OF_TWO | CLK_MESON_PLL_FIXED_EN0P5 |
|
||||
CLK_MESON_PLL_FIXED_FRAC_WEIGHT_PRECISION, /* dflags */
|
||||
CLK_MESON_PLL_FIXED_FRAC_WEIGHT_PRECISION |
|
||||
CLK_MESON_PLL_RSTN, /* dflags */
|
||||
&hifi1_pll_parent, 0, /* pdata, iflags */
|
||||
ANACTRL_HIFI1PLL_CTRL0, 20, 3 /* od */
|
||||
#ifdef CONFIG_ARM
|
||||
);
|
||||
#else
|
||||
, NULL, /* od_table */
|
||||
CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST); /* od_dflags */
|
||||
#endif
|
||||
ANACTRL_HIFI1PLL_CTRL0, 20, 3); /* od */
|
||||
|
||||
static const struct clk_parent_data rtc_dual_clkin_parent = {
|
||||
.fw_name = "xtal",
|
||||
@@ -1747,17 +1521,8 @@ static struct clk_hw_onecell_data s7d_hw_onecell_data = {
|
||||
[CLKID_FCLK_CLK50M_DIV] = &fclk_clk50m_div.hw,
|
||||
[CLKID_FCLK_CLK50M] = &fclk_clk50m.hw,
|
||||
|
||||
#ifndef CONFIG_ARM
|
||||
[CLKID_GP0_PLL_DCO] = &gp0_pll_dco.hw,
|
||||
#endif
|
||||
[CLKID_GP0_PLL] = &gp0_pll.hw,
|
||||
#ifndef CONFIG_ARM
|
||||
[CLKID_HIFI_PLL_DCO] = &hifi_pll_dco.hw,
|
||||
#endif
|
||||
[CLKID_HIFI_PLL] = &hifi_pll.hw,
|
||||
#ifndef CONFIG_ARM
|
||||
[CLKID_HIFI1_PLL_DCO] = &hifi1_pll_dco.hw,
|
||||
#endif
|
||||
[CLKID_HIFI1_PLL] = &hifi1_pll.hw,
|
||||
|
||||
[CLKID_RTC_DUAL_CLKIN] = &rtc_dual_clkin.hw,
|
||||
@@ -2317,17 +2082,8 @@ static struct clk_regmap *const s7d_pll_clk_regmaps[] = {
|
||||
&fclk_div7,
|
||||
&fclk_div2p5,
|
||||
&fclk_clk50m,
|
||||
#ifndef CONFIG_ARM
|
||||
&gp0_pll_dco,
|
||||
#endif
|
||||
&gp0_pll,
|
||||
#ifndef CONFIG_ARM
|
||||
&hifi_pll_dco,
|
||||
#endif
|
||||
&hifi_pll,
|
||||
#ifndef CONFIG_ARM
|
||||
&hifi1_pll_dco,
|
||||
#endif
|
||||
&hifi1_pll
|
||||
};
|
||||
|
||||
|
||||
@@ -24,14 +24,11 @@
|
||||
#define CLKID_FCLK_DIV2P5 (CLKID_PLL_BASE + 11)
|
||||
#define CLKID_FCLK_CLK50M_DIV (CLKID_PLL_BASE + 12)
|
||||
#define CLKID_FCLK_CLK50M (CLKID_PLL_BASE + 13)
|
||||
#define CLKID_GP0_PLL_DCO (CLKID_PLL_BASE + 14)
|
||||
#define CLKID_GP0_PLL (CLKID_PLL_BASE + 15)
|
||||
#define CLKID_HIFI_PLL_DCO (CLKID_PLL_BASE + 16)
|
||||
#define CLKID_HIFI_PLL (CLKID_PLL_BASE + 17)
|
||||
#define CLKID_HIFI1_PLL_DCO (CLKID_PLL_BASE + 18)
|
||||
#define CLKID_HIFI1_PLL (CLKID_PLL_BASE + 19)
|
||||
#define CLKID_GP0_PLL (CLKID_PLL_BASE + 14)
|
||||
#define CLKID_HIFI_PLL (CLKID_PLL_BASE + 15)
|
||||
#define CLKID_HIFI1_PLL (CLKID_PLL_BASE + 16)
|
||||
|
||||
#define CLKID_BASIC_BASE (CLKID_PLL_BASE + 20)
|
||||
#define CLKID_BASIC_BASE (CLKID_PLL_BASE + 17)
|
||||
#define CLKID_RTC_DUAL_CLKIN (CLKID_BASIC_BASE + 0)
|
||||
#define CLKID_RTC_DUAL_DIV (CLKID_BASIC_BASE + 1)
|
||||
#define CLKID_RTC_DUAL_SEL (CLKID_BASIC_BASE + 2)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define CLKID_SCMI_DSU_CLK 15
|
||||
#define CLKID_SCMI_FIXED_PLL 16
|
||||
#define CLKID_SCMI_GP1_PLL 17
|
||||
#define CLKID_SCMI_ACLKM 18
|
||||
|
||||
#endif /* __S7D_CLKC_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user