Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)  * OMAP4 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) 2011-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/cpu_pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "soc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "iomap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "vp.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "prm44xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include "prcm43xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "prm-regbits-44xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include "prcm44xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include "prminst44xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include "powerdomain.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include "pm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) /* Static data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static void omap44xx_prm_read_pending_irqs(unsigned long *events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static void omap44xx_prm_ocp_barrier(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static void omap44xx_prm_restore_irqen(u32 *saved_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static void omap44xx_prm_reconfigure_io_chain(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) static const struct omap_prcm_irq omap4_prcm_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	OMAP_PRCM_IRQ("io",     9,      1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	.ack			= OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	.mask			= OMAP4_PRM_IRQENABLE_MPU_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	.pm_ctrl		= OMAP4_PRM_IO_PMCTRL_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	.nr_regs		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	.irqs			= omap4_prcm_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	.nr_irqs		= ARRAY_SIZE(omap4_prcm_irqs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	.read_pending_irqs	= &omap44xx_prm_read_pending_irqs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	.ocp_barrier		= &omap44xx_prm_ocp_barrier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	.save_and_clear_irqen	= &omap44xx_prm_save_and_clear_irqen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	.restore_irqen		= &omap44xx_prm_restore_irqen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	.reconfigure_io_chain	= &omap44xx_prm_reconfigure_io_chain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) struct omap_prm_irq_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned long irq_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned long pm_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static struct omap_prm_irq_context omap_prm_context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *   hardware register (which are specific to OMAP44xx SoCs) to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  *   source ID bit shifts (which is an OMAP SoC-independent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  *   enumeration)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	{ OMAP4430_GLOBAL_WARM_SW_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	  OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	{ OMAP4430_GLOBAL_COLD_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	  OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	{ OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	  OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	{ OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	{ OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	{ OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{ OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	  OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	{ OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	  OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	{ OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	  OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	{ OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	{ OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	{ -1, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) /* PRM low-level functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) /* Read a register in a CM/PRM instance in the PRM module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	return readl_relaxed(prm_base.va + inst + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Write into a register in a CM/PRM instance in the PRM module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	writel_relaxed(val, prm_base.va + inst + reg);
^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) /* Read-modify-write a register in a PRM module. Caller must lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	v = omap4_prm_read_inst_reg(inst, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	v &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	v |= bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	omap4_prm_write_inst_reg(v, inst, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return v;
^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) /* PRM VP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * struct omap4_vp - OMAP4 VP register access description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct omap4_vp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	u32 irqstatus_mpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	u32 tranxdone_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static struct omap4_vp omap4_vp[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	[OMAP4_VP_VDD_MPU_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		.irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		.tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	[OMAP4_VP_VDD_IVA_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		.irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		.tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	[OMAP4_VP_VDD_CORE_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		.irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		.tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static u32 omap4_prm_vp_check_txdone(u8 vp_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct omap4_vp *vp = &omap4_vp[vp_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	u32 irqstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 						OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 						vp->irqstatus_mpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	return irqstatus & vp->tranxdone_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static void omap4_prm_vp_clear_txdone(u8 vp_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	struct omap4_vp *vp = &omap4_vp[vp_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	omap4_prminst_write_inst_reg(vp->tranxdone_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				     OMAP4430_PRM_PARTITION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				     OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				     vp->irqstatus_mpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u32 omap4_prm_vcvp_read(u8 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	s32 inst = omap4_prmst_get_prm_dev_inst();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (inst == PRM_INSTANCE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 					   inst, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) void omap4_prm_vcvp_write(u32 val, u8 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	s32 inst = omap4_prmst_get_prm_dev_inst();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	if (inst == PRM_INSTANCE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 				     inst, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	s32 inst = omap4_prmst_get_prm_dev_inst();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (inst == PRM_INSTANCE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	return omap4_prminst_rmw_inst_reg_bits(mask, bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 					       OMAP4430_PRM_PARTITION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 					       inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 					       offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	u32 mask, st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	/* XXX read mask from RAM? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 				       irqen_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	return mask & st;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  * @events: ptr to two consecutive u32s, preallocated by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * MPU IRQs, and store the result into the two u32s pointed to by @events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static void omap44xx_prm_read_pending_irqs(unsigned long *events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		events[i] = _read_pending_irq_reg(omap4_prcm_irq_setup.mask +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 				i * 4, omap4_prcm_irq_setup.ack + i * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  * Force any buffered writes to the PRM IP block to complete.  Needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * by the PRM IRQ handler, which reads and writes directly to the IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  * block, to avoid race conditions after acknowledging or clearing IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  * bits.  No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void omap44xx_prm_ocp_barrier(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 				OMAP4_REVISION_PRM_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * @saved_mask: ptr to a u32 array to save IRQENABLE bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * @saved_mask.  @saved_mask must be allocated by the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * Intended to be used in the PRM interrupt handler suspend callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * The OCP barrier is needed to ensure the write to disable PRM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * interrupts reaches the PRM before returning; otherwise, spurious
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * interrupts might occur.  No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	u16 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		reg = omap4_prcm_irq_setup.mask + i * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		saved_mask[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 						reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	/* OCP barrier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				OMAP4_REVISION_PRM_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  * @saved_mask.  Intended to be used in the PRM interrupt handler resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * callback to restore values saved by omap44xx_prm_save_and_clear_irqen().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * No OCP barrier should be needed here; any pending PRM interrupts will fire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * once the writes reach the PRM.  No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static void omap44xx_prm_restore_irqen(u32 *saved_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		omap4_prm_write_inst_reg(saved_mask[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 					 OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 					 omap4_prcm_irq_setup.mask + i * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  * Clear any previously-latched I/O wakeup events and ensure that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  * I/O wakeup gates are aligned with the current mux settings.  Works
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * No return value. XXX Are the final two steps necessary?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static void omap44xx_prm_reconfigure_io_chain(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	s32 inst = omap4_prmst_get_prm_dev_inst();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (inst == PRM_INSTANCE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	/* Trigger WUCLKIN enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 				    OMAP4430_WUCLK_CTRL_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 				    inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 				    omap4_prcm_irq_setup.pm_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	omap_test_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		(((omap4_prm_read_inst_reg(inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 					   omap4_prcm_irq_setup.pm_ctrl) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		   OMAP4430_WUCLK_STATUS_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		  OMAP4430_WUCLK_STATUS_SHIFT) == 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		MAX_IOPAD_LATCH_TIME, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (i == MAX_IOPAD_LATCH_TIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		pr_warn("PRM: I/O chain clock line assertion timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	/* Trigger WUCLKIN disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 				    inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 				    omap4_prcm_irq_setup.pm_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	omap_test_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		(((omap4_prm_read_inst_reg(inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 					   omap4_prcm_irq_setup.pm_ctrl) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		   OMAP4430_WUCLK_STATUS_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		  OMAP4430_WUCLK_STATUS_SHIFT) == 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		MAX_IOPAD_LATCH_TIME, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	if (i == MAX_IOPAD_LATCH_TIME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		pr_warn("PRM: I/O chain clock line deassertion timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)  * Activates the I/O wakeup event latches and allows events logged by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)  * those latches to signal a wakeup event to the PRCM.  For I/O wakeups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)  * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)  * omap44xx_prm_reconfigure_io_chain() must be called.  No return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void omap44xx_prm_enable_io_wakeup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	s32 inst = omap4_prmst_get_prm_dev_inst();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (inst == PRM_INSTANCE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 				    OMAP4430_GLOBAL_WUEN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 				    inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 				    omap4_prcm_irq_setup.pm_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)  * omap44xx_prm_read_reset_sources - return the last SoC reset source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)  * Return a u32 representing the last reset sources of the SoC.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)  * returned reset source bits are standardized across OMAP SoCs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static u32 omap44xx_prm_read_reset_sources(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	struct prm_reset_src_map *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	u32 r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	s32 inst = omap4_prmst_get_prm_dev_inst();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	if (inst == PRM_INSTANCE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	v = omap4_prm_read_inst_reg(inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 				    OMAP4_RM_RSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	p = omap44xx_prm_reset_src_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	while (p->reg_shift >= 0 && p->std_shift >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		if (v & (1 << p->reg_shift))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			r |= 1 << p->std_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	return r;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  * omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * @idx: CONTEXT register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  * Return 1 if any bits were set in the *_CONTEXT_* register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  * identified by (@part, @inst, @idx), which means that some context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * was lost for that module; otherwise, return 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)  * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)  * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  * @idx: CONTEXT register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  * Clear hardware context loss bits for the module identified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  * (@part, @inst, @idx).  No return value.  XXX Writes to reserved bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * is there a way to avoid this?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 						      u16 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
^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) /* Powerdomain low-level functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 					(pwrst << OMAP_POWERSTATE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 					pwrdm->prcm_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 					pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 					OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	v &= OMAP_POWERSTATE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	v >>= OMAP_POWERSTATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^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 = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 					OMAP4_PM_PWSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	v &= OMAP_POWERSTATEST_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	v >>= OMAP_POWERSTATEST_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 					OMAP4_PM_PWSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 					(1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 					pwrdm->prcm_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 					pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 					OMAP4430_LASTPOWERSTATEENTERED_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 					pwrdm->prcm_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 					pwrdm->prcm_offs, OMAP4_PM_PWSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 					pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 					OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 				    u8 pwrst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	u32 m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 					pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 					OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 				     u8 pwrst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	u32 m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 					pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 					OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 					OMAP4_PM_PWSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	v &= OMAP4430_LOGICSTATEST_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	v >>= OMAP4430_LOGICSTATEST_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	u32 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 					OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	v &= OMAP4430_LOGICRETSTATE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	v >>= OMAP4430_LOGICRETSTATE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)  * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)  * @pwrdm: struct powerdomain * to read the state for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)  * Reads the previous logic powerstate for a powerdomain. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)  * function must determine the previous logic powerstate by first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)  * checking the previous powerstate for the domain. If that was OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)  * then logic has been lost. If previous state was RETENTION, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  * function reads the setting for the next retention logic state to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)  * see the actual value.  In every other case, the logic is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)  * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)  * depending whether the logic was retained or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	state = omap4_pwrdm_read_prev_pwrst(pwrdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	if (state == PWRDM_POWER_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		return PWRDM_POWER_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	if (state != PWRDM_POWER_RET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		return PWRDM_POWER_RET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	return omap4_pwrdm_read_logic_retst(pwrdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	u32 m, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 					OMAP4_PM_PWSTST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	v &= m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	v >>= __ffs(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	u32 m, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 					OMAP4_PM_PWSTCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	v &= m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	v >>= __ffs(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)  * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)  * @pwrdm: struct powerdomain * to read mem powerstate for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)  * @bank: memory bank index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)  * Reads the previous memory powerstate for a powerdomain. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)  * function must determine the previous memory powerstate by first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)  * checking the previous powerstate for the domain. If that was OFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)  * then logic has been lost. If previous state was RETENTION, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)  * function reads the setting for the next memory retention state to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)  * see the actual value.  In every other case, the logic is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)  * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)  * depending whether logic was retained or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	state = omap4_pwrdm_read_prev_pwrst(pwrdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	if (state == PWRDM_POWER_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		return PWRDM_POWER_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	if (state != PWRDM_POWER_RET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 		return PWRDM_POWER_RET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	return omap4_pwrdm_read_mem_retst(pwrdm, bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	u32 c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	 * REVISIT: pwrdm_wait_transition() may be better implemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	 * via a callback and a periodic timer check -- how long do we expect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	 * powerdomain transitions to take?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	/* XXX Is this udelay() value meaningful? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 					    pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 					    OMAP4_PM_PWSTST) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		OMAP_INTRANSITION_MASK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	       (c++ < PWRDM_TRANSITION_BAILOUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	if (c > PWRDM_TRANSITION_BAILOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		pr_err("powerdomain: %s: waited too long to complete transition\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 		       pwrdm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	pr_debug("powerdomain: completed transition in %d loops\n", c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static int omap4_check_vcvp(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	if (prm_features & PRM_HAS_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)  * omap4_pwrdm_save_context - Saves the powerdomain state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)  * @pwrdm: pointer to individual powerdomain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)  * The function saves the powerdomain state control information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)  * This is needed in rtc+ddr modes where we lose powerdomain context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static void omap4_pwrdm_save_context(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	pwrdm->context = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 						     pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 						     pwrdm->pwrstctrl_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	 * Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	 * reading back a 1 indicates a request in progress.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	pwrdm->context &= ~OMAP4430_LOWPOWERSTATECHANGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)  * omap4_pwrdm_restore_context - Restores the powerdomain state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)  * @pwrdm: pointer to individual powerdomain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)  * The function restores the powerdomain state control information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)  * This is needed in rtc+ddr modes where we lose powerdomain context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static void omap4_pwrdm_restore_context(struct powerdomain *pwrdm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	int st, ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	st = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 					 pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 					 pwrdm->pwrstctrl_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	omap4_prminst_write_inst_reg(pwrdm->context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 				     pwrdm->prcm_partition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 				     pwrdm->prcm_offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 				     pwrdm->pwrstctrl_offs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	/* Make sure we only wait for a transition if there is one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	st &= OMAP_POWERSTATEST_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	if (st != ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		omap4_pwrdm_wait_transition(pwrdm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct pwrdm_ops omap4_pwrdm_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	.pwrdm_set_next_pwrst	= omap4_pwrdm_set_next_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	.pwrdm_read_next_pwrst	= omap4_pwrdm_read_next_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	.pwrdm_read_pwrst	= omap4_pwrdm_read_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	.pwrdm_read_prev_pwrst	= omap4_pwrdm_read_prev_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	.pwrdm_set_lowpwrstchange	= omap4_pwrdm_set_lowpwrstchange,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	.pwrdm_clear_all_prev_pwrst	= omap4_pwrdm_clear_all_prev_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	.pwrdm_set_logic_retst	= omap4_pwrdm_set_logic_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	.pwrdm_read_logic_pwrst	= omap4_pwrdm_read_logic_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	.pwrdm_read_prev_logic_pwrst	= omap4_pwrdm_read_prev_logic_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	.pwrdm_read_logic_retst	= omap4_pwrdm_read_logic_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	.pwrdm_read_mem_pwrst	= omap4_pwrdm_read_mem_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	.pwrdm_read_mem_retst	= omap4_pwrdm_read_mem_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	.pwrdm_read_prev_mem_pwrst	= omap4_pwrdm_read_prev_mem_pwrst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	.pwrdm_set_mem_onst	= omap4_pwrdm_set_mem_onst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	.pwrdm_set_mem_retst	= omap4_pwrdm_set_mem_retst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	.pwrdm_wait_transition	= omap4_pwrdm_wait_transition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	.pwrdm_has_voltdm	= omap4_check_vcvp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	.pwrdm_save_context	= omap4_pwrdm_save_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	.pwrdm_restore_context	= omap4_pwrdm_restore_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static int omap44xx_prm_late_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static void prm_save_context(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	omap_prm_context.irq_enable =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 			omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 						omap4_prcm_irq_setup.mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	omap_prm_context.pm_ctrl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 			omap4_prm_read_inst_reg(AM43XX_PRM_DEVICE_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 						omap4_prcm_irq_setup.pm_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static void prm_restore_context(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 				 OMAP4430_PRM_OCP_SOCKET_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 				 omap4_prcm_irq_setup.mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	omap4_prm_write_inst_reg(omap_prm_context.pm_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 				 AM43XX_PRM_DEVICE_INST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 				 omap4_prcm_irq_setup.pm_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	case CPU_CLUSTER_PM_ENTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		if (enable_off_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 			prm_save_context();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	case CPU_CLUSTER_PM_EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		if (enable_off_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 			prm_restore_context();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)  * XXX document
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static struct prm_ll_data omap44xx_prm_ll_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	.read_reset_sources = &omap44xx_prm_read_reset_sources,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	.late_init = &omap44xx_prm_late_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	.assert_hardreset	= omap4_prminst_assert_hardreset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	.deassert_hardreset	= omap4_prminst_deassert_hardreset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	.is_hardreset_asserted	= omap4_prminst_is_hardreset_asserted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	.reset_system		= omap4_prminst_global_warm_sw_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	.vp_check_txdone	= omap4_prm_vp_check_txdone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	.vp_clear_txdone	= omap4_prm_vp_clear_txdone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static const struct omap_prcm_init_data *prm_init_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	static struct notifier_block nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	omap_prm_base_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	prm_init_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	if (data->flags & PRM_HAS_IO_WAKEUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		prm_features |= PRM_HAS_IO_WAKEUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	if (data->flags & PRM_HAS_VOLTAGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		prm_features |= PRM_HAS_VOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	/* Add AM437X specific differences */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	if (of_device_is_compatible(data->np, "ti,am4-prcm")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 		omap4_prcm_irq_setup.nr_irqs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 		omap4_prcm_irq_setup.nr_regs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 		omap4_prcm_irq_setup.pm_ctrl = AM43XX_PRM_IO_PMCTRL_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 		omap4_prcm_irq_setup.ack = AM43XX_PRM_IRQSTATUS_MPU_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		omap4_prcm_irq_setup.mask = AM43XX_PRM_IRQENABLE_MPU_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	/* Only AM43XX can lose prm context during rtc-ddr suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	if (soc_is_am43xx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		nb.notifier_call = cpu_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 		cpu_pm_register_notifier(&nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	return prm_register(&omap44xx_prm_ll_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static int omap44xx_prm_late_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	int irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	if (!(prm_features & PRM_HAS_IO_WAKEUP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	irq_num = of_irq_get(prm_init_data->np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	if (irq_num == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 		return irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	omap4_prcm_irq_setup.irq = irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	omap44xx_prm_enable_io_wakeup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) static void __exit omap44xx_prm_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	prm_unregister(&omap44xx_prm_ll_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) __exitcall(omap44xx_prm_exit);