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

This commit is contained in:
qctecmdr 2019-09-05 18:45:26 -07:00 • committed by Gerrit - the friendly Code Review server
commit ecc667dddf
2 changed files with 55 additions and 18 deletions

View file

@ -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;
}

View file

@ -1,5 +1,5 @@
/* 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;