Lines Matching +full:no +full:- +full:reset +full:- +full:on +full:- +full:init

1 // SPDX-License-Identifier: GPL-2.0-only
3 * OMAP2+ common Power & Reset Management (PRM) IP block functions
6 * Tero Kristo <t-kristo@ti.com>
10 * underlying registers are located in the PRM on OMAP3/4.
17 #include <linux/init.h>
24 #include <linux/clk-provider.h>
44 * omap_prcm_register_chain_handler() could allocate this based on the
59 * is currently running on. Defined and passed by initialization code
76 * prm_ll_data: function pointers to SoC-specific implementations of
92 for (i = 0; i < prcm_irq_setup->nr_regs; i++) { in omap_prcm_events_filter_priority()
94 events[i] & prcm_irq_setup->priority_mask[i]; in omap_prcm_events_filter_priority()
113 int nr_irq = prcm_irq_setup->nr_regs * 32; in omap_prcm_irq_handler()
118 * re-enable the interrupts, at which point the in omap_prcm_irq_handler()
125 if (prcm_irq_setup->suspended) { in omap_prcm_irq_handler()
126 prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask); in omap_prcm_irq_handler()
127 prcm_irq_setup->suspend_save_flag = true; in omap_prcm_irq_handler()
134 while (!prcm_irq_setup->suspended) { in omap_prcm_irq_handler()
135 prcm_irq_setup->read_pending_irqs(pending); in omap_prcm_irq_handler()
137 /* No bit set, then all IRQs are handled */ in omap_prcm_irq_handler()
144 * Loop on all currently pending irqs so that new irqs in omap_prcm_irq_handler()
150 generic_handle_irq(prcm_irq_setup->base_irq + virtirq); in omap_prcm_irq_handler()
154 generic_handle_irq(prcm_irq_setup->base_irq + virtirq); in omap_prcm_irq_handler()
156 if (chip->irq_ack) in omap_prcm_irq_handler()
157 chip->irq_ack(&desc->irq_data); in omap_prcm_irq_handler()
158 if (chip->irq_eoi) in omap_prcm_irq_handler()
159 chip->irq_eoi(&desc->irq_data); in omap_prcm_irq_handler()
160 chip->irq_unmask(&desc->irq_data); in omap_prcm_irq_handler()
162 prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */ in omap_prcm_irq_handler()
168 * omap_prcm_event_to_irq - given a PRCM event name, returns the
169 * corresponding IRQ on which the handler should be registered
170 * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq
173 * or -ENOENT upon failure.
180 return -ENOENT; in omap_prcm_event_to_irq()
182 for (i = 0; i < prcm_irq_setup->nr_irqs; i++) in omap_prcm_event_to_irq()
183 if (!strcmp(prcm_irq_setup->irqs[i].name, name)) in omap_prcm_event_to_irq()
184 return prcm_irq_setup->base_irq + in omap_prcm_event_to_irq()
185 prcm_irq_setup->irqs[i].offset; in omap_prcm_event_to_irq()
187 return -ENOENT; in omap_prcm_event_to_irq()
191 * omap_prcm_irq_cleanup - reverses memory allocated and other steps
194 * No return value.
207 for (i = 0; i < prcm_irq_setup->nr_regs; i++) { in omap_prcm_irq_cleanup()
217 kfree(prcm_irq_setup->saved_mask); in omap_prcm_irq_cleanup()
218 prcm_irq_setup->saved_mask = NULL; in omap_prcm_irq_cleanup()
220 kfree(prcm_irq_setup->priority_mask); in omap_prcm_irq_cleanup()
221 prcm_irq_setup->priority_mask = NULL; in omap_prcm_irq_cleanup()
223 irq = prcm_irq_setup->irq; in omap_prcm_irq_cleanup()
226 if (prcm_irq_setup->base_irq > 0) in omap_prcm_irq_cleanup()
227 irq_free_descs(prcm_irq_setup->base_irq, in omap_prcm_irq_cleanup()
228 prcm_irq_setup->nr_regs * 32); in omap_prcm_irq_cleanup()
229 prcm_irq_setup->base_irq = 0; in omap_prcm_irq_cleanup()
234 prcm_irq_setup->suspended = true; in omap_prcm_irq_prepare()
239 prcm_irq_setup->suspended = false; in omap_prcm_irq_complete()
242 if (!prcm_irq_setup->suspend_save_flag) in omap_prcm_irq_complete()
245 prcm_irq_setup->suspend_save_flag = false; in omap_prcm_irq_complete()
248 * Re-enable all masked PRCM irq sources, this causes the PRCM in omap_prcm_irq_complete()
252 prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask); in omap_prcm_irq_complete()
256 * omap_prcm_register_chain_handler - initializes the prcm chained interrupt
257 * handler based on provided parameters
260 * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up
262 * Returns 0 upon success, -EINVAL if called twice or if invalid
263 * arguments are passed, or -ENOMEM on any other error.
274 return -EINVAL; in omap_prcm_register_chain_handler()
276 nr_regs = irq_setup->nr_regs; in omap_prcm_register_chain_handler()
280 return -EINVAL; in omap_prcm_register_chain_handler()
285 return -EINVAL; in omap_prcm_register_chain_handler()
291 prcm_irq_setup->saved_mask = kcalloc(nr_regs, sizeof(u32), in omap_prcm_register_chain_handler()
293 prcm_irq_setup->priority_mask = kcalloc(nr_regs, sizeof(u32), in omap_prcm_register_chain_handler()
296 if (!prcm_irq_chips || !prcm_irq_setup->saved_mask || in omap_prcm_register_chain_handler()
297 !prcm_irq_setup->priority_mask) in omap_prcm_register_chain_handler()
302 for (i = 0; i < irq_setup->nr_irqs; i++) { in omap_prcm_register_chain_handler()
303 offset = irq_setup->irqs[i].offset; in omap_prcm_register_chain_handler()
305 if (irq_setup->irqs[i].priority) in omap_prcm_register_chain_handler()
306 irq_setup->priority_mask[offset >> 5] |= in omap_prcm_register_chain_handler()
310 irq = irq_setup->irq; in omap_prcm_register_chain_handler()
313 irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32, in omap_prcm_register_chain_handler()
316 if (irq_setup->base_irq < 0) { in omap_prcm_register_chain_handler()
318 irq_setup->base_irq); in omap_prcm_register_chain_handler()
322 for (i = 0; i < irq_setup->nr_regs; i++) { in omap_prcm_register_chain_handler()
324 irq_setup->base_irq + i * 32, prm_base.va, in omap_prcm_register_chain_handler()
331 ct = gc->chip_types; in omap_prcm_register_chain_handler()
332 ct->chip.irq_ack = irq_gc_ack_set_bit; in omap_prcm_register_chain_handler()
333 ct->chip.irq_mask = irq_gc_mask_clr_bit; in omap_prcm_register_chain_handler()
334 ct->chip.irq_unmask = irq_gc_mask_set_bit; in omap_prcm_register_chain_handler()
336 ct->regs.ack = irq_setup->ack + i * 4; in omap_prcm_register_chain_handler()
337 ct->regs.mask = irq_setup->mask + i * 4; in omap_prcm_register_chain_handler()
344 omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); in omap_prcm_register_chain_handler()
350 return -ENOMEM; in omap_prcm_register_chain_handler()
354 * prm_was_any_context_lost_old - was device context lost? (old API)
362 * callers need to use a less-SoC-dependent way to identify hardware
369 if (prm_ll_data->was_any_context_lost_old) in prm_was_any_context_lost_old()
370 ret = prm_ll_data->was_any_context_lost_old(part, inst, idx); in prm_was_any_context_lost_old()
372 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in prm_was_any_context_lost_old()
379 * prm_clear_context_loss_flags_old - clear context loss flags (old API)
385 * (@part, @inst, @idx). No return value. XXX Deprecated; callers
386 * need to use a less-SoC-dependent way to identify hardware IP
391 if (prm_ll_data->clear_context_loss_flags_old) in prm_clear_context_loss_flags_old()
392 prm_ll_data->clear_context_loss_flags_old(part, inst, idx); in prm_clear_context_loss_flags_old()
394 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in prm_clear_context_loss_flags_old()
399 * omap_prm_assert_hardreset - assert hardreset for an IP block
400 * @shift: register bit shift corresponding to the reset line
405 * Asserts a hardware reset line for an IP block.
409 if (!prm_ll_data->assert_hardreset) { in omap_prm_assert_hardreset()
410 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_assert_hardreset()
412 return -EINVAL; in omap_prm_assert_hardreset()
415 return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset); in omap_prm_assert_hardreset()
419 * omap_prm_deassert_hardreset - deassert hardreset for an IP block
420 * @shift: register bit shift corresponding to the reset line
421 * @st_shift: reset status bit shift corresponding to the reset line
427 * Deasserts a hardware reset line for an IP block.
432 if (!prm_ll_data->deassert_hardreset) { in omap_prm_deassert_hardreset()
433 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_deassert_hardreset()
435 return -EINVAL; in omap_prm_deassert_hardreset()
438 return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod, in omap_prm_deassert_hardreset()
443 * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block
444 * @shift: register bit shift corresponding to the reset line
449 * Checks if a hardware reset line for an IP block is enabled or not.
453 if (!prm_ll_data->is_hardreset_asserted) { in omap_prm_is_hardreset_asserted()
454 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_is_hardreset_asserted()
456 return -EINVAL; in omap_prm_is_hardreset_asserted()
459 return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset); in omap_prm_is_hardreset_asserted()
463 * omap_prm_reset_system - trigger global SW reset
465 * Triggers SoC specific global warm reset to reboot the device.
469 if (!prm_ll_data->reset_system) { in omap_prm_reset_system()
470 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_reset_system()
475 prm_ll_data->reset_system(); in omap_prm_reset_system()
484 * omap_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt
495 if (!prm_ll_data->clear_mod_irqs) { in omap_prm_clear_mod_irqs()
496 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_clear_mod_irqs()
498 return -EINVAL; in omap_prm_clear_mod_irqs()
501 return prm_ll_data->clear_mod_irqs(module, regs, wkst_mask); in omap_prm_clear_mod_irqs()
505 * omap_prm_vp_check_txdone - check voltage processor TX done status
509 * Returns non-zero if a transmission has completed, 0 otherwise.
513 if (!prm_ll_data->vp_check_txdone) { in omap_prm_vp_check_txdone()
514 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_vp_check_txdone()
519 return prm_ll_data->vp_check_txdone(vp_id); in omap_prm_vp_check_txdone()
523 * omap_prm_vp_clear_txdone - clears voltage processor TX done status
531 if (!prm_ll_data->vp_clear_txdone) { in omap_prm_vp_clear_txdone()
532 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_vp_clear_txdone()
537 prm_ll_data->vp_clear_txdone(vp_id); in omap_prm_vp_clear_txdone()
541 * prm_register - register per-SoC low-level data with the PRM
542 * @pld: low-level per-SoC OMAP PRM data & function pointers to register
544 * Register per-SoC low-level OMAP PRM data and function pointers with
547 * it returns successfully. Returns 0 upon success, -EINVAL if @pld
548 * is NULL, or -EEXIST if prm_register() has already been called
554 return -EINVAL; in prm_register()
557 return -EEXIST; in prm_register()
565 * prm_unregister - unregister per-SoC low-level data & function pointers
566 * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
568 * Unregister per-SoC low-level OMAP PRM data and function pointers
572 * -EINVAL if @pld is NULL or if @pld does not match the struct
578 return -EINVAL; in prm_unregister()
588 .init = omap2xxx_prm_init,
595 .init = omap3xxx_prm_init,
601 .offset = -OMAP3430_IVA2_MOD,
608 .init = am33xx_prm_init,
615 .init = am33xx_prm_init,
622 .init = omap44xx_prm_init,
631 .init = omap44xx_prm_init,
640 .init = omap44xx_prm_init,
649 .init = omap44xx_prm_init,
663 { .compatible = "ti,am3-prcm", .data = &am3_prm_data },
666 { .compatible = "ti,am4-prcm", .data = &am4_prm_data },
669 { .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
670 { .compatible = "ti,dm814-pllss", .data = &dm814_pllss_data },
671 { .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
674 { .compatible = "ti,omap2-prcm", .data = &omap2_prm_data },
677 { .compatible = "ti,omap3-prm", .data = &omap3_prm_data },
680 { .compatible = "ti,omap4-prm", .data = &omap4_prm_data },
681 { .compatible = "ti,omap4-scrm", .data = &scrm_data },
684 { .compatible = "ti,omap5-prm", .data = &omap5_prm_data },
685 { .compatible = "ti,omap5-scrm", .data = &scrm_data },
688 { .compatible = "ti,dra7-prm", .data = &dra7_prm_data },
694 * omap2_prm_base_init - initialize iomappings for the PRM driver
697 * on the DT data. Returns 0 in success, negative error value
709 data = (struct omap_prcm_init_data *)match->data; in omap2_prm_base_init()
717 data->mem = ioremap(res.start, resource_size(&res)); in omap2_prm_base_init()
719 if (data->index == TI_CLKM_PRM) { in omap2_prm_base_init()
720 prm_base.va = data->mem + data->offset; in omap2_prm_base_init()
721 prm_base.pa = res.start + data->offset; in omap2_prm_base_init()
724 data->np = np; in omap2_prm_base_init()
726 if (data->init) in omap2_prm_base_init()
727 data->init(data); in omap2_prm_base_init()
745 * omap_prcm_init - low level init for the PRCM drivers
758 data = match->data; in omap_prcm_init()
760 ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); in omap_prcm_init()
774 if (prm_ll_data->late_init) in prm_late_init()
775 return prm_ll_data->late_init(); in prm_late_init()