From a00ce1c8cbd80275ff14d8616b3f94851056bb0e Mon Sep 17 00:00:00 2001 From: Padmanabhan Komanduru Date: Tue, 7 Aug 2018 18:09:07 +0530 Subject: clk: qcom: check for change in RCG configuration during set_rate For DSI byte clock RCG, check if there is a change in existing settings before updating RCG configuration. This is needed to avoid glitch on the display panel when there is a change in the DSI byte clock frequency with display enabled. Change-Id: I8ef0331cbb466b399cd12199b4d335ed44997dbc Signed-off-by: Padmanabhan Komanduru --- drivers/clk/qcom/clk-rcg2.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 3c3cf8e04eea..f22e07e87967 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -313,6 +313,39 @@ static int clk_rcg2_determine_rate(struct clk_hw *hw, return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req); } +static bool clk_rcg2_current_config(struct clk_rcg2 *rcg, + const struct freq_tbl *f) +{ + struct clk_hw *hw = &rcg->clkr.hw; + u32 cfg, mask, new_cfg; + int index; + + if (rcg->mnd_width) { + mask = BIT(rcg->mnd_width) - 1; + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + M_REG, &cfg); + if ((cfg & mask) != (f->m & mask)) + return false; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + N_REG, &cfg); + if ((cfg & mask) != (~(f->n - f->m) & mask)) + return false; + } + + mask = (BIT(rcg->hid_width) - 1) | CFG_SRC_SEL_MASK; + + index = qcom_find_src_index(hw, rcg->parent_map, f->src); + + new_cfg = ((f->pre_div << CFG_SRC_DIV_SHIFT) | + (rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT)) & mask; + + regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg); + + if (new_cfg != (cfg & mask)) + return false; + + return true; +} + static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f) { u32 cfg, mask, old_cfg; @@ -984,6 +1017,8 @@ static int clk_byte2_set_rate(struct clk_hw *hw, unsigned long rate, for (i = 0; i < num_parents; i++) { if (cfg == rcg->parent_map[i].cfg) { f.src = rcg->parent_map[i].src; + if (clk_rcg2_current_config(rcg, &f)) + return 0; return clk_rcg2_configure(rcg, &f); } } -- cgit v1.2.3