^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * OMAP3xxx PRM module functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010-2012 Texas Instruments, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2010 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Benoît Cousson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Paul Walmsley
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Rajendra Nayak <rnayak@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "soc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "vp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "powerdomain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "prm3xxx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "prm2xxx_3xxx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "cm2xxx_3xxx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "prm-regbits-34xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "cm3xxx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "cm-regbits-34xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "clock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static void omap3xxx_prm_read_pending_irqs(unsigned long *events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static void omap3xxx_prm_ocp_barrier(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static void omap3xxx_prm_restore_irqen(u32 *saved_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static const struct omap_prcm_irq omap3_prcm_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) OMAP_PRCM_IRQ("wkup", 0, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) OMAP_PRCM_IRQ("io", 9, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) static struct omap_prcm_irq_setup omap3_prcm_irq_setup = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .ack = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .mask = OMAP3_PRM_IRQENABLE_MPU_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .nr_regs = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) .irqs = omap3_prcm_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .nr_irqs = ARRAY_SIZE(omap3_prcm_irqs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .irq = 11 + OMAP_INTC_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .read_pending_irqs = &omap3xxx_prm_read_pending_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .ocp_barrier = &omap3xxx_prm_ocp_barrier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .restore_irqen = &omap3xxx_prm_restore_irqen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .reconfigure_io_chain = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * omap3_prm_reset_src_map - map from bits in the PRM_RSTST hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * register (which are specific to OMAP3xxx SoCs) to reset source ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * bit shifts (which is an OMAP SoC-independent enumeration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct prm_reset_src_map omap3xxx_prm_reset_src_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { OMAP3430_GLOBAL_COLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) { OMAP3430_GLOBAL_SW_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) { OMAP3430_SECURITY_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) { OMAP3430_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) { OMAP3430_SECURE_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) { OMAP3430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) { OMAP3430_VDD1_VOLTAGE_MANAGER_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) { OMAP3430_VDD2_VOLTAGE_MANAGER_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) { OMAP3430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) { OMAP3430_ICECRUSHER_RST_SHIFT, OMAP_ICECRUSHER_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) { -1, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* PRM VP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * struct omap3_vp - OMAP3 VP register access description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct omap3_vp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) u32 tranxdone_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static struct omap3_vp omap3_vp[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) [OMAP3_VP_VDD_MPU_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) [OMAP3_VP_VDD_CORE_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define MAX_VP_ID ARRAY_SIZE(omap3_vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static u32 omap3_prm_vp_check_txdone(u8 vp_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct omap3_vp *vp = &omap3_vp[vp_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) u32 irqstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return irqstatus & vp->tranxdone_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void omap3_prm_vp_clear_txdone(u8 vp_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct omap3_vp *vp = &omap3_vp[vp_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) omap2_prm_write_mod_reg(vp->tranxdone_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) u32 omap3_prm_vcvp_read(u8 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) void omap3_prm_vcvp_write(u32 val, u8 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * omap3xxx_prm_dpll3_reset - use DPLL3 reset to reboot the OMAP SoC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Set the DPLL3 reset bit, which should reboot the SoC. This is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * recommended way to restart the SoC, considering Errata i520. No
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void omap3xxx_prm_dpll3_reset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, OMAP3430_GR_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) OMAP2_RM_RSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* OCP barrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * omap3xxx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * @events: ptr to a u32, preallocated by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Read PRM_IRQSTATUS_MPU bits, AND'ed with the currently-enabled PRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * MPU IRQs, and store the result into the u32 pointed to by @events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static void omap3xxx_prm_read_pending_irqs(unsigned long *events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u32 mask, st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* XXX Can the mask read be avoided (e.g., can it come from RAM?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) mask = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) st = omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) events[0] = mask & st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * omap3xxx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Force any buffered writes to the PRM IP block to complete. Needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * by the PRM IRQ handler, which reads and writes directly to the IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * block, to avoid race conditions after acknowledging or clearing IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * bits. No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void omap3xxx_prm_ocp_barrier(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * omap3xxx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * @saved_mask: ptr to a u32 array to save IRQENABLE bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * Save the PRM_IRQENABLE_MPU register to @saved_mask. @saved_mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * must be allocated by the caller. Intended to be used in the PRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * interrupt handler suspend callback. The OCP barrier is needed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * ensure the write to disable PRM interrupts reaches the PRM before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * returning; otherwise, spurious interrupts might occur. No return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void omap3xxx_prm_save_and_clear_irqen(u32 *saved_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) saved_mask[0] = omap2_prm_read_mod_reg(OCP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) OMAP3_PRM_IRQENABLE_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /* OCP barrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) omap2_prm_read_mod_reg(OCP_MOD, OMAP3_PRM_REVISION_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * omap3xxx_prm_restore_irqen - set PRM_IRQENABLE_MPU register from args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Restore the PRM_IRQENABLE_MPU register from @saved_mask. Intended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * to be used in the PRM interrupt handler resume callback to restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * values saved by omap3xxx_prm_save_and_clear_irqen(). No OCP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * barrier should be needed here; any pending PRM interrupts will fire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * once the writes reach the PRM. No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static void omap3xxx_prm_restore_irqen(u32 *saved_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) omap2_prm_write_mod_reg(saved_mask[0], OCP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) OMAP3_PRM_IRQENABLE_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * omap3xxx_prm_clear_mod_irqs - clear wake-up events from PRCM interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * @module: PRM module to clear wakeups from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @regs: register set to clear, 1 or 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * @wkst_mask: wkst bits to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * The purpose of this function is to clear any wake-up events latched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * may occur whilst attempting to clear a PM_WKST_x register and thus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * set another bit in this register. A while loop is used to ensure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * that any peripheral wake-up events occurring while attempting to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * clear the PM_WKST_x are detected and cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) u32 wkst, fclk, iclk, clken;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u16 grpsel_off = (regs == 3) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) wkst = omap2_prm_read_mod_reg(module, wkst_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) wkst &= omap2_prm_read_mod_reg(module, grpsel_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) wkst &= wkst_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (wkst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) iclk = omap2_cm_read_mod_reg(module, iclk_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) fclk = omap2_cm_read_mod_reg(module, fclk_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) while (wkst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) clken = wkst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) omap2_cm_set_mod_reg_bits(clken, module, iclk_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * For USBHOST, we don't know whether HOST1 or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * HOST2 woke us up, so enable both f-clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (module == OMAP3430ES2_USBHOST_MOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) omap2_cm_set_mod_reg_bits(clken, module, fclk_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) omap2_prm_write_mod_reg(wkst, module, wkst_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) wkst = omap2_prm_read_mod_reg(module, wkst_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) wkst &= wkst_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) c++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) omap2_cm_write_mod_reg(iclk, module, iclk_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) omap2_cm_write_mod_reg(fclk, module, fclk_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * omap3_prm_reset_modem - toggle reset signal for modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * Toggles the reset signal to modem IP block. Required to allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * OMAP3430 without stacked modem to idle properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) void __init omap3_prm_reset_modem(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) omap2_prm_write_mod_reg(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) CORE_MOD, OMAP2_RM_RSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) omap2_prm_write_mod_reg(0, CORE_MOD, OMAP2_RM_RSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * omap3_prm_init_pm - initialize PM related registers for PRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * @has_uart4: SoC has UART4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * @has_iva: SoC has IVA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * Initializes PRM registers for PM use. Called from PM init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) void __init omap3_prm_init_pm(bool has_uart4, bool has_iva)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) u32 en_uart4_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) u32 grpsel_uart4_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * Enable control of expternal oscillator through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * sys_clkreq. In the long run clock framework should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * take care of this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) omap2_prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 1 << OMAP_AUTOEXTCLKMODE_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) OMAP3430_GR_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) OMAP3_PRM_CLKSRC_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* setup wakup source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) omap2_prm_write_mod_reg(OMAP3430_EN_IO_MASK | OMAP3430_EN_GPIO1_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) OMAP3430_EN_GPT1_MASK | OMAP3430_EN_GPT12_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) WKUP_MOD, PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* No need to write EN_IO, that is always enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) omap2_prm_write_mod_reg(OMAP3430_GRPSEL_GPIO1_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) OMAP3430_GRPSEL_GPT1_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) OMAP3430_GRPSEL_GPT12_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /* Enable PM_WKEN to support DSS LPR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) omap2_prm_write_mod_reg(OMAP3430_PM_WKEN_DSS_EN_DSS_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) OMAP3430_DSS_MOD, PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (has_uart4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) en_uart4_mask = OMAP3630_EN_UART4_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) grpsel_uart4_mask = OMAP3630_GRPSEL_UART4_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) en_uart4_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) grpsel_uart4_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Enable wakeups in PER */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) omap2_prm_write_mod_reg(en_uart4_mask |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) OMAP3430_EN_GPIO2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) OMAP3430_EN_GPIO3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) OMAP3430_EN_GPIO4_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) OMAP3430_EN_GPIO5_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) OMAP3430_EN_GPIO6_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) OMAP3430_EN_UART3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) OMAP3430_EN_MCBSP2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) OMAP3430_EN_MCBSP3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) OMAP3430_EN_MCBSP4_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) OMAP3430_PER_MOD, PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* and allow them to wake up MPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) omap2_prm_write_mod_reg(grpsel_uart4_mask |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) OMAP3430_GRPSEL_GPIO2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) OMAP3430_GRPSEL_GPIO3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) OMAP3430_GRPSEL_GPIO4_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) OMAP3430_GRPSEL_GPIO5_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) OMAP3430_GRPSEL_GPIO6_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) OMAP3430_GRPSEL_UART3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) OMAP3430_GRPSEL_MCBSP2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) OMAP3430_GRPSEL_MCBSP3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) OMAP3430_GRPSEL_MCBSP4_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* Don't attach IVA interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (has_iva) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) omap2_prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) omap2_prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) omap2_prm_write_mod_reg(0, OMAP3430_PER_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) OMAP3430_PM_IVAGRPSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* Clear any pending 'reset' flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) omap2_prm_write_mod_reg(0xffffffff, MPU_MOD, OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) omap2_prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) omap2_prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) omap2_prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) omap2_prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) omap2_prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* Clear any pending PRCM interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* We need to idle iva2_pwrdm even on am3703 with no iva2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) omap3xxx_prm_iva_idle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) omap3_prm_reset_modem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * omap3430_pre_es3_1_reconfigure_io_chain - restart wake-up daisy chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * The ST_IO_CHAIN bit does not exist in 3430 before es3.1. The only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * thing we can do is toggle EN_IO bit for earlier omaps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static void omap3430_pre_es3_1_reconfigure_io_chain(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) omap2_prm_read_mod_reg(WKUP_MOD, PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * omap3_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * Clear any previously-latched I/O wakeup events and ensure that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * I/O wakeup gates are aligned with the current mux settings. Works
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * deasserting WUCLKIN and clearing the ST_IO_CHAIN WKST bit. No
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * return value. These registers are only available in 3430 es3.1 and later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static void omap3_prm_reconfigure_io_chain(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) omap_test_timeout(omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) OMAP3430_ST_IO_CHAIN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) MAX_IOPAD_LATCH_TIME, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (i == MAX_IOPAD_LATCH_TIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) pr_warn("PRM: I/O chain clock line assertion timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) omap2_prm_clear_mod_reg_bits(OMAP3430_EN_IO_CHAIN_MASK, WKUP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) omap2_prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, WKUP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) PM_WKST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) omap2_prm_read_mod_reg(WKUP_MOD, PM_WKST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * omap3xxx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * Activates the I/O wakeup event latches and allows events logged by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * those latches to signal a wakeup event to the PRCM. For I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * wakeups to occur, WAKEUPENABLE bits must be set in the pad mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static void omap3xxx_prm_enable_io_wakeup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (prm_features & PRM_HAS_IO_WAKEUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) PM_WKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * omap3xxx_prm_read_reset_sources - return the last SoC reset source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * Return a u32 representing the last reset sources of the SoC. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * returned reset source bits are standardized across OMAP SoCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static u32 omap3xxx_prm_read_reset_sources(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct prm_reset_src_map *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u32 r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) p = omap3xxx_prm_reset_src_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) while (p->reg_shift >= 0 && p->std_shift >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (v & (1 << p->reg_shift))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) r |= 1 << p->std_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * omap3xxx_prm_iva_idle - ensure IVA is in idle so it can be put into retention
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * In cases where IVA2 is activated by bootcode, it may prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * full-chip retention or off-mode because it is not idle. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * function forces the IVA2 into idle state so it can go
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * into retention/off and thus allow full-chip retention/off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) void omap3xxx_prm_iva_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) /* ensure IVA2 clock is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* if no clock activity, nothing else to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!(omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) OMAP3430_CLKACTIVITY_IVA2_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* Reset IVA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) OMAP3430_RST2_IVA2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) OMAP3430_RST3_IVA2_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* Enable IVA2 clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) omap2_cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) OMAP3430_IVA2_MOD, CM_FCLKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* Un-reset IVA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) omap2_prm_write_mod_reg(0, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Disable IVA2 clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) omap2_cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* Reset IVA2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) omap2_prm_write_mod_reg(OMAP3430_RST1_IVA2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) OMAP3430_RST2_IVA2_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) OMAP3430_RST3_IVA2_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * omap3xxx_prm_clear_global_cold_reset - checks the global cold reset status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * and clears it if asserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * Checks if cold-reset has occurred and clears the status bit if yes. Returns
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * 1 if cold-reset has occurred, 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) int omap3xxx_prm_clear_global_cold_reset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) OMAP3430_GLOBAL_COLD_RST_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) OMAP3430_GR_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) OMAP3_PRM_RSTST_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) void omap3_prm_save_scratchpad_contents(u32 *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) OMAP3_PRM_CLKSRC_CTRL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) *ptr++ = omap2_prm_read_mod_reg(OMAP3430_GR_MOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) OMAP3_PRM_CLKSEL_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* Powerdomain low-level functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int omap3_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) (pwrst << OMAP_POWERSTATE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) static int omap3_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) OMAP2_PM_PWSTCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) OMAP_POWERSTATE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) static int omap3_pwrdm_read_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) OMAP2_PM_PWSTST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) OMAP_POWERSTATEST_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* Applicable only for OMAP3. Not supported on OMAP2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static int omap3_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) OMAP3430_PM_PREPWSTST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) OMAP3430_LASTPOWERSTATEENTERED_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static int omap3_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) OMAP2_PM_PWSTST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) OMAP3430_LOGICSTATEST_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int omap3_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) OMAP2_PM_PWSTCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) OMAP3430_LOGICSTATEST_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static int omap3_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) OMAP3430_PM_PREPWSTST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) OMAP3430_LASTLOGICSTATEENTERED_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static int omap3_get_mem_bank_lastmemst_mask(u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) switch (bank) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return OMAP3430_LASTMEM1STATEENTERED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return OMAP3430_LASTMEM2STATEENTERED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) WARN_ON(1); /* should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) static int omap3_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) u32 m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) m = omap3_get_mem_bank_lastmemst_mask(bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) OMAP3430_PM_PREPWSTST, m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static int omap3_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) omap2_prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int omap3_pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return omap2_prm_rmw_mod_reg_bits(0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int omap3_pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return omap2_prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 0, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) OMAP2_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct pwrdm_ops omap3_pwrdm_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .pwrdm_set_next_pwrst = omap3_pwrdm_set_next_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) .pwrdm_read_next_pwrst = omap3_pwrdm_read_next_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .pwrdm_read_pwrst = omap3_pwrdm_read_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) .pwrdm_read_prev_pwrst = omap3_pwrdm_read_prev_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .pwrdm_read_logic_pwrst = omap3_pwrdm_read_logic_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .pwrdm_read_logic_retst = omap3_pwrdm_read_logic_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .pwrdm_read_prev_logic_pwrst = omap3_pwrdm_read_prev_logic_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) .pwrdm_read_prev_mem_pwrst = omap3_pwrdm_read_prev_mem_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) .pwrdm_clear_all_prev_pwrst = omap3_pwrdm_clear_all_prev_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) .pwrdm_enable_hdwr_sar = omap3_pwrdm_enable_hdwr_sar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .pwrdm_disable_hdwr_sar = omap3_pwrdm_disable_hdwr_sar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static int omap3xxx_prm_late_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static struct prm_ll_data omap3xxx_prm_ll_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) .read_reset_sources = &omap3xxx_prm_read_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) .late_init = &omap3xxx_prm_late_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .assert_hardreset = &omap2_prm_assert_hardreset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .deassert_hardreset = &omap2_prm_deassert_hardreset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .reset_system = &omap3xxx_prm_dpll3_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .clear_mod_irqs = &omap3xxx_prm_clear_mod_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .vp_check_txdone = &omap3_prm_vp_check_txdone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .vp_clear_txdone = &omap3_prm_vp_clear_txdone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) omap2_clk_legacy_provider_init(TI_CLKM_PRM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) prm_base.va + OMAP3430_IVA2_MOD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (omap3_has_io_wakeup())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) prm_features |= PRM_HAS_IO_WAKEUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return prm_register(&omap3xxx_prm_ll_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static const struct of_device_id omap3_prm_dt_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) { .compatible = "ti,omap3-prm" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int omap3xxx_prm_late_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) int irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (!(prm_features & PRM_HAS_IO_WAKEUP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (omap3_has_io_chain_ctrl())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) omap3_prcm_irq_setup.reconfigure_io_chain =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) omap3_prm_reconfigure_io_chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) omap3_prcm_irq_setup.reconfigure_io_chain =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) omap3430_pre_es3_1_reconfigure_io_chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) np = of_find_matching_node(NULL, omap3_prm_dt_match_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) pr_err("PRM: no device tree node for interrupt?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) irq_num = of_irq_get(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (irq_num == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) omap3_prcm_irq_setup.irq = irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) omap3xxx_prm_enable_io_wakeup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static void __exit omap3xxx_prm_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) prm_unregister(&omap3xxx_prm_ll_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) __exitcall(omap3xxx_prm_exit);