1 /* 2 * r8a7790 Common Clock Framework support 3 * 4 * Copyright (C) 2013 Renesas Solutions Corp. 5 * 6 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; version 2 of the License. 11 */ 12 13 #include <linux/clk-provider.h> 14 #include <linux/init.h> 15 #include <linux/io.h> 16 #include <linux/kernel.h> 17 #include <linux/notifier.h> 18 #include <linux/of.h> 19 #include <linux/of_address.h> 20 #include <linux/pm.h> 21 #include <linux/slab.h> 22 23 #include "clk-div6.h" 24 25 #define CPG_DIV6_CKSTP BIT(8) 26 #define CPG_DIV6_DIV(d) ((d) & 0x3f) 27 #define CPG_DIV6_DIV_MASK 0x3f 28 29 /** 30 * struct div6_clock - CPG 6 bit divider clock 31 * @hw: handle between common and hardware-specific interfaces 32 * @reg: IO-remapped register 33 * @div: divisor value (1-64) 34 * @src_shift: Shift to access the register bits to select the parent clock 35 * @src_width: Number of register bits to select the parent clock (may be 0) 36 * @parents: Array to map from valid parent clocks indices to hardware indices 37 * @nb: Notifier block to save/restore clock state for system resume 38 */ 39 struct div6_clock { 40 struct clk_hw hw; 41 void __iomem *reg; 42 unsigned int div; 43 u32 src_shift; 44 u32 src_width; 45 u8 *parents; 46 struct notifier_block nb; 47 }; 48 49 #define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) 50 51 static int cpg_div6_clock_enable(struct clk_hw *hw) 52 { 53 struct div6_clock *clock = to_div6_clock(hw); 54 u32 val; 55 56 val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) 57 | CPG_DIV6_DIV(clock->div - 1); 58 clk_writel(val, clock->reg); 59 60 return 0; 61 } 62 63 static void cpg_div6_clock_disable(struct clk_hw *hw) 64 { 65 struct div6_clock *clock = to_div6_clock(hw); 66 u32 val; 67 68 val = clk_readl(clock->reg); 69 val |= CPG_DIV6_CKSTP; 70 /* 71 * DIV6 clocks require the divisor field to be non-zero when stopping 72 * the clock. However, some clocks (e.g. ZB on sh73a0) fail to be 73 * re-enabled later if the divisor field is changed when stopping the 74 * clock 75 */ 76 if (!(val & CPG_DIV6_DIV_MASK)) 77 val |= CPG_DIV6_DIV_MASK; 78 clk_writel(val, clock->reg); 79 } 80 81 static int cpg_div6_clock_is_enabled(struct clk_hw *hw) 82 { 83 struct div6_clock *clock = to_div6_clock(hw); 84 85 return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP); 86 } 87 88 static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw, 89 unsigned long parent_rate) 90 { 91 struct div6_clock *clock = to_div6_clock(hw); 92 93 return parent_rate / clock->div; 94 } 95 96 static unsigned int cpg_div6_clock_calc_div(unsigned long rate, 97 unsigned long parent_rate) 98 { 99 unsigned int div; 100 101 if (!rate) 102 rate = 1; 103 104 div = DIV_ROUND_CLOSEST(parent_rate, rate); 105 return clamp_t(unsigned int, div, 1, 64); 106 } 107 108 static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate, 109 unsigned long *parent_rate) 110 { 111 unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate); 112 113 return *parent_rate / div; 114 } 115 116 static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, 117 unsigned long parent_rate) 118 { 119 struct div6_clock *clock = to_div6_clock(hw); 120 unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate); 121 u32 val; 122 123 clock->div = div; 124 125 val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK; 126 /* Only program the new divisor if the clock isn't stopped. */ 127 if (!(val & CPG_DIV6_CKSTP)) 128 clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); 129 130 return 0; 131 } 132 133 static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) 134 { 135 struct div6_clock *clock = to_div6_clock(hw); 136 unsigned int i; 137 u8 hw_index; 138 139 if (clock->src_width == 0) 140 return 0; 141 142 hw_index = (clk_readl(clock->reg) >> clock->src_shift) & 143 (BIT(clock->src_width) - 1); 144 for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 145 if (clock->parents[i] == hw_index) 146 return i; 147 } 148 149 pr_err("%s: %s DIV6 clock set to invalid parent %u\n", 150 __func__, clk_hw_get_name(hw), hw_index); 151 return 0; 152 } 153 154 static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) 155 { 156 struct div6_clock *clock = to_div6_clock(hw); 157 u8 hw_index; 158 u32 mask; 159 160 if (index >= clk_hw_get_num_parents(hw)) 161 return -EINVAL; 162 163 mask = ~((BIT(clock->src_width) - 1) << clock->src_shift); 164 hw_index = clock->parents[index]; 165 166 clk_writel((clk_readl(clock->reg) & mask) | 167 (hw_index << clock->src_shift), clock->reg); 168 169 return 0; 170 } 171 172 static const struct clk_ops cpg_div6_clock_ops = { 173 .enable = cpg_div6_clock_enable, 174 .disable = cpg_div6_clock_disable, 175 .is_enabled = cpg_div6_clock_is_enabled, 176 .get_parent = cpg_div6_clock_get_parent, 177 .set_parent = cpg_div6_clock_set_parent, 178 .recalc_rate = cpg_div6_clock_recalc_rate, 179 .round_rate = cpg_div6_clock_round_rate, 180 .set_rate = cpg_div6_clock_set_rate, 181 }; 182 183 static int cpg_div6_clock_notifier_call(struct notifier_block *nb, 184 unsigned long action, void *data) 185 { 186 struct div6_clock *clock = container_of(nb, struct div6_clock, nb); 187 188 switch (action) { 189 case PM_EVENT_RESUME: 190 /* 191 * TODO: This does not yet support DIV6 clocks with multiple 192 * parents, as the parent selection bits are not restored. 193 * Fortunately so far such DIV6 clocks are found only on 194 * R/SH-Mobile SoCs, while the resume functionality is only 195 * needed on R-Car Gen3. 196 */ 197 if (__clk_get_enable_count(clock->hw.clk)) 198 cpg_div6_clock_enable(&clock->hw); 199 else 200 cpg_div6_clock_disable(&clock->hw); 201 return NOTIFY_OK; 202 } 203 204 return NOTIFY_DONE; 205 } 206 207 /** 208 * cpg_div6_register - Register a DIV6 clock 209 * @name: Name of the DIV6 clock 210 * @num_parents: Number of parent clocks of the DIV6 clock (1, 4, or 8) 211 * @parent_names: Array containing the names of the parent clocks 212 * @reg: Mapped register used to control the DIV6 clock 213 * @notifiers: Optional notifier chain to save/restore state for system resume 214 */ 215 struct clk * __init cpg_div6_register(const char *name, 216 unsigned int num_parents, 217 const char **parent_names, 218 void __iomem *reg, 219 struct raw_notifier_head *notifiers) 220 { 221 unsigned int valid_parents; 222 struct clk_init_data init; 223 struct div6_clock *clock; 224 struct clk *clk; 225 unsigned int i; 226 227 clock = kzalloc(sizeof(*clock), GFP_KERNEL); 228 if (!clock) 229 return ERR_PTR(-ENOMEM); 230 231 clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), 232 GFP_KERNEL); 233 if (!clock->parents) { 234 clk = ERR_PTR(-ENOMEM); 235 goto free_clock; 236 } 237 238 clock->reg = reg; 239 240 /* 241 * Read the divisor. Disabling the clock overwrites the divisor, so we 242 * need to cache its value for the enable operation. 243 */ 244 clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; 245 246 switch (num_parents) { 247 case 1: 248 /* fixed parent clock */ 249 clock->src_shift = clock->src_width = 0; 250 break; 251 case 4: 252 /* clock with EXSRC bits 6-7 */ 253 clock->src_shift = 6; 254 clock->src_width = 2; 255 break; 256 case 8: 257 /* VCLK with EXSRC bits 12-14 */ 258 clock->src_shift = 12; 259 clock->src_width = 3; 260 break; 261 default: 262 pr_err("%s: invalid number of parents for DIV6 clock %s\n", 263 __func__, name); 264 clk = ERR_PTR(-EINVAL); 265 goto free_parents; 266 } 267 268 /* Filter out invalid parents */ 269 for (i = 0, valid_parents = 0; i < num_parents; i++) { 270 if (parent_names[i]) { 271 parent_names[valid_parents] = parent_names[i]; 272 clock->parents[valid_parents] = i; 273 valid_parents++; 274 } 275 } 276 277 /* Register the clock. */ 278 init.name = name; 279 init.ops = &cpg_div6_clock_ops; 280 init.flags = CLK_IS_BASIC; 281 init.parent_names = parent_names; 282 init.num_parents = valid_parents; 283 284 clock->hw.init = &init; 285 286 clk = clk_register(NULL, &clock->hw); 287 if (IS_ERR(clk)) 288 goto free_parents; 289 290 if (notifiers) { 291 clock->nb.notifier_call = cpg_div6_clock_notifier_call; 292 raw_notifier_chain_register(notifiers, &clock->nb); 293 } 294 295 return clk; 296 297 free_parents: 298 kfree(clock->parents); 299 free_clock: 300 kfree(clock); 301 return clk; 302 } 303 304 static void __init cpg_div6_clock_init(struct device_node *np) 305 { 306 unsigned int num_parents; 307 const char **parent_names; 308 const char *clk_name = np->name; 309 void __iomem *reg; 310 struct clk *clk; 311 unsigned int i; 312 313 num_parents = of_clk_get_parent_count(np); 314 if (num_parents < 1) { 315 pr_err("%s: no parent found for %s DIV6 clock\n", 316 __func__, np->name); 317 return; 318 } 319 320 parent_names = kmalloc_array(num_parents, sizeof(*parent_names), 321 GFP_KERNEL); 322 if (!parent_names) 323 return; 324 325 reg = of_iomap(np, 0); 326 if (reg == NULL) { 327 pr_err("%s: failed to map %s DIV6 clock register\n", 328 __func__, np->name); 329 goto error; 330 } 331 332 /* Parse the DT properties. */ 333 of_property_read_string(np, "clock-output-names", &clk_name); 334 335 for (i = 0; i < num_parents; i++) 336 parent_names[i] = of_clk_get_parent_name(np, i); 337 338 clk = cpg_div6_register(clk_name, num_parents, parent_names, reg, NULL); 339 if (IS_ERR(clk)) { 340 pr_err("%s: failed to register %s DIV6 clock (%ld)\n", 341 __func__, np->name, PTR_ERR(clk)); 342 goto error; 343 } 344 345 of_clk_add_provider(np, of_clk_src_simple_get, clk); 346 347 kfree(parent_names); 348 return; 349 350 error: 351 if (reg) 352 iounmap(reg); 353 kfree(parent_names); 354 } 355 CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init); 356