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

Commit 2e7c9e96 authored by Padmanabhan Komanduru's avatar Padmanabhan Komanduru Committed by Ritesh Kumar
Browse files

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: default avatarPadmanabhan Komanduru <pkomandu@codeaurora.org>
Signed-off-by: default avatarRitesh Kumar <riteshk@codeaurora.org>
parent 65205701
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013, 2016-2019, 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
@@ -402,6 +402,39 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,
	return _freq_tbl_determine_rate(hw, rcg->freq_tbl, req, FLOOR);
}

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;
@@ -1058,6 +1091,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);
		}
	}
@@ -1154,6 +1189,8 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
		f.m = frac->num;
		f.n = frac->den;

		if (clk_rcg2_current_config(rcg, &f))
			return 0;
		return clk_rcg2_configure(rcg, &f);
	}
	return -EINVAL;