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 #include <linux/interrupt.h> 18 #include <linux/irq.h> 19 #include <linux/irqchip/chained_irq.h> 20 #include <linux/irqdomain.h> 21 #include <linux/of_irq.h> 22 23 #include <asm/proc-fns.h> 24 25 #include "pmc.h" 26 27 void __iomem *at91_pmc_base; 28 EXPORT_SYMBOL_GPL(at91_pmc_base); 29 30 void at91rm9200_idle(void) 31 { 32 /* 33 * Disable the processor clock. The processor will be automatically 34 * re-enabled by an interrupt or by a reset. 35 */ 36 at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); 37 } 38 39 void at91sam9_idle(void) 40 { 41 at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK); 42 cpu_do_idle(); 43 } 44 45 int of_at91_get_clk_range(struct device_node *np, const char *propname, 46 struct clk_range *range) 47 { 48 u32 min, max; 49 int ret; 50 51 ret = of_property_read_u32_index(np, propname, 0, &min); 52 if (ret) 53 return ret; 54 55 ret = of_property_read_u32_index(np, propname, 1, &max); 56 if (ret) 57 return ret; 58 59 if (range) { 60 range->min = min; 61 range->max = max; 62 } 63 64 return 0; 65 } 66 EXPORT_SYMBOL_GPL(of_at91_get_clk_range); 67 68 static void pmc_irq_mask(struct irq_data *d) 69 { 70 struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); 71 72 pmc_write(pmc, AT91_PMC_IDR, 1 << d->hwirq); 73 } 74 75 static void pmc_irq_unmask(struct irq_data *d) 76 { 77 struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); 78 79 pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq); 80 } 81 82 static int pmc_irq_set_type(struct irq_data *d, unsigned type) 83 { 84 if (type != IRQ_TYPE_LEVEL_HIGH) { 85 pr_warn("PMC: type not supported (support only IRQ_TYPE_LEVEL_HIGH type)\n"); 86 return -EINVAL; 87 } 88 89 return 0; 90 } 91 92 static void pmc_irq_suspend(struct irq_data *d) 93 { 94 struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); 95 96 pmc->imr = pmc_read(pmc, AT91_PMC_IMR); 97 pmc_write(pmc, AT91_PMC_IDR, pmc->imr); 98 } 99 100 static void pmc_irq_resume(struct irq_data *d) 101 { 102 struct at91_pmc *pmc = irq_data_get_irq_chip_data(d); 103 104 pmc_write(pmc, AT91_PMC_IER, pmc->imr); 105 } 106 107 static struct irq_chip pmc_irq = { 108 .name = "PMC", 109 .irq_disable = pmc_irq_mask, 110 .irq_mask = pmc_irq_mask, 111 .irq_unmask = pmc_irq_unmask, 112 .irq_set_type = pmc_irq_set_type, 113 .irq_suspend = pmc_irq_suspend, 114 .irq_resume = pmc_irq_resume, 115 }; 116 117 static struct lock_class_key pmc_lock_class; 118 119 static int pmc_irq_map(struct irq_domain *h, unsigned int virq, 120 irq_hw_number_t hw) 121 { 122 struct at91_pmc *pmc = h->host_data; 123 124 irq_set_lockdep_class(virq, &pmc_lock_class); 125 126 irq_set_chip_and_handler(virq, &pmc_irq, 127 handle_level_irq); 128 irq_set_chip_data(virq, pmc); 129 130 return 0; 131 } 132 133 static int pmc_irq_domain_xlate(struct irq_domain *d, 134 struct device_node *ctrlr, 135 const u32 *intspec, unsigned int intsize, 136 irq_hw_number_t *out_hwirq, 137 unsigned int *out_type) 138 { 139 struct at91_pmc *pmc = d->host_data; 140 const struct at91_pmc_caps *caps = pmc->caps; 141 142 if (WARN_ON(intsize < 1)) 143 return -EINVAL; 144 145 *out_hwirq = intspec[0]; 146 147 if (!(caps->available_irqs & (1 << *out_hwirq))) 148 return -EINVAL; 149 150 *out_type = IRQ_TYPE_LEVEL_HIGH; 151 152 return 0; 153 } 154 155 static const struct irq_domain_ops pmc_irq_ops = { 156 .map = pmc_irq_map, 157 .xlate = pmc_irq_domain_xlate, 158 }; 159 160 static irqreturn_t pmc_irq_handler(int irq, void *data) 161 { 162 struct at91_pmc *pmc = (struct at91_pmc *)data; 163 unsigned long sr; 164 int n; 165 166 sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR); 167 if (!sr) 168 return IRQ_NONE; 169 170 for_each_set_bit(n, &sr, BITS_PER_LONG) 171 generic_handle_irq(irq_find_mapping(pmc->irqdomain, n)); 172 173 return IRQ_HANDLED; 174 } 175 176 static const struct at91_pmc_caps at91rm9200_caps = { 177 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | 178 AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | 179 AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | 180 AT91_PMC_PCK3RDY, 181 }; 182 183 static const struct at91_pmc_caps at91sam9260_caps = { 184 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | 185 AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | 186 AT91_PMC_PCK1RDY, 187 }; 188 189 static const struct at91_pmc_caps at91sam9g45_caps = { 190 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 191 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 192 AT91_PMC_PCK1RDY, 193 }; 194 195 static const struct at91_pmc_caps at91sam9n12_caps = { 196 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | 197 AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | 198 AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | 199 AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, 200 }; 201 202 static const struct at91_pmc_caps at91sam9x5_caps = { 203 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 204 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 205 AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | 206 AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, 207 }; 208 209 static const struct at91_pmc_caps sama5d2_caps = { 210 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 211 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 212 AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | 213 AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | 214 AT91_PMC_CFDEV | AT91_PMC_GCKRDY, 215 }; 216 217 static const struct at91_pmc_caps sama5d3_caps = { 218 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 219 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 220 AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | 221 AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | 222 AT91_PMC_CFDEV, 223 }; 224 225 static struct at91_pmc *__init at91_pmc_init(struct device_node *np, 226 void __iomem *regbase, int virq, 227 const struct at91_pmc_caps *caps) 228 { 229 struct at91_pmc *pmc; 230 231 if (!regbase || !virq || !caps) 232 return NULL; 233 234 at91_pmc_base = regbase; 235 236 pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); 237 if (!pmc) 238 return NULL; 239 240 spin_lock_init(&pmc->lock); 241 pmc->regbase = regbase; 242 pmc->virq = virq; 243 pmc->caps = caps; 244 245 pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc); 246 247 if (!pmc->irqdomain) 248 goto out_free_pmc; 249 250 pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); 251 if (request_irq(pmc->virq, pmc_irq_handler, 252 IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc)) 253 goto out_remove_irqdomain; 254 255 return pmc; 256 257 out_remove_irqdomain: 258 irq_domain_remove(pmc->irqdomain); 259 out_free_pmc: 260 kfree(pmc); 261 262 return NULL; 263 } 264 265 static const struct of_device_id pmc_clk_ids[] __initconst = { 266 /* Slow oscillator */ 267 { 268 .compatible = "atmel,at91sam9260-clk-slow", 269 .data = of_at91sam9260_clk_slow_setup, 270 }, 271 /* Main clock */ 272 { 273 .compatible = "atmel,at91rm9200-clk-main-osc", 274 .data = of_at91rm9200_clk_main_osc_setup, 275 }, 276 { 277 .compatible = "atmel,at91sam9x5-clk-main-rc-osc", 278 .data = of_at91sam9x5_clk_main_rc_osc_setup, 279 }, 280 { 281 .compatible = "atmel,at91rm9200-clk-main", 282 .data = of_at91rm9200_clk_main_setup, 283 }, 284 { 285 .compatible = "atmel,at91sam9x5-clk-main", 286 .data = of_at91sam9x5_clk_main_setup, 287 }, 288 /* PLL clocks */ 289 { 290 .compatible = "atmel,at91rm9200-clk-pll", 291 .data = of_at91rm9200_clk_pll_setup, 292 }, 293 { 294 .compatible = "atmel,at91sam9g45-clk-pll", 295 .data = of_at91sam9g45_clk_pll_setup, 296 }, 297 { 298 .compatible = "atmel,at91sam9g20-clk-pllb", 299 .data = of_at91sam9g20_clk_pllb_setup, 300 }, 301 { 302 .compatible = "atmel,sama5d3-clk-pll", 303 .data = of_sama5d3_clk_pll_setup, 304 }, 305 { 306 .compatible = "atmel,at91sam9x5-clk-plldiv", 307 .data = of_at91sam9x5_clk_plldiv_setup, 308 }, 309 /* Master clock */ 310 { 311 .compatible = "atmel,at91rm9200-clk-master", 312 .data = of_at91rm9200_clk_master_setup, 313 }, 314 { 315 .compatible = "atmel,at91sam9x5-clk-master", 316 .data = of_at91sam9x5_clk_master_setup, 317 }, 318 /* System clocks */ 319 { 320 .compatible = "atmel,at91rm9200-clk-system", 321 .data = of_at91rm9200_clk_sys_setup, 322 }, 323 /* Peripheral clocks */ 324 { 325 .compatible = "atmel,at91rm9200-clk-peripheral", 326 .data = of_at91rm9200_clk_periph_setup, 327 }, 328 { 329 .compatible = "atmel,at91sam9x5-clk-peripheral", 330 .data = of_at91sam9x5_clk_periph_setup, 331 }, 332 /* Programmable clocks */ 333 { 334 .compatible = "atmel,at91rm9200-clk-programmable", 335 .data = of_at91rm9200_clk_prog_setup, 336 }, 337 { 338 .compatible = "atmel,at91sam9g45-clk-programmable", 339 .data = of_at91sam9g45_clk_prog_setup, 340 }, 341 { 342 .compatible = "atmel,at91sam9x5-clk-programmable", 343 .data = of_at91sam9x5_clk_prog_setup, 344 }, 345 /* UTMI clock */ 346 #if defined(CONFIG_HAVE_AT91_UTMI) 347 { 348 .compatible = "atmel,at91sam9x5-clk-utmi", 349 .data = of_at91sam9x5_clk_utmi_setup, 350 }, 351 #endif 352 /* USB clock */ 353 #if defined(CONFIG_HAVE_AT91_USB_CLK) 354 { 355 .compatible = "atmel,at91rm9200-clk-usb", 356 .data = of_at91rm9200_clk_usb_setup, 357 }, 358 { 359 .compatible = "atmel,at91sam9x5-clk-usb", 360 .data = of_at91sam9x5_clk_usb_setup, 361 }, 362 { 363 .compatible = "atmel,at91sam9n12-clk-usb", 364 .data = of_at91sam9n12_clk_usb_setup, 365 }, 366 #endif 367 /* SMD clock */ 368 #if defined(CONFIG_HAVE_AT91_SMD) 369 { 370 .compatible = "atmel,at91sam9x5-clk-smd", 371 .data = of_at91sam9x5_clk_smd_setup, 372 }, 373 #endif 374 #if defined(CONFIG_HAVE_AT91_H32MX) 375 { 376 .compatible = "atmel,sama5d4-clk-h32mx", 377 .data = of_sama5d4_clk_h32mx_setup, 378 }, 379 #endif 380 #if defined(CONFIG_HAVE_AT91_GENERATED_CLK) 381 { 382 .compatible = "atmel,sama5d2-clk-generated", 383 .data = of_sama5d2_clk_generated_setup, 384 }, 385 #endif 386 { /*sentinel*/ } 387 }; 388 389 static void __init of_at91_pmc_setup(struct device_node *np, 390 const struct at91_pmc_caps *caps) 391 { 392 struct at91_pmc *pmc; 393 struct device_node *childnp; 394 void (*clk_setup)(struct device_node *, struct at91_pmc *); 395 const struct of_device_id *clk_id; 396 void __iomem *regbase = of_iomap(np, 0); 397 int virq; 398 399 if (!regbase) 400 return; 401 402 virq = irq_of_parse_and_map(np, 0); 403 if (!virq) 404 return; 405 406 pmc = at91_pmc_init(np, regbase, virq, caps); 407 if (!pmc) 408 return; 409 for_each_child_of_node(np, childnp) { 410 clk_id = of_match_node(pmc_clk_ids, childnp); 411 if (!clk_id) 412 continue; 413 clk_setup = clk_id->data; 414 clk_setup(childnp, pmc); 415 } 416 } 417 418 static void __init of_at91rm9200_pmc_setup(struct device_node *np) 419 { 420 of_at91_pmc_setup(np, &at91rm9200_caps); 421 } 422 CLK_OF_DECLARE(at91rm9200_clk_pmc, "atmel,at91rm9200-pmc", 423 of_at91rm9200_pmc_setup); 424 425 static void __init of_at91sam9260_pmc_setup(struct device_node *np) 426 { 427 of_at91_pmc_setup(np, &at91sam9260_caps); 428 } 429 CLK_OF_DECLARE(at91sam9260_clk_pmc, "atmel,at91sam9260-pmc", 430 of_at91sam9260_pmc_setup); 431 432 static void __init of_at91sam9g45_pmc_setup(struct device_node *np) 433 { 434 of_at91_pmc_setup(np, &at91sam9g45_caps); 435 } 436 CLK_OF_DECLARE(at91sam9g45_clk_pmc, "atmel,at91sam9g45-pmc", 437 of_at91sam9g45_pmc_setup); 438 439 static void __init of_at91sam9n12_pmc_setup(struct device_node *np) 440 { 441 of_at91_pmc_setup(np, &at91sam9n12_caps); 442 } 443 CLK_OF_DECLARE(at91sam9n12_clk_pmc, "atmel,at91sam9n12-pmc", 444 of_at91sam9n12_pmc_setup); 445 446 static void __init of_at91sam9x5_pmc_setup(struct device_node *np) 447 { 448 of_at91_pmc_setup(np, &at91sam9x5_caps); 449 } 450 CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", 451 of_at91sam9x5_pmc_setup); 452 453 static void __init of_sama5d2_pmc_setup(struct device_node *np) 454 { 455 of_at91_pmc_setup(np, &sama5d2_caps); 456 } 457 CLK_OF_DECLARE(sama5d2_clk_pmc, "atmel,sama5d2-pmc", 458 of_sama5d2_pmc_setup); 459 460 static void __init of_sama5d3_pmc_setup(struct device_node *np) 461 { 462 of_at91_pmc_setup(np, &sama5d3_caps); 463 } 464 CLK_OF_DECLARE(sama5d3_clk_pmc, "atmel,sama5d3-pmc", 465 of_sama5d3_pmc_setup); 466