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/of.h> 18 #include <linux/of_address.h> 19 #include <linux/slab.h> 20 21 #include "clk-div6.h" 22 23 #define CPG_DIV6_CKSTP BIT(8) 24 #define CPG_DIV6_DIV(d) ((d) & 0x3f) 25 #define CPG_DIV6_DIV_MASK 0x3f 26 27 /** 28 * struct div6_clock - CPG 6 bit divider clock 29 * @hw: handle between common and hardware-specific interfaces 30 * @reg: IO-remapped register 31 * @div: divisor value (1-64) 32 */ 33 struct div6_clock { 34 struct clk_hw hw; 35 void __iomem *reg; 36 unsigned int div; 37 u32 src_shift; 38 u32 src_width; 39 u8 *parents; 40 }; 41 42 #define to_div6_clock(_hw) container_of(_hw, struct div6_clock, hw) 43 44 static int cpg_div6_clock_enable(struct clk_hw *hw) 45 { 46 struct div6_clock *clock = to_div6_clock(hw); 47 u32 val; 48 49 val = (clk_readl(clock->reg) & ~(CPG_DIV6_DIV_MASK | CPG_DIV6_CKSTP)) 50 | CPG_DIV6_DIV(clock->div - 1); 51 clk_writel(val, clock->reg); 52 53 return 0; 54 } 55 56 static void cpg_div6_clock_disable(struct clk_hw *hw) 57 { 58 struct div6_clock *clock = to_div6_clock(hw); 59 u32 val; 60 61 val = clk_readl(clock->reg); 62 val |= CPG_DIV6_CKSTP; 63 /* 64 * DIV6 clocks require the divisor field to be non-zero when stopping 65 * the clock. However, some clocks (e.g. ZB on sh73a0) fail to be 66 * re-enabled later if the divisor field is changed when stopping the 67 * clock 68 */ 69 if (!(val & CPG_DIV6_DIV_MASK)) 70 val |= CPG_DIV6_DIV_MASK; 71 clk_writel(val, clock->reg); 72 } 73 74 static int cpg_div6_clock_is_enabled(struct clk_hw *hw) 75 { 76 struct div6_clock *clock = to_div6_clock(hw); 77 78 return !(clk_readl(clock->reg) & CPG_DIV6_CKSTP); 79 } 80 81 static unsigned long cpg_div6_clock_recalc_rate(struct clk_hw *hw, 82 unsigned long parent_rate) 83 { 84 struct div6_clock *clock = to_div6_clock(hw); 85 86 return parent_rate / clock->div; 87 } 88 89 static unsigned int cpg_div6_clock_calc_div(unsigned long rate, 90 unsigned long parent_rate) 91 { 92 unsigned int div; 93 94 if (!rate) 95 rate = 1; 96 97 div = DIV_ROUND_CLOSEST(parent_rate, rate); 98 return clamp_t(unsigned int, div, 1, 64); 99 } 100 101 static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate, 102 unsigned long *parent_rate) 103 { 104 unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate); 105 106 return *parent_rate / div; 107 } 108 109 static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, 110 unsigned long parent_rate) 111 { 112 struct div6_clock *clock = to_div6_clock(hw); 113 unsigned int div = cpg_div6_clock_calc_div(rate, parent_rate); 114 u32 val; 115 116 clock->div = div; 117 118 val = clk_readl(clock->reg) & ~CPG_DIV6_DIV_MASK; 119 /* Only program the new divisor if the clock isn't stopped. */ 120 if (!(val & CPG_DIV6_CKSTP)) 121 clk_writel(val | CPG_DIV6_DIV(clock->div - 1), clock->reg); 122 123 return 0; 124 } 125 126 static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) 127 { 128 struct div6_clock *clock = to_div6_clock(hw); 129 unsigned int i; 130 u8 hw_index; 131 132 if (clock->src_width == 0) 133 return 0; 134 135 hw_index = (clk_readl(clock->reg) >> clock->src_shift) & 136 (BIT(clock->src_width) - 1); 137 for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 138 if (clock->parents[i] == hw_index) 139 return i; 140 } 141 142 pr_err("%s: %s DIV6 clock set to invalid parent %u\n", 143 __func__, clk_hw_get_name(hw), hw_index); 144 return 0; 145 } 146 147 static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) 148 { 149 struct div6_clock *clock = to_div6_clock(hw); 150 u8 hw_index; 151 u32 mask; 152 153 if (index >= clk_hw_get_num_parents(hw)) 154 return -EINVAL; 155 156 mask = ~((BIT(clock->src_width) - 1) << clock->src_shift); 157 hw_index = clock->parents[index]; 158 159 clk_writel((clk_readl(clock->reg) & mask) | 160 (hw_index << clock->src_shift), clock->reg); 161 162 return 0; 163 } 164 165 static const struct clk_ops cpg_div6_clock_ops = { 166 .enable = cpg_div6_clock_enable, 167 .disable = cpg_div6_clock_disable, 168 .is_enabled = cpg_div6_clock_is_enabled, 169 .get_parent = cpg_div6_clock_get_parent, 170 .set_parent = cpg_div6_clock_set_parent, 171 .recalc_rate = cpg_div6_clock_recalc_rate, 172 .round_rate = cpg_div6_clock_round_rate, 173 .set_rate = cpg_div6_clock_set_rate, 174 }; 175 176 177 /** 178 * cpg_div6_register - Register a DIV6 clock 179 * @name: Name of the DIV6 clock 180 * @num_parents: Number of parent clocks of the DIV6 clock (1, 4, or 8) 181 * @parent_names: Array containing the names of the parent clocks 182 * @reg: Mapped register used to control the DIV6 clock 183 */ 184 struct clk * __init cpg_div6_register(const char *name, 185 unsigned int num_parents, 186 const char **parent_names, 187 void __iomem *reg) 188 { 189 unsigned int valid_parents; 190 struct clk_init_data init; 191 struct div6_clock *clock; 192 struct clk *clk; 193 unsigned int i; 194 195 clock = kzalloc(sizeof(*clock), GFP_KERNEL); 196 if (!clock) 197 return ERR_PTR(-ENOMEM); 198 199 clock->parents = kmalloc_array(num_parents, sizeof(*clock->parents), 200 GFP_KERNEL); 201 if (!clock->parents) { 202 clk = ERR_PTR(-ENOMEM); 203 goto free_clock; 204 } 205 206 clock->reg = reg; 207 208 /* 209 * Read the divisor. Disabling the clock overwrites the divisor, so we 210 * need to cache its value for the enable operation. 211 */ 212 clock->div = (clk_readl(clock->reg) & CPG_DIV6_DIV_MASK) + 1; 213 214 switch (num_parents) { 215 case 1: 216 /* fixed parent clock */ 217 clock->src_shift = clock->src_width = 0; 218 break; 219 case 4: 220 /* clock with EXSRC bits 6-7 */ 221 clock->src_shift = 6; 222 clock->src_width = 2; 223 break; 224 case 8: 225 /* VCLK with EXSRC bits 12-14 */ 226 clock->src_shift = 12; 227 clock->src_width = 3; 228 break; 229 default: 230 pr_err("%s: invalid number of parents for DIV6 clock %s\n", 231 __func__, name); 232 clk = ERR_PTR(-EINVAL); 233 goto free_parents; 234 } 235 236 /* Filter out invalid parents */ 237 for (i = 0, valid_parents = 0; i < num_parents; i++) { 238 if (parent_names[i]) { 239 parent_names[valid_parents] = parent_names[i]; 240 clock->parents[valid_parents] = i; 241 valid_parents++; 242 } 243 } 244 245 /* Register the clock. */ 246 init.name = name; 247 init.ops = &cpg_div6_clock_ops; 248 init.flags = CLK_IS_BASIC; 249 init.parent_names = parent_names; 250 init.num_parents = valid_parents; 251 252 clock->hw.init = &init; 253 254 clk = clk_register(NULL, &clock->hw); 255 if (IS_ERR(clk)) 256 goto free_parents; 257 258 return clk; 259 260 free_parents: 261 kfree(clock->parents); 262 free_clock: 263 kfree(clock); 264 return clk; 265 } 266 267 static void __init cpg_div6_clock_init(struct device_node *np) 268 { 269 unsigned int num_parents; 270 const char **parent_names; 271 const char *clk_name = np->name; 272 void __iomem *reg; 273 struct clk *clk; 274 unsigned int i; 275 276 num_parents = of_clk_get_parent_count(np); 277 if (num_parents < 1) { 278 pr_err("%s: no parent found for %s DIV6 clock\n", 279 __func__, np->name); 280 return; 281 } 282 283 parent_names = kmalloc_array(num_parents, sizeof(*parent_names), 284 GFP_KERNEL); 285 if (!parent_names) 286 return; 287 288 reg = of_iomap(np, 0); 289 if (reg == NULL) { 290 pr_err("%s: failed to map %s DIV6 clock register\n", 291 __func__, np->name); 292 goto error; 293 } 294 295 /* Parse the DT properties. */ 296 of_property_read_string(np, "clock-output-names", &clk_name); 297 298 for (i = 0; i < num_parents; i++) 299 parent_names[i] = of_clk_get_parent_name(np, i); 300 301 clk = cpg_div6_register(clk_name, num_parents, parent_names, reg); 302 if (IS_ERR(clk)) { 303 pr_err("%s: failed to register %s DIV6 clock (%ld)\n", 304 __func__, np->name, PTR_ERR(clk)); 305 goto error; 306 } 307 308 of_clk_add_provider(np, of_clk_src_simple_get, clk); 309 310 kfree(parent_names); 311 return; 312 313 error: 314 if (reg) 315 iounmap(reg); 316 kfree(parent_names); 317 } 318 CLK_OF_DECLARE(cpg_div6_clk, "renesas,cpg-div6-clock", cpg_div6_clock_init); 319