Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: qcom: Add simple regmap based muxes

Add support for muxes that use regmap instead of readl/writel
directly. We don't support as many features as clk-mux.c, but
this is good enough to support getting and setting parents.
Adding a table based lookup can be added in the future if needed.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Tested-by: Kenneth Westfield <kwestfie@codeaurora.org>
Signed-off-by: Michael Turquette <mturquette@linaro.org>

authored by

Stephen Boyd and committed by
Michael Turquette
b3ee3eff 4116076e

+89
+1
drivers/clk/qcom/Makefile
··· 7 7 clk-qcom-y += clk-rcg2.o 8 8 clk-qcom-y += clk-branch.o 9 9 clk-qcom-y += clk-regmap-divider.o 10 + clk-qcom-y += clk-regmap-mux.o 10 11 clk-qcom-y += reset.o 11 12 12 13 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
+59
drivers/clk/qcom/clk-regmap-mux.c
··· 1 + /* 2 + * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #include <linux/kernel.h> 15 + #include <linux/bitops.h> 16 + #include <linux/regmap.h> 17 + #include <linux/export.h> 18 + 19 + #include "clk-regmap-mux.h" 20 + 21 + static inline struct clk_regmap_mux *to_clk_regmap_mux(struct clk_hw *hw) 22 + { 23 + return container_of(to_clk_regmap(hw), struct clk_regmap_mux, clkr); 24 + } 25 + 26 + static u8 mux_get_parent(struct clk_hw *hw) 27 + { 28 + struct clk_regmap_mux *mux = to_clk_regmap_mux(hw); 29 + struct clk_regmap *clkr = to_clk_regmap(hw); 30 + unsigned int mask = GENMASK(mux->width - 1, 0); 31 + unsigned int val; 32 + 33 + regmap_read(clkr->regmap, mux->reg, &val); 34 + 35 + val >>= mux->shift; 36 + val &= mask; 37 + 38 + return val; 39 + } 40 + 41 + static int mux_set_parent(struct clk_hw *hw, u8 index) 42 + { 43 + struct clk_regmap_mux *mux = to_clk_regmap_mux(hw); 44 + struct clk_regmap *clkr = to_clk_regmap(hw); 45 + unsigned int mask = GENMASK(mux->width + mux->shift - 1, mux->shift); 46 + unsigned int val; 47 + 48 + val = index; 49 + val <<= mux->shift; 50 + 51 + return regmap_update_bits(clkr->regmap, mux->reg, mask, val); 52 + } 53 + 54 + const struct clk_ops clk_regmap_mux_closest_ops = { 55 + .get_parent = mux_get_parent, 56 + .set_parent = mux_set_parent, 57 + .determine_rate = __clk_mux_determine_rate_closest, 58 + }; 59 + EXPORT_SYMBOL_GPL(clk_regmap_mux_closest_ops);
+29
drivers/clk/qcom/clk-regmap-mux.h
··· 1 + /* 2 + * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 + * 4 + * This software is licensed under the terms of the GNU General Public 5 + * License version 2, as published by the Free Software Foundation, and 6 + * may be copied, distributed, and modified under those terms. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + */ 13 + 14 + #ifndef __QCOM_CLK_REGMAP_MUX_H__ 15 + #define __QCOM_CLK_REGMAP_MUX_H__ 16 + 17 + #include <linux/clk-provider.h> 18 + #include "clk-regmap.h" 19 + 20 + struct clk_regmap_mux { 21 + u32 reg; 22 + u32 shift; 23 + u32 width; 24 + struct clk_regmap clkr; 25 + }; 26 + 27 + extern const struct clk_ops clk_regmap_mux_closest_ops; 28 + 29 + #endif