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

Commit d57e0ccd authored by Taniya Das's avatar Taniya Das
Browse files

clk: qcom: Update parent map to use parent_map struct



Add support to use parent_map structure for mux clk parent.

There could be instances where the RCG configuration update or readback
could fail. Notify the caller of the failure. Add support to change
scope of mux_div_get_src_div() in order to use it globally.

Change-Id: Ica07c28cede695785db81697effcb40ab6b717d4
Signed-off-by: default avatarTaniya Das <tdas@codeaurora.org>
parent d64fa8eb
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -17,7 +17,15 @@
#include "clk-regmap.h"
#include "clk-regmap-mux-div.h"

static const u32 gpll0_a53cc_map[] = { 4, 5 };
enum apcs_mux_clk_parent {
	P_GPLL0,
	P_APCS_CPU_PLL,
};

static const struct parent_map gpll0_a53cc_map[] = {
	{ P_GPLL0, 4 },
	{ P_APCS_CPU_PLL, 5 },
};

static const char * const gpll0_a53cc[] = {
	"gpll0_vote",
+18 −10
Original line number Diff line number Diff line
@@ -56,20 +56,26 @@ int mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div)
}
EXPORT_SYMBOL_GPL(mux_div_set_src_div);

static void mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src,
int mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src,
				  u32 *div)
{
	int ret = 0;
	u32 val, d, s;
	const char *name = clk_hw_get_name(&md->clkr.hw);

	regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val);
	ret = regmap_read(md->clkr.regmap, CMD_RCGR + md->reg_offset, &val);
	if (ret)
		return ret;

	if (val & CMD_RCGR_DIRTY_CFG) {
		pr_err("%s: RCG configuration is pending\n", name);
		return;
		return -EBUSY;
	}

	regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val);
	ret = regmap_read(md->clkr.regmap, CFG_RCGR + md->reg_offset, &val);
	if (ret)
		return ret;

	s = (val >> md->src_shift);
	s &= BIT(md->src_width) - 1;
	*src = s;
@@ -77,6 +83,8 @@ static void mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src,
	d = (val >> md->hid_shift);
	d &= BIT(md->hid_width) - 1;
	*div = d;

	return ret;
}

static inline bool is_better_rate(unsigned long req, unsigned long best,
@@ -142,7 +150,7 @@ static int __mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,

			if (is_better_rate(rate, best_rate, actual_rate)) {
				best_rate = actual_rate;
				best_src = md->parent_map[i];
				best_src = md->parent_map[i].cfg;
				best_div = div - 1;
			}

@@ -169,7 +177,7 @@ static u8 mux_div_get_parent(struct clk_hw *hw)
	mux_div_get_src_div(md, &src, &div);

	for (i = 0; i < clk_hw_get_num_parents(hw); i++)
		if (src == md->parent_map[i])
		if (src == md->parent_map[i].cfg)
			return i;

	pr_err("%s: Can't find parent with src %d\n", name, src);
@@ -180,7 +188,7 @@ static int mux_div_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);

	return mux_div_set_src_div(md, md->parent_map[index], md->div);
	return mux_div_set_src_div(md, md->parent_map[index].cfg, md->div);
}

static int mux_div_set_rate(struct clk_hw *hw,
@@ -197,7 +205,7 @@ static int mux_div_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
	struct clk_regmap_mux_div *md = to_clk_regmap_mux_div(hw);

	return __mux_div_set_rate_and_parent(hw, rate, prate,
					     md->parent_map[index]);
					     md->parent_map[index].cfg);
}

static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate)
@@ -209,7 +217,7 @@ static unsigned long mux_div_recalc_rate(struct clk_hw *hw, unsigned long prate)

	mux_div_get_src_div(md, &src, &div);
	for (i = 0; i < num_parents; i++)
		if (src == md->parent_map[i]) {
		if (src == md->parent_map[i].cfg) {
			struct clk_hw *p = clk_hw_get_parent_by_index(hw, i);
			unsigned long parent_rate = clk_hw_get_rate(p);

+4 −2
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
#define __QCOM_CLK_REGMAP_MUX_DIV_H__

#include <linux/clk-provider.h>
#include "common.h"
#include "clk-regmap.h"

/**
@@ -19,7 +20,7 @@
 * @src_shift:	lowest bit of source select field
 * @div:	the divider raw configuration value
 * @src:	the mux index which will be used if the clock is enabled
 * @parent_map: map from parent_names index to src_sel field
 * @parent_map: pointer to parent_map struct
 * @clkr:	handle between common and hardware-specific interfaces
 * @pclk:	the input PLL clock
 * @clk_nb:	clock notifier for rate changes of the input PLL
@@ -32,7 +33,7 @@ struct clk_regmap_mux_div {
	u32				src_shift;
	u32				div;
	u32				src;
	const u32			*parent_map;
	const struct parent_map		*parent_map;
	struct clk_regmap		clkr;
	struct clk			*pclk;
	struct notifier_block		clk_nb;
@@ -40,5 +41,6 @@ struct clk_regmap_mux_div {

extern const struct clk_ops clk_regmap_mux_div_ops;
extern int mux_div_set_src_div(struct clk_regmap_mux_div *md, u32 src, u32 div);
int mux_div_get_src_div(struct clk_regmap_mux_div *md, u32 *src, u32 *div);

#endif