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