FILE
owl-composite.c
File preview with syntax highlighting.
linux-6.19.14/drivers/clk/actions/owl-composite.c
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// OWL composite clock driver 4// 5// Copyright (c) 2014 Actions Semi Inc. 6// Author: David Liu <liuwei@actions-semi.com> 7// 8// Copyright (c) 2018 Linaro Ltd. 9// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 10 11#include <linux/clk-provider.h> 12#include <linux/regmap.h> 13 14#include "owl-composite.h" 15 16static u8 owl_comp_get_parent(struct clk_hw *hw) 17{ 18 struct owl_composite *comp = hw_to_owl_comp(hw); 19 20 return owl_mux_helper_get_parent(&comp->common, &comp->mux_hw); 21} 22 23static int owl_comp_set_parent(struct clk_hw *hw, u8 index) 24{ 25 struct owl_composite *comp = hw_to_owl_comp(hw); 26 27 return owl_mux_helper_set_parent(&comp->common, &comp->mux_hw, index); 28} 29 30static void owl_comp_disable(struct clk_hw *hw) 31{ 32 struct owl_composite *comp = hw_to_owl_comp(hw); 33 struct owl_clk_common *common = &comp->common; 34 35 owl_gate_set(common, &comp->gate_hw, false); 36} 37 38static int owl_comp_enable(struct clk_hw *hw) 39{ 40 struct owl_composite *comp = hw_to_owl_comp(hw); 41 struct owl_clk_common *common = &comp->common; 42 43 owl_gate_set(common, &comp->gate_hw, true); 44 45 return 0; 46} 47 48static int owl_comp_is_enabled(struct clk_hw *hw) 49{ 50 struct owl_composite *comp = hw_to_owl_comp(hw); 51 struct owl_clk_common *common = &comp->common; 52 53 return owl_gate_clk_is_enabled(common, &comp->gate_hw); 54} 55 56static int owl_comp_div_determine_rate(struct clk_hw *hw, 57 struct clk_rate_request *req) 58{ 59 struct owl_composite *comp = hw_to_owl_comp(hw); 60 struct owl_divider_hw *div = &comp->rate.div_hw; 61 62 return divider_determine_rate(&comp->common.hw, req, div->table, 63 div->width, div->div_flags); 64} 65 66static unsigned long owl_comp_div_recalc_rate(struct clk_hw *hw, 67 unsigned long parent_rate) 68{ 69 struct owl_composite *comp = hw_to_owl_comp(hw); 70 71 return owl_divider_helper_recalc_rate(&comp->common, &comp->rate.div_hw, 72 parent_rate); 73} 74 75static int owl_comp_div_set_rate(struct clk_hw *hw, unsigned long rate, 76 unsigned long parent_rate) 77{ 78 struct owl_composite *comp = hw_to_owl_comp(hw); 79 80 return owl_divider_helper_set_rate(&comp->common, &comp->rate.div_hw, 81 rate, parent_rate); 82} 83 84static int owl_comp_fact_determine_rate(struct clk_hw *hw, 85 struct clk_rate_request *req) 86{ 87 struct owl_composite *comp = hw_to_owl_comp(hw); 88 long rate; 89 90 rate = owl_factor_helper_round_rate(&comp->common, 91 &comp->rate.factor_hw, 92 req->rate, &req->best_parent_rate); 93 if (rate < 0) 94 return rate; 95 96 req->rate = rate; 97 return 0; 98} 99 100static unsigned long owl_comp_fact_recalc_rate(struct clk_hw *hw, 101 unsigned long parent_rate) 102{ 103 struct owl_composite *comp = hw_to_owl_comp(hw); 104 105 return owl_factor_helper_recalc_rate(&comp->common, 106 &comp->rate.factor_hw, 107 parent_rate); 108} 109 110static int owl_comp_fact_set_rate(struct clk_hw *hw, unsigned long rate, 111 unsigned long parent_rate) 112{ 113 struct owl_composite *comp = hw_to_owl_comp(hw); 114 115 return owl_factor_helper_set_rate(&comp->common, 116 &comp->rate.factor_hw, 117 rate, parent_rate); 118} 119 120static int owl_comp_fix_fact_determine_rate(struct clk_hw *hw, 121 struct clk_rate_request *req) 122{ 123 struct owl_composite *comp = hw_to_owl_comp(hw); 124 struct clk_fixed_factor *fix_fact_hw = &comp->rate.fix_fact_hw; 125 126 return comp->fix_fact_ops->determine_rate(&fix_fact_hw->hw, req); 127} 128 129static unsigned long owl_comp_fix_fact_recalc_rate(struct clk_hw *hw, 130 unsigned long parent_rate) 131{ 132 struct owl_composite *comp = hw_to_owl_comp(hw); 133 struct clk_fixed_factor *fix_fact_hw = &comp->rate.fix_fact_hw; 134 135 return comp->fix_fact_ops->recalc_rate(&fix_fact_hw->hw, parent_rate); 136 137} 138 139static int owl_comp_fix_fact_set_rate(struct clk_hw *hw, unsigned long rate, 140 unsigned long parent_rate) 141{ 142 /* 143 * We must report success but we can do so unconditionally because 144 * owl_comp_fix_fact_round_rate returns values that ensure this call is 145 * a nop. 146 */ 147 148 return 0; 149} 150 151const struct clk_ops owl_comp_div_ops = { 152 /* mux_ops */ 153 .get_parent = owl_comp_get_parent, 154 .set_parent = owl_comp_set_parent, 155 156 /* gate_ops */ 157 .disable = owl_comp_disable, 158 .enable = owl_comp_enable, 159 .is_enabled = owl_comp_is_enabled, 160 161 /* div_ops */ 162 .determine_rate = owl_comp_div_determine_rate, 163 .recalc_rate = owl_comp_div_recalc_rate, 164 .set_rate = owl_comp_div_set_rate, 165}; 166 167 168const struct clk_ops owl_comp_fact_ops = { 169 /* mux_ops */ 170 .get_parent = owl_comp_get_parent, 171 .set_parent = owl_comp_set_parent, 172 173 /* gate_ops */ 174 .disable = owl_comp_disable, 175 .enable = owl_comp_enable, 176 .is_enabled = owl_comp_is_enabled, 177 178 /* fact_ops */ 179 .determine_rate = owl_comp_fact_determine_rate, 180 .recalc_rate = owl_comp_fact_recalc_rate, 181 .set_rate = owl_comp_fact_set_rate, 182}; 183 184const struct clk_ops owl_comp_fix_fact_ops = { 185 /* gate_ops */ 186 .disable = owl_comp_disable, 187 .enable = owl_comp_enable, 188 .is_enabled = owl_comp_is_enabled, 189 190 /* fix_fact_ops */ 191 .determine_rate = owl_comp_fix_fact_determine_rate, 192 .recalc_rate = owl_comp_fix_fact_recalc_rate, 193 .set_rate = owl_comp_fix_fact_set_rate, 194}; 195 196 197const struct clk_ops owl_comp_pass_ops = { 198 /* mux_ops */ 199 .determine_rate = clk_hw_determine_rate_no_reparent, 200 .get_parent = owl_comp_get_parent, 201 .set_parent = owl_comp_set_parent, 202 203 /* gate_ops */ 204 .disable = owl_comp_disable, 205 .enable = owl_comp_enable, 206 .is_enabled = owl_comp_is_enabled, 207};
~/
Read-only file preview.