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 return parent_rate / (usbdiv + 1); 56 } 57 58 static long at91sam9x5_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, 59 unsigned long *parent_rate) 60 { 61 unsigned long div; 62 unsigned long bestrate; 63 unsigned long tmp; 64 65 if (rate >= *parent_rate) 66 return *parent_rate; 67 68 div = *parent_rate / rate; 69 if (div >= SAM9X5_USB_MAX_DIV) 70 return *parent_rate / (SAM9X5_USB_MAX_DIV + 1); 71 72 bestrate = *parent_rate / div; 73 tmp = *parent_rate / (div + 1); 74 if (bestrate - rate > rate - tmp) 75 bestrate = tmp; 76 77 return bestrate; 78 } 79 80 static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) 81 { 82 u32 tmp; 83 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 84 struct at91_pmc *pmc = usb->pmc; 85 86 if (index > 1) 87 return -EINVAL; 88 tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS; 89 if (index) 90 tmp |= AT91_PMC_USBS; 91 pmc_write(pmc, AT91_PMC_USB, tmp); 92 return 0; 93 } 94 95 static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) 96 { 97 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 98 struct at91_pmc *pmc = usb->pmc; 99 100 return pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS; 101 } 102 103 static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, 104 unsigned long parent_rate) 105 { 106 u32 tmp; 107 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 108 struct at91_pmc *pmc = usb->pmc; 109 unsigned long div = parent_rate / rate; 110 111 if (parent_rate % rate || div < 1 || div >= SAM9X5_USB_MAX_DIV) 112 return -EINVAL; 113 114 tmp = pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_OHCIUSBDIV; 115 tmp |= (div - 1) << SAM9X5_USB_DIV_SHIFT; 116 pmc_write(pmc, AT91_PMC_USB, tmp); 117 118 return 0; 119 } 120 121 static const struct clk_ops at91sam9x5_usb_ops = { 122 .recalc_rate = at91sam9x5_clk_usb_recalc_rate, 123 .round_rate = at91sam9x5_clk_usb_round_rate, 124 .get_parent = at91sam9x5_clk_usb_get_parent, 125 .set_parent = at91sam9x5_clk_usb_set_parent, 126 .set_rate = at91sam9x5_clk_usb_set_rate, 127 }; 128 129 static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) 130 { 131 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 132 struct at91_pmc *pmc = usb->pmc; 133 134 pmc_write(pmc, AT91_PMC_USB, 135 pmc_read(pmc, AT91_PMC_USB) | AT91_PMC_USBS); 136 return 0; 137 } 138 139 static void at91sam9n12_clk_usb_disable(struct clk_hw *hw) 140 { 141 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 142 struct at91_pmc *pmc = usb->pmc; 143 144 pmc_write(pmc, AT91_PMC_USB, 145 pmc_read(pmc, AT91_PMC_USB) & ~AT91_PMC_USBS); 146 } 147 148 static int at91sam9n12_clk_usb_is_enabled(struct clk_hw *hw) 149 { 150 struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); 151 struct at91_pmc *pmc = usb->pmc; 152 153 return !!(pmc_read(pmc, AT91_PMC_USB) & AT91_PMC_USBS); 154 } 155 156 static const struct clk_ops at91sam9n12_usb_ops = { 157 .enable = at91sam9n12_clk_usb_enable, 158 .disable = at91sam9n12_clk_usb_disable, 159 .is_enabled = at91sam9n12_clk_usb_is_enabled, 160 .recalc_rate = at91sam9x5_clk_usb_recalc_rate, 161 .round_rate = at91sam9x5_clk_usb_round_rate, 162 .set_rate = at91sam9x5_clk_usb_set_rate, 163 }; 164 165 static struct clk * __init 166 at91sam9x5_clk_register_usb(struct at91_pmc *pmc, const char *name, 167 const char **parent_names, u8 num_parents) 168 { 169 struct at91sam9x5_clk_usb *usb; 170 struct clk *clk = NULL; 171 struct clk_init_data init; 172 173 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 174 if (!usb) 175 return ERR_PTR(-ENOMEM); 176 177 init.name = name; 178 init.ops = &at91sam9x5_usb_ops; 179 init.parent_names = parent_names; 180 init.num_parents = num_parents; 181 init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 182 183 usb->hw.init = &init; 184 usb->pmc = pmc; 185 186 clk = clk_register(NULL, &usb->hw); 187 if (IS_ERR(clk)) 188 kfree(usb); 189 190 return clk; 191 } 192 193 static struct clk * __init 194 at91sam9n12_clk_register_usb(struct at91_pmc *pmc, const char *name, 195 const char *parent_name) 196 { 197 struct at91sam9x5_clk_usb *usb; 198 struct clk *clk = NULL; 199 struct clk_init_data init; 200 201 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 202 if (!usb) 203 return ERR_PTR(-ENOMEM); 204 205 init.name = name; 206 init.ops = &at91sam9n12_usb_ops; 207 init.parent_names = &parent_name; 208 init.num_parents = 1; 209 init.flags = CLK_SET_RATE_GATE; 210 211 usb->hw.init = &init; 212 usb->pmc = pmc; 213 214 clk = clk_register(NULL, &usb->hw); 215 if (IS_ERR(clk)) 216 kfree(usb); 217 218 return clk; 219 } 220 221 static unsigned long at91rm9200_clk_usb_recalc_rate(struct clk_hw *hw, 222 unsigned long parent_rate) 223 { 224 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 225 struct at91_pmc *pmc = usb->pmc; 226 u32 tmp; 227 u8 usbdiv; 228 229 tmp = pmc_read(pmc, AT91_CKGR_PLLBR); 230 usbdiv = (tmp & AT91_PMC_USBDIV) >> RM9200_USB_DIV_SHIFT; 231 if (usb->divisors[usbdiv]) 232 return parent_rate / usb->divisors[usbdiv]; 233 234 return 0; 235 } 236 237 static long at91rm9200_clk_usb_round_rate(struct clk_hw *hw, unsigned long rate, 238 unsigned long *parent_rate) 239 { 240 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 241 unsigned long bestrate = 0; 242 int bestdiff = -1; 243 unsigned long tmprate; 244 int tmpdiff; 245 int i = 0; 246 247 for (i = 0; i < 4; i++) { 248 if (!usb->divisors[i]) 249 continue; 250 tmprate = *parent_rate / usb->divisors[i]; 251 if (tmprate < rate) 252 tmpdiff = rate - tmprate; 253 else 254 tmpdiff = tmprate - rate; 255 256 if (bestdiff < 0 || bestdiff > tmpdiff) { 257 bestrate = tmprate; 258 bestdiff = tmpdiff; 259 } 260 261 if (!bestdiff) 262 break; 263 } 264 265 return bestrate; 266 } 267 268 static int at91rm9200_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, 269 unsigned long parent_rate) 270 { 271 u32 tmp; 272 int i; 273 struct at91rm9200_clk_usb *usb = to_at91rm9200_clk_usb(hw); 274 struct at91_pmc *pmc = usb->pmc; 275 unsigned long div = parent_rate / rate; 276 277 if (parent_rate % rate) 278 return -EINVAL; 279 for (i = 0; i < RM9200_USB_DIV_TAB_SIZE; i++) { 280 if (usb->divisors[i] == div) { 281 tmp = pmc_read(pmc, AT91_CKGR_PLLBR) & 282 ~AT91_PMC_USBDIV; 283 tmp |= i << RM9200_USB_DIV_SHIFT; 284 pmc_write(pmc, AT91_CKGR_PLLBR, tmp); 285 return 0; 286 } 287 } 288 289 return -EINVAL; 290 } 291 292 static const struct clk_ops at91rm9200_usb_ops = { 293 .recalc_rate = at91rm9200_clk_usb_recalc_rate, 294 .round_rate = at91rm9200_clk_usb_round_rate, 295 .set_rate = at91rm9200_clk_usb_set_rate, 296 }; 297 298 static struct clk * __init 299 at91rm9200_clk_register_usb(struct at91_pmc *pmc, const char *name, 300 const char *parent_name, const u32 *divisors) 301 { 302 struct at91rm9200_clk_usb *usb; 303 struct clk *clk = NULL; 304 struct clk_init_data init; 305 306 usb = kzalloc(sizeof(*usb), GFP_KERNEL); 307 if (!usb) 308 return ERR_PTR(-ENOMEM); 309 310 init.name = name; 311 init.ops = &at91rm9200_usb_ops; 312 init.parent_names = &parent_name; 313 init.num_parents = 1; 314 init.flags = 0; 315 316 usb->hw.init = &init; 317 usb->pmc = pmc; 318 memcpy(usb->divisors, divisors, sizeof(usb->divisors)); 319 320 clk = clk_register(NULL, &usb->hw); 321 if (IS_ERR(clk)) 322 kfree(usb); 323 324 return clk; 325 } 326 327 void __init of_at91sam9x5_clk_usb_setup(struct device_node *np, 328 struct at91_pmc *pmc) 329 { 330 struct clk *clk; 331 int i; 332 int num_parents; 333 const char *parent_names[USB_SOURCE_MAX]; 334 const char *name = np->name; 335 336 num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); 337 if (num_parents <= 0 || num_parents > USB_SOURCE_MAX) 338 return; 339 340 for (i = 0; i < num_parents; i++) { 341 parent_names[i] = of_clk_get_parent_name(np, i); 342 if (!parent_names[i]) 343 return; 344 } 345 346 of_property_read_string(np, "clock-output-names", &name); 347 348 clk = at91sam9x5_clk_register_usb(pmc, name, parent_names, num_parents); 349 if (IS_ERR(clk)) 350 return; 351 352 of_clk_add_provider(np, of_clk_src_simple_get, clk); 353 } 354 355 void __init of_at91sam9n12_clk_usb_setup(struct device_node *np, 356 struct at91_pmc *pmc) 357 { 358 struct clk *clk; 359 const char *parent_name; 360 const char *name = np->name; 361 362 parent_name = of_clk_get_parent_name(np, 0); 363 if (!parent_name) 364 return; 365 366 of_property_read_string(np, "clock-output-names", &name); 367 368 clk = at91sam9n12_clk_register_usb(pmc, name, parent_name); 369 if (IS_ERR(clk)) 370 return; 371 372 of_clk_add_provider(np, of_clk_src_simple_get, clk); 373 } 374 375 void __init of_at91rm9200_clk_usb_setup(struct device_node *np, 376 struct at91_pmc *pmc) 377 { 378 struct clk *clk; 379 const char *parent_name; 380 const char *name = np->name; 381 u32 divisors[4] = {0, 0, 0, 0}; 382 383 parent_name = of_clk_get_parent_name(np, 0); 384 if (!parent_name) 385 return; 386 387 of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4); 388 if (!divisors[0]) 389 return; 390 391 of_property_read_string(np, "clock-output-names", &name); 392 393 clk = at91rm9200_clk_register_usb(pmc, name, parent_name, divisors); 394 if (IS_ERR(clk)) 395 return; 396 397 of_clk_add_provider(np, of_clk_src_simple_get, clk); 398 } 399