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

Commit ecc667dd authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: clk-debug: Add support for enable mask for debug clk"

parents 3e3f0266 e08df662
Loading
Loading
Loading
Loading
+51 −17
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ static DEFINE_MUTEX(clk_debug_lock);
#define XO_DIV4_CNT_DONE	BIT(25)
#define CNT_EN			BIT(20)
#define MEASURE_CNT		GENMASK(24, 0)
#define CBCR_ENA		BIT(0)

/* Sample clock for 'ticks' reference clock ticks. */
static u32 run_measurement(unsigned int ticks, struct regmap *regmap,
@@ -170,15 +171,6 @@ static int clk_debug_mux_set_parent(struct clk_hw *hw, u8 index)
				meas->parent[index].post_div_shift;
		regmap_write(meas->regmap[dbg_cc],
				meas->parent[index].post_div_offset, regval);

		/* Not all recursive muxes have a DEBUG clock. */
		if (meas->parent[index].cbcr_offset != U32_MAX) {
			regmap_read(meas->regmap[dbg_cc],
				meas->parent[index].cbcr_offset, &regval);
			regval |= BIT(0);
			regmap_write(meas->regmap[dbg_cc],
				meas->parent[index].cbcr_offset, regval);
		}
	}

	/* Update the debug sel for GCC */
@@ -195,11 +187,6 @@ static int clk_debug_mux_set_parent(struct clk_hw *hw, u8 index)
			meas->post_div_mask) << meas->post_div_shift;
	regmap_write(meas->regmap[GCC], meas->post_div_offset, regval);

	/* Turn on the GCC_DEBUG_CBCR */
	regmap_read(meas->regmap[GCC], meas->cbcr_offset, &regval);
	regval |= BIT(0);
	regmap_write(meas->regmap[GCC], meas->cbcr_offset, regval);

	return 0;
}

@@ -209,6 +196,44 @@ const struct clk_ops clk_debug_mux_ops = {
};
EXPORT_SYMBOL(clk_debug_mux_ops);

static void enable_debug_clks(struct clk_debug_mux *meas, u8 index)
{
	int dbg_cc = meas->parent[index].dbg_cc;

	meas->en_mask = meas->en_mask ? meas->en_mask : CBCR_ENA;

	if (dbg_cc != GCC) {
		/* Not all recursive muxes have a DEBUG clock. */
		if (meas->parent[index].cbcr_offset != U32_MAX)
			regmap_update_bits(meas->regmap[dbg_cc],
					meas->parent[index].cbcr_offset,
					meas->en_mask, meas->en_mask);
	}

	/* Turn on the GCC_DEBUG_CBCR */
	regmap_update_bits(meas->regmap[GCC], meas->cbcr_offset,
					meas->en_mask, meas->en_mask);

}

static void disable_debug_clks(struct clk_debug_mux *meas, u8 index)
{
	int dbg_cc = meas->parent[index].dbg_cc;

	meas->en_mask = meas->en_mask ? meas->en_mask : CBCR_ENA;

	/* Turn off the GCC_DEBUG_CBCR */
	regmap_update_bits(meas->regmap[GCC], meas->cbcr_offset,
					meas->en_mask, 0);

	if (dbg_cc != GCC) {
		if (meas->parent[index].cbcr_offset != U32_MAX)
			regmap_update_bits(meas->regmap[dbg_cc],
					meas->parent[index].cbcr_offset,
					meas->en_mask, 0);
	}
}

static int clk_debug_measure_get(void *data, u64 *val)
{
	struct clk_hw *hw = data, *par;
@@ -223,6 +248,8 @@ static int clk_debug_measure_get(void *data, u64 *val)
	if (!ret) {
		par = measure;
		index =  clk_debug_mux_get_parent(measure);

		enable_debug_clks(meas, index);
		while (par && par != hw) {
			if (par->init->ops->enable)
				par->init->ops->enable(par);
@@ -236,18 +263,25 @@ static int clk_debug_measure_get(void *data, u64 *val)
		/* Accommodate for any pre-set dividers */
		if (meas->parent[index].misc_div_val)
			*val *= meas->parent[index].misc_div_val;
	} else {
		pr_err("Failed to set the debug mux's parent.\n");
		goto exit;
	}

	meas_rate = clk_get_rate(hw->clk);
	par = clk_hw_get_parent(measure);
	if (!par)
		return -EINVAL;
	if (!par) {
		ret = -EINVAL;
		goto exit1;
	}

	sw_rate = clk_get_rate(par->clk);
	if (sw_rate && meas_rate >= (sw_rate * 2))
		*val *= DIV_ROUND_CLOSEST(meas_rate, sw_rate);
exit1:
	disable_debug_clks(meas, index);
exit:
	mutex_unlock(&clk_debug_lock);

	return ret;
}

+4 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2016, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2016, 2019, The Linux Foundation. All rights reserved. */

#ifndef __QCOM_CLK_DEBUG_H__
#define __QCOM_CLK_DEBUG_H__
@@ -88,6 +88,8 @@ struct clk_src {
 * @num_parents:	number of parents
 * @regmap:		regmaps of debug mux
 * @priv:		private measure_clk_data to be used by debug mux
 * @en_mask:		indicates the enable bit mask at global clock
 *			controller debug mux.
 * @debug_offset:	debug mux offset.
 * @post_div_offset:	register with post-divider settings for the debug mux.
 * @cbcr_offset:	branch register to turn on debug mux.
@@ -106,6 +108,7 @@ struct clk_debug_mux {
	int num_parents;
	struct regmap **regmap;
	void *priv;
	u32 en_mask;
	u32 debug_offset;
	u32 post_div_offset;
	u32 cbcr_offset;