1*103c5e1bSManivannan Sadhasivam // SPDX-License-Identifier: GPL-2.0+ 2*103c5e1bSManivannan Sadhasivam // 3*103c5e1bSManivannan Sadhasivam // OWL gate clock driver 4*103c5e1bSManivannan Sadhasivam // 5*103c5e1bSManivannan Sadhasivam // Copyright (c) 2014 Actions Semi Inc. 6*103c5e1bSManivannan Sadhasivam // Author: David Liu <liuwei@actions-semi.com> 7*103c5e1bSManivannan Sadhasivam // 8*103c5e1bSManivannan Sadhasivam // Copyright (c) 2018 Linaro Ltd. 9*103c5e1bSManivannan Sadhasivam // Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 10*103c5e1bSManivannan Sadhasivam 11*103c5e1bSManivannan Sadhasivam #include <linux/clk-provider.h> 12*103c5e1bSManivannan Sadhasivam #include <linux/regmap.h> 13*103c5e1bSManivannan Sadhasivam 14*103c5e1bSManivannan Sadhasivam #include "owl-gate.h" 15*103c5e1bSManivannan Sadhasivam 16*103c5e1bSManivannan Sadhasivam void owl_gate_set(const struct owl_clk_common *common, 17*103c5e1bSManivannan Sadhasivam const struct owl_gate_hw *gate_hw, bool enable) 18*103c5e1bSManivannan Sadhasivam { 19*103c5e1bSManivannan Sadhasivam int set = gate_hw->gate_flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; 20*103c5e1bSManivannan Sadhasivam u32 reg; 21*103c5e1bSManivannan Sadhasivam 22*103c5e1bSManivannan Sadhasivam set ^= enable; 23*103c5e1bSManivannan Sadhasivam 24*103c5e1bSManivannan Sadhasivam regmap_read(common->regmap, gate_hw->reg, ®); 25*103c5e1bSManivannan Sadhasivam 26*103c5e1bSManivannan Sadhasivam if (set) 27*103c5e1bSManivannan Sadhasivam reg |= BIT(gate_hw->bit_idx); 28*103c5e1bSManivannan Sadhasivam else 29*103c5e1bSManivannan Sadhasivam reg &= ~BIT(gate_hw->bit_idx); 30*103c5e1bSManivannan Sadhasivam 31*103c5e1bSManivannan Sadhasivam regmap_write(common->regmap, gate_hw->reg, reg); 32*103c5e1bSManivannan Sadhasivam } 33*103c5e1bSManivannan Sadhasivam 34*103c5e1bSManivannan Sadhasivam static void owl_gate_disable(struct clk_hw *hw) 35*103c5e1bSManivannan Sadhasivam { 36*103c5e1bSManivannan Sadhasivam struct owl_gate *gate = hw_to_owl_gate(hw); 37*103c5e1bSManivannan Sadhasivam struct owl_clk_common *common = &gate->common; 38*103c5e1bSManivannan Sadhasivam 39*103c5e1bSManivannan Sadhasivam owl_gate_set(common, &gate->gate_hw, false); 40*103c5e1bSManivannan Sadhasivam } 41*103c5e1bSManivannan Sadhasivam 42*103c5e1bSManivannan Sadhasivam static int owl_gate_enable(struct clk_hw *hw) 43*103c5e1bSManivannan Sadhasivam { 44*103c5e1bSManivannan Sadhasivam struct owl_gate *gate = hw_to_owl_gate(hw); 45*103c5e1bSManivannan Sadhasivam struct owl_clk_common *common = &gate->common; 46*103c5e1bSManivannan Sadhasivam 47*103c5e1bSManivannan Sadhasivam owl_gate_set(common, &gate->gate_hw, true); 48*103c5e1bSManivannan Sadhasivam 49*103c5e1bSManivannan Sadhasivam return 0; 50*103c5e1bSManivannan Sadhasivam } 51*103c5e1bSManivannan Sadhasivam 52*103c5e1bSManivannan Sadhasivam int owl_gate_clk_is_enabled(const struct owl_clk_common *common, 53*103c5e1bSManivannan Sadhasivam const struct owl_gate_hw *gate_hw) 54*103c5e1bSManivannan Sadhasivam { 55*103c5e1bSManivannan Sadhasivam u32 reg; 56*103c5e1bSManivannan Sadhasivam 57*103c5e1bSManivannan Sadhasivam regmap_read(common->regmap, gate_hw->reg, ®); 58*103c5e1bSManivannan Sadhasivam 59*103c5e1bSManivannan Sadhasivam if (gate_hw->gate_flags & CLK_GATE_SET_TO_DISABLE) 60*103c5e1bSManivannan Sadhasivam reg ^= BIT(gate_hw->bit_idx); 61*103c5e1bSManivannan Sadhasivam 62*103c5e1bSManivannan Sadhasivam return !!(reg & BIT(gate_hw->bit_idx)); 63*103c5e1bSManivannan Sadhasivam } 64*103c5e1bSManivannan Sadhasivam 65*103c5e1bSManivannan Sadhasivam static int owl_gate_is_enabled(struct clk_hw *hw) 66*103c5e1bSManivannan Sadhasivam { 67*103c5e1bSManivannan Sadhasivam struct owl_gate *gate = hw_to_owl_gate(hw); 68*103c5e1bSManivannan Sadhasivam struct owl_clk_common *common = &gate->common; 69*103c5e1bSManivannan Sadhasivam 70*103c5e1bSManivannan Sadhasivam return owl_gate_clk_is_enabled(common, &gate->gate_hw); 71*103c5e1bSManivannan Sadhasivam } 72*103c5e1bSManivannan Sadhasivam 73*103c5e1bSManivannan Sadhasivam const struct clk_ops owl_gate_ops = { 74*103c5e1bSManivannan Sadhasivam .disable = owl_gate_disable, 75*103c5e1bSManivannan Sadhasivam .enable = owl_gate_enable, 76*103c5e1bSManivannan Sadhasivam .is_enabled = owl_gate_is_enabled, 77*103c5e1bSManivannan Sadhasivam }; 78