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