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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/genalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/fncpy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/system_misc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/tlbflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "cpuidle.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include "hardware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define MXC_CCM_CLPCR			0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define MXC_CCM_CLPCR_LPM_OFFSET	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define MXC_CCM_CLPCR_LPM_MASK		0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define MXC_CCM_CLPCR_STBY_COUNT_OFFSET	9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define MXC_CCM_CLPCR_VSTBY		(0x1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define MXC_CCM_CLPCR_SBYOS		(0x1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define MXC_CORTEXA8_PLAT_LPC		0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define MXC_CORTEXA8_PLAT_LPC_DSM	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define MXC_CORTEXA8_PLAT_LPC_DBG_DSM	(1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define MXC_SRPG_NEON_SRPGCR		0x280
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define MXC_SRPG_ARM_SRPGCR		0x2a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define MXC_SRPG_EMPGC0_SRPGCR		0x2c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define MXC_SRPG_EMPGC1_SRPGCR		0x2d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define MXC_SRPGCR_PCR			1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * The WAIT_UNCLOCKED_POWER_OFF state only requires <= 500ns to exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * This is also the lowest power state possible without affecting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * non-cpu parts of the system.  For these reasons, imx5 should default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * to always using this state for cpu idling.  The PM_SUSPEND_STANDBY also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * uses this state and needs to take no action when registers remain confgiured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * for this state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) struct imx5_suspend_io_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	u32	offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	u32	clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	u32	set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	u32	saved_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) struct imx5_pm_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	phys_addr_t ccm_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	phys_addr_t cortex_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	phys_addr_t gpc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	phys_addr_t m4if_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	phys_addr_t iomuxc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	void (*suspend_asm)(void __iomem *ocram_vbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	const u32 *suspend_asm_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	const struct imx5_suspend_io_state *suspend_io_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	int suspend_io_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static const struct imx5_suspend_io_state imx53_suspend_io_config[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define MX53_DSE_HIGHZ_MASK (0x7 << 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	{.offset = 0x584, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	{.offset = 0x594, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	{.offset = 0x560, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	{.offset = 0x554, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	{.offset = 0x574, .clear = MX53_DSE_HIGHZ_MASK}, /* CAS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	{.offset = 0x588, .clear = MX53_DSE_HIGHZ_MASK}, /* RAS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	{.offset = 0x578, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	{.offset = 0x570, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	{.offset = 0x580, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	{.offset = 0x564, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	{.offset = 0x57c, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	{.offset = 0x590, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	{.offset = 0x568, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	{.offset = 0x558, .clear = MX53_DSE_HIGHZ_MASK}, /* SDSQ3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	{.offset = 0x6f0, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_ADDS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	{.offset = 0x718, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_BODS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	{.offset = 0x71c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B1DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	{.offset = 0x728, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B2DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	{.offset = 0x72c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B3DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	/* Controls the CKE signal which is required to leave self refresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{.offset = 0x720, .clear = MX53_DSE_HIGHZ_MASK, .set = 1 << 19}, /* CTLDS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static const struct imx5_pm_data imx51_pm_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	.ccm_addr = 0x73fd4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	.cortex_addr = 0x83fa0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	.gpc_addr = 0x73fd8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static const struct imx5_pm_data imx53_pm_data __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	.ccm_addr = 0x53fd4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	.cortex_addr = 0x63fa0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.gpc_addr = 0x53fd8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.m4if_addr = 0x63fd8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	.iomuxc_addr = 0x53fa8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	.suspend_asm = &imx53_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	.suspend_asm_sz = &imx53_suspend_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	.suspend_io_config = imx53_suspend_io_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	.suspend_io_count = ARRAY_SIZE(imx53_suspend_io_config),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define MX5_MAX_SUSPEND_IOSTATE ARRAY_SIZE(imx53_suspend_io_config)
^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)  * This structure is for passing necessary data for low level ocram
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * suspend code(arch/arm/mach-imx/suspend-imx53.S), if this struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * definition is changed, the offset definition in that file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * must be also changed accordingly otherwise, the suspend to ocram
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * function will be broken!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct imx5_cpu_suspend_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	void __iomem	*m4if_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	void __iomem	*iomuxc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	u32		io_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	struct imx5_suspend_io_state io_state[MX5_MAX_SUSPEND_IOSTATE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) } __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void __iomem *ccm_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static void __iomem *cortex_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static void __iomem *gpc_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void __iomem *suspend_ocram_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void (*imx5_suspend_in_ocram_fn)(void __iomem *ocram_vbase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * set cpu low power mode before WFI instruction. This function is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * mx5 because it can be used for mx51, and mx53.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	u32 plat_lpc, arm_srpgcr, ccm_clpcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	u32 empgc0, empgc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	int stop_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	/* always allow platform to issue a deep sleep mode request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	plat_lpc = imx_readl(cortex_base + MXC_CORTEXA8_PLAT_LPC) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	    ~(MXC_CORTEXA8_PLAT_LPC_DSM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ccm_clpcr = imx_readl(ccm_base + MXC_CCM_CLPCR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		    ~(MXC_CCM_CLPCR_LPM_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	arm_srpgcr = imx_readl(gpc_base + MXC_SRPG_ARM_SRPGCR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		     ~(MXC_SRPGCR_PCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	empgc0 = imx_readl(gpc_base + MXC_SRPG_EMPGC0_SRPGCR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		 ~(MXC_SRPGCR_PCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	empgc1 = imx_readl(gpc_base + MXC_SRPG_EMPGC1_SRPGCR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		 ~(MXC_SRPGCR_PCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	case WAIT_CLOCKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	case WAIT_UNCLOCKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	case WAIT_UNCLOCKED_POWER_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	case STOP_POWER_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			    | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		if (mode == WAIT_UNCLOCKED_POWER_OFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 			ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			stop_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			stop_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		arm_srpgcr |= MXC_SRPGCR_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	case STOP_POWER_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	imx_writel(plat_lpc, cortex_base + MXC_CORTEXA8_PLAT_LPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	imx_writel(ccm_clpcr, ccm_base + MXC_CCM_CLPCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_ARM_SRPGCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	imx_writel(arm_srpgcr, gpc_base + MXC_SRPG_NEON_SRPGCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (stop_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		empgc0 |= MXC_SRPGCR_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		empgc1 |= MXC_SRPGCR_PCR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		imx_writel(empgc0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		imx_writel(empgc1, gpc_base + MXC_SRPG_EMPGC1_SRPGCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int mx5_suspend_enter(suspend_state_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	case PM_SUSPEND_MEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		mx5_cpu_lp_set(STOP_POWER_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	case PM_SUSPEND_STANDBY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		/* DEFAULT_IDLE_STATE already configured */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	if (state == PM_SUSPEND_MEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		local_flush_tlb_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		flush_cache_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		/*clear the EMPGC0/1 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		imx_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		imx_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		if (imx5_suspend_in_ocram_fn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			imx5_suspend_in_ocram_fn(suspend_ocram_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			cpu_do_idle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		cpu_do_idle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	/* return registers to default idle state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int mx5_pm_valid(suspend_state_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
^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) static const struct platform_suspend_ops mx5_suspend_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	.valid = mx5_pm_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	.enter = mx5_suspend_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static inline int imx5_cpu_do_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	int ret = tzic_enable_wake();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (likely(!ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		cpu_do_idle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	return ret;
^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) static void imx5_pm_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	imx5_cpu_do_idle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int __init imx_suspend_alloc_ocram(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 				size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 				void __iomem **virt_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				phys_addr_t *phys_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	struct gen_pool *ocram_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	unsigned long ocram_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	void __iomem *virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	phys_addr_t phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	/* Copied from imx6: TODO factorize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	node = of_find_compatible_node(NULL, NULL, "mmio-sram");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	if (!node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		pr_warn("%s: failed to find ocram node!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	pdev = of_find_device_by_node(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		pr_warn("%s: failed to find ocram device!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		goto put_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	ocram_pool = gen_pool_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (!ocram_pool) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		pr_warn("%s: ocram pool unavailable!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		goto put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	ocram_base = gen_pool_alloc(ocram_pool, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	if (!ocram_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		pr_warn("%s: unable to alloc ocram!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		goto put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	phys = gen_pool_virt_to_phys(ocram_pool, ocram_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	virt = __arm_ioremap_exec(phys, size, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (phys_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		*phys_out = phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	if (virt_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		*virt_out = virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) put_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	put_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) put_node:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	of_node_put(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static int __init imx5_suspend_init(const struct imx5_pm_data *soc_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	struct imx5_cpu_suspend_info *suspend_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	/* Need this to avoid compile error due to const typeof in fncpy.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	void (*suspend_asm)(void __iomem *) = soc_data->suspend_asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (!suspend_asm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (!soc_data->suspend_asm_sz || !*soc_data->suspend_asm_sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	ret = imx_suspend_alloc_ocram(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		*soc_data->suspend_asm_sz + sizeof(*suspend_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		&suspend_ocram_base, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	suspend_info = suspend_ocram_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	suspend_info->io_count = soc_data->suspend_io_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	memcpy(suspend_info->io_state, soc_data->suspend_io_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	       sizeof(*suspend_info->io_state) * soc_data->suspend_io_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	suspend_info->m4if_base = ioremap(soc_data->m4if_addr, SZ_16K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	if (!suspend_info->m4if_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		goto failed_map_m4if;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	suspend_info->iomuxc_base = ioremap(soc_data->iomuxc_addr, SZ_16K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (!suspend_info->iomuxc_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		goto failed_map_iomuxc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	imx5_suspend_in_ocram_fn = fncpy(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		suspend_ocram_base + sizeof(*suspend_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		suspend_asm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		*soc_data->suspend_asm_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) failed_map_iomuxc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	iounmap(suspend_info->m4if_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) failed_map_m4if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static int __init imx5_pm_common_init(const struct imx5_pm_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	struct clk *gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	if (IS_ERR(gpc_dvfs_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		return PTR_ERR(gpc_dvfs_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	ret = clk_prepare_enable(gpc_dvfs_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	arm_pm_idle = imx5_pm_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	ccm_base = ioremap(data->ccm_addr, SZ_16K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	cortex_base = ioremap(data->cortex_addr, SZ_16K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	gpc_base = ioremap(data->gpc_addr, SZ_16K);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	WARN_ON(!ccm_base || !cortex_base || !gpc_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	/* Set the registers to the default cpu idle state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	ret = imx5_cpuidle_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		pr_warn("%s: cpuidle init failed %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	ret = imx5_suspend_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		pr_warn("%s: No DDR LPM support with suspend %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			__func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	suspend_set_ops(&mx5_suspend_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	return 0;
^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) void __init imx51_pm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	if (IS_ENABLED(CONFIG_SOC_IMX51))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		imx5_pm_common_init(&imx51_pm_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) void __init imx53_pm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	if (IS_ENABLED(CONFIG_SOC_IMX53))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		imx5_pm_common_init(&imx53_pm_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }