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