blob: caa02655fc4934607bbc660d83b26b5a9e33cfc0 [file] [log] [blame]
Angus Ainslie466a9ea2022-08-25 06:46:02 -07001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2018 NXP
4 * Copyright 2021 Purism
5 */
6
7#include <common.h>
8#include <malloc.h>
9#include <errno.h>
10#include <asm/io.h>
11#include <miiphy.h>
12#include <asm/mach-imx/iomux-v3.h>
13#include <asm-generic/gpio.h>
14#include <asm/arch/sys_proto.h>
15#include <fsl_esdhc.h>
16#include <mmc.h>
17#include <asm/arch/imx8mq_pins.h>
18#include <asm/arch/sys_proto.h>
19#include <asm/mach-imx/gpio.h>
20#include <asm/mach-imx/mxc_i2c.h>
21#include <asm/arch/clock.h>
22#include <asm/mach-imx/video.h>
23#include <fuse.h>
24#include <i2c.h>
25#include <spl.h>
26#include <usb.h>
27#include <dwc3-uboot.h>
28#include <linux/delay.h>
29#include <linux/bitfield.h>
30#include <power/regulator.h>
31#include <usb/xhci.h>
32#include "librem5.h"
33
34DECLARE_GLOBAL_DATA_PTR;
35
36int board_early_init_f(void)
37{
38 return 0;
39}
40
41#if IS_ENABLED(CONFIG_LOAD_ENV_FROM_MMC_BOOT_PARTITION)
42uint board_mmc_get_env_part(struct mmc *mmc)
43{
44 uint part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
45
46 if (part == 7)
47 part = 0;
48 return part;
49}
50#endif
51
52int tps65982_wait_for_app(int timeout, int timeout_step)
53{
54 int ret;
55 char response[6];
56 struct udevice *udev, *bus;
57
58 log_debug("%s: starting\n", __func__);
59
60 /* Set the i2c bus */
61 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
62 if (ret) {
63 log_err("%s: No bus %d\n", __func__, 0);
64 return 1;
65 }
66
67 ret = i2c_get_chip(bus, 0x3f, 1, &udev);
68 if (ret) {
69 log_err("%s: setting chip offset failed %d\n", __func__, ret);
70 return 1;
71 }
72
73 while (timeout > 0) {
74 ret = dm_i2c_read(udev, 0x03, (u8 *)response, 5);
75 log_debug("tps65982 mode %s\n", response);
76 if (response[1] == 'A')
77 return 0;
78 mdelay(timeout_step);
79 timeout -= timeout_step;
80 log_debug("tps65982 waited %d ms %c\n", timeout_step, response[1]);
81 }
82
83 return 1;
84}
85
86int tps65982_clear_dead_battery(void)
87{
88 int ret;
89 char cmd[5] = "\04DBfg";
90 struct udevice *udev, *bus;
91
92 log_debug("%s: starting\n", __func__);
93
94 /* Set the i2c bus */
95 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
96 if (ret) {
97 log_err("%s: No bus %d\n", __func__, 0);
98 return 1;
99 }
100
101 ret = i2c_get_chip(bus, 0x3f, 1, &udev);
102 if (ret) {
103 log_err("%s: setting chip offset failed %d\n", __func__, ret);
104 return 1;
105 }
106
107 /* clearing the dead battery flag when not in dead battery condition
108 * is a no-op, so there's no need to check if it's in effect
109 */
110 ret = dm_i2c_write(udev, 0x08, cmd, 5);
111 if (ret) {
112 log_err("%s: writing 4CC command failed %d", __func__, ret);
113 return 1;
114 }
115
116 return 0;
117}
118
119#define TPS_POWER_STATUS_PWROPMODE(x) FIELD_GET(GENMASK(3, 2), x)
120
121#define TPS_PDO_CONTRACT_TYPE(x) FIELD_GET(GENMASK(31, 30), x)
122#define TPS_PDO_CONTRACT_FIXED 0
123#define TPS_PDO_CONTRACT_BATTERY 1
124#define TPS_PDO_CONTRACT_VARIABLE 2
125
126#define TPS_TYPEC_PWR_MODE_USB 0
127#define TPS_TYPEC_PWR_MODE_1_5A 1
128#define TPS_TYPEC_PWR_MODE_3_0A 2
129#define TPS_TYPEC_PWR_MODE_PD 3
130
131#define TPS_PDO_FIXED_CONTRACT_MAX_CURRENT(x) (FIELD_GET(GENMASK(9, 0), x) * 10)
132#define TPS_PDO_VAR_CONTRACT_MAX_CURRENT(x) (FIELD_GET(GENMASK(9, 0), x) * 10)
133#define TPS_PDO_BAT_CONTRACT_MAX_VOLTAGE(x) (FIELD_GET(GENMASK(29, 20), x) * 50)
134#define TPS_PDO_BAT_CONTRACT_MAX_POWER(x) (FIELD_GET(GENMASK(9, 0), x) * 250)
135
136int tps65982_get_max_current(void)
137{
138 int ret;
139 u8 buf[7];
140 u8 pwr_status;
141 u32 contract;
142 int type, mode;
143 struct udevice *udev, *bus;
144
145 log_debug("%s: starting\n", __func__);
146
147 /* Set the i2c bus */
148 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &bus);
149 if (ret) {
150 log_debug("%s: No bus %d\n", __func__, 0);
151 return -1;
152 }
153
154 ret = i2c_get_chip(bus, 0x3f, 1, &udev);
155 if (ret) {
156 log_debug("%s: setting chip offset failed %d\n", __func__, ret);
157 return -1;
158 }
159
160 ret = dm_i2c_read(udev, 0x3f, buf, 3);
161 if (ret) {
162 log_debug("%s: reading pwr_status failed %d\n", __func__, ret);
163 return -1;
164 }
165
166 pwr_status = buf[1];
167
168 if (!(pwr_status & 1))
169 return 0;
170
171 mode = TPS_POWER_STATUS_PWROPMODE(pwr_status);
172 switch (mode) {
173 case TPS_TYPEC_PWR_MODE_1_5A:
174 return 1500;
175 case TPS_TYPEC_PWR_MODE_3_0A:
176 return 3000;
177 case TPS_TYPEC_PWR_MODE_PD:
178 ret = dm_i2c_read(udev, 0x34, buf, 7);
179 if (ret) {
180 log_debug("%s: reading active contract failed %d\n", __func__, ret);
181 return -1;
182 }
183
184 contract = buf[1] + (buf[2] << 8) + (buf[3] << 16) + (buf[4] << 24);
185
186 type = TPS_PDO_CONTRACT_TYPE(contract);
187
188 switch (type) {
189 case TPS_PDO_CONTRACT_FIXED:
190 return TPS_PDO_FIXED_CONTRACT_MAX_CURRENT(contract);
191 case TPS_PDO_CONTRACT_BATTERY:
192 return 1000 * TPS_PDO_BAT_CONTRACT_MAX_POWER(contract)
193 / TPS_PDO_BAT_CONTRACT_MAX_VOLTAGE(contract);
194 case TPS_PDO_CONTRACT_VARIABLE:
195 return TPS_PDO_VAR_CONTRACT_MAX_CURRENT(contract);
196 default:
197 log_debug("Unknown contract type: %d\n", type);
198 return -1;
199 }
200 case TPS_TYPEC_PWR_MODE_USB:
201 return 500;
202 default:
203 log_debug("Unknown power mode: %d\n", mode);
204 return -1;
205 }
206}
207
208int init_tps65982(void)
209{
210 log_debug("%s: starting\n", __func__);
211
212 if (tps65982_wait_for_app(500, 100)) {
213 log_err("tps65982 APP boot failed\n");
214 return 1;
215 }
216
217 log_info("tps65982 boot successful\n");
218 return 0;
219}
220
221int bq25895_set_iinlim(int current)
222{
223 u8 val, iinlim;
224 int ret;
225 struct udevice *udev, *bus;
226
227 /* Set the i2c bus */
228 ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus);
229 if (ret) {
230 log_err("%s: No bus 3\n", __func__);
231 return ret;
232 }
233
234 ret = i2c_get_chip(bus, 0x6a, 1, &udev);
235 if (ret) {
236 log_err("%s: setting chip offset failed %d\n", __func__, ret);
237 return ret;
238 }
239
240 if (current > 3250)
241 current = 3250;
242 if (current < 100)
243 current = 100;
244
245 val = dm_i2c_reg_read(udev, 0x00);
246 iinlim = ((current - 100) / 50) & 0x3f;
247 val = (val & 0xc0) | iinlim;
248 dm_i2c_reg_write(udev, 0x00, val);
249 log_debug("REG00 0x%x\n", val);
250
251 return 0;
252}
253
254bool bq25895_battery_present(void)
255{
256 u8 val;
257 int ret;
258 struct udevice *udev, *bus;
259
260 /* Set the i2c bus */
261 ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus);
262 if (ret) {
263 log_err("%s: No bus 3\n", __func__);
264 return ret;
265 }
266
267 ret = i2c_get_chip(bus, 0x6a, 1, &udev);
268 if (ret) {
269 log_err("%s: setting chip offset failed %d\n", __func__, ret);
270 return ret;
271 }
272
273 /* note that this may return false negatives when there's
274 * no external power applied and the battery voltage is below
275 * Vsys. this isn't a problem when used for clearing the dead
276 * battery flag though, since it's certain that there's an external
277 * power applied in this case
278 */
279 val = dm_i2c_reg_read(udev, 0x0e) & 0x7f;
280 if (val == 0x00 || val == 0x7f)
281 return false;
282
283 return true;
284}
285
286/*
287 * set some safe defaults for the battery charger
288 */
289int init_charger_bq25895(void)
290{
291 u8 val;
292 int iinlim, ret;
293 struct udevice *udev, *bus;
294
295 /* Set the i2c bus */
296 ret = uclass_get_device_by_seq(UCLASS_I2C, 3, &bus);
297 if (ret) {
298 log_debug("%s: No bus 3\n", __func__);
299 return ret;
300 }
301
302 ret = i2c_get_chip(bus, 0x6a, 1, &udev);
303 if (ret) {
304 log_debug("%s: setting chip offset failed %d\n", __func__, ret);
305 return ret;
306 }
307
308 val = dm_i2c_reg_read(udev, 0x0b);
309 log_debug("REG0B 0x%x\n", val);
310
311 log_debug("VBUS_STAT 0x%x\n", val >> 5);
312 switch (val >> 5) {
313 case 0:
314 log_debug("VBUS not detected\n");
315 break;
316 case 1:
317 log_debug("USB SDP IINLIM 500mA\n");
318 break;
319 case 2:
320 log_debug("USB CDP IINLIM 1500mA\n");
321 break;
322 case 3:
323 log_debug("USB DCP IINLIM 3500mA\n");
324 break;
325 case 4:
326 log_debug("MAXCHARGE IINLIM 1500mA\n");
327 break;
328 case 5:
329 log_debug("Unknown IINLIM 500mA\n");
330 break;
331 case 6:
332 log_debug("DIVIDER IINLIM > 1000mA\n");
333 break;
334 case 7:
335 log_debug("OTG\n");
336 break;
337 };
338
339 log_debug("CHRG_STAT 0x%x\n", (val >> 3) & 0x3);
340 log_debug("PG_STAT 0x%x\n", (val >> 2) & 1);
341 log_debug("SDP_STAT 0x%x\n", (val >> 1) & 1);
342 log_debug("VSYS_STAT 0x%x\n", val & 1);
343
344 val = dm_i2c_reg_read(udev, 0x00);
345 log_debug("REG00 0x%x\n", val);
346 iinlim = 100 + (val & 0x3f) * 50;
347 log_debug("IINLIM %d mA\n", iinlim);
348 log_debug("EN_HIZ 0x%x\n", (val >> 7) & 1);
349 log_debug("EN_ILIM 0x%x\n", (val >> 6) & 1);
350
351 /* set 1.6A charge limit */
352 dm_i2c_reg_write(udev, 0x04, 0x19);
353
354 /* re-enable charger */
355 val = dm_i2c_reg_read(udev, 0x03);
356 val = val | 0x10;
357 dm_i2c_reg_write(udev, 0x03, val);
358
359 return 0;
360}
361
362int board_init(void)
363{
364 struct udevice *dev;
365 int tps_ret;
366
367 if (IS_ENABLED(CONFIG_USB_DWC3) || IS_ENABLED(CONFIG_USB_XHCI_IMX8M)) {
368 log_debug("%s: initializing USB clk\n", __func__);
369
370 /* init_usb_clk won't enable the second clock if it's a USB boot */
371 if (is_usb_boot()) {
372 clock_enable(CCGR_USB_CTRL2, 1);
373 clock_enable(CCGR_USB_PHY2, 1);
374 }
375
376 printf("Enabling regulator-hub\n");
377 if (!regulator_get_by_devname("regulator-hub", &dev)) {
378 if (regulator_set_enable(dev, true))
379 pr_err("Failed to enable regulator-hub\n");
380 }
381 }
382
383 tps_ret = init_tps65982();
384 init_charger_bq25895();
385
386 if (!tps_ret) {
387 int current = tps65982_get_max_current();
388
389 if (current > 500)
390 bq25895_set_iinlim(current);
391
392 if (bq25895_battery_present())
393 tps65982_clear_dead_battery();
394 }
395
396 return 0;
397}
398
399int board_late_init(void)
400{
401 if (IS_ENABLED(CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG)) {
402 u32 rev;
403 char rev_str[3];
404
405 env_set("board_name", "librem5");
406 if (fuse_read(9, 0, &rev)) {
407 env_set("board_rev", BOARD_REV_ERROR);
408 } else if (rev == 0) {
409 env_set("board_rev", BOARD_REV_UNKNOWN);
410 } else if (rev > 0) {
411 sprintf(rev_str, "%u", rev);
412 env_set("board_rev", rev_str);
413 }
414
415 printf("Board name: %s\n", env_get("board_name"));
416 printf("Board rev: %s\n", env_get("board_rev"));
417 }
418
419 if (is_usb_boot()) {
420 puts("USB Boot\n");
421 env_set("bootcmd", "fastboot 0");
422 }
423
424 return 0;
425}