blob: 9aa97f0f2cad7782901e03a21459406a56b4ddd4 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +02002/*
3 * Copyright (C) 2014 Samsung Electronics
4 * Przemyslaw Marczak <p.marczak@samsung.com>
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +02005 */
6
7#include <common.h>
8#include <asm/arch/pinmux.h>
9#include <asm/arch/power.h>
10#include <asm/arch/clock.h>
11#include <asm/arch/gpio.h>
12#include <asm/gpio.h>
13#include <asm/arch/cpu.h>
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +020014#include <dm.h>
Simon Glass0af6e2d2019-08-01 09:46:52 -060015#include <env.h>
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020016#include <power/pmic.h>
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +020017#include <power/regulator.h>
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020018#include <power/max77686_pmic.h>
19#include <errno.h>
Inha Songae731ec2015-02-17 12:24:12 +010020#include <mmc.h>
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020021#include <usb.h>
Marek Vasutf1be9cb2015-12-04 02:51:20 +010022#include <usb/dwc2_udc.h>
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020023#include <samsung/misc.h>
24#include "setup.h"
25
26DECLARE_GLOBAL_DATA_PTR;
27
28#ifdef CONFIG_BOARD_TYPES
29/* Odroid board types */
30enum {
31 ODROID_TYPE_U3,
32 ODROID_TYPE_X2,
33 ODROID_TYPES,
34};
35
36void set_board_type(void)
37{
38 /* Set GPA1 pin 1 to HI - enable XCL205 output */
39 writel(XCL205_EN_GPIO_CON_CFG, XCL205_EN_GPIO_CON);
40 writel(XCL205_EN_GPIO_DAT_CFG, XCL205_EN_GPIO_CON + 0x4);
41 writel(XCL205_EN_GPIO_PUD_CFG, XCL205_EN_GPIO_CON + 0x8);
42 writel(XCL205_EN_GPIO_DRV_CFG, XCL205_EN_GPIO_CON + 0xc);
43
44 /* Set GPC1 pin 2 to IN - check XCL205 output state */
45 writel(XCL205_STATE_GPIO_CON_CFG, XCL205_STATE_GPIO_CON);
46 writel(XCL205_STATE_GPIO_PUD_CFG, XCL205_STATE_GPIO_CON + 0x8);
47
48 /* XCL205 - needs some latch time */
49 sdelay(200000);
50
51 /* Check GPC1 pin2 - LED supplied by XCL205 - X2 only */
52 if (readl(XCL205_STATE_GPIO_DAT) & (1 << XCL205_STATE_GPIO_PIN))
53 gd->board_type = ODROID_TYPE_X2;
54 else
55 gd->board_type = ODROID_TYPE_U3;
56}
57
Krzysztof Kozlowski36476ee2019-03-06 19:37:51 +010058void set_board_revision(void)
59{
60 /*
61 * Revision already set by set_board_type() because it can be
62 * executed early.
63 */
64}
65
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020066const char *get_board_type(void)
67{
68 const char *board_type[] = {"u3", "x2"};
69
70 return board_type[gd->board_type];
71}
72#endif
73
74#ifdef CONFIG_SET_DFU_ALT_INFO
Inha Songae731ec2015-02-17 12:24:12 +010075char *get_dfu_alt_system(char *interface, char *devstr)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020076{
Simon Glass64b723f2017-08-03 12:22:12 -060077 return env_get("dfu_alt_system");
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020078}
79
Inha Songae731ec2015-02-17 12:24:12 +010080char *get_dfu_alt_boot(char *interface, char *devstr)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020081{
Inha Songae731ec2015-02-17 12:24:12 +010082 struct mmc *mmc;
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020083 char *alt_boot;
Inha Songae731ec2015-02-17 12:24:12 +010084 int dev_num;
85
86 dev_num = simple_strtoul(devstr, NULL, 10);
87
88 mmc = find_mmc_device(dev_num);
89 if (!mmc)
90 return NULL;
91
92 if (mmc_init(mmc))
93 return NULL;
94
95 alt_boot = IS_SD(mmc) ? CONFIG_DFU_ALT_BOOT_SD :
96 CONFIG_DFU_ALT_BOOT_EMMC;
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020097
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +020098 return alt_boot;
99}
100#endif
101
102static void board_clock_init(void)
103{
104 unsigned int set, clr, clr_src_cpu, clr_pll_con0, clr_src_dmc;
105 struct exynos4x12_clock *clk = (struct exynos4x12_clock *)
106 samsung_get_base_clock();
107
108 /*
109 * CMU_CPU clocks src to MPLL
110 * Bit values: 0 ; 1
111 * MUX_APLL_SEL: FIN_PLL ; FOUT_APLL
112 * MUX_CORE_SEL: MOUT_APLL ; SCLK_MPLL
113 * MUX_HPM_SEL: MOUT_APLL ; SCLK_MPLL_USER_C
114 * MUX_MPLL_USER_SEL_C: FIN_PLL ; SCLK_MPLL
115 */
116 clr_src_cpu = MUX_APLL_SEL(1) | MUX_CORE_SEL(1) |
117 MUX_HPM_SEL(1) | MUX_MPLL_USER_SEL_C(1);
118 set = MUX_APLL_SEL(0) | MUX_CORE_SEL(1) | MUX_HPM_SEL(1) |
119 MUX_MPLL_USER_SEL_C(1);
120
121 clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set);
122
123 /* Wait for mux change */
124 while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING)
125 continue;
126
127 /* Set APLL to 1000MHz */
128 clr_pll_con0 = SDIV(7) | PDIV(63) | MDIV(1023) | FSEL(1);
129 set = SDIV(0) | PDIV(3) | MDIV(125) | FSEL(1);
130
131 clrsetbits_le32(&clk->apll_con0, clr_pll_con0, set);
132
133 /* Wait for PLL to be locked */
134 while (!(readl(&clk->apll_con0) & PLL_LOCKED_BIT))
135 continue;
136
137 /* Set CMU_CPU clocks src to APLL */
138 set = MUX_APLL_SEL(1) | MUX_CORE_SEL(0) | MUX_HPM_SEL(0) |
139 MUX_MPLL_USER_SEL_C(1);
140 clrsetbits_le32(&clk->src_cpu, clr_src_cpu, set);
141
142 /* Wait for mux change */
143 while (readl(&clk->mux_stat_cpu) & MUX_STAT_CPU_CHANGING)
144 continue;
145
146 set = CORE_RATIO(0) | COREM0_RATIO(2) | COREM1_RATIO(5) |
147 PERIPH_RATIO(0) | ATB_RATIO(4) | PCLK_DBG_RATIO(1) |
148 APLL_RATIO(0) | CORE2_RATIO(0);
149 /*
150 * Set dividers for MOUTcore = 1000 MHz
151 * coreout = MOUT / (ratio + 1) = 1000 MHz (0)
152 * corem0 = armclk / (ratio + 1) = 333 MHz (2)
153 * corem1 = armclk / (ratio + 1) = 166 MHz (5)
154 * periph = armclk / (ratio + 1) = 1000 MHz (0)
155 * atbout = MOUT / (ratio + 1) = 200 MHz (4)
156 * pclkdbgout = atbout / (ratio + 1) = 100 MHz (1)
157 * sclkapll = MOUTapll / (ratio + 1) = 1000 MHz (0)
158 * core2out = core_out / (ratio + 1) = 1000 MHz (0) (armclk)
159 */
160 clr = CORE_RATIO(7) | COREM0_RATIO(7) | COREM1_RATIO(7) |
161 PERIPH_RATIO(7) | ATB_RATIO(7) | PCLK_DBG_RATIO(7) |
162 APLL_RATIO(7) | CORE2_RATIO(7);
163
164 clrsetbits_le32(&clk->div_cpu0, clr, set);
165
166 /* Wait for divider ready status */
167 while (readl(&clk->div_stat_cpu0) & DIV_STAT_CPU0_CHANGING)
168 continue;
169
170 /*
171 * For MOUThpm = 1000 MHz (MOUTapll)
172 * doutcopy = MOUThpm / (ratio + 1) = 200 (4)
173 * sclkhpm = doutcopy / (ratio + 1) = 200 (4)
Przemyslaw Marczak239b1712014-09-23 12:46:43 +0200174 * cores_out = armclk / (ratio + 1) = 200 (4)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200175 */
176 clr = COPY_RATIO(7) | HPM_RATIO(7) | CORES_RATIO(7);
Przemyslaw Marczak239b1712014-09-23 12:46:43 +0200177 set = COPY_RATIO(4) | HPM_RATIO(4) | CORES_RATIO(4);
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200178
179 clrsetbits_le32(&clk->div_cpu1, clr, set);
180
181 /* Wait for divider ready status */
182 while (readl(&clk->div_stat_cpu1) & DIV_STAT_CPU1_CHANGING)
183 continue;
184
185 /*
186 * Set CMU_DMC clocks src to APLL
187 * Bit values: 0 ; 1
188 * MUX_C2C_SEL: SCLKMPLL ; SCLKAPLL
189 * MUX_DMC_BUS_SEL: SCLKMPLL ; SCLKAPLL
190 * MUX_DPHY_SEL: SCLKMPLL ; SCLKAPLL
191 * MUX_MPLL_SEL: FINPLL ; MOUT_MPLL_FOUT
192 * MUX_PWI_SEL: 0110 (MPLL); 0111 (EPLL); 1000 (VPLL); 0(XXTI)
193 * MUX_G2D_ACP0_SEL: SCLKMPLL ; SCLKAPLL
194 * MUX_G2D_ACP1_SEL: SCLKEPLL ; SCLKVPLL
195 * MUX_G2D_ACP_SEL: OUT_ACP0 ; OUT_ACP1
196 */
197 clr_src_dmc = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) |
198 MUX_DPHY_SEL(1) | MUX_MPLL_SEL(1) |
199 MUX_PWI_SEL(15) | MUX_G2D_ACP0_SEL(1) |
200 MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1);
201 set = MUX_C2C_SEL(1) | MUX_DMC_BUS_SEL(1) | MUX_DPHY_SEL(1) |
202 MUX_MPLL_SEL(0) | MUX_PWI_SEL(0) | MUX_G2D_ACP0_SEL(1) |
203 MUX_G2D_ACP1_SEL(1) | MUX_G2D_ACP_SEL(1);
204
205 clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set);
206
207 /* Wait for mux change */
208 while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING)
209 continue;
210
Minkyu Kangec54c592014-09-11 14:02:03 +0900211 /* Set MPLL to 800MHz */
212 set = SDIV(0) | PDIV(3) | MDIV(100) | FSEL(0) | PLL_ENABLE(1);
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200213
214 clrsetbits_le32(&clk->mpll_con0, clr_pll_con0, set);
215
216 /* Wait for PLL to be locked */
217 while (!(readl(&clk->mpll_con0) & PLL_LOCKED_BIT))
218 continue;
219
220 /* Switch back CMU_DMC mux */
221 set = MUX_C2C_SEL(0) | MUX_DMC_BUS_SEL(0) | MUX_DPHY_SEL(0) |
222 MUX_MPLL_SEL(1) | MUX_PWI_SEL(8) | MUX_G2D_ACP0_SEL(0) |
223 MUX_G2D_ACP1_SEL(0) | MUX_G2D_ACP_SEL(0);
224
225 clrsetbits_le32(&clk->src_dmc, clr_src_dmc, set);
226
227 /* Wait for mux change */
228 while (readl(&clk->mux_stat_dmc) & MUX_STAT_DMC_CHANGING)
229 continue;
230
231 /* CLK_DIV_DMC0 */
232 clr = ACP_RATIO(7) | ACP_PCLK_RATIO(7) | DPHY_RATIO(7) |
233 DMC_RATIO(7) | DMCD_RATIO(7) | DMCP_RATIO(7);
234 /*
235 * For:
Minkyu Kangec54c592014-09-11 14:02:03 +0900236 * MOUTdmc = 800 MHz
237 * MOUTdphy = 800 MHz
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200238 *
Minkyu Kangec54c592014-09-11 14:02:03 +0900239 * aclk_acp = MOUTdmc / (ratio + 1) = 200 (3)
240 * pclk_acp = aclk_acp / (ratio + 1) = 100 (1)
241 * sclk_dphy = MOUTdphy / (ratio + 1) = 400 (1)
242 * sclk_dmc = MOUTdmc / (ratio + 1) = 400 (1)
243 * aclk_dmcd = sclk_dmc / (ratio + 1) = 200 (1)
244 * aclk_dmcp = aclk_dmcd / (ratio + 1) = 100 (1)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200245 */
246 set = ACP_RATIO(3) | ACP_PCLK_RATIO(1) | DPHY_RATIO(1) |
247 DMC_RATIO(1) | DMCD_RATIO(1) | DMCP_RATIO(1);
248
249 clrsetbits_le32(&clk->div_dmc0, clr, set);
250
251 /* Wait for divider ready status */
252 while (readl(&clk->div_stat_dmc0) & DIV_STAT_DMC0_CHANGING)
253 continue;
254
255 /* CLK_DIV_DMC1 */
256 clr = G2D_ACP_RATIO(15) | C2C_RATIO(7) | PWI_RATIO(15) |
257 C2C_ACLK_RATIO(7) | DVSEM_RATIO(127) | DPM_RATIO(127);
258 /*
259 * For:
Minkyu Kangec54c592014-09-11 14:02:03 +0900260 * MOUTg2d = 800 MHz
261 * MOUTc2c = 800 Mhz
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200262 * MOUTpwi = 108 MHz
263 *
Joonyoung Shim400bed22015-01-23 17:30:07 +0900264 * sclk_g2d_acp = MOUTg2d / (ratio + 1) = 200 (3)
Minkyu Kangec54c592014-09-11 14:02:03 +0900265 * sclk_c2c = MOUTc2c / (ratio + 1) = 400 (1)
266 * aclk_c2c = sclk_c2c / (ratio + 1) = 200 (1)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200267 * sclk_pwi = MOUTpwi / (ratio + 1) = 18 (5)
268 */
Joonyoung Shim400bed22015-01-23 17:30:07 +0900269 set = G2D_ACP_RATIO(3) | C2C_RATIO(1) | PWI_RATIO(5) |
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200270 C2C_ACLK_RATIO(1) | DVSEM_RATIO(1) | DPM_RATIO(1);
271
272 clrsetbits_le32(&clk->div_dmc1, clr, set);
273
274 /* Wait for divider ready status */
275 while (readl(&clk->div_stat_dmc1) & DIV_STAT_DMC1_CHANGING)
276 continue;
277
278 /* CLK_SRC_PERIL0 */
279 clr = UART0_SEL(15) | UART1_SEL(15) | UART2_SEL(15) |
280 UART3_SEL(15) | UART4_SEL(15);
281 /*
282 * Set CLK_SRC_PERIL0 clocks src to MPLL
283 * src values: 0(XXTI); 1(XusbXTI); 2(SCLK_HDMI24M); 3(SCLK_USBPHY0);
284 * 5(SCLK_HDMIPHY); 6(SCLK_MPLL_USER_T); 7(SCLK_EPLL);
285 * 8(SCLK_VPLL)
286 *
287 * Set all to SCLK_MPLL_USER_T
288 */
289 set = UART0_SEL(6) | UART1_SEL(6) | UART2_SEL(6) | UART3_SEL(6) |
290 UART4_SEL(6);
291
292 clrsetbits_le32(&clk->src_peril0, clr, set);
293
294 /* CLK_DIV_PERIL0 */
295 clr = UART0_RATIO(15) | UART1_RATIO(15) | UART2_RATIO(15) |
296 UART3_RATIO(15) | UART4_RATIO(15);
297 /*
Minkyu Kangec54c592014-09-11 14:02:03 +0900298 * For MOUTuart0-4: 800MHz
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200299 *
Minkyu Kangec54c592014-09-11 14:02:03 +0900300 * SCLK_UARTx = MOUTuartX / (ratio + 1) = 100 (7)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200301 */
302 set = UART0_RATIO(7) | UART1_RATIO(7) | UART2_RATIO(7) |
303 UART3_RATIO(7) | UART4_RATIO(7);
304
305 clrsetbits_le32(&clk->div_peril0, clr, set);
306
307 while (readl(&clk->div_stat_peril0) & DIV_STAT_PERIL0_CHANGING)
308 continue;
309
310 /* CLK_DIV_FSYS1 */
311 clr = MMC0_RATIO(15) | MMC0_PRE_RATIO(255) | MMC1_RATIO(15) |
312 MMC1_PRE_RATIO(255);
313 /*
Minkyu Kangec54c592014-09-11 14:02:03 +0900314 * For MOUTmmc0-3 = 800 MHz (MPLL)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200315 *
Minkyu Kangec54c592014-09-11 14:02:03 +0900316 * DOUTmmc1 = MOUTmmc1 / (ratio + 1) = 100 (7)
317 * sclk_mmc1 = DOUTmmc1 / (ratio + 1) = 50 (1)
318 * DOUTmmc0 = MOUTmmc0 / (ratio + 1) = 100 (7)
319 * sclk_mmc0 = DOUTmmc0 / (ratio + 1) = 50 (1)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200320 */
321 set = MMC0_RATIO(7) | MMC0_PRE_RATIO(1) | MMC1_RATIO(7) |
322 MMC1_PRE_RATIO(1);
323
324 clrsetbits_le32(&clk->div_fsys1, clr, set);
325
326 /* Wait for divider ready status */
327 while (readl(&clk->div_stat_fsys1) & DIV_STAT_FSYS1_CHANGING)
328 continue;
329
330 /* CLK_DIV_FSYS2 */
331 clr = MMC2_RATIO(15) | MMC2_PRE_RATIO(255) | MMC3_RATIO(15) |
332 MMC3_PRE_RATIO(255);
333 /*
Minkyu Kangec54c592014-09-11 14:02:03 +0900334 * For MOUTmmc0-3 = 800 MHz (MPLL)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200335 *
Minkyu Kangec54c592014-09-11 14:02:03 +0900336 * DOUTmmc3 = MOUTmmc3 / (ratio + 1) = 100 (7)
337 * sclk_mmc3 = DOUTmmc3 / (ratio + 1) = 50 (1)
338 * DOUTmmc2 = MOUTmmc2 / (ratio + 1) = 100 (7)
339 * sclk_mmc2 = DOUTmmc2 / (ratio + 1) = 50 (1)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200340 */
341 set = MMC2_RATIO(7) | MMC2_PRE_RATIO(1) | MMC3_RATIO(7) |
342 MMC3_PRE_RATIO(1);
343
344 clrsetbits_le32(&clk->div_fsys2, clr, set);
345
346 /* Wait for divider ready status */
347 while (readl(&clk->div_stat_fsys2) & DIV_STAT_FSYS2_CHANGING)
348 continue;
349
350 /* CLK_DIV_FSYS3 */
351 clr = MMC4_RATIO(15) | MMC4_PRE_RATIO(255);
352 /*
Minkyu Kangec54c592014-09-11 14:02:03 +0900353 * For MOUTmmc4 = 800 MHz (MPLL)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200354 *
Minkyu Kangec54c592014-09-11 14:02:03 +0900355 * DOUTmmc4 = MOUTmmc4 / (ratio + 1) = 100 (7)
356 * sclk_mmc4 = DOUTmmc4 / (ratio + 1) = 100 (0)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200357 */
358 set = MMC4_RATIO(7) | MMC4_PRE_RATIO(0);
359
360 clrsetbits_le32(&clk->div_fsys3, clr, set);
361
362 /* Wait for divider ready status */
363 while (readl(&clk->div_stat_fsys3) & DIV_STAT_FSYS3_CHANGING)
364 continue;
365
366 return;
367}
368
369static void board_gpio_init(void)
370{
371 /* eMMC Reset Pin */
Przemyslaw Marczak41573752014-10-28 17:31:07 +0100372 gpio_request(EXYNOS4X12_GPIO_K12, "eMMC Reset");
373
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200374 gpio_cfg_pin(EXYNOS4X12_GPIO_K12, S5P_GPIO_FUNC(0x1));
375 gpio_set_pull(EXYNOS4X12_GPIO_K12, S5P_GPIO_PULL_NONE);
376 gpio_set_drv(EXYNOS4X12_GPIO_K12, S5P_GPIO_DRV_4X);
377
378 /* Enable FAN (Odroid U3) */
Przemyslaw Marczak41573752014-10-28 17:31:07 +0100379 gpio_request(EXYNOS4X12_GPIO_D00, "FAN Control");
380
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200381 gpio_set_pull(EXYNOS4X12_GPIO_D00, S5P_GPIO_PULL_UP);
382 gpio_set_drv(EXYNOS4X12_GPIO_D00, S5P_GPIO_DRV_4X);
383 gpio_direction_output(EXYNOS4X12_GPIO_D00, 1);
384
385 /* OTG Vbus output (Odroid U3+) */
Przemyslaw Marczak41573752014-10-28 17:31:07 +0100386 gpio_request(EXYNOS4X12_GPIO_L20, "OTG Vbus");
387
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200388 gpio_set_pull(EXYNOS4X12_GPIO_L20, S5P_GPIO_PULL_NONE);
389 gpio_set_drv(EXYNOS4X12_GPIO_L20, S5P_GPIO_DRV_4X);
390 gpio_direction_output(EXYNOS4X12_GPIO_L20, 0);
391
392 /* OTG INT (Odroid U3+) */
Przemyslaw Marczak41573752014-10-28 17:31:07 +0100393 gpio_request(EXYNOS4X12_GPIO_X31, "OTG INT");
394
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200395 gpio_set_pull(EXYNOS4X12_GPIO_X31, S5P_GPIO_PULL_UP);
396 gpio_set_drv(EXYNOS4X12_GPIO_X31, S5P_GPIO_DRV_4X);
397 gpio_direction_input(EXYNOS4X12_GPIO_X31);
Suriyan Ramasami4de08b52014-11-20 17:26:30 -0800398
Suriyan Ramasamia29cfb12014-11-23 22:15:32 -0800399 /* Blue LED (Odroid X2/U2/U3) */
400 gpio_request(EXYNOS4X12_GPIO_C10, "Blue LED");
401
402 gpio_direction_output(EXYNOS4X12_GPIO_C10, 0);
403
Suriyan Ramasami4de08b52014-11-20 17:26:30 -0800404#ifdef CONFIG_CMD_USB
405 /* USB3503A Reference frequency */
406 gpio_request(EXYNOS4X12_GPIO_X30, "USB3503A RefFreq");
407
408 /* USB3503A Connect */
409 gpio_request(EXYNOS4X12_GPIO_X34, "USB3503A Connect");
410
411 /* USB3503A Reset */
412 gpio_request(EXYNOS4X12_GPIO_X35, "USB3503A Reset");
413#endif
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200414}
415
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200416int exynos_early_init_f(void)
417{
418 board_clock_init();
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200419
420 return 0;
421}
422
423int exynos_init(void)
424{
Przemyslaw Marczak41573752014-10-28 17:31:07 +0100425 board_gpio_init();
426
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200427 return 0;
428}
429
430int exynos_power_init(void)
431{
Minkyu Kangabf4a622015-10-23 16:15:04 +0900432 const char *mmc_regulators[] = {
433 "VDDQ_EMMC_1.8V",
434 "VDDQ_EMMC_2.8V",
435 "TFLASH_2.8V",
436 NULL,
437 };
438
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200439 if (regulator_list_autoset(mmc_regulators, NULL, true))
Seung-Woo Kimca211662018-06-04 16:03:05 +0900440 pr_err("Unable to init all mmc regulators\n");
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200441
442 return 0;
443}
444
445#ifdef CONFIG_USB_GADGET
446static int s5pc210_phy_control(int on)
447{
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200448 struct udevice *dev;
449 int ret;
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200450
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200451 ret = regulator_get_by_platname("VDD_UOTG_3.0V", &dev);
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200452 if (ret) {
Seung-Woo Kimca211662018-06-04 16:03:05 +0900453 pr_err("Regulator get error: %d\n", ret);
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200454 return ret;
455 }
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200456
457 if (on)
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200458 return regulator_set_mode(dev, OPMODE_ON);
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200459 else
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200460 return regulator_set_mode(dev, OPMODE_LPM);
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200461}
462
Marek Vasut6939aca2015-12-04 02:23:29 +0100463struct dwc2_plat_otg_data s5pc210_otg_data = {
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200464 .phy_control = s5pc210_phy_control,
465 .regs_phy = EXYNOS4X12_USBPHY_BASE,
466 .regs_otg = EXYNOS4X12_USBOTG_BASE,
467 .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL,
468 .usb_flags = PHY0_SLEEP,
469};
Suriyan Ramasami97f4ef62014-10-29 09:22:43 -0700470#endif
471
472#if defined(CONFIG_USB_GADGET) || defined(CONFIG_CMD_USB)
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200473
Krzysztof Kozlowski1b2b3822019-03-06 10:23:09 +0100474static void set_usb3503_ref_clk(void)
475{
476#ifdef CONFIG_BOARD_TYPES
477 /*
478 * gpx3-0 chooses primary (low) or secondary (high) reference clock
479 * frequencies table. The choice of clock is done through hard-wired
480 * REF_SEL pins.
481 * The Odroid Us have reference clock at 24 MHz (00 entry from secondary
482 * table) and Odroid Xs have it at 26 MHz (01 entry from primary table).
483 */
484 if (gd->board_type == ODROID_TYPE_U3)
485 gpio_direction_output(EXYNOS4X12_GPIO_X30, 0);
486 else
487 gpio_direction_output(EXYNOS4X12_GPIO_X30, 1);
488#else
489 /* Choose Odroid Xs frequency without board types */
490 gpio_direction_output(EXYNOS4X12_GPIO_X30, 1);
491#endif /* CONFIG_BOARD_TYPES */
492}
493
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200494int board_usb_init(int index, enum usb_init_type init)
495{
Suriyan Ramasami97f4ef62014-10-29 09:22:43 -0700496#ifdef CONFIG_CMD_USB
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200497 struct udevice *dev;
498 int ret;
Suriyan Ramasami97f4ef62014-10-29 09:22:43 -0700499
Krzysztof Kozlowski1b2b3822019-03-06 10:23:09 +0100500 set_usb3503_ref_clk();
Suriyan Ramasami97f4ef62014-10-29 09:22:43 -0700501
502 /* Disconnect, Reset, Connect */
503 gpio_direction_output(EXYNOS4X12_GPIO_X34, 0);
504 gpio_direction_output(EXYNOS4X12_GPIO_X35, 0);
505 gpio_direction_output(EXYNOS4X12_GPIO_X35, 1);
506 gpio_direction_output(EXYNOS4X12_GPIO_X34, 1);
507
508 /* Power off and on BUCK8 for LAN9730 */
509 debug("LAN9730 - Turning power buck 8 OFF and ON.\n");
510
Przemyslaw Marczak75692a32015-05-13 13:38:27 +0200511 ret = regulator_get_by_platname("VCC_P3V3_2.85V", &dev);
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200512 if (ret) {
Seung-Woo Kimca211662018-06-04 16:03:05 +0900513 pr_err("Regulator get error: %d\n", ret);
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200514 return ret;
Suriyan Ramasami97f4ef62014-10-29 09:22:43 -0700515 }
516
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200517 ret = regulator_set_enable(dev, true);
518 if (ret) {
Seung-Woo Kimca211662018-06-04 16:03:05 +0900519 pr_err("Regulator %s enable setting error: %d\n", dev->name, ret);
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200520 return ret;
521 }
Suriyan Ramasami97f4ef62014-10-29 09:22:43 -0700522
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200523 ret = regulator_set_value(dev, 750000);
524 if (ret) {
Seung-Woo Kimca211662018-06-04 16:03:05 +0900525 pr_err("Regulator %s value setting error: %d\n", dev->name, ret);
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200526 return ret;
527 }
528
529 ret = regulator_set_value(dev, 3300000);
530 if (ret) {
Seung-Woo Kimca211662018-06-04 16:03:05 +0900531 pr_err("Regulator %s value setting error: %d\n", dev->name, ret);
Przemyslaw Marczake7781bc2015-05-13 13:38:25 +0200532 return ret;
533 }
534#endif
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200535 debug("USB_udc_probe\n");
Marek Vasut01b61fa2015-12-04 02:26:33 +0100536 return dwc2_udc_probe(&s5pc210_otg_data);
Przemyslaw Marczak0b217aa2014-09-01 13:50:51 +0200537}
538#endif