1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2012 Samsung Electronics
4 * Donghwa Lee <dh09.lee@samsung.com>
5 */
6
7 #include <mach/cpu.h>
8 #include <asm/io.h>
9 #include <asm/arch/power.h>
10
exynos4_mipi_phy_control(unsigned int dev_index,unsigned int enable)11 static void exynos4_mipi_phy_control(unsigned int dev_index,
12 unsigned int enable)
13 {
14 struct exynos4_power *pmu =
15 (struct exynos4_power *)samsung_get_base_power();
16 unsigned int addr, cfg = 0;
17
18 if (dev_index == 0)
19 addr = (unsigned int)&pmu->mipi_phy0_control;
20 else
21 addr = (unsigned int)&pmu->mipi_phy1_control;
22
23 cfg = readl(addr);
24 if (enable)
25 cfg |= (EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
26 else
27 cfg &= ~(EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
28
29 writel(cfg, addr);
30 }
31
set_mipi_phy_ctrl(unsigned int dev_index,unsigned int enable)32 void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable)
33 {
34 if (cpu_is_exynos4())
35 exynos4_mipi_phy_control(dev_index, enable);
36 }
37
exynos5_set_usbhost_phy_ctrl(unsigned int enable)38 void exynos5_set_usbhost_phy_ctrl(unsigned int enable)
39 {
40 struct exynos5_power *power =
41 (struct exynos5_power *)samsung_get_base_power();
42
43 if (enable) {
44 /* Enabling USBHOST_PHY */
45 setbits_le32(&power->usbhost_phy_control,
46 POWER_USB_HOST_PHY_CTRL_EN);
47 } else {
48 /* Disabling USBHOST_PHY */
49 clrbits_le32(&power->usbhost_phy_control,
50 POWER_USB_HOST_PHY_CTRL_EN);
51 }
52 }
53
exynos4412_set_usbhost_phy_ctrl(unsigned int enable)54 void exynos4412_set_usbhost_phy_ctrl(unsigned int enable)
55 {
56 struct exynos4412_power *power =
57 (struct exynos4412_power *)samsung_get_base_power();
58
59 if (enable) {
60 /* Enabling USBHOST_PHY */
61 setbits_le32(&power->usbhost_phy_control,
62 POWER_USB_HOST_PHY_CTRL_EN);
63 setbits_le32(&power->hsic1_phy_control,
64 POWER_USB_HOST_PHY_CTRL_EN);
65 setbits_le32(&power->hsic2_phy_control,
66 POWER_USB_HOST_PHY_CTRL_EN);
67 } else {
68 /* Disabling USBHOST_PHY */
69 clrbits_le32(&power->usbhost_phy_control,
70 POWER_USB_HOST_PHY_CTRL_EN);
71 clrbits_le32(&power->hsic1_phy_control,
72 POWER_USB_HOST_PHY_CTRL_EN);
73 clrbits_le32(&power->hsic2_phy_control,
74 POWER_USB_HOST_PHY_CTRL_EN);
75 }
76 }
77
set_usbhost_phy_ctrl(unsigned int enable)78 void set_usbhost_phy_ctrl(unsigned int enable)
79 {
80 if (cpu_is_exynos5())
81 exynos5_set_usbhost_phy_ctrl(enable);
82 else if (cpu_is_exynos4())
83 if (proid_is_exynos4412())
84 exynos4412_set_usbhost_phy_ctrl(enable);
85 }
86
exynos5_set_usbdrd_phy_ctrl(unsigned int enable)87 static void exynos5_set_usbdrd_phy_ctrl(unsigned int enable)
88 {
89 struct exynos5_power *power =
90 (struct exynos5_power *)samsung_get_base_power();
91
92 if (enable) {
93 /* Enabling USBDRD_PHY */
94 setbits_le32(&power->usbdrd_phy_control,
95 POWER_USB_DRD_PHY_CTRL_EN);
96 } else {
97 /* Disabling USBDRD_PHY */
98 clrbits_le32(&power->usbdrd_phy_control,
99 POWER_USB_DRD_PHY_CTRL_EN);
100 }
101 }
102
exynos5420_set_usbdev_phy_ctrl(unsigned int enable)103 static void exynos5420_set_usbdev_phy_ctrl(unsigned int enable)
104 {
105 struct exynos5420_power *power =
106 (struct exynos5420_power *)samsung_get_base_power();
107
108 if (enable) {
109 /* Enabling USBDEV_PHY */
110 setbits_le32(&power->usbdev_phy_control,
111 POWER_USB_DRD_PHY_CTRL_EN);
112 setbits_le32(&power->usbdev1_phy_control,
113 POWER_USB_DRD_PHY_CTRL_EN);
114 } else {
115 /* Disabling USBDEV_PHY */
116 clrbits_le32(&power->usbdev_phy_control,
117 POWER_USB_DRD_PHY_CTRL_EN);
118 clrbits_le32(&power->usbdev1_phy_control,
119 POWER_USB_DRD_PHY_CTRL_EN);
120 }
121 }
122
set_usbdrd_phy_ctrl(unsigned int enable)123 void set_usbdrd_phy_ctrl(unsigned int enable)
124 {
125 if (cpu_is_exynos5()) {
126 if (proid_is_exynos542x())
127 exynos5420_set_usbdev_phy_ctrl(enable);
128 else
129 exynos5_set_usbdrd_phy_ctrl(enable);
130 }
131 }
132
exynos5_dp_phy_control(unsigned int enable)133 static void exynos5_dp_phy_control(unsigned int enable)
134 {
135 unsigned int cfg;
136 struct exynos5_power *power =
137 (struct exynos5_power *)samsung_get_base_power();
138
139 cfg = readl(&power->dptx_phy_control);
140 if (enable)
141 cfg |= EXYNOS_DP_PHY_ENABLE;
142 else
143 cfg &= ~EXYNOS_DP_PHY_ENABLE;
144
145 writel(cfg, &power->dptx_phy_control);
146 }
147
exynos_dp_phy_ctrl(unsigned int enable)148 void exynos_dp_phy_ctrl(unsigned int enable)
149 {
150 if (cpu_is_exynos5())
151 exynos5_dp_phy_control(enable);
152 }
153
exynos5_set_ps_hold_ctrl(void)154 static void exynos5_set_ps_hold_ctrl(void)
155 {
156 struct exynos5_power *power =
157 (struct exynos5_power *)samsung_get_base_power();
158
159 /* Set PS-Hold high */
160 setbits_le32(&power->ps_hold_control,
161 EXYNOS_PS_HOLD_CONTROL_DATA_HIGH);
162 }
163
164 /*
165 * Set ps_hold data driving value high
166 * This enables the machine to stay powered on
167 * after the initial power-on condition goes away
168 * (e.g. power button).
169 */
set_ps_hold_ctrl(void)170 void set_ps_hold_ctrl(void)
171 {
172 if (cpu_is_exynos5())
173 exynos5_set_ps_hold_ctrl();
174 }
175
exynos5_set_xclkout(void)176 static void exynos5_set_xclkout(void)
177 {
178 struct exynos5_power *power =
179 (struct exynos5_power *)samsung_get_base_power();
180
181 /* use xxti for xclk out */
182 clrsetbits_le32(&power->pmu_debug, PMU_DEBUG_CLKOUT_SEL_MASK,
183 PMU_DEBUG_XXTI);
184 }
185
set_xclkout(void)186 void set_xclkout(void)
187 {
188 if (cpu_is_exynos5())
189 exynos5_set_xclkout();
190 }
191
192 /* Enables hardware tripping to power off the system when TMU fails */
set_hw_thermal_trip(void)193 void set_hw_thermal_trip(void)
194 {
195 if (cpu_is_exynos5()) {
196 struct exynos5_power *power =
197 (struct exynos5_power *)samsung_get_base_power();
198
199 /* PS_HOLD_CONTROL register ENABLE_HW_TRIP bit*/
200 setbits_le32(&power->ps_hold_control, POWER_ENABLE_HW_TRIP);
201 }
202 }
203
exynos5_get_reset_status(void)204 static uint32_t exynos5_get_reset_status(void)
205 {
206 struct exynos5_power *power =
207 (struct exynos5_power *)samsung_get_base_power();
208
209 return power->inform1;
210 }
211
exynos4_get_reset_status(void)212 static uint32_t exynos4_get_reset_status(void)
213 {
214 struct exynos4_power *power =
215 (struct exynos4_power *)samsung_get_base_power();
216
217 return power->inform1;
218 }
219
get_reset_status(void)220 uint32_t get_reset_status(void)
221 {
222 if (cpu_is_exynos5())
223 return exynos5_get_reset_status();
224 else
225 return exynos4_get_reset_status();
226 }
227
exynos5_power_exit_wakeup(void)228 static void exynos5_power_exit_wakeup(void)
229 {
230 struct exynos5_power *power =
231 (struct exynos5_power *)samsung_get_base_power();
232 typedef void (*resume_func)(void);
233
234 ((resume_func)power->inform0)();
235 }
236
exynos4_power_exit_wakeup(void)237 static void exynos4_power_exit_wakeup(void)
238 {
239 struct exynos4_power *power =
240 (struct exynos4_power *)samsung_get_base_power();
241 typedef void (*resume_func)(void);
242
243 ((resume_func)power->inform0)();
244 }
245
power_exit_wakeup(void)246 void power_exit_wakeup(void)
247 {
248 if (cpu_is_exynos5())
249 exynos5_power_exit_wakeup();
250 else
251 exynos4_power_exit_wakeup();
252 }
253
get_boot_mode(void)254 unsigned int get_boot_mode(void)
255 {
256 unsigned int om_pin = samsung_get_base_power();
257
258 return readl(om_pin) & OM_PIN_MASK;
259 }
260