Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c763e61a authored by Jerome Brunet's avatar Jerome Brunet Committed by Neil Armstrong
Browse files

clk: meson: migrate mplls clocks to clk_regmap



Rework meson mpll driver to use clk_regmap and move meson8b, gxbb
and axg clocks using meson_clk_mpll to clk_regmap

Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
Signed-off-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
parent f510c32a
Loading
Loading
Loading
Loading
+121 −124
Original line number Diff line number Diff line
@@ -267,7 +267,8 @@ static struct clk_fixed_factor axg_fclk_div7 = {
	},
};

static struct meson_clk_mpll axg_mpll0 = {
static struct clk_regmap axg_mpll0 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL7,
			.shift   = 0,
@@ -299,6 +300,7 @@ static struct meson_clk_mpll axg_mpll0 = {
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll0",
		.ops = &meson_clk_mpll_ops,
@@ -307,7 +309,8 @@ static struct meson_clk_mpll axg_mpll0 = {
	},
};

static struct meson_clk_mpll axg_mpll1 = {
static struct clk_regmap axg_mpll1 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL8,
			.shift   = 0,
@@ -334,6 +337,7 @@ static struct meson_clk_mpll axg_mpll1 = {
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll1",
		.ops = &meson_clk_mpll_ops,
@@ -342,7 +346,8 @@ static struct meson_clk_mpll axg_mpll1 = {
	},
};

static struct meson_clk_mpll axg_mpll2 = {
static struct clk_regmap axg_mpll2 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL9,
			.shift   = 0,
@@ -369,6 +374,7 @@ static struct meson_clk_mpll axg_mpll2 = {
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll2",
		.ops = &meson_clk_mpll_ops,
@@ -377,7 +383,8 @@ static struct meson_clk_mpll axg_mpll2 = {
	},
};

static struct meson_clk_mpll axg_mpll3 = {
static struct clk_regmap axg_mpll3 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL3_CNTL0,
			.shift   = 12,
@@ -404,6 +411,7 @@ static struct meson_clk_mpll axg_mpll3 = {
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll3",
		.ops = &meson_clk_mpll_ops,
@@ -698,13 +706,6 @@ static struct meson_clk_pll *const axg_clk_plls[] = {
	&axg_gp0_pll,
};

static struct meson_clk_mpll *const axg_clk_mplls[] = {
	&axg_mpll0,
	&axg_mpll1,
	&axg_mpll2,
	&axg_mpll3,
};

static struct clk_regmap *const axg_clk_regmaps[] = {
	&axg_clk81,
	&axg_ddr,
@@ -759,19 +760,19 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
	&axg_mpeg_clk_sel,
	&axg_sd_emmc_b_clk0_sel,
	&axg_sd_emmc_c_clk0_sel,
	&axg_mpll0,
	&axg_mpll1,
	&axg_mpll2,
	&axg_mpll3,
};

struct clkc_data {
	struct meson_clk_mpll *const *clk_mplls;
	unsigned int clk_mplls_count;
	struct meson_clk_pll *const *clk_plls;
	unsigned int clk_plls_count;
	struct clk_hw_onecell_data *hw_onecell_data;
};

static const struct clkc_data axg_clkc_data = {
	.clk_mplls = axg_clk_mplls,
	.clk_mplls_count = ARRAY_SIZE(axg_clk_mplls),
	.clk_plls = axg_clk_plls,
	.clk_plls_count = ARRAY_SIZE(axg_clk_plls),
	.hw_onecell_data = &axg_hw_onecell_data,
@@ -820,10 +821,6 @@ static int axg_clkc_probe(struct platform_device *pdev)
	for (i = 0; i < clkc_data->clk_plls_count; i++)
		clkc_data->clk_plls[i]->base = clk_base;

	/* Populate base address for MPLLs */
	for (i = 0; i < clkc_data->clk_mplls_count; i++)
		clkc_data->clk_mplls[i]->base = clk_base;

	/* Populate regmap for the regmap backed clocks */
	for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++)
		axg_clk_regmaps[i]->map = map;
+37 −65
Original line number Diff line number Diff line
@@ -68,11 +68,15 @@
#define N2_MIN	4
#define N2_MAX	511

#define to_meson_clk_mpll(_hw) container_of(_hw, struct meson_clk_mpll, hw)
static inline struct meson_clk_mpll_data *
meson_clk_mpll_data(struct clk_regmap *clk)
{
	return (struct meson_clk_mpll_data *)clk->data;
}

static long rate_from_params(unsigned long parent_rate,
				      unsigned long sdm,
				      unsigned long n2)
			     unsigned int sdm,
			     unsigned int n2)
{
	unsigned long divisor = (SDM_DEN * n2) + sdm;

@@ -84,8 +88,8 @@ static long rate_from_params(unsigned long parent_rate,

static void params_from_rate(unsigned long requested_rate,
			     unsigned long parent_rate,
			     unsigned long *sdm,
			     unsigned long *n2)
			     unsigned int *sdm,
			     unsigned int *n2)
{
	uint64_t div = parent_rate;
	unsigned long rem = do_div(div, requested_rate);
@@ -105,31 +109,23 @@ static void params_from_rate(unsigned long requested_rate,
static unsigned long mpll_recalc_rate(struct clk_hw *hw,
		unsigned long parent_rate)
{
	struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
	struct parm *p;
	unsigned long reg, sdm, n2;
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
	unsigned int sdm, n2;
	long rate;

	p = &mpll->sdm;
	reg = readl(mpll->base + p->reg_off);
	sdm = PARM_GET(p->width, p->shift, reg);

	p = &mpll->n2;
	reg = readl(mpll->base + p->reg_off);
	n2 = PARM_GET(p->width, p->shift, reg);
	sdm = meson_parm_read(clk->map, &mpll->sdm);
	n2 = meson_parm_read(clk->map, &mpll->n2);

	rate = rate_from_params(parent_rate, sdm, n2);
	if (rate < 0)
		return 0;

	return rate;
	return rate < 0 ? 0 : rate;
}

static long mpll_round_rate(struct clk_hw *hw,
			    unsigned long rate,
			    unsigned long *parent_rate)
{
	unsigned long sdm, n2;
	unsigned int sdm, n2;

	params_from_rate(rate, *parent_rate, &sdm, &n2);
	return rate_from_params(*parent_rate, sdm, n2);
@@ -139,9 +135,9 @@ static int mpll_set_rate(struct clk_hw *hw,
			 unsigned long rate,
			 unsigned long parent_rate)
{
	struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
	struct parm *p;
	unsigned long reg, sdm, n2;
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
	unsigned int sdm, n2;
	unsigned long flags = 0;

	params_from_rate(rate, parent_rate, &sdm, &n2);
@@ -151,34 +147,20 @@ static int mpll_set_rate(struct clk_hw *hw,
	else
		__acquire(mpll->lock);

	p = &mpll->sdm;
	reg = readl(mpll->base + p->reg_off);
	reg = PARM_SET(p->width, p->shift, reg, sdm);
	writel(reg, mpll->base + p->reg_off);

	p = &mpll->sdm_en;
	reg = readl(mpll->base + p->reg_off);
	reg = PARM_SET(p->width, p->shift, reg, 1);
	writel(reg, mpll->base + p->reg_off);

	p = &mpll->ssen;
	if (p->width != 0) {
		reg = readl(mpll->base + p->reg_off);
		reg = PARM_SET(p->width, p->shift, reg, 1);
		writel(reg, mpll->base + p->reg_off);
	}
	/* Enable and set the fractional part */
	meson_parm_write(clk->map, &mpll->sdm, sdm);
	meson_parm_write(clk->map, &mpll->sdm_en, 1);

	p = &mpll->n2;
	reg = readl(mpll->base + p->reg_off);
	reg = PARM_SET(p->width, p->shift, reg, n2);
	writel(reg, mpll->base + p->reg_off);
	/* Set additional fractional part enable if required */
	if (MESON_PARM_APPLICABLE(&mpll->ssen))
		meson_parm_write(clk->map, &mpll->ssen, 1);

	p = &mpll->misc;
	if (p->width != 0) {
		reg = readl(mpll->base + p->reg_off);
		reg = PARM_SET(p->width, p->shift, reg, 1);
		writel(reg, mpll->base + p->reg_off);
	}
	/* Set the integer divider part */
	meson_parm_write(clk->map, &mpll->n2, n2);

	/* Set the magic misc bit if required */
	if (MESON_PARM_APPLICABLE(&mpll->misc))
		meson_parm_write(clk->map, &mpll->misc, 1);

	if (mpll->lock)
		spin_unlock_irqrestore(mpll->lock, flags);
@@ -190,9 +172,8 @@ static int mpll_set_rate(struct clk_hw *hw,

static void mpll_enable_core(struct clk_hw *hw, int enable)
{
	struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
	struct parm *p;
	unsigned long reg;
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
	unsigned long flags = 0;

	if (mpll->lock)
@@ -200,10 +181,7 @@ static void mpll_enable_core(struct clk_hw *hw, int enable)
	else
		__acquire(mpll->lock);

	p = &mpll->en;
	reg = readl(mpll->base + p->reg_off);
	reg = PARM_SET(p->width, p->shift, reg, enable ? 1 : 0);
	writel(reg, mpll->base + p->reg_off);
	meson_parm_write(clk->map, &mpll->en, enable ? 1 : 0);

	if (mpll->lock)
		spin_unlock_irqrestore(mpll->lock, flags);
@@ -226,16 +204,10 @@ static void mpll_disable(struct clk_hw *hw)

static int mpll_is_enabled(struct clk_hw *hw)
{
	struct meson_clk_mpll *mpll = to_meson_clk_mpll(hw);
	struct parm *p;
	unsigned long reg;
	int en;

	p = &mpll->en;
	reg = readl(mpll->base + p->reg_off);
	en = PARM_GET(p->width, p->shift, reg);
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);

	return en;
	return meson_parm_read(clk->map, &mpll->en);
}

const struct clk_ops meson_clk_mpll_ro_ops = {
+1 −3
Original line number Diff line number Diff line
@@ -132,9 +132,7 @@ struct meson_clk_cpu {
int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
		void *data);

struct meson_clk_mpll {
	struct clk_hw hw;
	void __iomem *base;
struct meson_clk_mpll_data {
	struct parm sdm;
	struct parm sdm_en;
	struct parm n2;
+77 −84
Original line number Diff line number Diff line
@@ -482,7 +482,8 @@ static struct clk_fixed_factor gxbb_fclk_div7 = {
	},
};

static struct meson_clk_mpll gxbb_mpll0 = {
static struct clk_regmap gxbb_mpll0 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL7,
			.shift   = 0,
@@ -509,6 +510,7 @@ static struct meson_clk_mpll gxbb_mpll0 = {
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll0",
		.ops = &meson_clk_mpll_ops,
@@ -517,7 +519,8 @@ static struct meson_clk_mpll gxbb_mpll0 = {
	},
};

static struct meson_clk_mpll gxbb_mpll1 = {
static struct clk_regmap gxbb_mpll1 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL8,
			.shift   = 0,
@@ -539,6 +542,7 @@ static struct meson_clk_mpll gxbb_mpll1 = {
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll1",
		.ops = &meson_clk_mpll_ops,
@@ -547,7 +551,8 @@ static struct meson_clk_mpll gxbb_mpll1 = {
	},
};

static struct meson_clk_mpll gxbb_mpll2 = {
static struct clk_regmap gxbb_mpll2 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL9,
			.shift   = 0,
@@ -569,6 +574,7 @@ static struct meson_clk_mpll gxbb_mpll2 = {
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll2",
		.ops = &meson_clk_mpll_ops,
@@ -1771,12 +1777,6 @@ static struct meson_clk_pll *const gxl_clk_plls[] = {
	&gxl_gp0_pll,
};

static struct meson_clk_mpll *const gxbb_clk_mplls[] = {
	&gxbb_mpll0,
	&gxbb_mpll1,
	&gxbb_mpll2,
};

static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
	&gxbb_cts_amclk_div,
};
@@ -1909,11 +1909,12 @@ static struct clk_regmap *const gx_clk_regmaps[] = {
	&gxbb_vapb_0_sel,
	&gxbb_vapb_1_sel,
	&gxbb_vapb_sel,
	&gxbb_mpll0,
	&gxbb_mpll1,
	&gxbb_mpll2,
};

struct clkc_data {
	struct meson_clk_mpll *const *clk_mplls;
	unsigned int clk_mplls_count;
	struct meson_clk_pll *const *clk_plls;
	unsigned int clk_plls_count;
	struct meson_clk_audio_divider *const *clk_audio_dividers;
@@ -1922,8 +1923,6 @@ struct clkc_data {
};

static const struct clkc_data gxbb_clkc_data = {
	.clk_mplls = gxbb_clk_mplls,
	.clk_mplls_count = ARRAY_SIZE(gxbb_clk_mplls),
	.clk_plls = gxbb_clk_plls,
	.clk_plls_count = ARRAY_SIZE(gxbb_clk_plls),
	.clk_audio_dividers = gxbb_audio_dividers,
@@ -1932,8 +1931,6 @@ static const struct clkc_data gxbb_clkc_data = {
};

static const struct clkc_data gxl_clkc_data = {
	.clk_mplls = gxbb_clk_mplls,
	.clk_mplls_count = ARRAY_SIZE(gxbb_clk_mplls),
	.clk_plls = gxl_clk_plls,
	.clk_plls_count = ARRAY_SIZE(gxl_clk_plls),
	.clk_audio_dividers = gxbb_audio_dividers,
@@ -1984,10 +1981,6 @@ static int gxbb_clkc_probe(struct platform_device *pdev)
	for (i = 0; i < clkc_data->clk_plls_count; i++)
		clkc_data->clk_plls[i]->base = clk_base;

	/* Populate base address for MPLLs */
	for (i = 0; i < clkc_data->clk_mplls_count; i++)
		clkc_data->clk_mplls[i]->base = clk_base;

	/* Populate base address for the audio dividers */
	for (i = 0; i < clkc_data->clk_audio_dividers_count; i++)
		clkc_data->clk_audio_dividers[i]->base = clk_base;
+77 −78
Original line number Diff line number Diff line
@@ -257,7 +257,8 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
	},
};

static struct meson_clk_mpll meson8b_mpll0 = {
static struct clk_regmap meson8b_mpll0 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL7,
			.shift   = 0,
@@ -284,6 +285,7 @@ static struct meson_clk_mpll meson8b_mpll0 = {
			.width   = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll0",
		.ops = &meson_clk_mpll_ops,
@@ -292,7 +294,8 @@ static struct meson_clk_mpll meson8b_mpll0 = {
	},
};

static struct meson_clk_mpll meson8b_mpll1 = {
static struct clk_regmap meson8b_mpll1 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL8,
			.shift   = 0,
@@ -314,6 +317,7 @@ static struct meson_clk_mpll meson8b_mpll1 = {
			.width   = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll1",
		.ops = &meson_clk_mpll_ops,
@@ -322,7 +326,8 @@ static struct meson_clk_mpll meson8b_mpll1 = {
	},
};

static struct meson_clk_mpll meson8b_mpll2 = {
static struct clk_regmap meson8b_mpll2 = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL9,
			.shift   = 0,
@@ -344,6 +349,7 @@ static struct meson_clk_mpll meson8b_mpll2 = {
			.width   = 1,
		},
		.lock = &meson_clk_lock,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll2",
		.ops = &meson_clk_mpll_ops,
@@ -613,12 +619,6 @@ static struct meson_clk_pll *const meson8b_clk_plls[] = {
	&meson8b_sys_pll,
};

static struct meson_clk_mpll *const meson8b_clk_mplls[] = {
	&meson8b_mpll0,
	&meson8b_mpll1,
	&meson8b_mpll2,
};

static struct clk_regmap *const meson8b_clk_regmaps[] = {
	&meson8b_clk81,
	&meson8b_ddr,
@@ -700,6 +700,9 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
	&meson8b_ao_iface,
	&meson8b_mpeg_clk_div,
	&meson8b_mpeg_clk_sel,
	&meson8b_mpll0,
	&meson8b_mpll1,
	&meson8b_mpll2,
};

static const struct meson8b_clk_reset_line {
@@ -826,10 +829,6 @@ static int meson8b_clkc_probe(struct platform_device *pdev)
	for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
		meson8b_clk_plls[i]->base = clk_base;

	/* Populate base address for MPLLs */
	for (i = 0; i < ARRAY_SIZE(meson8b_clk_mplls); i++)
		meson8b_clk_mplls[i]->base = clk_base;

	/* Populate the base address for CPU clk */
	meson8b_cpu_clk.base = clk_base;