Commit 7d3142e5 authored by Jerome Brunet's avatar Jerome Brunet
Browse files

clk: meson: add od3 to the pll driver



Some meson plls, such as the hdmi pll, are using a 3rd od parameter,
which is yet another "power of 2" post divider. Add it to fix the
calculation of the hdmi_pll rate

Fixes: 738f66d3 ("clk: gxbb: add AmLogic GXBB clk controller driver")
Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
parent 4c5f67b7
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
	struct meson_clk_pll *pll = to_meson_clk_pll(hw);
	struct parm *p;
	u64 rate;
	u16 n, m, frac = 0, od, od2 = 0;
	u16 n, m, frac = 0, od, od2 = 0, od3 = 0;
	u32 reg;

	p = &pll->n;
@@ -74,7 +74,13 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
		od2 = PARM_GET(p->width, p->shift, reg);
	}

	rate = (u64)parent_rate * m;
	p = &pll->od3;
	if (p->width) {
		reg = readl(pll->base + p->reg_off);
		od3 = PARM_GET(p->width, p->shift, reg);
	}

	rate = (u64)m * parent_rate;

	p = &pll->frac;
	if (p->width) {
@@ -85,7 +91,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
		rate *= 2;
	}

	return div_u64(rate, n) >> od >> od2;
	return div_u64(rate, n) >> od >> od2 >> od3;
}

static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -226,6 +232,13 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
		writel(reg, pll->base + p->reg_off);
	}

	p = &pll->od3;
	if (p->width) {
		reg = readl(pll->base + p->reg_off);
		reg = PARM_SET(p->width, p->shift, reg, rate_set->od3);
		writel(reg, pll->base + p->reg_off);
	}

	p = &pll->frac;
	if (p->width) {
		reg = readl(pll->base + p->reg_off);
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct pll_rate_table {
	u16		n;
	u16		od;
	u16		od2;
	u16		od3;
	u16		frac;
};

@@ -92,6 +93,7 @@ struct meson_clk_pll {
	struct parm frac;
	struct parm od;
	struct parm od2;
	struct parm od3;
	const struct pll_setup_params params;
	const struct pll_rate_table *rate_table;
	unsigned int rate_count;
+5 −0
Original line number Diff line number Diff line
@@ -238,6 +238,11 @@ static struct meson_clk_pll gxbb_hdmi_pll = {
		.shift   = 22,
		.width   = 2,
	},
	.od3 = {
		.reg_off = HHI_HDMI_PLL_CNTL2,
		.shift   = 18,
		.width   = 2,
	},
	.lock = &meson_clk_lock,
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_pll",