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
70 * prm_ll_data: function pointers to SoC-specific implementations of
86 for (i = 0; i < prcm_irq_setup->nr_regs; i++) { in omap_prcm_events_filter_priority()
88 events[i] & prcm_irq_setup->priority_mask[i]; in omap_prcm_events_filter_priority()
107 int nr_irq = prcm_irq_setup->nr_regs * 32; in omap_prcm_irq_handler()
112 * re-enable the interrupts, at which point the in omap_prcm_irq_handler()
119 if (prcm_irq_setup->suspended) { in omap_prcm_irq_handler()
120 prcm_irq_setup->save_and_clear_irqen(prcm_irq_setup->saved_mask); in omap_prcm_irq_handler()
121 prcm_irq_setup->suspend_save_flag = true; in omap_prcm_irq_handler()
128 while (!prcm_irq_setup->suspended) { in omap_prcm_irq_handler()
129 prcm_irq_setup->read_pending_irqs(pending); in omap_prcm_irq_handler()
131 /* No bit set, then all IRQs are handled */ in omap_prcm_irq_handler()
138 * Loop on all currently pending irqs so that new irqs in omap_prcm_irq_handler()
144 generic_handle_irq(prcm_irq_setup->base_irq + virtirq); in omap_prcm_irq_handler()
148 generic_handle_irq(prcm_irq_setup->base_irq + virtirq); in omap_prcm_irq_handler()
150 if (chip->irq_ack) in omap_prcm_irq_handler()
151 chip->irq_ack(&desc->irq_data); in omap_prcm_irq_handler()
152 if (chip->irq_eoi) in omap_prcm_irq_handler()
153 chip->irq_eoi(&desc->irq_data); in omap_prcm_irq_handler()
154 chip->irq_unmask(&desc->irq_data); in omap_prcm_irq_handler()
156 prcm_irq_setup->ocp_barrier(); /* avoid spurious IRQs */ in omap_prcm_irq_handler()
162 * omap_prcm_event_to_irq - given a PRCM event name, returns the
163 * corresponding IRQ on which the handler should be registered
164 * @name: name of the PRCM interrupt bit to look up - see struct omap_prcm_irq
167 * or -ENOENT upon failure.
174 return -ENOENT; in omap_prcm_event_to_irq()
176 for (i = 0; i < prcm_irq_setup->nr_irqs; i++) in omap_prcm_event_to_irq()
177 if (!strcmp(prcm_irq_setup->irqs[i].name, name)) in omap_prcm_event_to_irq()
178 return prcm_irq_setup->base_irq + in omap_prcm_event_to_irq()
179 prcm_irq_setup->irqs[i].offset; in omap_prcm_event_to_irq()
181 return -ENOENT; in omap_prcm_event_to_irq()
185 * omap_prcm_irq_cleanup - reverses memory allocated and other steps
188 * No return value.
201 for (i = 0; i < prcm_irq_setup->nr_regs; i++) { in omap_prcm_irq_cleanup()
211 kfree(prcm_irq_setup->saved_mask); in omap_prcm_irq_cleanup()
212 prcm_irq_setup->saved_mask = NULL; in omap_prcm_irq_cleanup()
214 kfree(prcm_irq_setup->priority_mask); in omap_prcm_irq_cleanup()
215 prcm_irq_setup->priority_mask = NULL; in omap_prcm_irq_cleanup()
217 irq = prcm_irq_setup->irq; in omap_prcm_irq_cleanup()
220 if (prcm_irq_setup->base_irq > 0) in omap_prcm_irq_cleanup()
221 irq_free_descs(prcm_irq_setup->base_irq, in omap_prcm_irq_cleanup()
222 prcm_irq_setup->nr_regs * 32); in omap_prcm_irq_cleanup()
223 prcm_irq_setup->base_irq = 0; in omap_prcm_irq_cleanup()
228 prcm_irq_setup->suspended = true; in omap_prcm_irq_prepare()
233 prcm_irq_setup->suspended = false; in omap_prcm_irq_complete()
236 if (!prcm_irq_setup->suspend_save_flag) in omap_prcm_irq_complete()
239 prcm_irq_setup->suspend_save_flag = false; in omap_prcm_irq_complete()
242 * Re-enable all masked PRCM irq sources, this causes the PRCM in omap_prcm_irq_complete()
246 prcm_irq_setup->restore_irqen(prcm_irq_setup->saved_mask); in omap_prcm_irq_complete()
250 * omap_prcm_register_chain_handler - initializes the prcm chained interrupt
251 * handler based on provided parameters
254 * Set up the PRCM chained interrupt handler on the PRCM IRQ. Sets up
256 * Returns 0 upon success, -EINVAL if called twice or if invalid
257 * arguments are passed, or -ENOMEM on any other error.
268 return -EINVAL; in omap_prcm_register_chain_handler()
270 nr_regs = irq_setup->nr_regs; in omap_prcm_register_chain_handler()
274 return -EINVAL; in omap_prcm_register_chain_handler()
279 return -EINVAL; in omap_prcm_register_chain_handler()
285 prcm_irq_setup->saved_mask = kcalloc(nr_regs, sizeof(u32), in omap_prcm_register_chain_handler()
287 prcm_irq_setup->priority_mask = kcalloc(nr_regs, sizeof(u32), in omap_prcm_register_chain_handler()
290 if (!prcm_irq_chips || !prcm_irq_setup->saved_mask || in omap_prcm_register_chain_handler()
291 !prcm_irq_setup->priority_mask) in omap_prcm_register_chain_handler()
296 for (i = 0; i < irq_setup->nr_irqs; i++) { in omap_prcm_register_chain_handler()
297 offset = irq_setup->irqs[i].offset; in omap_prcm_register_chain_handler()
299 if (irq_setup->irqs[i].priority) in omap_prcm_register_chain_handler()
300 irq_setup->priority_mask[offset >> 5] |= in omap_prcm_register_chain_handler()
304 irq = irq_setup->irq; in omap_prcm_register_chain_handler()
307 irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32, in omap_prcm_register_chain_handler()
310 if (irq_setup->base_irq < 0) { in omap_prcm_register_chain_handler()
312 irq_setup->base_irq); in omap_prcm_register_chain_handler()
316 for (i = 0; i < irq_setup->nr_regs; i++) { in omap_prcm_register_chain_handler()
318 irq_setup->base_irq + i * 32, prm_base.va, in omap_prcm_register_chain_handler()
325 ct = gc->chip_types; in omap_prcm_register_chain_handler()
326 ct->chip.irq_ack = irq_gc_ack_set_bit; in omap_prcm_register_chain_handler()
327 ct->chip.irq_mask = irq_gc_mask_clr_bit; in omap_prcm_register_chain_handler()
328 ct->chip.irq_unmask = irq_gc_mask_set_bit; in omap_prcm_register_chain_handler()
330 ct->regs.ack = irq_setup->ack + i * 4; in omap_prcm_register_chain_handler()
331 ct->regs.mask = irq_setup->mask + i * 4; in omap_prcm_register_chain_handler()
338 omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); in omap_prcm_register_chain_handler()
344 return -ENOMEM; in omap_prcm_register_chain_handler()
348 * omap2_set_globals_prm - set the PRM base address (for early use)
359 * prm_read_reset_sources - return the sources of the SoC's last reset
361 * Return a u32 bitmask representing the reset sources that caused the
362 * SoC to reset. The low-level per-SoC functions called by this
363 * function remap the SoC-specific reset source bits into an
364 * OMAP-common set of reset source bits, defined in
365 * arch/arm/mach-omap2/prm.h. Returns the standardized reset source
367 * OMAP_UNKNOWN_RST_SRC_ID_SHIFT) if no low-level read_reset_sources()
374 if (prm_ll_data->read_reset_sources) in prm_read_reset_sources()
375 ret = prm_ll_data->read_reset_sources(); in prm_read_reset_sources()
377 WARN_ONCE(1, "prm: %s: no mapping function defined for reset sources\n", __func__); in prm_read_reset_sources()
383 * prm_was_any_context_lost_old - was device context lost? (old API)
391 * callers need to use a less-SoC-dependent way to identify hardware
398 if (prm_ll_data->was_any_context_lost_old) in prm_was_any_context_lost_old()
399 ret = prm_ll_data->was_any_context_lost_old(part, inst, idx); in prm_was_any_context_lost_old()
401 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in prm_was_any_context_lost_old()
408 * prm_clear_context_lost_flags_old - clear context loss flags (old API)
414 * (@part, @inst, @idx). No return value. XXX Deprecated; callers
415 * need to use a less-SoC-dependent way to identify hardware IP
420 if (prm_ll_data->clear_context_loss_flags_old) in prm_clear_context_loss_flags_old()
421 prm_ll_data->clear_context_loss_flags_old(part, inst, idx); in prm_clear_context_loss_flags_old()
423 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in prm_clear_context_loss_flags_old()
428 * omap_prm_assert_hardreset - assert hardreset for an IP block
429 * @shift: register bit shift corresponding to the reset line
434 * Asserts a hardware reset line for an IP block.
438 if (!prm_ll_data->assert_hardreset) { in omap_prm_assert_hardreset()
439 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_assert_hardreset()
441 return -EINVAL; in omap_prm_assert_hardreset()
444 return prm_ll_data->assert_hardreset(shift, part, prm_mod, offset); in omap_prm_assert_hardreset()
448 * omap_prm_deassert_hardreset - deassert hardreset for an IP block
449 * @shift: register bit shift corresponding to the reset line
450 * @st_shift: reset status bit shift corresponding to the reset line
456 * Deasserts a hardware reset line for an IP block.
461 if (!prm_ll_data->deassert_hardreset) { in omap_prm_deassert_hardreset()
462 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_deassert_hardreset()
464 return -EINVAL; in omap_prm_deassert_hardreset()
467 return prm_ll_data->deassert_hardreset(shift, st_shift, part, prm_mod, in omap_prm_deassert_hardreset()
472 * omap_prm_is_hardreset_asserted - check the hardreset status for an IP block
473 * @shift: register bit shift corresponding to the reset line
478 * Checks if a hardware reset line for an IP block is enabled or not.
482 if (!prm_ll_data->is_hardreset_asserted) { in omap_prm_is_hardreset_asserted()
483 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_is_hardreset_asserted()
485 return -EINVAL; in omap_prm_is_hardreset_asserted()
488 return prm_ll_data->is_hardreset_asserted(shift, part, prm_mod, offset); in omap_prm_is_hardreset_asserted()
492 * omap_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
494 * Clear any previously-latched I/O wakeup events and ensure that the
501 if (!prcm_irq_setup || !prcm_irq_setup->reconfigure_io_chain) in omap_prm_reconfigure_io_chain()
504 prcm_irq_setup->reconfigure_io_chain(); in omap_prm_reconfigure_io_chain()
508 * omap_prm_reset_system - trigger global SW reset
510 * Triggers SoC specific global warm reset to reboot the device.
514 if (!prm_ll_data->reset_system) { in omap_prm_reset_system()
515 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_reset_system()
520 prm_ll_data->reset_system(); in omap_prm_reset_system()
529 * omap_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt
540 if (!prm_ll_data->clear_mod_irqs) { in omap_prm_clear_mod_irqs()
541 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_clear_mod_irqs()
543 return -EINVAL; in omap_prm_clear_mod_irqs()
546 return prm_ll_data->clear_mod_irqs(module, regs, wkst_mask); in omap_prm_clear_mod_irqs()
550 * omap_prm_vp_check_txdone - check voltage processor TX done status
553 * Returns non-zero if a transmission has completed, 0 otherwise.
557 if (!prm_ll_data->vp_check_txdone) { in omap_prm_vp_check_txdone()
558 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_vp_check_txdone()
563 return prm_ll_data->vp_check_txdone(vp_id); in omap_prm_vp_check_txdone()
567 * omap_prm_vp_clear_txdone - clears voltage processor TX done status
574 if (!prm_ll_data->vp_clear_txdone) { in omap_prm_vp_clear_txdone()
575 WARN_ONCE(1, "prm: %s: no mapping function defined\n", in omap_prm_vp_clear_txdone()
580 prm_ll_data->vp_clear_txdone(vp_id); in omap_prm_vp_clear_txdone()
584 * prm_register - register per-SoC low-level data with the PRM
585 * @pld: low-level per-SoC OMAP PRM data & function pointers to register
587 * Register per-SoC low-level OMAP PRM data and function pointers with
590 * it returns successfully. Returns 0 upon success, -EINVAL if @pld
591 * is NULL, or -EEXIST if prm_register() has already been called
597 return -EINVAL; in prm_register()
600 return -EEXIST; in prm_register()
608 * prm_unregister - unregister per-SoC low-level data & function pointers
609 * @pld: low-level per-SoC OMAP PRM data & function pointers to unregister
611 * Unregister per-SoC low-level OMAP PRM data and function pointers
615 * -EINVAL if @pld is NULL or if @pld does not match the struct
621 return -EINVAL; in prm_unregister()
631 .init = omap2xxx_prm_init,
638 .init = omap3xxx_prm_init,
644 .offset = -OMAP3430_IVA2_MOD,
651 .init = am33xx_prm_init,
658 .init = am33xx_prm_init,
665 .init = omap44xx_prm_init,
674 .init = omap44xx_prm_init,
683 .init = omap44xx_prm_init,
692 .init = omap44xx_prm_init,
706 { .compatible = "ti,am3-prcm", .data = &am3_prm_data },
709 { .compatible = "ti,am4-prcm", .data = &am4_prm_data },
712 { .compatible = "ti,dm814-prcm", .data = &am3_prm_data },
713 { .compatible = "ti,dm814-pllss", .data = &dm814_pllss_data },
714 { .compatible = "ti,dm816-prcm", .data = &am3_prm_data },
717 { .compatible = "ti,omap2-prcm", .data = &omap2_prm_data },
720 { .compatible = "ti,omap3-prm", .data = &omap3_prm_data },
723 { .compatible = "ti,omap4-prm", .data = &omap4_prm_data },
724 { .compatible = "ti,omap4-scrm", .data = &scrm_data },
727 { .compatible = "ti,omap5-prm", .data = &omap5_prm_data },
728 { .compatible = "ti,omap5-scrm", .data = &scrm_data },
731 { .compatible = "ti,dra7-prm", .data = &dra7_prm_data },
737 * omap2_prm_base_init - initialize iomappings for the PRM driver
740 * on the DT data. Returns 0 in success, negative error value
752 data = (struct omap_prcm_init_data *)match->data; in omap2_prm_base_init()
760 data->mem = ioremap(res.start, resource_size(&res)); in omap2_prm_base_init()
762 if (data->index == TI_CLKM_PRM) { in omap2_prm_base_init()
763 prm_base.va = data->mem + data->offset; in omap2_prm_base_init()
764 prm_base.pa = res.start + data->offset; in omap2_prm_base_init()
767 data->np = np; in omap2_prm_base_init()
769 if (data->init) in omap2_prm_base_init()
770 data->init(data); in omap2_prm_base_init()
788 * omap_prcm_init - low level init for the PRCM drivers
801 data = match->data; in omap_prcm_init()
803 ret = omap2_clk_provider_init(np, data->index, NULL, data->mem); in omap_prcm_init()
817 if (prm_ll_data->late_init) in prm_late_init()
818 return prm_ll_data->late_init(); in prm_late_init()