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