blob: 81ccc124c809578a384276cb78b1f65f941a2978 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +02002/*
3 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * Sanghee Kim <sh0130.kim@samsung.com>
5 * Piotr Wilczek <p.wilczek@samsung.com>
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +02006 */
7
8#include <common.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.h>
Simon Glass37f11622014-10-20 19:48:37 -060010#include <asm/gpio.h>
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020011#include <asm/arch/pinmux.h>
12#include <asm/arch/power.h>
Piotr Wilczek87d2e782014-03-07 14:59:49 +010013#include <asm/arch/mipi_dsim.h>
Simon Glassdbd79542020-05-10 11:40:11 -060014#include <linux/delay.h>
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020015#include <power/pmic.h>
16#include <power/max77686_pmic.h>
17#include <power/battery.h>
18#include <power/max77693_pmic.h>
19#include <power/max77693_muic.h>
20#include <power/max77693_fg.h>
21#include <libtizen.h>
22#include <errno.h>
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +010023#include <usb.h>
Marek Vasutf1be9cb2015-12-04 02:51:20 +010024#include <usb/dwc2_udc.h>
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +010025#include <usb_mass_storage.h>
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020026
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020027static unsigned int board_rev = -1;
28
29static inline u32 get_model_rev(void);
30
31static void check_hw_revision(void)
32{
33 int modelrev = 0;
Simon Glass4f83d3d2014-10-20 19:48:39 -060034 char str[12];
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020035 int i;
36
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020037 /*
38 * GPM1[1:0]: MODEL_REV[1:0]
39 * Don't set as pull-none for these N/C pin.
40 * TRM say that it may cause unexcepted state and leakage current.
41 * and pull-none is only for output function.
42 */
Simon Glass4f83d3d2014-10-20 19:48:39 -060043 for (i = 0; i < 2; i++) {
44 int pin = i + EXYNOS4X12_GPIO_M10;
45
46 sprintf(str, "model_rev%d", i);
47 gpio_request(pin, str);
48 gpio_cfg_pin(pin, S5P_GPIO_INPUT);
49 }
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020050
51 /* GPM1[5:2]: HW_REV[3:0] */
Simon Glass4f83d3d2014-10-20 19:48:39 -060052 for (i = 0; i < 4; i++) {
53 int pin = i + EXYNOS4X12_GPIO_M12;
54
55 sprintf(str, "hw_rev%d", i);
56 gpio_request(pin, str);
57 gpio_cfg_pin(pin, S5P_GPIO_INPUT);
58 gpio_set_pull(pin, S5P_GPIO_PULL_NONE);
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020059 }
60
61 /* GPM1[1:0]: MODEL_REV[1:0] */
62 for (i = 0; i < 2; i++)
Akshay Saraswat1376cdd2014-05-13 10:30:14 +053063 modelrev |= (gpio_get_value(EXYNOS4X12_GPIO_M10 + i) << i);
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020064
65 /* board_rev[15:8] = model */
66 board_rev = modelrev << 8;
67}
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020068
Tom Rini4cc38852021-08-30 09:16:30 -040069#ifdef CONFIG_REVISION_TAG
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020070u32 get_board_rev(void)
71{
72 return board_rev;
73}
Tom Rini4cc38852021-08-30 09:16:30 -040074#endif
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020075
76static inline u32 get_model_rev(void)
77{
78 return (board_rev >> 8) & 0xff;
79}
80
81static void board_external_gpio_init(void)
82{
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +020083 /*
84 * some pins which in alive block are connected with external pull-up
85 * but it's default setting is pull-down.
86 * if that pin set as input then that floated
87 */
88
Akshay Saraswat1376cdd2014-05-13 10:30:14 +053089 gpio_set_pull(EXYNOS4X12_GPIO_X02, S5P_GPIO_PULL_NONE); /* PS_ALS_INT */
90 gpio_set_pull(EXYNOS4X12_GPIO_X04, S5P_GPIO_PULL_NONE); /* TSP_nINT */
91 gpio_set_pull(EXYNOS4X12_GPIO_X07, S5P_GPIO_PULL_NONE); /* AP_PMIC_IRQ*/
92 gpio_set_pull(EXYNOS4X12_GPIO_X15, S5P_GPIO_PULL_NONE); /* IF_PMIC_IRQ*/
93 gpio_set_pull(EXYNOS4X12_GPIO_X20, S5P_GPIO_PULL_NONE); /* VOL_UP */
94 gpio_set_pull(EXYNOS4X12_GPIO_X21, S5P_GPIO_PULL_NONE); /* VOL_DOWN */
95 gpio_set_pull(EXYNOS4X12_GPIO_X23, S5P_GPIO_PULL_NONE); /* FUEL_ALERT */
96 gpio_set_pull(EXYNOS4X12_GPIO_X24, S5P_GPIO_PULL_NONE); /* ADC_INT */
97 gpio_set_pull(EXYNOS4X12_GPIO_X27, S5P_GPIO_PULL_NONE); /* nPOWER */
98 gpio_set_pull(EXYNOS4X12_GPIO_X30, S5P_GPIO_PULL_NONE); /* WPC_INT */
99 gpio_set_pull(EXYNOS4X12_GPIO_X35, S5P_GPIO_PULL_NONE); /* OK_KEY */
100 gpio_set_pull(EXYNOS4X12_GPIO_X37, S5P_GPIO_PULL_NONE); /* HDMI_HPD */
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200101}
102
Piotr Wilczek87d2e782014-03-07 14:59:49 +0100103int exynos_early_init_f(void)
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200104{
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200105 board_external_gpio_init();
106
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200107 return 0;
108}
109
Tom Rini757dc982023-09-21 19:32:48 -0400110void exynos_init(void)
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200111{
Łukasz Majewski27937c02014-04-09 15:09:44 +0200112 struct exynos4_power *pwr =
113 (struct exynos4_power *)samsung_get_base_power();
114
Piotr Wilczek87d2e782014-03-07 14:59:49 +0100115 check_hw_revision();
116 printf("HW Revision:\t0x%04x\n", board_rev);
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200117
Łukasz Majewski27937c02014-04-09 15:09:44 +0200118 /*
119 * First bootloader on the TRATS2 platform uses
120 * INFORM4 and INFORM5 registers for recovery
121 *
122 * To indicate correct boot chain - those two
123 * registers must be cleared out
124 */
125 writel(0, &pwr->inform4);
126 writel(0, &pwr->inform5);
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200127}
128
Piotr Wilczek87d2e782014-03-07 14:59:49 +0100129int exynos_power_init(void)
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200130{
Igor Opaniukf7c91762021-02-09 13:52:45 +0200131#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200132 int chrg;
133 struct power_battery *pb;
134 struct pmic *p_chrg, *p_muic, *p_fg, *p_bat;
135
Piotr Wilczek97ae1832013-12-18 15:43:37 +0100136 pmic_init_max77693(I2C_10); /* I2C adapter 10 - bus name soft1 */
137 power_muic_init(I2C_10); /* I2C adapter 10 - bus name soft1 */
138 power_fg_init(I2C_9); /* I2C adapter 9 - bus name soft0 */
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200139 power_bat_init(0);
140
141 p_chrg = pmic_get("MAX77693_PMIC");
142 if (!p_chrg) {
143 puts("MAX77693_PMIC: Not found\n");
144 return -ENODEV;
145 }
146
147 p_muic = pmic_get("MAX77693_MUIC");
148 if (!p_muic) {
149 puts("MAX77693_MUIC: Not found\n");
150 return -ENODEV;
151 }
152
153 p_fg = pmic_get("MAX77693_FG");
154 if (!p_fg) {
155 puts("MAX17042_FG: Not found\n");
156 return -ENODEV;
157 }
158
159 if (p_chrg->chrg->chrg_bat_present(p_chrg) == 0)
160 puts("No battery detected\n");
161
162 p_bat = pmic_get("BAT_TRATS2");
163 if (!p_bat) {
164 puts("BAT_TRATS2: Not found\n");
165 return -ENODEV;
166 }
167
168 p_fg->parent = p_bat;
169 p_chrg->parent = p_bat;
170 p_muic->parent = p_bat;
171
172 p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic);
173
174 pb = p_bat->pbat;
175 chrg = p_muic->chrg->chrg_type(p_muic);
176 debug("CHARGER TYPE: %d\n", chrg);
177
178 if (!p_chrg->chrg->chrg_bat_present(p_chrg)) {
179 puts("No battery detected\n");
Przemyslaw Marczakdd0c48e2014-06-10 16:55:08 +0200180 return 0;
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200181 }
182
183 p_fg->fg->fg_battery_check(p_fg, p_bat);
184
185 if (pb->bat->state == CHARGE && chrg == CHARGER_USB)
186 puts("CHARGE Battery !\n");
Simon Glass7bbb7d92016-11-23 06:34:40 -0700187#endif
Piotr Wilczek2b3c92a2013-09-20 15:01:27 +0200188 return 0;
189}
190
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100191#ifdef CONFIG_USB_GADGET
192static int s5pc210_phy_control(int on)
193{
Igor Opaniukf7c91762021-02-09 13:52:45 +0200194#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100195 int ret = 0;
196 unsigned int val;
197 struct pmic *p, *p_pmic, *p_muic;
198
199 p_pmic = pmic_get("MAX77686_PMIC");
200 if (!p_pmic)
201 return -ENODEV;
202
203 if (pmic_probe(p_pmic))
204 return -1;
205
206 p_muic = pmic_get("MAX77693_MUIC");
207 if (!p_muic)
208 return -ENODEV;
209
210 if (pmic_probe(p_muic))
211 return -1;
212
213 if (on) {
214 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON);
215 if (ret)
216 return -1;
217
218 p = pmic_get("MAX77693_PMIC");
219 if (!p)
220 return -ENODEV;
221
222 if (pmic_probe(p))
223 return -1;
224
225 /* SAFEOUT */
226 ret = pmic_reg_read(p, MAX77693_SAFEOUT, &val);
227 if (ret)
228 return -1;
229
230 val |= MAX77693_ENSAFEOUT1;
231 ret = pmic_reg_write(p, MAX77693_SAFEOUT, val);
232 if (ret)
233 return -1;
234
235 /* PATH: USB */
236 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1,
237 MAX77693_MUIC_CTRL1_DN1DP2);
238
239 } else {
240 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM);
241 if (ret)
242 return -1;
243
244 /* PATH: UART */
245 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1,
246 MAX77693_MUIC_CTRL1_UT1UR2);
247 }
248
249 if (ret)
250 return -1;
Simon Glass7bbb7d92016-11-23 06:34:40 -0700251#endif
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100252 return 0;
253}
254
Marek Vasut6939aca2015-12-04 02:23:29 +0100255struct dwc2_plat_otg_data s5pc210_otg_data = {
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100256 .phy_control = s5pc210_phy_control,
257 .regs_phy = EXYNOS4X12_USBPHY_BASE,
258 .regs_otg = EXYNOS4X12_USBOTG_BASE,
259 .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL,
260 .usb_flags = PHY0_SLEEP,
261};
262
263int board_usb_init(int index, enum usb_init_type init)
264{
265 debug("USB_udc_probe\n");
Marek Vasut01b61fa2015-12-04 02:26:33 +0100266 return dwc2_udc_probe(&s5pc210_otg_data);
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100267}
268
Mateusz Zalega21fe3f72014-04-30 13:07:48 +0200269int g_dnl_board_usb_cable_connected(void)
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100270{
Igor Opaniukf7c91762021-02-09 13:52:45 +0200271#if !CONFIG_IS_ENABLED(DM_I2C) /* TODO(maintainer): Convert to driver model */
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100272 struct pmic *muic = pmic_get("MAX77693_MUIC");
273 if (!muic)
274 return 0;
275
276 return !!muic->chrg->chrg_type(muic);
Simon Glass7bbb7d92016-11-23 06:34:40 -0700277#else
278 return false;
279#endif
Piotr Wilczek0c2ba4c2013-11-21 15:46:45 +0100280}
281#endif