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