1 /* linux/arch/arm/mach-exynos4/pmu.c
2  *
3  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4  *		http://www.samsung.com/
5  *
6  * EXYNOS4210 - CPU PMU(Power Management Unit) support
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/io.h>
14 #include <linux/kernel.h>
15 
16 #include <mach/regs-clock.h>
17 #include <mach/pmu.h>
18 
19 static struct exynos4_pmu_conf *exynos4_pmu_config;
20 
21 static struct exynos4_pmu_conf exynos4210_pmu_config[] = {
22 	/* { .reg = address, .val = { AFTR, LPA, SLEEP } */
23 	{ S5P_ARM_CORE0_LOWPWR,			{ 0x0, 0x0, 0x2 } },
24 	{ S5P_DIS_IRQ_CORE0,			{ 0x0, 0x0, 0x0 } },
25 	{ S5P_DIS_IRQ_CENTRAL0,			{ 0x0, 0x0, 0x0 } },
26 	{ S5P_ARM_CORE1_LOWPWR,			{ 0x0, 0x0, 0x2 } },
27 	{ S5P_DIS_IRQ_CORE1,			{ 0x0, 0x0, 0x0 } },
28 	{ S5P_DIS_IRQ_CENTRAL1,			{ 0x0, 0x0, 0x0 } },
29 	{ S5P_ARM_COMMON_LOWPWR,		{ 0x0, 0x0, 0x2 } },
30 	{ S5P_L2_0_LOWPWR,			{ 0x2, 0x2, 0x3 } },
31 	{ S5P_L2_1_LOWPWR,			{ 0x2, 0x2, 0x3 } },
32 	{ S5P_CMU_ACLKSTOP_LOWPWR,		{ 0x1, 0x0, 0x0 } },
33 	{ S5P_CMU_SCLKSTOP_LOWPWR,		{ 0x1, 0x0, 0x0 } },
34 	{ S5P_CMU_RESET_LOWPWR,			{ 0x1, 0x1, 0x0 } },
35 	{ S5P_APLL_SYSCLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
36 	{ S5P_MPLL_SYSCLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
37 	{ S5P_VPLL_SYSCLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
38 	{ S5P_EPLL_SYSCLK_LOWPWR,		{ 0x1, 0x1, 0x0 } },
39 	{ S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR,	{ 0x1, 0x1, 0x0 } },
40 	{ S5P_CMU_RESET_GPSALIVE_LOWPWR,	{ 0x1, 0x1, 0x0 } },
41 	{ S5P_CMU_CLKSTOP_CAM_LOWPWR,		{ 0x1, 0x1, 0x0 } },
42 	{ S5P_CMU_CLKSTOP_TV_LOWPWR,		{ 0x1, 0x1, 0x0 } },
43 	{ S5P_CMU_CLKSTOP_MFC_LOWPWR,		{ 0x1, 0x1, 0x0 } },
44 	{ S5P_CMU_CLKSTOP_G3D_LOWPWR,		{ 0x1, 0x1, 0x0 } },
45 	{ S5P_CMU_CLKSTOP_LCD0_LOWPWR,		{ 0x1, 0x1, 0x0 } },
46 	{ S5P_CMU_CLKSTOP_LCD1_LOWPWR,		{ 0x1, 0x1, 0x0 } },
47 	{ S5P_CMU_CLKSTOP_MAUDIO_LOWPWR,	{ 0x1, 0x1, 0x0 } },
48 	{ S5P_CMU_CLKSTOP_GPS_LOWPWR,		{ 0x1, 0x1, 0x0 } },
49 	{ S5P_CMU_RESET_CAM_LOWPWR,		{ 0x1, 0x1, 0x0 } },
50 	{ S5P_CMU_RESET_TV_LOWPWR,		{ 0x1, 0x1, 0x0 } },
51 	{ S5P_CMU_RESET_MFC_LOWPWR,		{ 0x1, 0x1, 0x0 } },
52 	{ S5P_CMU_RESET_G3D_LOWPWR,		{ 0x1, 0x1, 0x0 } },
53 	{ S5P_CMU_RESET_LCD0_LOWPWR,		{ 0x1, 0x1, 0x0 } },
54 	{ S5P_CMU_RESET_LCD1_LOWPWR,		{ 0x1, 0x1, 0x0 } },
55 	{ S5P_CMU_RESET_MAUDIO_LOWPWR,		{ 0x1, 0x1, 0x0 } },
56 	{ S5P_CMU_RESET_GPS_LOWPWR,		{ 0x1, 0x1, 0x0 } },
57 	{ S5P_TOP_BUS_LOWPWR,			{ 0x3, 0x0, 0x0 } },
58 	{ S5P_TOP_RETENTION_LOWPWR,		{ 0x1, 0x0, 0x1 } },
59 	{ S5P_TOP_PWR_LOWPWR,			{ 0x3, 0x0, 0x3 } },
60 	{ S5P_LOGIC_RESET_LOWPWR,		{ 0x1, 0x1, 0x0 } },
61 	{ S5P_ONENAND_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
62 	{ S5P_MODIMIF_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
63 	{ S5P_G2D_ACP_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
64 	{ S5P_USBOTG_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
65 	{ S5P_HSMMC_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
66 	{ S5P_CSSYS_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
67 	{ S5P_SECSS_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
68 	{ S5P_PCIE_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
69 	{ S5P_SATA_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
70 	{ S5P_PAD_RETENTION_DRAM_LOWPWR,	{ 0x1, 0x0, 0x0 } },
71 	{ S5P_PAD_RETENTION_MAUDIO_LOWPWR,	{ 0x1, 0x1, 0x0 } },
72 	{ S5P_PAD_RETENTION_GPIO_LOWPWR,	{ 0x1, 0x0, 0x0 } },
73 	{ S5P_PAD_RETENTION_UART_LOWPWR,	{ 0x1, 0x0, 0x0 } },
74 	{ S5P_PAD_RETENTION_MMCA_LOWPWR,	{ 0x1, 0x0, 0x0 } },
75 	{ S5P_PAD_RETENTION_MMCB_LOWPWR,	{ 0x1, 0x0, 0x0 } },
76 	{ S5P_PAD_RETENTION_EBIA_LOWPWR,	{ 0x1, 0x0, 0x0 } },
77 	{ S5P_PAD_RETENTION_EBIB_LOWPWR,	{ 0x1, 0x0, 0x0 } },
78 	{ S5P_PAD_RETENTION_ISOLATION_LOWPWR,	{ 0x1, 0x0, 0x0 } },
79 	{ S5P_PAD_RETENTION_ALV_SEL_LOWPWR,	{ 0x1, 0x0, 0x0 } },
80 	{ S5P_XUSBXTI_LOWPWR,			{ 0x1, 0x1, 0x0 } },
81 	{ S5P_XXTI_LOWPWR,			{ 0x1, 0x1, 0x0 } },
82 	{ S5P_EXT_REGULATOR_LOWPWR,		{ 0x1, 0x1, 0x0 } },
83 	{ S5P_GPIO_MODE_LOWPWR,			{ 0x1, 0x0, 0x0 } },
84 	{ S5P_GPIO_MODE_MAUDIO_LOWPWR,		{ 0x1, 0x1, 0x0 } },
85 	{ S5P_CAM_LOWPWR,			{ 0x7, 0x0, 0x0 } },
86 	{ S5P_TV_LOWPWR,			{ 0x7, 0x0, 0x0 } },
87 	{ S5P_MFC_LOWPWR,			{ 0x7, 0x0, 0x0 } },
88 	{ S5P_G3D_LOWPWR,			{ 0x7, 0x0, 0x0 } },
89 	{ S5P_LCD0_LOWPWR,			{ 0x7, 0x0, 0x0 } },
90 	{ S5P_LCD1_LOWPWR,			{ 0x7, 0x0, 0x0 } },
91 	{ S5P_MAUDIO_LOWPWR,			{ 0x7, 0x7, 0x0 } },
92 	{ S5P_GPS_LOWPWR,			{ 0x7, 0x0, 0x0 } },
93 	{ S5P_GPS_ALIVE_LOWPWR,			{ 0x7, 0x0, 0x0 } },
94 	{ PMU_TABLE_END,},
95 };
96 
97 static struct exynos4_pmu_conf exynos4212_pmu_config[] = {
98 	{ S5P_ARM_CORE0_LOWPWR,			{ 0x0, 0x0, 0x2 } },
99 	{ S5P_DIS_IRQ_CORE0,			{ 0x0, 0x0, 0x0 } },
100 	{ S5P_DIS_IRQ_CENTRAL0,			{ 0x0, 0x0, 0x0 } },
101 	{ S5P_ARM_CORE1_LOWPWR,			{ 0x0, 0x0, 0x2 } },
102 	{ S5P_DIS_IRQ_CORE1,			{ 0x0, 0x0, 0x0 } },
103 	{ S5P_DIS_IRQ_CENTRAL1,			{ 0x0, 0x0, 0x0 } },
104 	{ S5P_ISP_ARM_LOWPWR,			{ 0x1, 0x0, 0x0 } },
105 	{ S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR,	{ 0x0, 0x0, 0x0 } },
106 	{ S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR,	{ 0x0, 0x0, 0x0 } },
107 	{ S5P_ARM_COMMON_LOWPWR,		{ 0x0, 0x0, 0x2 } },
108 	{ S5P_L2_0_LOWPWR,			{ 0x0, 0x0, 0x3 } },
109 	/* XXX_OPTION register should be set other field */
110 	{ S5P_ARM_L2_0_OPTION,			{ 0x10, 0x10, 0x0 } },
111 	{ S5P_L2_1_LOWPWR,			{ 0x0, 0x0, 0x3 } },
112 	{ S5P_ARM_L2_1_OPTION,			{ 0x10, 0x10, 0x0 } },
113 	{ S5P_CMU_ACLKSTOP_LOWPWR,		{ 0x1, 0x0, 0x0 } },
114 	{ S5P_CMU_SCLKSTOP_LOWPWR,		{ 0x1, 0x0, 0x0 } },
115 	{ S5P_CMU_RESET_LOWPWR,			{ 0x1, 0x1, 0x0 } },
116 	{ S5P_DRAM_FREQ_DOWN_LOWPWR,		{ 0x1, 0x1, 0x1 } },
117 	{ S5P_DDRPHY_DLLOFF_LOWPWR,		{ 0x1, 0x1, 0x1 } },
118 	{ S5P_LPDDR_PHY_DLL_LOCK_LOWPWR,	{ 0x1, 0x1, 0x1 } },
119 	{ S5P_CMU_ACLKSTOP_COREBLK_LOWPWR,	{ 0x1, 0x0, 0x0 } },
120 	{ S5P_CMU_SCLKSTOP_COREBLK_LOWPWR,	{ 0x1, 0x0, 0x0 } },
121 	{ S5P_CMU_RESET_COREBLK_LOWPWR,		{ 0x1, 0x1, 0x0 } },
122 	{ S5P_APLL_SYSCLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
123 	{ S5P_MPLL_SYSCLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
124 	{ S5P_VPLL_SYSCLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
125 	{ S5P_EPLL_SYSCLK_LOWPWR,		{ 0x1, 0x1, 0x0 } },
126 	{ S5P_MPLLUSER_SYSCLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
127 	{ S5P_CMU_CLKSTOP_GPS_ALIVE_LOWPWR,	{ 0x1, 0x0, 0x0 } },
128 	{ S5P_CMU_RESET_GPSALIVE_LOWPWR,	{ 0x1, 0x0, 0x0 } },
129 	{ S5P_CMU_CLKSTOP_CAM_LOWPWR,		{ 0x1, 0x0, 0x0 } },
130 	{ S5P_CMU_CLKSTOP_TV_LOWPWR,		{ 0x1, 0x0, 0x0 } },
131 	{ S5P_CMU_CLKSTOP_MFC_LOWPWR,		{ 0x1, 0x0, 0x0 } },
132 	{ S5P_CMU_CLKSTOP_G3D_LOWPWR,		{ 0x1, 0x0, 0x0 } },
133 	{ S5P_CMU_CLKSTOP_LCD0_LOWPWR,		{ 0x1, 0x0, 0x0 } },
134 	{ S5P_CMU_CLKSTOP_ISP_LOWPWR,		{ 0x1, 0x0, 0x0 } },
135 	{ S5P_CMU_CLKSTOP_MAUDIO_LOWPWR,	{ 0x1, 0x0, 0x0 } },
136 	{ S5P_CMU_CLKSTOP_GPS_LOWPWR,		{ 0x1, 0x0, 0x0 } },
137 	{ S5P_CMU_RESET_CAM_LOWPWR,		{ 0x1, 0x0, 0x0 } },
138 	{ S5P_CMU_RESET_TV_LOWPWR,		{ 0x1, 0x0, 0x0 } },
139 	{ S5P_CMU_RESET_MFC_LOWPWR,		{ 0x1, 0x0, 0x0 } },
140 	{ S5P_CMU_RESET_G3D_LOWPWR,		{ 0x1, 0x0, 0x0 } },
141 	{ S5P_CMU_RESET_LCD0_LOWPWR,		{ 0x1, 0x0, 0x0 } },
142 	{ S5P_CMU_RESET_ISP_LOWPWR,		{ 0x1, 0x0, 0x0 } },
143 	{ S5P_CMU_RESET_MAUDIO_LOWPWR,		{ 0x1, 0x1, 0x0 } },
144 	{ S5P_CMU_RESET_GPS_LOWPWR,		{ 0x1, 0x0, 0x0 } },
145 	{ S5P_TOP_BUS_LOWPWR,			{ 0x3, 0x0, 0x0 } },
146 	{ S5P_TOP_RETENTION_LOWPWR,		{ 0x1, 0x0, 0x1 } },
147 	{ S5P_TOP_PWR_LOWPWR,			{ 0x3, 0x0, 0x3 } },
148 	{ S5P_TOP_BUS_COREBLK_LOWPWR,		{ 0x3, 0x0, 0x0 } },
149 	{ S5P_TOP_RETENTION_COREBLK_LOWPWR,	{ 0x1, 0x0, 0x1 } },
150 	{ S5P_TOP_PWR_COREBLK_LOWPWR,		{ 0x3, 0x0, 0x3 } },
151 	{ S5P_LOGIC_RESET_LOWPWR,		{ 0x1, 0x1, 0x0 } },
152 	{ S5P_OSCCLK_GATE_LOWPWR,		{ 0x1, 0x0, 0x1 } },
153 	{ S5P_LOGIC_RESET_COREBLK_LOWPWR,	{ 0x1, 0x1, 0x0 } },
154 	{ S5P_OSCCLK_GATE_COREBLK_LOWPWR,	{ 0x1, 0x0, 0x1 } },
155 	{ S5P_ONENAND_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
156 	{ S5P_ONENAND_MEM_OPTION,		{ 0x10, 0x10, 0x0 } },
157 	{ S5P_HSI_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
158 	{ S5P_HSI_MEM_OPTION,			{ 0x10, 0x10, 0x0 } },
159 	{ S5P_G2D_ACP_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
160 	{ S5P_G2D_ACP_MEM_OPTION,		{ 0x10, 0x10, 0x0 } },
161 	{ S5P_USBOTG_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
162 	{ S5P_USBOTG_MEM_OPTION,		{ 0x10, 0x10, 0x0 } },
163 	{ S5P_HSMMC_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
164 	{ S5P_HSMMC_MEM_OPTION,			{ 0x10, 0x10, 0x0 } },
165 	{ S5P_CSSYS_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
166 	{ S5P_CSSYS_MEM_OPTION,			{ 0x10, 0x10, 0x0 } },
167 	{ S5P_SECSS_MEM_LOWPWR,			{ 0x3, 0x0, 0x0 } },
168 	{ S5P_SECSS_MEM_OPTION,			{ 0x10, 0x10, 0x0 } },
169 	{ S5P_ROTATOR_MEM_LOWPWR,		{ 0x3, 0x0, 0x0 } },
170 	{ S5P_ROTATOR_MEM_OPTION,		{ 0x10, 0x10, 0x0 } },
171 	{ S5P_PAD_RETENTION_DRAM_LOWPWR,	{ 0x1, 0x0, 0x0 } },
172 	{ S5P_PAD_RETENTION_MAUDIO_LOWPWR,	{ 0x1, 0x1, 0x0 } },
173 	{ S5P_PAD_RETENTION_GPIO_LOWPWR,	{ 0x1, 0x0, 0x0 } },
174 	{ S5P_PAD_RETENTION_UART_LOWPWR,	{ 0x1, 0x0, 0x0 } },
175 	{ S5P_PAD_RETENTION_MMCA_LOWPWR,	{ 0x1, 0x0, 0x0 } },
176 	{ S5P_PAD_RETENTION_MMCB_LOWPWR,	{ 0x1, 0x0, 0x0 } },
177 	{ S5P_PAD_RETENTION_EBIA_LOWPWR,	{ 0x1, 0x0, 0x0 } },
178 	{ S5P_PAD_RETENTION_EBIB_LOWPWR,	{ 0x1, 0x0, 0x0 } },
179 	{ S5P_PAD_RETENTION_GPIO_COREBLK_LOWPWR,{ 0x1, 0x0, 0x0 } },
180 	{ S5P_PAD_RETENTION_ISOLATION_LOWPWR,	{ 0x1, 0x0, 0x0 } },
181 	{ S5P_PAD_ISOLATION_COREBLK_LOWPWR,	{ 0x1, 0x0, 0x0 } },
182 	{ S5P_PAD_RETENTION_ALV_SEL_LOWPWR,	{ 0x1, 0x0, 0x0 } },
183 	{ S5P_XUSBXTI_LOWPWR,			{ 0x1, 0x1, 0x0 } },
184 	{ S5P_XXTI_LOWPWR,			{ 0x1, 0x1, 0x0 } },
185 	{ S5P_EXT_REGULATOR_LOWPWR,		{ 0x1, 0x1, 0x0 } },
186 	{ S5P_GPIO_MODE_LOWPWR,			{ 0x1, 0x0, 0x0 } },
187 	{ S5P_GPIO_MODE_COREBLK_LOWPWR,		{ 0x1, 0x0, 0x0 } },
188 	{ S5P_GPIO_MODE_MAUDIO_LOWPWR,		{ 0x1, 0x1, 0x0 } },
189 	{ S5P_TOP_ASB_RESET_LOWPWR,		{ 0x1, 0x1, 0x1 } },
190 	{ S5P_TOP_ASB_ISOLATION_LOWPWR,		{ 0x1, 0x0, 0x1 } },
191 	{ S5P_CAM_LOWPWR,			{ 0x7, 0x0, 0x0 } },
192 	{ S5P_TV_LOWPWR,			{ 0x7, 0x0, 0x0 } },
193 	{ S5P_MFC_LOWPWR,			{ 0x7, 0x0, 0x0 } },
194 	{ S5P_G3D_LOWPWR,			{ 0x7, 0x0, 0x0 } },
195 	{ S5P_LCD0_LOWPWR,			{ 0x7, 0x0, 0x0 } },
196 	{ S5P_ISP_LOWPWR,			{ 0x7, 0x0, 0x0 } },
197 	{ S5P_MAUDIO_LOWPWR,			{ 0x7, 0x7, 0x0 } },
198 	{ S5P_GPS_LOWPWR,			{ 0x7, 0x0, 0x0 } },
199 	{ S5P_GPS_ALIVE_LOWPWR,			{ 0x7, 0x0, 0x0 } },
200 	{ S5P_CMU_SYSCLK_ISP_LOWPWR,		{ 0x1, 0x0, 0x0 } },
201 	{ S5P_CMU_SYSCLK_GPS_LOWPWR,		{ 0x1, 0x0, 0x0 } },
202 	{ PMU_TABLE_END,},
203 };
204 
exynos4_sys_powerdown_conf(enum sys_powerdown mode)205 void exynos4_sys_powerdown_conf(enum sys_powerdown mode)
206 {
207 	unsigned int i;
208 
209 	for (i = 0; (exynos4_pmu_config[i].reg != PMU_TABLE_END) ; i++)
210 		__raw_writel(exynos4_pmu_config[i].val[mode],
211 				exynos4_pmu_config[i].reg);
212 }
213 
exynos4_pmu_init(void)214 static int __init exynos4_pmu_init(void)
215 {
216 	exynos4_pmu_config = exynos4210_pmu_config;
217 
218 	if (soc_is_exynos4210()) {
219 		exynos4_pmu_config = exynos4210_pmu_config;
220 		pr_info("EXYNOS4210 PMU Initialize\n");
221 	} else if (soc_is_exynos4212()) {
222 		exynos4_pmu_config = exynos4212_pmu_config;
223 		pr_info("EXYNOS4212 PMU Initialize\n");
224 	} else {
225 		pr_info("EXYNOS4: PMU not supported\n");
226 	}
227 
228 	return 0;
229 }
230 arch_initcall(exynos4_pmu_init);
231