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

Commit ba492e90 authored by Haojian Zhuang's avatar Haojian Zhuang Committed by Mike Turquette
Browse files

clk: mux: add CLK_MUX_HIWORD_MASK



In both Hisilicon & Rockchip Cortex-A9 based chips, they don't use the
paradigm of reading-changing-writing the register contents.
Instead they use a hiword mask to indicate the changed bits.

When b01 should be set as switching mux, it also needs to indicate
the change by setting hiword mask (b11 << 16).

The patch adds mux flag for this usage.

Signed-off-by: default avatarHeiko Stuebner <heiko@sntech.de>
Signed-off-by: default avatarHaojian Zhuang <haojian.zhuang@linaro.org>
Signed-off-by: default avatarMike Turquette <mturquette@linaro.org>
parent f3aab5d6
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -86,8 +86,12 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
	if (mux->lock)
		spin_lock_irqsave(mux->lock, flags);

	if (mux->flags & CLK_MUX_HIWORD_MASK) {
		val = mux->mask << (mux->shift + 16);
	} else {
		val = readl(mux->reg);
		val &= ~(mux->mask << mux->shift);
	}
	val |= index << mux->shift;
	writel(val, mux->reg);

@@ -111,6 +115,15 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
	struct clk_mux *mux;
	struct clk *clk;
	struct clk_init_data init;
	u8 width = 0;

	if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
		width = fls(mask) - ffs(mask) + 1;
		if (width + shift > 16) {
			pr_err("mux value exceeds LOWORD field\n");
			return ERR_PTR(-EINVAL);
		}
	}

	/* allocate the mux */
	mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
+5 −0
Original line number Diff line number Diff line
@@ -299,6 +299,10 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 * Flags:
 * CLK_MUX_INDEX_ONE - register index starts at 1, not 0
 * CLK_MUX_INDEX_BIT - register index is a single bit (power of two)
 * CLK_MUX_HIWORD_MASK - The mux settings are only in lower 16-bit of this
 *   register, and mask of mux bits are in higher 16-bit of this register.
 *   While setting the mux bits, higher 16-bit should also be updated to
 *   indicate changing mux bits.
 */
struct clk_mux {
	struct clk_hw	hw;
@@ -312,6 +316,7 @@ struct clk_mux {

#define CLK_MUX_INDEX_ONE		BIT(0)
#define CLK_MUX_INDEX_BIT		BIT(1)
#define CLK_MUX_HIWORD_MASK		BIT(2)

extern const struct clk_ops clk_mux_ops;