0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/kernel.h>
0016 #include <linux/module.h>
0017 #include <linux/init.h>
0018 #include <linux/io.h>
0019 #include <linux/irq.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/slab.h>
0022 #include <linux/of.h>
0023 #include <linux/of_address.h>
0024 #include <linux/clk-provider.h>
0025 #include <linux/clk/ti.h>
0026
0027 #include "soc.h"
0028 #include "prm2xxx_3xxx.h"
0029 #include "prm2xxx.h"
0030 #include "prm3xxx.h"
0031 #include "prm33xx.h"
0032 #include "prm44xx.h"
0033 #include "prm54xx.h"
0034 #include "prm7xx.h"
0035 #include "prcm43xx.h"
0036 #include "common.h"
0037 #include "clock.h"
0038 #include "cm.h"
0039 #include "control.h"
0040
0041
0042
0043
0044
0045
0046
0047 #define OMAP_PRCM_MAX_NR_PENDING_REG 2
0048
0049
0050
0051
0052
0053
0054
0055 static struct irq_chip_generic **prcm_irq_chips;
0056
0057
0058
0059
0060
0061
0062 static struct omap_prcm_irq_setup *prcm_irq_setup;
0063
0064
0065 struct omap_domain_base prm_base;
0066
0067 u16 prm_features;
0068
0069
0070
0071
0072
0073 static struct prm_ll_data null_prm_ll_data;
0074 static struct prm_ll_data *prm_ll_data = &null_prm_ll_data;
0075
0076
0077
0078
0079
0080
0081 static void omap_prcm_events_filter_priority(unsigned long *events,
0082 unsigned long *priority_events)
0083 {
0084 int i;
0085
0086 for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
0087 priority_events[i] =
0088 events[i] & prcm_irq_setup->priority_mask[i];
0089 events[i] ^= priority_events[i];
0090 }
0091 }
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 static void omap_prcm_irq_handler(struct irq_desc *desc)
0102 {
0103 unsigned long pending[OMAP_PRCM_MAX_NR_PENDING_REG];
0104 unsigned long priority_pending[OMAP_PRCM_MAX_NR_PENDING_REG];
0105 struct irq_chip *chip = irq_desc_get_chip(desc);
0106 unsigned int virtirq;
0107 int nr_irq = prcm_irq_setup->nr_regs * 32;
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 if (prcm_irq_setup->suspended) {
0120 prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask);
0121 prcm_irq_setup->suspend_save_flag = true;
0122 }
0123
0124
0125
0126
0127
0128 while (!prcm_irq_setup->suspended) {
0129 prcm_irq_setup->read_pending_irqs(pending);
0130
0131
0132 if (find_first_bit(pending, nr_irq) >= nr_irq)
0133 break;
0134
0135 omap_prcm_events_filter_priority(pending, priority_pending);
0136
0137
0138
0139
0140
0141
0142
0143 for_each_set_bit(virtirq, priority_pending, nr_irq)
0144 generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
0145
0146
0147 for_each_set_bit(virtirq, pending, nr_irq)
0148 generic_handle_irq(prcm_irq_setup->base_irq + virtirq);
0149 }
0150 if (chip->irq_ack)
0151 chip->irq_ack(&desc->irq_data);
0152 if (chip->irq_eoi)
0153 chip->irq_eoi(&desc->irq_data);
0154 chip->irq_unmask(&desc->irq_data);
0155
0156 prcm_irq_setup->ocp_barrier();
0157 }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169 int omap_prcm_event_to_irq(const char *name)
0170 {
0171 int i;
0172
0173 if (!prcm_irq_setup || !name)
0174 return -ENOENT;
0175
0176 for (i = 0; i < prcm_irq_setup->nr_irqs; i++)
0177 if (!strcmp(prcm_irq_setup->irqs[i].name, name))
0178 return prcm_irq_setup->base_irq +
0179 prcm_irq_setup->irqs[i].offset;
0180
0181 return -ENOENT;
0182 }
0183
0184
0185
0186
0187
0188
0189
0190 void omap_prcm_irq_cleanup(void)
0191 {
0192 unsigned int irq;
0193 int i;
0194
0195 if (!prcm_irq_setup) {
0196 pr_err("PRCM: IRQ handler not initialized; cannot cleanup\n");
0197 return;
0198 }
0199
0200 if (prcm_irq_chips) {
0201 for (i = 0; i < prcm_irq_setup->nr_regs; i++) {
0202 if (prcm_irq_chips[i])
0203 irq_remove_generic_chip(prcm_irq_chips[i],
0204 0xffffffff, 0, 0);
0205 prcm_irq_chips[i] = NULL;
0206 }
0207 kfree(prcm_irq_chips);
0208 prcm_irq_chips = NULL;
0209 }
0210
0211 kfree(prcm_irq_setup->saved_mask);
0212 prcm_irq_setup->saved_mask = NULL;
0213
0214 kfree(prcm_irq_setup->priority_mask);
0215 prcm_irq_setup->priority_mask = NULL;
0216
0217 irq = prcm_irq_setup->irq;
0218 irq_set_chained_handler(irq, NULL);
0219
0220 if (prcm_irq_setup->base_irq > 0)
0221 irq_free_descs(prcm_irq_setup->base_irq,
0222 prcm_irq_setup->nr_regs * 32);
0223 prcm_irq_setup->base_irq = 0;
0224 }
0225
0226 void omap_prcm_irq_prepare(void)
0227 {
0228 prcm_irq_setup->suspended = true;
0229 }
0230
0231 void omap_prcm_irq_complete(void)
0232 {
0233 prcm_irq_setup->suspended = false;
0234
0235
0236 if (!prcm_irq_setup->suspend_save_flag)
0237 return;
0238
0239 prcm_irq_setup->suspend_save_flag = false;
0240
0241
0242
0243
0244
0245
0246 prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask);
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
0260 {
0261 int nr_regs;
0262 u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
0263 int offset, i, irq;
0264 struct irq_chip_generic *gc;
0265 struct irq_chip_type *ct;
0266
0267 if (!irq_setup)
0268 return -EINVAL;
0269
0270 nr_regs = irq_setup->nr_regs;
0271
0272 if (prcm_irq_setup) {
0273 pr_err("PRCM: already initialized; won't reinitialize\n");
0274 return -EINVAL;
0275 }
0276
0277 if (nr_regs > OMAP_PRCM_MAX_NR_PENDING_REG) {
0278 pr_err("PRCM: nr_regs too large\n");
0279 return -EINVAL;
0280 }
0281
0282 prcm_irq_setup = irq_setup;
0283
0284 prcm_irq_chips = kcalloc(nr_regs, sizeof(void *), GFP_KERNEL);
0285 prcm_irq_setup->saved_mask = kcalloc(nr_regs, sizeof(u32),
0286 GFP_KERNEL);
0287 prcm_irq_setup->priority_mask = kcalloc(nr_regs, sizeof(u32),
0288 GFP_KERNEL);
0289
0290 if (!prcm_irq_chips || !prcm_irq_setup->saved_mask ||
0291 !prcm_irq_setup->priority_mask)
0292 goto err;
0293
0294 memset(mask, 0, sizeof(mask));
0295
0296 for (i = 0; i < irq_setup->nr_irqs; i++) {
0297 offset = irq_setup->irqs[i].offset;
0298 mask[offset >> 5] |= 1 << (offset & 0x1f);
0299 if (irq_setup->irqs[i].priority)
0300 irq_setup->priority_mask[offset >> 5] |=
0301 1 << (offset & 0x1f);
0302 }
0303
0304 irq = irq_setup->irq;
0305 irq_set_chained_handler(irq, omap_prcm_irq_handler);
0306
0307 irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
0308 0);
0309
0310 if (irq_setup->base_irq < 0) {
0311 pr_err("PRCM: failed to allocate irq descs: %d\n",
0312 irq_setup->base_irq);
0313 goto err;
0314 }
0315
0316 for (i = 0; i < irq_setup->nr_regs; i++) {
0317 gc = irq_alloc_generic_chip("PRCM", 1,
0318 irq_setup->base_irq + i * 32, prm_base.va,
0319 handle_level_irq);
0320
0321 if (!gc) {
0322 pr_err("PRCM: failed to allocate generic chip\n");
0323 goto err;
0324 }
0325 ct = gc->chip_types;
0326 ct->chip.irq_ack = irq_gc_ack_set_bit;
0327 ct->chip.irq_mask = irq_gc_mask_clr_bit;
0328 ct->chip.irq_unmask = irq_gc_mask_set_bit;
0329
0330 ct->regs.ack = irq_setup->ack + i * 4;
0331 ct->regs.mask = irq_setup->mask + i * 4;
0332
0333 irq_setup_generic_chip(gc, mask[i], 0, IRQ_NOREQUEST, 0);
0334 prcm_irq_chips[i] = gc;
0335 }
0336
0337 irq = omap_prcm_event_to_irq("io");
0338 omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain);
0339
0340 return 0;
0341
0342 err:
0343 omap_prcm_irq_cleanup();
0344 return -ENOMEM;
0345 }
0346
0347
0348
0349
0350
0351
0352
0353 void __init omap2_set_globals_prm(void __iomem *prm)
0354 {
0355 prm_base.va = prm;
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370 u32 prm_read_reset_sources(void)
0371 {
0372 u32 ret = 1 << OMAP_UNKNOWN_RST_SRC_ID_SHIFT;
0373
0374 if (prm_ll_data->read_reset_sources)
0375 ret = prm_ll_data->read_reset_sources();
0376 else
0377 WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__);
0378
0379 return ret;
0380 }
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 bool prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
0395 {
0396 bool ret = true;
0397
0398 if (prm_ll_data->was_any_context_lost_old)
0399 ret = prm_ll_data->was_any_context_lost_old(part, inst, idx);
0400 else
0401 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0402 __func__);
0403
0404 return ret;
0405 }
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418 void prm_clear_context_loss_flags_old(u8 part, s16 inst, u16 idx)
0419 {
0420 if (prm_ll_data->clear_context_loss_flags_old)
0421 prm_ll_data->clear_context_loss_flags_old(part, inst, idx);
0422 else
0423 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0424 __func__);
0425 }
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 int omap_prm_assert_hardreset(u8 shift, u8 part, s16 prm_mod, u16 offset)
0437 {
0438 if (!prm_ll_data->assert_hardreset) {
0439 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0440 __func__);
0441 return -EINVAL;
0442 }
0443
0444 return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset);
0445 }
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458 int omap_prm_deassert_hardreset(u8 shift, u8 st_shift, u8 part, s16 prm_mod,
0459 u16 offset, u16 st_offset)
0460 {
0461 if (!prm_ll_data->deassert_hardreset) {
0462 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0463 __func__);
0464 return -EINVAL;
0465 }
0466
0467 return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod,
0468 offset, st_offset);
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480 int omap_prm_is_hardreset_asserted(u8 shift, u8 part, s16 prm_mod, u16 offset)
0481 {
0482 if (!prm_ll_data->is_hardreset_asserted) {
0483 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0484 __func__);
0485 return -EINVAL;
0486 }
0487
0488 return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset);
0489 }
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499 void omap_prm_reconfigure_io_chain(void)
0500 {
0501 if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain)
0502 return;
0503
0504 prcm_irq_setup->reconfigure_io_chain();
0505 }
0506
0507
0508
0509
0510
0511
0512 void omap_prm_reset_system(void)
0513 {
0514 if (!prm_ll_data->reset_system) {
0515 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0516 __func__);
0517 return;
0518 }
0519
0520 prm_ll_data->reset_system();
0521
0522 while (1) {
0523 cpu_relax();
0524 wfe();
0525 }
0526 }
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538 int omap_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
0539 {
0540 if (!prm_ll_data->clear_mod_irqs) {
0541 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0542 __func__);
0543 return -EINVAL;
0544 }
0545
0546 return prm_ll_data->clear_mod_irqs(module, regs, wkst_mask);
0547 }
0548
0549
0550
0551
0552
0553
0554
0555 u32 omap_prm_vp_check_txdone(u8 vp_id)
0556 {
0557 if (!prm_ll_data->vp_check_txdone) {
0558 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0559 __func__);
0560 return 0;
0561 }
0562
0563 return prm_ll_data->vp_check_txdone(vp_id);
0564 }
0565
0566
0567
0568
0569
0570
0571
0572 void omap_prm_vp_clear_txdone(u8 vp_id)
0573 {
0574 if (!prm_ll_data->vp_clear_txdone) {
0575 WARN_ONCE(1, "prm: %s: no mapping function defined\n",
0576 __func__);
0577 return;
0578 }
0579
0580 prm_ll_data->vp_clear_txdone(vp_id);
0581 }
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594 int prm_register(struct prm_ll_data *pld)
0595 {
0596 if (!pld)
0597 return -EINVAL;
0598
0599 if (prm_ll_data != &null_prm_ll_data)
0600 return -EEXIST;
0601
0602 prm_ll_data = pld;
0603
0604 return 0;
0605 }
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618 int prm_unregister(struct prm_ll_data *pld)
0619 {
0620 if (!pld || prm_ll_data != pld)
0621 return -EINVAL;
0622
0623 prm_ll_data = &null_prm_ll_data;
0624
0625 return 0;
0626 }
0627
0628 #ifdef CONFIG_ARCH_OMAP2
0629 static struct omap_prcm_init_data omap2_prm_data __initdata = {
0630 .index = TI_CLKM_PRM,
0631 .init = omap2xxx_prm_init,
0632 };
0633 #endif
0634
0635 #ifdef CONFIG_ARCH_OMAP3
0636 static struct omap_prcm_init_data omap3_prm_data __initdata = {
0637 .index = TI_CLKM_PRM,
0638 .init = omap3xxx_prm_init,
0639
0640
0641
0642
0643
0644 .offset = -OMAP3430_IVA2_MOD,
0645 };
0646 #endif
0647
0648 #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_TI81XX)
0649 static struct omap_prcm_init_data am3_prm_data __initdata = {
0650 .index = TI_CLKM_PRM,
0651 .init = am33xx_prm_init,
0652 };
0653 #endif
0654
0655 #ifdef CONFIG_SOC_TI81XX
0656 static struct omap_prcm_init_data dm814_pllss_data __initdata = {
0657 .index = TI_CLKM_PLLSS,
0658 .init = am33xx_prm_init,
0659 };
0660 #endif
0661
0662 #ifdef CONFIG_ARCH_OMAP4
0663 static struct omap_prcm_init_data omap4_prm_data __initdata = {
0664 .index = TI_CLKM_PRM,
0665 .init = omap44xx_prm_init,
0666 .device_inst_offset = OMAP4430_PRM_DEVICE_INST,
0667 .flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE,
0668 };
0669 #endif
0670
0671 #ifdef CONFIG_SOC_OMAP5
0672 static struct omap_prcm_init_data omap5_prm_data __initdata = {
0673 .index = TI_CLKM_PRM,
0674 .init = omap44xx_prm_init,
0675 .device_inst_offset = OMAP54XX_PRM_DEVICE_INST,
0676 .flags = PRM_HAS_IO_WAKEUP | PRM_HAS_VOLTAGE,
0677 };
0678 #endif
0679
0680 #ifdef CONFIG_SOC_DRA7XX
0681 static struct omap_prcm_init_data dra7_prm_data __initdata = {
0682 .index = TI_CLKM_PRM,
0683 .init = omap44xx_prm_init,
0684 .device_inst_offset = DRA7XX_PRM_DEVICE_INST,
0685 .flags = PRM_HAS_IO_WAKEUP,
0686 };
0687 #endif
0688
0689 #ifdef CONFIG_SOC_AM43XX
0690 static struct omap_prcm_init_data am4_prm_data __initdata = {
0691 .index = TI_CLKM_PRM,
0692 .init = omap44xx_prm_init,
0693 .device_inst_offset = AM43XX_PRM_DEVICE_INST,
0694 .flags = PRM_HAS_IO_WAKEUP,
0695 };
0696 #endif
0697
0698 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
0699 static struct omap_prcm_init_data scrm_data __initdata = {
0700 .index = TI_CLKM_SCRM,
0701 };
0702 #endif
0703
0704 static const struct of_device_id omap_prcm_dt_match_table[] __initconst = {
0705 #ifdef CONFIG_SOC_AM33XX
0706 { .compatible = "ti,am3-prcm", .data = &am3_prm_data },
0707 #endif
0708 #ifdef CONFIG_SOC_AM43XX
0709 { .compatible = "ti,am4-prcm", .data = &am4_prm_data },
0710 #endif
0711 #ifdef CONFIG_SOC_TI81XX
0712 { .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
0713 { .compatible = "ti,dm814-pllss", .data = &dm814_pllss_data },
0714 { .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
0715 #endif
0716 #ifdef CONFIG_ARCH_OMAP2
0717 { .compatible = "ti,omap2-prcm", .data = &omap2_prm_data },
0718 #endif
0719 #ifdef CONFIG_ARCH_OMAP3
0720 { .compatible = "ti,omap3-prm", .data = &omap3_prm_data },
0721 #endif
0722 #ifdef CONFIG_ARCH_OMAP4
0723 { .compatible = "ti,omap4-prm", .data = &omap4_prm_data },
0724 { .compatible = "ti,omap4-scrm", .data = &scrm_data },
0725 #endif
0726 #ifdef CONFIG_SOC_OMAP5
0727 { .compatible = "ti,omap5-prm", .data = &omap5_prm_data },
0728 { .compatible = "ti,omap5-scrm", .data = &scrm_data },
0729 #endif
0730 #ifdef CONFIG_SOC_DRA7XX
0731 { .compatible = "ti,dra7-prm", .data = &dra7_prm_data },
0732 #endif
0733 { }
0734 };
0735
0736
0737
0738
0739
0740
0741
0742
0743 int __init omap2_prm_base_init(void)
0744 {
0745 struct device_node *np;
0746 const struct of_device_id *match;
0747 struct omap_prcm_init_data *data;
0748 struct resource res;
0749 int ret;
0750
0751 for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
0752 data = (struct omap_prcm_init_data *)match->data;
0753
0754 ret = of_address_to_resource(np, 0, &res);
0755 if (ret) {
0756 of_node_put(np);
0757 return ret;
0758 }
0759
0760 data->mem = ioremap(res.start, resource_size(&res));
0761
0762 if (data->index == TI_CLKM_PRM) {
0763 prm_base.va = data->mem + data->offset;
0764 prm_base.pa = res.start + data->offset;
0765 }
0766
0767 data->np = np;
0768
0769 if (data->init)
0770 data->init(data);
0771 }
0772
0773 return 0;
0774 }
0775
0776 int __init omap2_prcm_base_init(void)
0777 {
0778 int ret;
0779
0780 ret = omap2_prm_base_init();
0781 if (ret)
0782 return ret;
0783
0784 return omap2_cm_base_init();
0785 }
0786
0787
0788
0789
0790
0791
0792
0793 int __init omap_prcm_init(void)
0794 {
0795 struct device_node *np;
0796 const struct of_device_id *match;
0797 const struct omap_prcm_init_data *data;
0798 int ret;
0799
0800 for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
0801 data = match->data;
0802
0803 ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
0804 if (ret) {
0805 of_node_put(np);
0806 return ret;
0807 }
0808 }
0809
0810 omap_cm_init();
0811
0812 return 0;
0813 }
0814
0815 static int __init prm_late_init(void)
0816 {
0817 if (prm_ll_data->late_init)
0818 return prm_ll_data->late_init();
0819 return 0;
0820 }
0821 subsys_initcall(prm_late_init);