summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTaniya Das <tdas@codeaurora.org>2017-01-30 18:17:43 +0530
committerTaniya Das <tdas@codeaurora.org>2017-02-09 16:59:43 +0530
commitf2b160b422ab519388af45d06aa1850270791e1e (patch)
tree986e56d9a7a1a6b903815b707bb3cc67c2d5bfaa /drivers
parentd24550bbf50f61b07668a28a20878e1f91cf544c (diff)
clk: qcom: Add support for post divider for debug mux
There could be cases where the post div in different debug muxes could be set previously and not cleared, so add support to clear and set it, in case required. Change-Id: I15fedb4672179cb604804e7cbb0d6afc68bc473b Signed-off-by: Taniya Das <tdas@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/qcom/common.c21
-rw-r--r--drivers/clk/qcom/common.h12
2 files changed, 30 insertions, 3 deletions
diff --git a/drivers/clk/qcom/common.c b/drivers/clk/qcom/common.c
index cba778b827ec..f6ce3106ab6f 100644
--- a/drivers/clk/qcom/common.c
+++ b/drivers/clk/qcom/common.c
@@ -334,16 +334,17 @@ static u32 run_measurement(unsigned ticks, struct regmap *regmap,
static unsigned long clk_debug_mux_measure_rate(struct clk_hw *hw)
{
unsigned long flags, ret = 0;
- u32 gcc_xo4_reg, sample_ticks = 0x10000, multiplier = 1;
+ u32 gcc_xo4_reg, sample_ticks = 0x10000, multiplier;
u64 raw_count_short, raw_count_full;
struct clk_debug_mux *meas = to_clk_measure(hw);
struct measure_clk_data *data = meas->priv;
-
clk_prepare_enable(data->cxo);
spin_lock_irqsave(&clk_reg_lock, flags);
+ multiplier = meas->multiplier + 1;
+
/* Enable CXO/4 and RINGOSC branch. */
regmap_read(meas->regmap[GCC], data->xo_div4_cbcr, &gcc_xo4_reg);
gcc_xo4_reg |= BIT(0);
@@ -404,6 +405,7 @@ static u8 clk_debug_mux_get_parent(struct clk_hw *hw)
static int clk_debug_mux_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_debug_mux *meas = to_clk_measure(hw);
+ unsigned long lsb = 0;
u32 regval = 0;
int dbg_cc = 0;
@@ -412,6 +414,16 @@ static int clk_debug_mux_set_parent(struct clk_hw *hw, u8 index)
if (dbg_cc != GCC) {
regmap_read(meas->regmap[dbg_cc], 0x0, &regval);
+ /* Clear & Set post divider bits */
+ if (meas->parent[index].post_div_mask) {
+ regval &= ~meas->parent[index].post_div_mask;
+ lsb = find_first_bit((unsigned long *)
+ &meas->parent[index].post_div_mask, 32);
+ regval |= (meas->parent[index].post_div_val << lsb) &
+ meas->parent[index].post_div_mask;
+ meas->multiplier = meas->parent[index].post_div_val;
+ }
+
if (meas->parent[index].mask)
regval &= ~meas->parent[index].mask <<
meas->parent[index].shift;
@@ -436,6 +448,11 @@ static int clk_debug_mux_set_parent(struct clk_hw *hw, u8 index)
/* clear post divider bits */
regval &= ~BM(15, 12);
+ lsb = find_first_bit((unsigned long *)
+ &meas->parent[index].post_div_mask, 32);
+ regval |= (meas->parent[index].post_div_val << lsb) &
+ meas->parent[index].post_div_mask;
+ meas->multiplier = meas->parent[index].post_div_val;
regval &= ~meas->mask;
regval |= (meas->parent[index].sel & meas->mask);
regval |= meas->en_mask;
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 76c010970b51..06ec0bb0bc29 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016-2017, 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
@@ -94,6 +94,10 @@ enum debug_cc {
* Incase the recursive debug mux does not have a enable bit,
* 0xFF should be used to indicate the same, otherwise global
* enable bit would be used.
+ * @post_div_mask: indicates the post div mask to be used at debug/recursive
+ * debug mux.
+ * @post_div_val: indicates the post div value to be used at debug/recursive
+ * debug mux.
*/
struct clk_src {
const char *parents;
@@ -103,6 +107,8 @@ struct clk_src {
u32 mask;
u32 shift;
u32 en_mask;
+ u32 post_div_mask;
+ u32 post_div_val;
};
#define MUX_SRC_LIST(...) \
@@ -123,6 +129,7 @@ struct clk_src {
* controller debug mux.
* @debug_offset: Start of debug mux offset.
* @hw: handle between common and hardware-specific interfaces.
+ * @multiplier: internally used by debug mux as post div multiplier.
*/
struct clk_debug_mux {
struct clk_src *parent;
@@ -134,6 +141,9 @@ struct clk_debug_mux {
u32 mask;
u32 debug_offset;
struct clk_hw hw;
+
+ /* internal */
+ u32 multiplier;
};
#define BM(msb, lsb) (((((uint32_t)-1) << (31-msb)) >> (31-msb+lsb)) << lsb)