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 struct irq_chip pmc_irq = { 93 .name = "PMC", 94 .irq_disable = pmc_irq_mask, 95 .irq_mask = pmc_irq_mask, 96 .irq_unmask = pmc_irq_unmask, 97 .irq_set_type = pmc_irq_set_type, 98 }; 99 100 static struct lock_class_key pmc_lock_class; 101 102 static int pmc_irq_map(struct irq_domain *h, unsigned int virq, 103 irq_hw_number_t hw) 104 { 105 struct at91_pmc *pmc = h->host_data; 106 107 irq_set_lockdep_class(virq, &pmc_lock_class); 108 109 irq_set_chip_and_handler(virq, &pmc_irq, 110 handle_level_irq); 111 set_irq_flags(virq, IRQF_VALID); 112 irq_set_chip_data(virq, pmc); 113 114 return 0; 115 } 116 117 static int pmc_irq_domain_xlate(struct irq_domain *d, 118 struct device_node *ctrlr, 119 const u32 *intspec, unsigned int intsize, 120 irq_hw_number_t *out_hwirq, 121 unsigned int *out_type) 122 { 123 struct at91_pmc *pmc = d->host_data; 124 const struct at91_pmc_caps *caps = pmc->caps; 125 126 if (WARN_ON(intsize < 1)) 127 return -EINVAL; 128 129 *out_hwirq = intspec[0]; 130 131 if (!(caps->available_irqs & (1 << *out_hwirq))) 132 return -EINVAL; 133 134 *out_type = IRQ_TYPE_LEVEL_HIGH; 135 136 return 0; 137 } 138 139 static struct irq_domain_ops pmc_irq_ops = { 140 .map = pmc_irq_map, 141 .xlate = pmc_irq_domain_xlate, 142 }; 143 144 static irqreturn_t pmc_irq_handler(int irq, void *data) 145 { 146 struct at91_pmc *pmc = (struct at91_pmc *)data; 147 unsigned long sr; 148 int n; 149 150 sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR); 151 if (!sr) 152 return IRQ_NONE; 153 154 for_each_set_bit(n, &sr, BITS_PER_LONG) 155 generic_handle_irq(irq_find_mapping(pmc->irqdomain, n)); 156 157 return IRQ_HANDLED; 158 } 159 160 static const struct at91_pmc_caps at91rm9200_caps = { 161 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | 162 AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | 163 AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | 164 AT91_PMC_PCK3RDY, 165 }; 166 167 static const struct at91_pmc_caps at91sam9260_caps = { 168 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | 169 AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | 170 AT91_PMC_PCK1RDY, 171 }; 172 173 static const struct at91_pmc_caps at91sam9g45_caps = { 174 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 175 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 176 AT91_PMC_PCK1RDY, 177 }; 178 179 static const struct at91_pmc_caps at91sam9n12_caps = { 180 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_LOCKB | 181 AT91_PMC_MCKRDY | AT91_PMC_PCK0RDY | 182 AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | 183 AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, 184 }; 185 186 static const struct at91_pmc_caps at91sam9x5_caps = { 187 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 188 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 189 AT91_PMC_PCK1RDY | AT91_PMC_MOSCSELS | 190 AT91_PMC_MOSCRCS | AT91_PMC_CFDEV, 191 }; 192 193 static const struct at91_pmc_caps sama5d3_caps = { 194 .available_irqs = AT91_PMC_MOSCS | AT91_PMC_LOCKA | AT91_PMC_MCKRDY | 195 AT91_PMC_LOCKU | AT91_PMC_PCK0RDY | 196 AT91_PMC_PCK1RDY | AT91_PMC_PCK2RDY | 197 AT91_PMC_MOSCSELS | AT91_PMC_MOSCRCS | 198 AT91_PMC_CFDEV, 199 }; 200 201 static struct at91_pmc *__init at91_pmc_init(struct device_node *np, 202 void __iomem *regbase, int virq, 203 const struct at91_pmc_caps *caps) 204 { 205 struct at91_pmc *pmc; 206 207 if (!regbase || !virq || !caps) 208 return NULL; 209 210 at91_pmc_base = regbase; 211 212 pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); 213 if (!pmc) 214 return NULL; 215 216 spin_lock_init(&pmc->lock); 217 pmc->regbase = regbase; 218 pmc->virq = virq; 219 pmc->caps = caps; 220 221 pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc); 222 223 if (!pmc->irqdomain) 224 goto out_free_pmc; 225 226 pmc_write(pmc, AT91_PMC_IDR, 0xffffffff); 227 if (request_irq(pmc->virq, pmc_irq_handler, IRQF_SHARED, "pmc", pmc)) 228 goto out_remove_irqdomain; 229 230 return pmc; 231 232 out_remove_irqdomain: 233 irq_domain_remove(pmc->irqdomain); 234 out_free_pmc: 235 kfree(pmc); 236 237 return NULL; 238 } 239 240 static const struct of_device_id pmc_clk_ids[] __initconst = { 241 /* Slow oscillator */ 242 { 243 .compatible = "atmel,at91sam9260-clk-slow", 244 .data = of_at91sam9260_clk_slow_setup, 245 }, 246 /* Main clock */ 247 { 248 .compatible = "atmel,at91rm9200-clk-main-osc", 249 .data = of_at91rm9200_clk_main_osc_setup, 250 }, 251 { 252 .compatible = "atmel,at91sam9x5-clk-main-rc-osc", 253 .data = of_at91sam9x5_clk_main_rc_osc_setup, 254 }, 255 { 256 .compatible = "atmel,at91rm9200-clk-main", 257 .data = of_at91rm9200_clk_main_setup, 258 }, 259 { 260 .compatible = "atmel,at91sam9x5-clk-main", 261 .data = of_at91sam9x5_clk_main_setup, 262 }, 263 /* PLL clocks */ 264 { 265 .compatible = "atmel,at91rm9200-clk-pll", 266 .data = of_at91rm9200_clk_pll_setup, 267 }, 268 { 269 .compatible = "atmel,at91sam9g45-clk-pll", 270 .data = of_at91sam9g45_clk_pll_setup, 271 }, 272 { 273 .compatible = "atmel,at91sam9g20-clk-pllb", 274 .data = of_at91sam9g20_clk_pllb_setup, 275 }, 276 { 277 .compatible = "atmel,sama5d3-clk-pll", 278 .data = of_sama5d3_clk_pll_setup, 279 }, 280 { 281 .compatible = "atmel,at91sam9x5-clk-plldiv", 282 .data = of_at91sam9x5_clk_plldiv_setup, 283 }, 284 /* Master clock */ 285 { 286 .compatible = "atmel,at91rm9200-clk-master", 287 .data = of_at91rm9200_clk_master_setup, 288 }, 289 { 290 .compatible = "atmel,at91sam9x5-clk-master", 291 .data = of_at91sam9x5_clk_master_setup, 292 }, 293 /* System clocks */ 294 { 295 .compatible = "atmel,at91rm9200-clk-system", 296 .data = of_at91rm9200_clk_sys_setup, 297 }, 298 /* Peripheral clocks */ 299 { 300 .compatible = "atmel,at91rm9200-clk-peripheral", 301 .data = of_at91rm9200_clk_periph_setup, 302 }, 303 { 304 .compatible = "atmel,at91sam9x5-clk-peripheral", 305 .data = of_at91sam9x5_clk_periph_setup, 306 }, 307 /* Programmable clocks */ 308 { 309 .compatible = "atmel,at91rm9200-clk-programmable", 310 .data = of_at91rm9200_clk_prog_setup, 311 }, 312 { 313 .compatible = "atmel,at91sam9g45-clk-programmable", 314 .data = of_at91sam9g45_clk_prog_setup, 315 }, 316 { 317 .compatible = "atmel,at91sam9x5-clk-programmable", 318 .data = of_at91sam9x5_clk_prog_setup, 319 }, 320 /* UTMI clock */ 321 #if defined(CONFIG_HAVE_AT91_UTMI) 322 { 323 .compatible = "atmel,at91sam9x5-clk-utmi", 324 .data = of_at91sam9x5_clk_utmi_setup, 325 }, 326 #endif 327 /* USB clock */ 328 #if defined(CONFIG_HAVE_AT91_USB_CLK) 329 { 330 .compatible = "atmel,at91rm9200-clk-usb", 331 .data = of_at91rm9200_clk_usb_setup, 332 }, 333 { 334 .compatible = "atmel,at91sam9x5-clk-usb", 335 .data = of_at91sam9x5_clk_usb_setup, 336 }, 337 { 338 .compatible = "atmel,at91sam9n12-clk-usb", 339 .data = of_at91sam9n12_clk_usb_setup, 340 }, 341 #endif 342 /* SMD clock */ 343 #if defined(CONFIG_HAVE_AT91_SMD) 344 { 345 .compatible = "atmel,at91sam9x5-clk-smd", 346 .data = of_at91sam9x5_clk_smd_setup, 347 }, 348 #endif 349 #if defined(CONFIG_HAVE_AT91_H32MX) 350 { 351 .compatible = "atmel,sama5d4-clk-h32mx", 352 .data = of_sama5d4_clk_h32mx_setup, 353 }, 354 #endif 355 { /*sentinel*/ } 356 }; 357 358 static void __init of_at91_pmc_setup(struct device_node *np, 359 const struct at91_pmc_caps *caps) 360 { 361 struct at91_pmc *pmc; 362 struct device_node *childnp; 363 void (*clk_setup)(struct device_node *, struct at91_pmc *); 364 const struct of_device_id *clk_id; 365 void __iomem *regbase = of_iomap(np, 0); 366 int virq; 367 368 if (!regbase) 369 return; 370 371 virq = irq_of_parse_and_map(np, 0); 372 if (!virq) 373 return; 374 375 pmc = at91_pmc_init(np, regbase, virq, caps); 376 if (!pmc) 377 return; 378 for_each_child_of_node(np, childnp) { 379 clk_id = of_match_node(pmc_clk_ids, childnp); 380 if (!clk_id) 381 continue; 382 clk_setup = clk_id->data; 383 clk_setup(childnp, pmc); 384 } 385 } 386 387 static void __init of_at91rm9200_pmc_setup(struct device_node *np) 388 { 389 of_at91_pmc_setup(np, &at91rm9200_caps); 390 } 391 CLK_OF_DECLARE(at91rm9200_clk_pmc, "atmel,at91rm9200-pmc", 392 of_at91rm9200_pmc_setup); 393 394 static void __init of_at91sam9260_pmc_setup(struct device_node *np) 395 { 396 of_at91_pmc_setup(np, &at91sam9260_caps); 397 } 398 CLK_OF_DECLARE(at91sam9260_clk_pmc, "atmel,at91sam9260-pmc", 399 of_at91sam9260_pmc_setup); 400 401 static void __init of_at91sam9g45_pmc_setup(struct device_node *np) 402 { 403 of_at91_pmc_setup(np, &at91sam9g45_caps); 404 } 405 CLK_OF_DECLARE(at91sam9g45_clk_pmc, "atmel,at91sam9g45-pmc", 406 of_at91sam9g45_pmc_setup); 407 408 static void __init of_at91sam9n12_pmc_setup(struct device_node *np) 409 { 410 of_at91_pmc_setup(np, &at91sam9n12_caps); 411 } 412 CLK_OF_DECLARE(at91sam9n12_clk_pmc, "atmel,at91sam9n12-pmc", 413 of_at91sam9n12_pmc_setup); 414 415 static void __init of_at91sam9x5_pmc_setup(struct device_node *np) 416 { 417 of_at91_pmc_setup(np, &at91sam9x5_caps); 418 } 419 CLK_OF_DECLARE(at91sam9x5_clk_pmc, "atmel,at91sam9x5-pmc", 420 of_at91sam9x5_pmc_setup); 421 422 static void __init of_sama5d3_pmc_setup(struct device_node *np) 423 { 424 of_at91_pmc_setup(np, &sama5d3_caps); 425 } 426 CLK_OF_DECLARE(sama5d3_clk_pmc, "atmel,sama5d3-pmc", 427 of_sama5d3_pmc_setup); 428