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

Commit 1b443516 authored by Shefali Jain's avatar Shefali Jain
Browse files

clk: qcom: clk-pll: Add support for HF PLLs clock ops



The current PLL set rate does not support determining
the L val at runtime. Add the new HF pll clock ops to
calculate L val for the requested frequency and also
update the determine rate for this requirement.

Change-Id: I104754e6d6aa1d824863431a63ce1c0bbf3f9fe8
Signed-off-by: default avatarShefali Jain <shefjain@codeaurora.org>
parent ac121119
Loading
Loading
Loading
Loading
+41 −3
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -28,6 +28,7 @@
#define PLL_OUTCTRL		BIT(0)
#define PLL_BYPASSNL		BIT(1)
#define PLL_RESET_N		BIT(2)
#define XO_RATE			19200000

static int clk_pll_enable(struct clk_hw *hw)
{
@@ -138,9 +139,11 @@ clk_pll_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)

	f = find_freq(pll->freq_tbl, req->rate);
	if (!f)
		req->rate = clk_pll_recalc_rate(hw, req->best_parent_rate);
		req->rate = DIV_ROUND_UP_ULL(req->rate, req->best_parent_rate)
							* req->best_parent_rate;

	else
		req->rate = f->freq;
		req->rate = req->rate = f->freq;

	return 0;
}
@@ -342,3 +345,38 @@ const struct clk_ops clk_pll_sr2_ops = {
	.determine_rate = clk_pll_determine_rate,
};
EXPORT_SYMBOL_GPL(clk_pll_sr2_ops);

static int
clk_pll_hf_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
{
	struct clk_pll *pll = to_clk_pll(hw);
	bool enabled;
	u32 mode, l_val;
	u32 enable_mask = PLL_OUTCTRL | PLL_BYPASSNL | PLL_RESET_N;

	l_val = rate / XO_RATE;

	regmap_read(pll->clkr.regmap, pll->mode_reg, &mode);
	enabled = (mode & enable_mask) == enable_mask;

	if (enabled)
		clk_pll_disable(hw);

	regmap_update_bits(pll->clkr.regmap, pll->l_reg, 0x3ff, l_val);
	regmap_update_bits(pll->clkr.regmap, pll->m_reg, 0x7ffff, 0);
	regmap_update_bits(pll->clkr.regmap, pll->n_reg, 0x7ffff, 1);

	if (enabled)
		clk_pll_sr2_enable(hw);

	return 0;
}

const struct clk_ops clk_pll_hf_ops = {
	.enable = clk_pll_sr2_enable,
	.disable = clk_pll_disable,
	.set_rate = clk_pll_hf_set_rate,
	.recalc_rate = clk_pll_recalc_rate,
	.determine_rate = clk_pll_determine_rate,
};
EXPORT_SYMBOL(clk_pll_hf_ops);
+2 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
@@ -63,6 +63,7 @@ struct clk_pll {
extern const struct clk_ops clk_pll_ops;
extern const struct clk_ops clk_pll_vote_ops;
extern const struct clk_ops clk_pll_sr2_ops;
extern const struct clk_ops clk_pll_hf_ops;

#define to_clk_pll(_hw) container_of(to_clk_regmap(_hw), struct clk_pll, clkr)