xref: /openbmc/linux/drivers/clk/actions/owl-mux.c (revision a8338772)
1a8338772SManivannan Sadhasivam // SPDX-License-Identifier: GPL-2.0+
2a8338772SManivannan Sadhasivam //
3a8338772SManivannan Sadhasivam // OWL mux clock driver
4a8338772SManivannan Sadhasivam //
5a8338772SManivannan Sadhasivam // Copyright (c) 2014 Actions Semi Inc.
6a8338772SManivannan Sadhasivam // Author: David Liu <liuwei@actions-semi.com>
7a8338772SManivannan Sadhasivam //
8a8338772SManivannan Sadhasivam // Copyright (c) 2018 Linaro Ltd.
9a8338772SManivannan Sadhasivam // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
10a8338772SManivannan Sadhasivam 
11a8338772SManivannan Sadhasivam #include <linux/clk-provider.h>
12a8338772SManivannan Sadhasivam #include <linux/regmap.h>
13a8338772SManivannan Sadhasivam 
14a8338772SManivannan Sadhasivam #include "owl-mux.h"
15a8338772SManivannan Sadhasivam 
owl_mux_helper_get_parent(const struct owl_clk_common * common,const struct owl_mux_hw * mux_hw)16a8338772SManivannan Sadhasivam u8 owl_mux_helper_get_parent(const struct owl_clk_common *common,
17a8338772SManivannan Sadhasivam 			     const struct owl_mux_hw *mux_hw)
18a8338772SManivannan Sadhasivam {
19a8338772SManivannan Sadhasivam 	u32 reg;
20a8338772SManivannan Sadhasivam 	u8 parent;
21a8338772SManivannan Sadhasivam 
22a8338772SManivannan Sadhasivam 	regmap_read(common->regmap, mux_hw->reg, &reg);
23a8338772SManivannan Sadhasivam 	parent = reg >> mux_hw->shift;
24a8338772SManivannan Sadhasivam 	parent &= BIT(mux_hw->width) - 1;
25a8338772SManivannan Sadhasivam 
26a8338772SManivannan Sadhasivam 	return parent;
27a8338772SManivannan Sadhasivam }
28a8338772SManivannan Sadhasivam 
owl_mux_get_parent(struct clk_hw * hw)29a8338772SManivannan Sadhasivam static u8 owl_mux_get_parent(struct clk_hw *hw)
30a8338772SManivannan Sadhasivam {
31a8338772SManivannan Sadhasivam 	struct owl_mux *mux = hw_to_owl_mux(hw);
32a8338772SManivannan Sadhasivam 
33a8338772SManivannan Sadhasivam 	return owl_mux_helper_get_parent(&mux->common, &mux->mux_hw);
34a8338772SManivannan Sadhasivam }
35a8338772SManivannan Sadhasivam 
owl_mux_helper_set_parent(const struct owl_clk_common * common,struct owl_mux_hw * mux_hw,u8 index)36a8338772SManivannan Sadhasivam int owl_mux_helper_set_parent(const struct owl_clk_common *common,
37a8338772SManivannan Sadhasivam 			      struct owl_mux_hw *mux_hw, u8 index)
38a8338772SManivannan Sadhasivam {
39a8338772SManivannan Sadhasivam 	u32 reg;
40a8338772SManivannan Sadhasivam 
41a8338772SManivannan Sadhasivam 	regmap_read(common->regmap, mux_hw->reg, &reg);
42a8338772SManivannan Sadhasivam 	reg &= ~GENMASK(mux_hw->width + mux_hw->shift - 1, mux_hw->shift);
43a8338772SManivannan Sadhasivam 	regmap_write(common->regmap, mux_hw->reg,
44a8338772SManivannan Sadhasivam 			reg | (index << mux_hw->shift));
45a8338772SManivannan Sadhasivam 
46a8338772SManivannan Sadhasivam 	return 0;
47a8338772SManivannan Sadhasivam }
48a8338772SManivannan Sadhasivam 
owl_mux_set_parent(struct clk_hw * hw,u8 index)49a8338772SManivannan Sadhasivam static int owl_mux_set_parent(struct clk_hw *hw, u8 index)
50a8338772SManivannan Sadhasivam {
51a8338772SManivannan Sadhasivam 	struct owl_mux *mux = hw_to_owl_mux(hw);
52a8338772SManivannan Sadhasivam 
53a8338772SManivannan Sadhasivam 	return owl_mux_helper_set_parent(&mux->common, &mux->mux_hw, index);
54a8338772SManivannan Sadhasivam }
55a8338772SManivannan Sadhasivam 
56a8338772SManivannan Sadhasivam const struct clk_ops owl_mux_ops = {
57a8338772SManivannan Sadhasivam 	.get_parent = owl_mux_get_parent,
58a8338772SManivannan Sadhasivam 	.set_parent = owl_mux_set_parent,
59a8338772SManivannan Sadhasivam 	.determine_rate = __clk_mux_determine_rate,
60a8338772SManivannan Sadhasivam };
61