mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 21:51:40 +00:00
Merge branch 'clk-fixes' into clk-next
This commit is contained in:
commit
5cf065f556
@ -211,8 +211,9 @@ static void __init imx6q_1588_init(void)
|
||||
* set bit IOMUXC_GPR1[21]. Or the PTP clock must be from pad
|
||||
* (external OSC), and we need to clear the bit.
|
||||
*/
|
||||
clksel = ptp_clk == enet_ref ? IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
|
||||
IMX6Q_GPR1_ENET_CLK_SEL_PAD;
|
||||
clksel = clk_is_match(ptp_clk, enet_ref) ?
|
||||
IMX6Q_GPR1_ENET_CLK_SEL_ANATOP :
|
||||
IMX6Q_GPR1_ENET_CLK_SEL_PAD;
|
||||
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
|
||||
if (!IS_ERR(gpr))
|
||||
regmap_update_bits(gpr, IOMUXC_GPR1,
|
||||
|
@ -144,12 +144,6 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
|
||||
divider->flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* The reverse of DIV_ROUND_UP: The maximum number which
|
||||
* divided by m is r
|
||||
*/
|
||||
#define MULT_ROUND_UP(r, m) ((r) * (m) + (m) - 1)
|
||||
|
||||
static bool _is_valid_table_div(const struct clk_div_table *table,
|
||||
unsigned int div)
|
||||
{
|
||||
@ -225,19 +219,24 @@ static int _div_round_closest(const struct clk_div_table *table,
|
||||
unsigned long parent_rate, unsigned long rate,
|
||||
unsigned long flags)
|
||||
{
|
||||
int up, down, div;
|
||||
int up, down;
|
||||
unsigned long up_rate, down_rate;
|
||||
|
||||
up = down = div = DIV_ROUND_CLOSEST(parent_rate, rate);
|
||||
up = DIV_ROUND_UP(parent_rate, rate);
|
||||
down = parent_rate / rate;
|
||||
|
||||
if (flags & CLK_DIVIDER_POWER_OF_TWO) {
|
||||
up = __roundup_pow_of_two(div);
|
||||
down = __rounddown_pow_of_two(div);
|
||||
up = __roundup_pow_of_two(up);
|
||||
down = __rounddown_pow_of_two(down);
|
||||
} else if (table) {
|
||||
up = _round_up_table(table, div);
|
||||
down = _round_down_table(table, div);
|
||||
up = _round_up_table(table, up);
|
||||
down = _round_down_table(table, down);
|
||||
}
|
||||
|
||||
return (up - div) <= (div - down) ? up : down;
|
||||
up_rate = DIV_ROUND_UP(parent_rate, up);
|
||||
down_rate = DIV_ROUND_UP(parent_rate, down);
|
||||
|
||||
return (rate - up_rate) <= (down_rate - rate) ? up : down;
|
||||
}
|
||||
|
||||
static int _div_round(const struct clk_div_table *table,
|
||||
@ -313,7 +312,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
|
||||
return i;
|
||||
}
|
||||
parent_rate = __clk_round_rate(__clk_get_parent(hw->clk),
|
||||
MULT_ROUND_UP(rate, i));
|
||||
rate * i);
|
||||
now = DIV_ROUND_UP(parent_rate, i);
|
||||
if (_is_best_div(rate, now, best, flags)) {
|
||||
bestdiv = i;
|
||||
@ -353,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
bestdiv = readl(divider->reg) >> divider->shift;
|
||||
bestdiv &= div_mask(divider->width);
|
||||
bestdiv = _get_div(divider->table, bestdiv, divider->flags);
|
||||
return bestdiv;
|
||||
return DIV_ROUND_UP(*prate, bestdiv);
|
||||
}
|
||||
|
||||
return divider_round_rate(hw, rate, prate, divider->table,
|
||||
|
@ -1382,7 +1382,6 @@ static unsigned long clk_core_get_rate(struct clk_core *clk)
|
||||
|
||||
return rate;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_core_get_rate);
|
||||
|
||||
/**
|
||||
* clk_get_rate - return the rate of clk
|
||||
@ -2216,6 +2215,32 @@ int clk_get_phase(struct clk *clk)
|
||||
return clk_core_get_phase(clk->core);
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_is_match - check if two clk's point to the same hardware clock
|
||||
* @p: clk compared against q
|
||||
* @q: clk compared against p
|
||||
*
|
||||
* Returns true if the two struct clk pointers both point to the same hardware
|
||||
* clock node. Put differently, returns true if struct clk *p and struct clk *q
|
||||
* share the same struct clk_core object.
|
||||
*
|
||||
* Returns false otherwise. Note that two NULL clks are treated as matching.
|
||||
*/
|
||||
bool clk_is_match(const struct clk *p, const struct clk *q)
|
||||
{
|
||||
/* trivial case: identical struct clk's or both NULL */
|
||||
if (p == q)
|
||||
return true;
|
||||
|
||||
/* true if clk->core pointers match. Avoid derefing garbage */
|
||||
if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
|
||||
if (p->core == q->core)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_is_match);
|
||||
|
||||
/**
|
||||
* __clk_init - initialize the data structures in a struct clk
|
||||
* @dev: device initializing this clk, placeholder for now
|
||||
|
@ -48,6 +48,17 @@ static struct clk_pll pll3 = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap pll4_vote = {
|
||||
.enable_reg = 0x34c0,
|
||||
.enable_mask = BIT(4),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pll4_vote",
|
||||
.parent_names = (const char *[]){ "pll4" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_pll_vote_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_pll pll8 = {
|
||||
.l_reg = 0x3144,
|
||||
.m_reg = 0x3148,
|
||||
@ -3023,6 +3034,7 @@ static struct clk_branch rpm_msg_ram_h_clk = {
|
||||
|
||||
static struct clk_regmap *gcc_msm8960_clks[] = {
|
||||
[PLL3] = &pll3.clkr,
|
||||
[PLL4_VOTE] = &pll4_vote,
|
||||
[PLL8] = &pll8.clkr,
|
||||
[PLL8_VOTE] = &pll8_vote,
|
||||
[PLL14] = &pll14.clkr,
|
||||
@ -3247,6 +3259,7 @@ static const struct qcom_reset_map gcc_msm8960_resets[] = {
|
||||
|
||||
static struct clk_regmap *gcc_apq8064_clks[] = {
|
||||
[PLL3] = &pll3.clkr,
|
||||
[PLL4_VOTE] = &pll4_vote,
|
||||
[PLL8] = &pll8.clkr,
|
||||
[PLL8_VOTE] = &pll8_vote,
|
||||
[PLL14] = &pll14.clkr,
|
||||
|
@ -461,7 +461,6 @@ static struct platform_driver lcc_ipq806x_driver = {
|
||||
.remove = lcc_ipq806x_remove,
|
||||
.driver = {
|
||||
.name = "lcc-ipq806x",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = lcc_ipq806x_match_table,
|
||||
},
|
||||
};
|
||||
|
@ -417,8 +417,8 @@ static struct clk_rcg slimbus_src = {
|
||||
.mnctr_en_bit = 8,
|
||||
.mnctr_reset_bit = 7,
|
||||
.mnctr_mode_shift = 5,
|
||||
.n_val_shift = 16,
|
||||
.m_val_shift = 16,
|
||||
.n_val_shift = 24,
|
||||
.m_val_shift = 8,
|
||||
.width = 8,
|
||||
},
|
||||
.p = {
|
||||
@ -547,7 +547,7 @@ static int lcc_msm8960_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
/* Use the correct frequency plan depending on speed of PLL4 */
|
||||
val = regmap_read(regmap, 0x4, &val);
|
||||
regmap_read(regmap, 0x4, &val);
|
||||
if (val == 0x12) {
|
||||
slimbus_src.freq_tbl = clk_tbl_aif_osr_492;
|
||||
mi2s_osr_src.freq_tbl = clk_tbl_aif_osr_492;
|
||||
@ -574,7 +574,6 @@ static struct platform_driver lcc_msm8960_driver = {
|
||||
.remove = lcc_msm8960_remove,
|
||||
.driver = {
|
||||
.name = "lcc-msm8960",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = lcc_msm8960_match_table,
|
||||
},
|
||||
};
|
||||
|
@ -84,7 +84,7 @@ static int ti_fapll_enable(struct clk_hw *hw)
|
||||
struct fapll_data *fd = to_fapll(hw);
|
||||
u32 v = readl_relaxed(fd->base);
|
||||
|
||||
v |= (1 << FAPLL_MAIN_PLLEN);
|
||||
v |= FAPLL_MAIN_PLLEN;
|
||||
writel_relaxed(v, fd->base);
|
||||
|
||||
return 0;
|
||||
@ -95,7 +95,7 @@ static void ti_fapll_disable(struct clk_hw *hw)
|
||||
struct fapll_data *fd = to_fapll(hw);
|
||||
u32 v = readl_relaxed(fd->base);
|
||||
|
||||
v &= ~(1 << FAPLL_MAIN_PLLEN);
|
||||
v &= ~FAPLL_MAIN_PLLEN;
|
||||
writel_relaxed(v, fd->base);
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ static int ti_fapll_is_enabled(struct clk_hw *hw)
|
||||
struct fapll_data *fd = to_fapll(hw);
|
||||
u32 v = readl_relaxed(fd->base);
|
||||
|
||||
return v & (1 << FAPLL_MAIN_PLLEN);
|
||||
return v & FAPLL_MAIN_PLLEN;
|
||||
}
|
||||
|
||||
static unsigned long ti_fapll_recalc_rate(struct clk_hw *hw,
|
||||
|
@ -125,6 +125,19 @@ int clk_set_phase(struct clk *clk, int degrees);
|
||||
*/
|
||||
int clk_get_phase(struct clk *clk);
|
||||
|
||||
/**
|
||||
* clk_is_match - check if two clk's point to the same hardware clock
|
||||
* @p: clk compared against q
|
||||
* @q: clk compared against p
|
||||
*
|
||||
* Returns true if the two struct clk pointers both point to the same hardware
|
||||
* clock node. Put differently, returns true if struct clk *p and struct clk *q
|
||||
* share the same struct clk_core object.
|
||||
*
|
||||
* Returns false otherwise. Note that two NULL clks are treated as matching.
|
||||
*/
|
||||
bool clk_is_match(const struct clk *p, const struct clk *q);
|
||||
|
||||
#else
|
||||
|
||||
static inline long clk_get_accuracy(struct clk *clk)
|
||||
@ -142,6 +155,11 @@ static inline long clk_get_phase(struct clk *clk)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline bool clk_is_match(const struct clk *p, const struct clk *q)
|
||||
{
|
||||
return p == q;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -1049,7 +1049,7 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv,
|
||||
enum spdif_txrate index, bool round)
|
||||
{
|
||||
const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
|
||||
bool is_sysclk = clk == spdif_priv->sysclk;
|
||||
bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk);
|
||||
u64 rate_ideal, rate_actual, sub;
|
||||
u32 sysclk_dfmin, sysclk_dfmax;
|
||||
u32 txclk_df, sysclk_df, arate;
|
||||
@ -1143,7 +1143,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
|
||||
spdif_priv->txclk_src[index], rate[index]);
|
||||
dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n",
|
||||
spdif_priv->txclk_df[index], rate[index]);
|
||||
if (spdif_priv->txclk[index] == spdif_priv->sysclk)
|
||||
if (clk_is_match(spdif_priv->txclk[index], spdif_priv->sysclk))
|
||||
dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n",
|
||||
spdif_priv->sysclk_df[index], rate[index]);
|
||||
dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n",
|
||||
|
@ -579,7 +579,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
|
||||
if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
} else {
|
||||
if (priv->extclk == priv->clk) {
|
||||
if (clk_is_match(priv->extclk, priv->clk)) {
|
||||
devm_clk_put(&pdev->dev, priv->extclk);
|
||||
priv->extclk = ERR_PTR(-EINVAL);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user