1 /* 2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 */ 10 11 #include <linux/clk-provider.h> 12 #include <linux/clkdev.h> 13 #include <linux/clk/at91_pmc.h> 14 #include <linux/of.h> 15 #include <linux/of_address.h> 16 #include <linux/io.h> 17 18 #include "pmc.h" 19 20 #define USB_SOURCE_MAX 2 21 22 #define SAM9X5_USB_DIV_SHIFT 8 23 #define SAM9X5_USB_MAX_DIV 0xf 24 25 #define RM9200_USB_DIV_SHIFT 28 26 #define RM9200_USB_DIV_TAB_SIZE 4 27 28 struct at91sam9x5_clk_usb { 29 struct clk_hw hw; 30 struct at91_pmc *pmc; 31 }; 32 33 #define to_at91sam9x5_clk_usb(hw) \ 34 container_of(hw, struct at91sam9x5_clk_usb, hw) 35 36 struct at91rm9200_clk_usb { 37 struct clk_hw hw; 38 struct at91_pmc *pmc; 39 u32 divisors[4]; 40 }; 41 42 #define to_at91rm9200_clk_usb(hw) \ 43 container_of(hw, struct at91rm9200_clk_usb, hw) 44 45 static unsigned long at91sam9x5_clk_usb_recalc_rate(struct clk_hw *hw, 46 unsigned long parent_rate) 47 { 48 u32 tmp; 49 u8 usbdiv; 50 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 51 struct at91_pmc *pmc = usb->pmc; 52 53 tmp = pmc_read(pmc, AT91_PMC_USB); 54 usbdiv = (tmp & AT91_PMC_OHCIUSBDIV) >> SAM9X5_USB_DIV_SHIFT; 55 56 return DIV_ROUND_CLOSEST(parent_rate, (usbdiv + 1)); 57 } 58 59 static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, 60 unsigned long *parent_rate) 61 { 62 unsigned long div; 63 64 if (!rate) 65 return -EINVAL; 66 67 if (rate >= *parent_rate) 68 return *parent_rate; 69 70 div = DIV_ROUND_CLOSEST(*parent_rate, rate); 71 if (div > SAM9X5_USB_MAX_DIV + 1) 72 div = SAM9X5_USB_MAX_DIV + 1; 73 74 return DIV_ROUND_CLOSEST(*parent_rate, div); 75 } 76 77 static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) 78 { 79 u32 tmp; 80 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 81 struct at91_pmc *pmc = usb->pmc; 82 83 if (index > 1) 84 return -EINVAL; 85 tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS; 86 if (index) 87 tmp |= AT91_PMC_USBS; 88 pmc_write(pmc, AT91_PMC_USB, tmp); 89 return 0; 90 } 91 92 static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) 93 { 94 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 95 struct at91_pmc *pmc = usb->pmc; 96 97 return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS; 98 } 99 100 static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, 101 unsigned long parent_rate) 102 { 103 u32 tmp; 104 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 105 struct at91_pmc *pmc = usb->pmc; 106 unsigned long div; 107 108 if (!rate) 109 return -EINVAL; 110 111 div = DIV_ROUND_CLOSEST(parent_rate, rate); 112 if (div > SAM9X5_USB_MAX_DIV + 1 || !div) 113 return -EINVAL; 114 115 tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; 116 tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT; 117 pmc_write(pmc, AT91_PMC_USB, tmp); 118 119 return 0; 120 } 121 122 static const struct clk_ops at91sam9x5_usb_ops = { 123 .recalc_rate = at91sam9x5_clk_usb_recalc_rate, 124 .round_rate = at91sam9x5_clk_usb_round_rate, 125 .get_parent = at91sam9x5_clk_usb_get_parent, 126 .set_parent = at91sam9x5_clk_usb_set_parent, 127 .set_rate = at91sam9x5_clk_usb_set_rate, 128 }; 129 130 static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) 131 { 132 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 133 struct at91_pmc *pmc = usb->pmc; 134 135 pmc_write(pmc, AT91_PMC_USB, 136 pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS); 137 return 0; 138 } 139 140 static void at91sam9n12_clk_usb_disable(struct clk_hw *hw) 141 { 142 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 143 struct at91_pmc *pmc = usb->pmc; 144 145 pmc_write(pmc, AT91_PMC_USB, 146 pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS); 147 } 148 149 static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw) 150 { 151 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 152 struct at91_pmc *pmc = usb->pmc; 153 154 return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS); 155 } 156 157 static const struct clk_ops at91sam9n12_usb_ops = { 158 .enable = at91sam9n12_clk_usb_enable, 159 .disable = at91sam9n12_clk_usb_disable, 160 .is_enabled = at91sam9n12_clk_usb_is_enabled, 161 .recalc_rate = at91sam9x5_clk_usb_recalc_rate, 162 .round_rate = at91sam9x5_clk_usb_round_rate, 163 .set_rate = at91sam9x5_clk_usb_set_rate, 164 }; 165 166 static struct clk * __init 167 at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, 168 const char **parent_names, u8 num_parents) 169 { 170 struct at91sam9x5_clk_usb *usb; 171 struct clk *clk = NULL; 172 struct clk_init_data init; 173 174 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 175 if (!usb) 176 return ERR_PTR(-ENOMEM); 177 178 init.name = name; 179 init.ops = &at91sam9x5_usb_ops; 180 init.parent_names = parent_names; 181 init.num_parents = num_parents; 182 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 183 184 usb->hw.init = &init; 185 usb->pmc = pmc; 186 187 clk = clk_register(NULL, &usb->hw); 188 if (IS_ERR(clk)) 189 kfree(usb); 190 191 return clk; 192 } 193 194 static struct clk * __init 195 at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name, 196 const char *parent_name) 197 { 198 struct at91sam9x5_clk_usb *usb; 199 struct clk *clk = NULL; 200 struct clk_init_data init; 201 202 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 203 if (!usb) 204 return ERR_PTR(-ENOMEM); 205 206 init.name = name; 207 init.ops = &at91sam9n12_usb_ops; 208 init.parent_names = &parent_name; 209 init.num_parents = 1; 210 init.flags = CLK_SET_RATE_GATE; 211 212 usb->hw.init = &init; 213 usb->pmc = pmc; 214 215 clk = clk_register(NULL, &usb->hw); 216 if (IS_ERR(clk)) 217 kfree(usb); 218 219 return clk; 220 } 221 222 static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw, 223 unsigned long parent_rate) 224 { 225 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 226 struct at91_pmc *pmc = usb->pmc; 227 u32 tmp; 228 u8 usbdiv; 229 230 tmp = pmc_read(pmc, AT91_CKGR_PLLBR); 231 usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT; 232 if (usb->divisors[usbdiv]) 233 return parent_rate / usb->divisors[usbdiv]; 234 235 return 0; 236 } 237 238 static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, 239 unsigned long *parent_rate) 240 { 241 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 242 struct clk *parent = __clk_get_parent(hw->clk); 243 unsigned long bestrate = 0; 244 int bestdiff = -1; 245 unsigned long tmprate; 246 int tmpdiff; 247 int i = 0; 248 249 for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { 250 unsigned long tmp_parent_rate; 251 252 if (!usb->divisors[i]) 253 continue; 254 255 tmp_parent_rate = rate * usb->divisors[i]; 256 tmp_parent_rate = __clk_round_rate(parent, tmp_parent_rate); 257 tmprate = DIV_ROUND_CLOSEST(tmp_parent_rate, usb->divisors[i]); 258 if (tmprate < rate) 259 tmpdiff = rate - tmprate; 260 else 261 tmpdiff = tmprate - rate; 262 263 if (bestdiff < 0 || bestdiff > tmpdiff) { 264 bestrate = tmprate; 265 bestdiff = tmpdiff; 266 *parent_rate = tmp_parent_rate; 267 } 268 269 if (!bestdiff) 270 break; 271 } 272 273 return bestrate; 274 } 275 276 static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, 277 unsigned long parent_rate) 278 { 279 u32 tmp; 280 int i; 281 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 282 struct at91_pmc *pmc = usb->pmc; 283 unsigned long div; 284 285 if (!rate) 286 return -EINVAL; 287 288 div = DIV_ROUND_CLOSEST(parent_rate, rate); 289 290 for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { 291 if (usb->divisors[i] == div) { 292 tmp = pmc_read(pmc, AT91_CKGR_PLLBR) & 293 ~AT91_PMC_USBDIV; 294 tmp |= i << RM9200_USB_DIV_SHIFT; 295 pmc_write(pmc, AT91_CKGR_PLLBR, tmp); 296 return 0; 297 } 298 } 299 300 return -EINVAL; 301 } 302 303 static const struct clk_ops at91rm9200_usb_ops = { 304 .recalc_rate = at91rm9200_clk_usb_recalc_rate, 305 .round_rate = at91rm9200_clk_usb_round_rate, 306 .set_rate = at91rm9200_clk_usb_set_rate, 307 }; 308 309 static struct clk * __init 310 at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, 311 const char *parent_name, const u32 *divisors) 312 { 313 struct at91rm9200_clk_usb *usb; 314 struct clk *clk = NULL; 315 struct clk_init_data init; 316 317 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 318 if (!usb) 319 return ERR_PTR(-ENOMEM); 320 321 init.name = name; 322 init.ops = &at91rm9200_usb_ops; 323 init.parent_names = &parent_name; 324 init.num_parents = 1; 325 init.flags = CLK_SET_RATE_PARENT; 326 327 usb->hw.init = &init; 328 usb->pmc = pmc; 329 memcpy(usb->divisors, divisors, sizeof(usb->divisors)); 330 331 clk = clk_register(NULL, &usb->hw); 332 if (IS_ERR(clk)) 333 kfree(usb); 334 335 return clk; 336 } 337 338 void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, 339 struct at91_pmc *pmc) 340 { 341 struct clk *clk; 342 int i; 343 int num_parents; 344 const char *parent_names[USB_SOURCE_MAX]; 345 const char *name = np->name; 346 347 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 348 if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) 349 return; 350 351 for (i = 0; i < num_parents; i++) { 352 parent_names[i] = of_clk_get_parent_name(np, i); 353 if (!parent_names[i]) 354 return; 355 } 356 357 of_property_read_string(np, "clock-output-names", &name); 358 359 clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents); 360 if (IS_ERR(clk)) 361 return; 362 363 of_clk_add_provider(np, of_clk_src_simple_get, clk); 364 } 365 366 void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, 367 struct at91_pmc *pmc) 368 { 369 struct clk *clk; 370 const char *parent_name; 371 const char *name = np->name; 372 373 parent_name = of_clk_get_parent_name(np, 0); 374 if (!parent_name) 375 return; 376 377 of_property_read_string(np, "clock-output-names", &name); 378 379 clk = at91sam9n12_clk_register_usb(pmc, name, parent_name); 380 if (IS_ERR(clk)) 381 return; 382 383 of_clk_add_provider(np, of_clk_src_simple_get, clk); 384 } 385 386 void __init of_at91rm9200_clk_usb_setup(struct device_node *np, 387 struct at91_pmc *pmc) 388 { 389 struct clk *clk; 390 const char *parent_name; 391 const char *name = np->name; 392 u32 divisors[4] = {0, 0, 0, 0}; 393 394 parent_name = of_clk_get_parent_name(np, 0); 395 if (!parent_name) 396 return; 397 398 of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4); 399 if (!divisors[0]) 400 return; 401 402 of_property_read_string(np, "clock-output-names", &name); 403 404 clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors); 405 if (IS_ERR(clk)) 406 return; 407 408 of_clk_add_provider(np, of_clk_src_simple_get, clk); 409 } 410