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)  * 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);