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

Commit 3295850b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: Add support to log clock registers in case of failure" into msm-next

parents 0399933d 8dc79c03
Loading
Loading
Loading
Loading
+2 −11
Original line number Diff line number Diff line
@@ -2632,16 +2632,6 @@ static int clock_debug_enable_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get,
			clock_debug_enable_set, "%lld\n");

#define clock_debug_output(m, c, fmt, ...)		\
do {							\
	if (m)						\
		seq_printf(m, fmt, ##__VA_ARGS__);	\
	else if (c)					\
		pr_cont(fmt, ##__VA_ARGS__);		\
	else						\
		pr_info(fmt, ##__VA_ARGS__);		\
} while (0)

/*
 * clock_debug_print_enabled_debug_suspend() - Print names of enabled clocks
 * during suspend.
@@ -2757,7 +2747,7 @@ static const struct file_operations clk_enabled_list_fops = {
	.release	= seq_release,
};

static void clk_debug_print_hw(struct clk_core *clk, struct seq_file *f)
void clk_debug_print_hw(struct clk_core *clk, struct seq_file *f)
{
	if (IS_ERR_OR_NULL(clk))
		return;
@@ -2771,6 +2761,7 @@ static void clk_debug_print_hw(struct clk_core *clk, struct seq_file *f)

	clk->ops->list_registers(f, clk->hw);
}
EXPORT_SYMBOL(clk_debug_print_hw);

static int print_hw_show(struct seq_file *m, void *unused)
{
+16 −0
Original line number Diff line number Diff line
@@ -23,6 +23,22 @@ void __clk_free_clk(struct clk *clk);

/* Debugfs API to print the enabled clocks */
void clock_debug_print_enabled(void);
void clk_debug_print_hw(struct clk_core *clk, struct seq_file *f);

#define WARN_CLK(core, name, cond, fmt, ...) do {		\
		clk_debug_print_hw(core, NULL);			\
		WARN(cond, "%s: " fmt, name, ##__VA_ARGS__);	\
} while (0)

#define clock_debug_output(m, c, fmt, ...)		\
do {							\
	if (m)						\
		seq_printf(m, fmt, ##__VA_ARGS__);	\
	else if (c)					\
		pr_cont(fmt, ##__VA_ARGS__);		\
	else						\
		pr_info(fmt, ##__VA_ARGS__);		\
} while (0)

#else
/* All these casts to avoid ifdefs in clkdev... */
+16 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/sched/clock.h>

#include "clk-alpha-pll.h"
#include "common.h"
@@ -110,13 +111,17 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
	u32 val, off;
	int count;
	int ret;
	const char *name = clk_hw_get_name(&pll->clkr.hw);
	u64 time;
	struct clk_hw *hw = &pll->clkr.hw;
	const char *name = clk_hw_get_name(hw);

	off = pll->offset;
	ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
	if (ret)
		return ret;

	time = sched_clock();

	for (count = 100; count > 0; count--) {
		ret = regmap_read(pll->clkr.regmap, off + PLL_MODE, &val);
		if (ret)
@@ -129,7 +134,12 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
		udelay(1);
	}

	WARN(1, "%s failed to %s!\n", name, action);
	time = sched_clock() - time;

	pr_err("PLL lock bit detection total wait time: %lld ns", time);

	WARN_CLK(hw->core, name, 1, "failed to %s!\n", action);

	return -ETIMEDOUT;
}

@@ -499,7 +509,8 @@ static void print_pll_registers(struct seq_file *f, struct clk_hw *hw,
	for (i = 0; i < size; i++) {
		regmap_read(pll->clkr.regmap, pll->offset + pll_regs[i].offset,
					&val);
		seq_printf(f, "%20s: 0x%.8x\n", pll_regs[i].name, val);
		clock_debug_output(f, false, "%20s: 0x%.8x\n", pll_regs[i].name,
					val);
	}

	regmap_read(pll->clkr.regmap, pll->offset + PLL_MODE, &val);
@@ -507,7 +518,8 @@ static void print_pll_registers(struct seq_file *f, struct clk_hw *hw,
	if (val & PLL_FSM_ENA) {
		regmap_read(pll->clkr.regmap, pll->clkr.enable_reg +
					pll_vote_reg->offset, &val);
		seq_printf(f, "%20s: 0x%.8x\n", pll_vote_reg->name, val);
		clock_debug_output(f, false, "%20s: 0x%.8x\n",
					pll_vote_reg->name, val);
	}
}

+12 −6
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@

#include "clk-branch.h"
#include "clk-regmap.h"
#include "common.h"

static bool clk_branch_in_hwcg_mode(const struct clk_branch *br)
{
@@ -78,7 +79,8 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling,
		bool (check_halt)(const struct clk_branch *, bool))
{
	bool voted = br->halt_check & BRANCH_VOTED;
	const char *name = clk_hw_get_name(&br->clkr.hw);
	const struct clk_hw *hw = &br->clkr.hw;
	const char *name = clk_hw_get_name(hw);

	/* Skip checking halt bit if the clock is in hardware gated mode */
	if (clk_branch_in_hwcg_mode(br))
@@ -96,8 +98,10 @@ static int clk_branch_wait(const struct clk_branch *br, bool enabling,
				return 0;
			udelay(1);
		}
		WARN(1, "%s status stuck at 'o%s'", name,

		WARN_CLK(hw->core, name, 1, "status stuck at 'o%s'",
						enabling ? "ff" : "n");

		return -EBUSY;
	}
	return 0;
@@ -340,7 +344,8 @@ static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
	for (i = 0; i < size; i++) {
		regmap_read(br->clkr.regmap, br->halt_reg + data[i].offset,
					&val);
		seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
		clock_debug_output(f, false, "%20s: 0x%.8x\n",
							data[i].name, val);
	}

	if ((br->halt_check & BRANCH_HALT_VOTED) &&
@@ -350,7 +355,7 @@ static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
			for (i = 0; i < size; i++) {
				regmap_read(br->clkr.regmap, rclk->enable_reg +
						data1[i].offset, &val);
				seq_printf(f, "%20s: 0x%.8x\n",
				clock_debug_output(f, false, "%20s: 0x%.8x\n",
						data1[i].name, val);
			}
		}
@@ -479,7 +484,8 @@ static void clk_gate2_list_registers(struct seq_file *f, struct clk_hw *hw)
	for (i = 0; i < size; i++) {
		regmap_read(gt->clkr.regmap, gt->clkr.enable_reg +
					data[i].offset, &val);
		seq_printf(f, "%20s: 0x%.8x\n", data[i].name, val);
		clock_debug_output(f, false, "%20s: 0x%.8x\n",
						data[i].name, val);
	}
}

+25 −9
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ static u8 clk_rcg2_get_parent(struct clk_hw *hw)
	return 0;
}

static int update_config(struct clk_rcg2 *rcg)
static int update_config(struct clk_rcg2 *rcg, u32 cfg)
{
	int count, ret;
	u32 cmd;
@@ -131,7 +131,11 @@ static int update_config(struct clk_rcg2 *rcg)
		udelay(1);
	}

	WARN(1, "%s: rcg didn't update its configuration.", name);
	pr_err("CFG_RCGR old frequency configuration 0x%x !\n", cfg);

	WARN_CLK(hw->core, name, count == 0,
			"rcg didn't update its configuration.");

	return 0;
}

@@ -140,6 +144,10 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	int ret;
	u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
	u32 old_cfg;

	/* Read back the old configuration */
	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &old_cfg);

	if (rcg->flags & DFS_ENABLE_RCG)
		return 0;
@@ -149,7 +157,7 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
	if (ret)
		return ret;

	return update_config(rcg);
	return update_config(rcg, old_cfg);
}

static int clk_rcg2_set_force_enable(struct clk_hw *hw)
@@ -352,7 +360,7 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,

static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
{
	u32 cfg, mask;
	u32 cfg, mask, old_cfg;
	struct clk_hw *hw = &rcg->clkr.hw;
	int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);

@@ -362,6 +370,9 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
	if (index < 0)
		return index;

	/* Read back the old configuration */
	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &old_cfg);

	if (rcg->mnd_width && f->n) {
		mask = BIT(rcg->mnd_width) - 1;
		ret = regmap_update_bits(rcg->clkr.regmap,
@@ -391,7 +402,7 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
	if (ret)
		return ret;

	return update_config(rcg);
	return update_config(rcg, old_cfg);
}

static void clk_rcg2_list_registers(struct seq_file *f, struct clk_hw *hw)
@@ -417,14 +428,16 @@ static void clk_rcg2_list_registers(struct seq_file *f, struct clk_hw *hw)
		for (i = 0; i < size; i++) {
			regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr +
					data1[i].offset), &val);
			seq_printf(f, "%20s: 0x%.8x\n",	data1[i].name, val);
			clock_debug_output(f, false, "%20s: 0x%.8x\n",
						data1[i].name, val);
		}
	} else {
		size = ARRAY_SIZE(data);
		for (i = 0; i < size; i++) {
			regmap_read(rcg->clkr.regmap, (rcg->cmd_rcgr +
				data[i].offset), &val);
			seq_printf(f, "%20s: 0x%.8x\n",	data[i].name, val);
			clock_debug_output(f, false, "%20s: 0x%.8x\n",
						data[i].name, val);
		}
	}
}
@@ -1204,16 +1217,19 @@ static int clk_gfx3d_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate, u8 index)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	u32 cfg;
	u32 cfg, old_cfg;
	int ret;

	/* Read back the old configuration */
	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &old_cfg);

	/* Just mux it, we don't use the division or m/n hardware */
	cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
	ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
	if (ret)
		return ret;

	return update_config(rcg);
	return update_config(rcg, old_cfg);
}

static int clk_gfx3d_set_rate(struct clk_hw *hw, unsigned long rate,
Loading