#define MCU_BUS_MSK GENMASK(10, 9)
#define MCU_BUS_SEL(x) ((x) << 9)
+enum {
+ CLK_PAD_CLK25M,
+};
+
+static const ulong ext_clock_rates[] = {
+ [CLK_PAD_CLK25M] = 25 * MHZ,
+};
+
/* apmixedsys */
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
_pd_shift, _pcw_reg, _pcw_shift) { \
};
static const struct mtk_clk_tree mt7622_apmixed_clk_tree = {
- .xtal2_rate = 25 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK25M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
.gates_offs = CLK_APMIXED_MAIN_CORE_EN,
.gates = apmixed_cgs,
#define AXI_DIV_MSK GENMASK(4, 0)
#define AXI_DIV_SEL(x) (x)
+enum {
+ CLK_PAD_CLK26M,
+};
+
+static const ulong ext_clock_rates[] = {
+ [CLK_PAD_CLK26M] = 26 * MHZ,
+};
+
/* apmixedsys */
static const int pll_id_offs_map[] = {
[0 ... CLK_APMIXED_NR - 1] = -1,
};
static const struct mtk_clk_tree mt7623_apmixedsys_clk_tree = {
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.id_offs_map = pll_id_offs_map,
.id_offs_map_size = ARRAY_SIZE(pll_id_offs_map),
.plls = apmixed_plls,
#define MCU_BUS_MSK GENMASK(10, 9)
#define MCU_BUS_SEL(x) ((x) << 9)
+enum {
+ CLK_PAD_CLK20M,
+};
+
+static const ulong ext_clock_rates[] = {
+ [CLK_PAD_CLK20M] = 20 * MHZ,
+};
+
/* apmixedsys */
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
_pd_shift, _pcw_reg, _pcw_shift) { \
static const struct mtk_clk_tree mt7629_clk_tree = {
.xtal_rate = 40 * MHZ,
- .xtal2_rate = 20 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK20M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_TO_USB3_SYS,
.muxes_offs = CLK_TOP_AXI_SEL,
.plls = apmixed_plls,
static const struct mtk_clk_tree mt7629_peri_clk_tree = {
.xtal_rate = 40 * MHZ,
- .xtal2_rate = 20 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK20M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_TO_USB3_SYS,
.muxes_offs = CLK_TOP_AXI_SEL,
.plls = apmixed_plls,
#define MT8183_PLL_FMAX (3800UL * MHZ)
#define MT8183_PLL_FMIN (1500UL * MHZ)
+enum {
+ CLK_PAD_CLK26M,
+};
+
+static const ulong ext_clock_rates[] = {
+ [CLK_PAD_CLK26M] = 26 * MHZ,
+};
+
/* apmixedsys */
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, _pcwbits, \
_pcwibits, _pd_reg, _pd_shift, _pcw_reg, _pcw_shift) { \
static const struct mtk_clk_tree mt8183_clk_tree = {
.xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_CLK13M,
.muxes_offs = CLK_TOP_MUX_AXI,
.plls = apmixed_plls,
static const struct mtk_clk_tree mt8188_apmixedsys_clk_tree = {
.xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
};
static const struct mtk_clk_tree mt8189_apmixedsys_clk_tree = {
- .xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
};
static const struct mtk_clk_tree mt8189_topckgen_clk_tree = {
- .xtal_rate = 26 * MHZ,
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_MAINPLL_D3,
static const struct mtk_clk_tree mt8195_apmixedsys_clk_tree = {
.xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
static const struct mtk_clk_tree mt8365_apmixed_tree = {
.xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
.ext_clk_rates = ext_clock_rates,
.num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.plls = apmixed_plls,
#define MT8512_PLL_FMIN (1500UL * MHZ)
#define MT8512_CON0_RST_BAR BIT(23)
+enum {
+ CLK_PAD_CLK26M,
+};
+
+static const ulong ext_clock_rates[] = {
+ [CLK_PAD_CLK26M] = 26 * MHZ,
+};
+
/* apmixedsys */
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
_pd_shift, _pcw_reg, _pcw_shift, _pcw_chg_reg) { \
static const struct mtk_clk_tree mt8512_clk_tree = {
.xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_SYSPLL1_D2,
.muxes_offs = CLK_TOP_AXI_SEL,
.plls = apmixed_plls,
#define MT8516_PLL_FMAX (1502UL * MHZ)
#define MT8516_CON0_RST_BAR BIT(27)
+enum {
+ CLK_PAD_CLK26M,
+};
+
+static const ulong ext_clock_rates[] = {
+ [CLK_PAD_CLK26M] = 26 * MHZ,
+};
+
/* apmixedsys */
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
_pd_shift, _pcw_reg, _pcw_shift) { \
static const struct mtk_clk_tree mt8516_clk_tree = {
.xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_DMPLL,
.muxes_offs = CLK_TOP_UART0_SEL,
.plls = apmixed_plls,
#define MT8518_PLL_FMAX (3000UL * MHZ)
#define MT8518_CON0_RST_BAR BIT(27)
+enum {
+ CLK_PAD_CLK26M,
+};
+
+static const ulong ext_clock_rates[] = {
+ [CLK_PAD_CLK26M] = 26 * MHZ,
+};
+
/* apmixedsys */
#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
_pd_shift, _pcw_reg, _pcw_shift) { \
static const struct mtk_clk_tree mt8518_clk_tree = {
.xtal_rate = 26 * MHZ,
- .xtal2_rate = 26 * MHZ,
+ .pll_parent = EXT_PARENT(CLK_PAD_CLK26M),
+ .ext_clk_rates = ext_clock_rates,
+ .num_ext_clks = ARRAY_SIZE(ext_clock_rates),
.fdivs_offs = CLK_TOP_DMPLL,
.muxes_offs = CLK_TOP_UART0_SEL,
.plls = apmixed_plls,
* @postdiv: The post divider (output)
* @freq: The desired target frequency
*/
-static void mtk_pll_calc_values(struct mtk_clk_priv *priv, u32 id,
- u32 *pcw, u32 *postdiv, u32 freq)
+static int mtk_pll_calc_values(struct mtk_clk_priv *priv, struct clk *clk,
+ u32 *pcw, u32 *postdiv, u32 freq)
{
const struct mtk_pll_data *pll;
- unsigned long fmin;
+ const struct mtk_parent *parent = &priv->tree->pll_parent;
+ unsigned long xtal_rate, fmin;
u64 _pcw;
int ibits;
u32 val;
- pll = &priv->tree->plls[id];
+ xtal_rate = mtk_find_parent_rate(priv, clk, parent->id, parent->flags);
+ if (IS_ERR_VALUE(xtal_rate))
+ return xtal_rate;
+
+ pll = &priv->tree->plls[clk->id];
fmin = pll->fmin ? pll->fmin : 1000 * MHZ;
if (freq > pll->fmax)
/* _pcw = freq * postdiv / xtal_rate * 2^pcwfbits */
ibits = pll->pcwibits ? pll->pcwibits : INTEGER_BITS;
_pcw = ((u64)freq << val) << (pll->pcwbits - ibits);
- do_div(_pcw, priv->tree->xtal2_rate);
+ do_div(_pcw, xtal_rate);
*pcw = (u32)_pcw;
+
+ return 0;
}
static ulong mtk_apmixedsys_set_rate(struct clk *clk, ulong rate)
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
u32 pcw = 0;
u32 postdiv;
+ int ret;
if (!mtk_clk_id_is_pll(priv->tree, clk->id))
return -EINVAL;
- mtk_pll_calc_values(priv, clk->id, &pcw, &postdiv, rate);
+ ret = mtk_pll_calc_values(priv, clk, &pcw, &postdiv, rate);
+ if (ret)
+ return ret;
+
mtk_pll_set_rate_regs(priv, clk->id, pcw, postdiv);
return 0;
static ulong mtk_apmixedsys_get_rate(struct clk *clk)
{
struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_parent *parent;
const struct mtk_pll_data *pll;
const struct mtk_gate *gate;
+ unsigned long xtal_rate;
u32 postdiv;
u32 pcw;
return mtk_find_parent_rate(priv, clk, gate->parent, gate->flags);
}
+ parent = &priv->tree->pll_parent;
+ xtal_rate = mtk_find_parent_rate(priv, clk, parent->id, parent->flags);
+ if (IS_ERR_VALUE(xtal_rate))
+ return xtal_rate;
+
pll = &priv->tree->plls[clk->id];
postdiv = (readl(priv->base + pll->pd_reg) >> pll->pd_shift) &
pcw = readl(priv->base + pll->pcw_reg) >> pll->pcw_shift;
pcw &= GENMASK(pll->pcwbits - 1, 0);
- return __mtk_pll_recalc_rate(pll, priv->tree->xtal2_rate,
- pcw, postdiv);
+ return __mtk_pll_recalc_rate(pll, xtal_rate, pcw, postdiv);
}
static int mtk_apmixedsys_enable(struct clk *clk)
/* struct mtk_clk_tree - clock tree */
struct mtk_clk_tree {
unsigned long xtal_rate;
- unsigned long xtal2_rate;
+ const struct mtk_parent pll_parent;
/* External fixed clocks - excluded from mapping. */
const ulong *ext_clk_rates;
const int num_ext_clks;