1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * PRCMU clock implementation for ux500 platform. 4 * 5 * Copyright (C) 2012 ST-Ericsson SA 6 * Author: Ulf Hansson <ulf.hansson@linaro.org> 7 */ 8 9 #include <linux/clk-provider.h> 10 #include <linux/mfd/dbx500-prcmu.h> 11 #include <linux/slab.h> 12 #include <linux/io.h> 13 #include <linux/err.h> 14 #include "clk.h" 15 16 #define to_clk_prcmu(_hw) container_of(_hw, struct clk_prcmu, hw) 17 18 struct clk_prcmu { 19 struct clk_hw hw; 20 u8 cg_sel; 21 int is_prepared; 22 int is_enabled; 23 int opp_requested; 24 }; 25 26 /* PRCMU clock operations. */ 27 28 static int clk_prcmu_prepare(struct clk_hw *hw) 29 { 30 int ret; 31 struct clk_prcmu *clk = to_clk_prcmu(hw); 32 33 ret = prcmu_request_clock(clk->cg_sel, true); 34 if (!ret) 35 clk->is_prepared = 1; 36 37 return ret; 38 } 39 40 static void clk_prcmu_unprepare(struct clk_hw *hw) 41 { 42 struct clk_prcmu *clk = to_clk_prcmu(hw); 43 if (prcmu_request_clock(clk->cg_sel, false)) 44 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, 45 clk_hw_get_name(hw)); 46 else 47 clk->is_prepared = 0; 48 } 49 50 static int clk_prcmu_is_prepared(struct clk_hw *hw) 51 { 52 struct clk_prcmu *clk = to_clk_prcmu(hw); 53 return clk->is_prepared; 54 } 55 56 static int clk_prcmu_enable(struct clk_hw *hw) 57 { 58 struct clk_prcmu *clk = to_clk_prcmu(hw); 59 clk->is_enabled = 1; 60 return 0; 61 } 62 63 static void clk_prcmu_disable(struct clk_hw *hw) 64 { 65 struct clk_prcmu *clk = to_clk_prcmu(hw); 66 clk->is_enabled = 0; 67 } 68 69 static int clk_prcmu_is_enabled(struct clk_hw *hw) 70 { 71 struct clk_prcmu *clk = to_clk_prcmu(hw); 72 return clk->is_enabled; 73 } 74 75 static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw, 76 unsigned long parent_rate) 77 { 78 struct clk_prcmu *clk = to_clk_prcmu(hw); 79 return prcmu_clock_rate(clk->cg_sel); 80 } 81 82 static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate, 83 unsigned long *parent_rate) 84 { 85 struct clk_prcmu *clk = to_clk_prcmu(hw); 86 return prcmu_round_clock_rate(clk->cg_sel, rate); 87 } 88 89 static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate, 90 unsigned long parent_rate) 91 { 92 struct clk_prcmu *clk = to_clk_prcmu(hw); 93 return prcmu_set_clock_rate(clk->cg_sel, rate); 94 } 95 96 static int clk_prcmu_opp_prepare(struct clk_hw *hw) 97 { 98 int err; 99 struct clk_prcmu *clk = to_clk_prcmu(hw); 100 101 if (!clk->opp_requested) { 102 err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, 103 (char *)clk_hw_get_name(hw), 104 100); 105 if (err) { 106 pr_err("clk_prcmu: %s fail req APE OPP for %s.\n", 107 __func__, clk_hw_get_name(hw)); 108 return err; 109 } 110 clk->opp_requested = 1; 111 } 112 113 err = prcmu_request_clock(clk->cg_sel, true); 114 if (err) { 115 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, 116 (char *)clk_hw_get_name(hw)); 117 clk->opp_requested = 0; 118 return err; 119 } 120 121 clk->is_prepared = 1; 122 return 0; 123 } 124 125 static void clk_prcmu_opp_unprepare(struct clk_hw *hw) 126 { 127 struct clk_prcmu *clk = to_clk_prcmu(hw); 128 129 if (prcmu_request_clock(clk->cg_sel, false)) { 130 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, 131 clk_hw_get_name(hw)); 132 return; 133 } 134 135 if (clk->opp_requested) { 136 prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, 137 (char *)clk_hw_get_name(hw)); 138 clk->opp_requested = 0; 139 } 140 141 clk->is_prepared = 0; 142 } 143 144 static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw) 145 { 146 int err; 147 struct clk_prcmu *clk = to_clk_prcmu(hw); 148 149 if (!clk->opp_requested) { 150 err = prcmu_request_ape_opp_100_voltage(true); 151 if (err) { 152 pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n", 153 __func__, clk_hw_get_name(hw)); 154 return err; 155 } 156 clk->opp_requested = 1; 157 } 158 159 err = prcmu_request_clock(clk->cg_sel, true); 160 if (err) { 161 prcmu_request_ape_opp_100_voltage(false); 162 clk->opp_requested = 0; 163 return err; 164 } 165 166 clk->is_prepared = 1; 167 return 0; 168 } 169 170 static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw) 171 { 172 struct clk_prcmu *clk = to_clk_prcmu(hw); 173 174 if (prcmu_request_clock(clk->cg_sel, false)) { 175 pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, 176 clk_hw_get_name(hw)); 177 return; 178 } 179 180 if (clk->opp_requested) { 181 prcmu_request_ape_opp_100_voltage(false); 182 clk->opp_requested = 0; 183 } 184 185 clk->is_prepared = 0; 186 } 187 188 static const struct clk_ops clk_prcmu_scalable_ops = { 189 .prepare = clk_prcmu_prepare, 190 .unprepare = clk_prcmu_unprepare, 191 .is_prepared = clk_prcmu_is_prepared, 192 .enable = clk_prcmu_enable, 193 .disable = clk_prcmu_disable, 194 .is_enabled = clk_prcmu_is_enabled, 195 .recalc_rate = clk_prcmu_recalc_rate, 196 .round_rate = clk_prcmu_round_rate, 197 .set_rate = clk_prcmu_set_rate, 198 }; 199 200 static const struct clk_ops clk_prcmu_gate_ops = { 201 .prepare = clk_prcmu_prepare, 202 .unprepare = clk_prcmu_unprepare, 203 .is_prepared = clk_prcmu_is_prepared, 204 .enable = clk_prcmu_enable, 205 .disable = clk_prcmu_disable, 206 .is_enabled = clk_prcmu_is_enabled, 207 .recalc_rate = clk_prcmu_recalc_rate, 208 }; 209 210 static const struct clk_ops clk_prcmu_scalable_rate_ops = { 211 .is_enabled = clk_prcmu_is_enabled, 212 .recalc_rate = clk_prcmu_recalc_rate, 213 .round_rate = clk_prcmu_round_rate, 214 .set_rate = clk_prcmu_set_rate, 215 }; 216 217 static const struct clk_ops clk_prcmu_rate_ops = { 218 .is_enabled = clk_prcmu_is_enabled, 219 .recalc_rate = clk_prcmu_recalc_rate, 220 }; 221 222 static const struct clk_ops clk_prcmu_opp_gate_ops = { 223 .prepare = clk_prcmu_opp_prepare, 224 .unprepare = clk_prcmu_opp_unprepare, 225 .is_prepared = clk_prcmu_is_prepared, 226 .enable = clk_prcmu_enable, 227 .disable = clk_prcmu_disable, 228 .is_enabled = clk_prcmu_is_enabled, 229 .recalc_rate = clk_prcmu_recalc_rate, 230 }; 231 232 static const struct clk_ops clk_prcmu_opp_volt_scalable_ops = { 233 .prepare = clk_prcmu_opp_volt_prepare, 234 .unprepare = clk_prcmu_opp_volt_unprepare, 235 .is_prepared = clk_prcmu_is_prepared, 236 .enable = clk_prcmu_enable, 237 .disable = clk_prcmu_disable, 238 .is_enabled = clk_prcmu_is_enabled, 239 .recalc_rate = clk_prcmu_recalc_rate, 240 .round_rate = clk_prcmu_round_rate, 241 .set_rate = clk_prcmu_set_rate, 242 }; 243 244 static struct clk *clk_reg_prcmu(const char *name, 245 const char *parent_name, 246 u8 cg_sel, 247 unsigned long rate, 248 unsigned long flags, 249 const struct clk_ops *clk_prcmu_ops) 250 { 251 struct clk_prcmu *clk; 252 struct clk_init_data clk_prcmu_init; 253 struct clk *clk_reg; 254 255 if (!name) { 256 pr_err("clk_prcmu: %s invalid arguments passed\n", __func__); 257 return ERR_PTR(-EINVAL); 258 } 259 260 clk = kzalloc(sizeof(*clk), GFP_KERNEL); 261 if (!clk) 262 return ERR_PTR(-ENOMEM); 263 264 clk->cg_sel = cg_sel; 265 clk->is_prepared = 1; 266 clk->is_enabled = 1; 267 clk->opp_requested = 0; 268 /* "rate" can be used for changing the initial frequency */ 269 if (rate) 270 prcmu_set_clock_rate(cg_sel, rate); 271 272 clk_prcmu_init.name = name; 273 clk_prcmu_init.ops = clk_prcmu_ops; 274 clk_prcmu_init.flags = flags; 275 clk_prcmu_init.parent_names = (parent_name ? &parent_name : NULL); 276 clk_prcmu_init.num_parents = (parent_name ? 1 : 0); 277 clk->hw.init = &clk_prcmu_init; 278 279 clk_reg = clk_register(NULL, &clk->hw); 280 if (IS_ERR_OR_NULL(clk_reg)) 281 goto free_clk; 282 283 return clk_reg; 284 285 free_clk: 286 kfree(clk); 287 pr_err("clk_prcmu: %s failed to register clk\n", __func__); 288 return ERR_PTR(-ENOMEM); 289 } 290 291 struct clk *clk_reg_prcmu_scalable(const char *name, 292 const char *parent_name, 293 u8 cg_sel, 294 unsigned long rate, 295 unsigned long flags) 296 { 297 return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, 298 &clk_prcmu_scalable_ops); 299 } 300 301 struct clk *clk_reg_prcmu_gate(const char *name, 302 const char *parent_name, 303 u8 cg_sel, 304 unsigned long flags) 305 { 306 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, 307 &clk_prcmu_gate_ops); 308 } 309 310 struct clk *clk_reg_prcmu_scalable_rate(const char *name, 311 const char *parent_name, 312 u8 cg_sel, 313 unsigned long rate, 314 unsigned long flags) 315 { 316 return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, 317 &clk_prcmu_scalable_rate_ops); 318 } 319 320 struct clk *clk_reg_prcmu_rate(const char *name, 321 const char *parent_name, 322 u8 cg_sel, 323 unsigned long flags) 324 { 325 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, 326 &clk_prcmu_rate_ops); 327 } 328 329 struct clk *clk_reg_prcmu_opp_gate(const char *name, 330 const char *parent_name, 331 u8 cg_sel, 332 unsigned long flags) 333 { 334 return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, 335 &clk_prcmu_opp_gate_ops); 336 } 337 338 struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, 339 const char *parent_name, 340 u8 cg_sel, 341 unsigned long rate, 342 unsigned long flags) 343 { 344 return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, 345 &clk_prcmu_opp_volt_scalable_ops); 346 } 347