1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2495f3774SAndy Shevchenko /*
3495f3774SAndy Shevchenko * Copyright (c) 2017 Intel Corporation
4495f3774SAndy Shevchenko */
5495f3774SAndy Shevchenko #include <common.h>
6495f3774SAndy Shevchenko #include <dwc3-uboot.h>
701510091SSimon Glass #include <environment.h>
8495f3774SAndy Shevchenko #include <mmc.h>
9495f3774SAndy Shevchenko #include <u-boot/md5.h>
10495f3774SAndy Shevchenko #include <usb.h>
11495f3774SAndy Shevchenko #include <watchdog.h>
12495f3774SAndy Shevchenko
13495f3774SAndy Shevchenko #include <linux/usb/gadget.h>
14495f3774SAndy Shevchenko
15495f3774SAndy Shevchenko #include <asm/cache.h>
16495f3774SAndy Shevchenko #include <asm/scu.h>
17495f3774SAndy Shevchenko #include <asm/u-boot-x86.h>
18495f3774SAndy Shevchenko
19495f3774SAndy Shevchenko static struct dwc3_device dwc3_device_data = {
20495f3774SAndy Shevchenko .maximum_speed = USB_SPEED_HIGH,
21495f3774SAndy Shevchenko .base = CONFIG_SYS_USB_OTG_BASE,
22495f3774SAndy Shevchenko .dr_mode = USB_DR_MODE_PERIPHERAL,
23495f3774SAndy Shevchenko .index = 0,
24495f3774SAndy Shevchenko };
25495f3774SAndy Shevchenko
usb_gadget_handle_interrupts(int controller_index)26495f3774SAndy Shevchenko int usb_gadget_handle_interrupts(int controller_index)
27495f3774SAndy Shevchenko {
28495f3774SAndy Shevchenko dwc3_uboot_handle_interrupt(controller_index);
29495f3774SAndy Shevchenko WATCHDOG_RESET();
30495f3774SAndy Shevchenko return 0;
31495f3774SAndy Shevchenko }
32495f3774SAndy Shevchenko
board_usb_init(int index,enum usb_init_type init)33495f3774SAndy Shevchenko int board_usb_init(int index, enum usb_init_type init)
34495f3774SAndy Shevchenko {
35495f3774SAndy Shevchenko if (index == 0 && init == USB_INIT_DEVICE)
36495f3774SAndy Shevchenko return dwc3_uboot_init(&dwc3_device_data);
37495f3774SAndy Shevchenko return -EINVAL;
38495f3774SAndy Shevchenko }
39495f3774SAndy Shevchenko
board_usb_cleanup(int index,enum usb_init_type init)40495f3774SAndy Shevchenko int board_usb_cleanup(int index, enum usb_init_type init)
41495f3774SAndy Shevchenko {
42495f3774SAndy Shevchenko if (index == 0 && init == USB_INIT_DEVICE) {
43495f3774SAndy Shevchenko dwc3_uboot_exit(index);
44495f3774SAndy Shevchenko return 0;
45495f3774SAndy Shevchenko }
46495f3774SAndy Shevchenko return -EINVAL;
47495f3774SAndy Shevchenko }
48495f3774SAndy Shevchenko
assign_serial(void)49495f3774SAndy Shevchenko static void assign_serial(void)
50495f3774SAndy Shevchenko {
51495f3774SAndy Shevchenko struct mmc *mmc = find_mmc_device(0);
52495f3774SAndy Shevchenko unsigned char ssn[16];
53495f3774SAndy Shevchenko char usb0addr[18];
54495f3774SAndy Shevchenko char serial[33];
55495f3774SAndy Shevchenko int i;
56495f3774SAndy Shevchenko
57495f3774SAndy Shevchenko if (!mmc)
58495f3774SAndy Shevchenko return;
59495f3774SAndy Shevchenko
60495f3774SAndy Shevchenko md5((unsigned char *)mmc->cid, sizeof(mmc->cid), ssn);
61495f3774SAndy Shevchenko
62495f3774SAndy Shevchenko snprintf(usb0addr, sizeof(usb0addr), "02:00:86:%02x:%02x:%02x",
63495f3774SAndy Shevchenko ssn[13], ssn[14], ssn[15]);
64382bee57SSimon Glass env_set("usb0addr", usb0addr);
65495f3774SAndy Shevchenko
66495f3774SAndy Shevchenko for (i = 0; i < 16; i++)
67495f3774SAndy Shevchenko snprintf(&serial[2 * i], 3, "%02x", ssn[i]);
68382bee57SSimon Glass env_set("serial#", serial);
69495f3774SAndy Shevchenko
70495f3774SAndy Shevchenko #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
7101510091SSimon Glass env_save();
72495f3774SAndy Shevchenko #endif
73495f3774SAndy Shevchenko }
74495f3774SAndy Shevchenko
assign_hardware_id(void)75495f3774SAndy Shevchenko static void assign_hardware_id(void)
76495f3774SAndy Shevchenko {
77495f3774SAndy Shevchenko struct ipc_ifwi_version v;
78495f3774SAndy Shevchenko char hardware_id[4];
79495f3774SAndy Shevchenko int ret;
80495f3774SAndy Shevchenko
81495f3774SAndy Shevchenko ret = scu_ipc_command(IPCMSG_GET_FW_REVISION, 1, NULL, 0, (u32 *)&v, 4);
82495f3774SAndy Shevchenko if (ret < 0)
83495f3774SAndy Shevchenko printf("Can't retrieve hardware revision\n");
84495f3774SAndy Shevchenko
85495f3774SAndy Shevchenko snprintf(hardware_id, sizeof(hardware_id), "%02X", v.hardware_id);
86382bee57SSimon Glass env_set("hardware_id", hardware_id);
87495f3774SAndy Shevchenko
88495f3774SAndy Shevchenko #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
8901510091SSimon Glass env_save();
90495f3774SAndy Shevchenko #endif
91495f3774SAndy Shevchenko }
92495f3774SAndy Shevchenko
board_late_init(void)93495f3774SAndy Shevchenko int board_late_init(void)
94495f3774SAndy Shevchenko {
9500caae6dSSimon Glass if (!env_get("serial#"))
96495f3774SAndy Shevchenko assign_serial();
97495f3774SAndy Shevchenko
9800caae6dSSimon Glass if (!env_get("hardware_id"))
99495f3774SAndy Shevchenko assign_hardware_id();
100495f3774SAndy Shevchenko
101495f3774SAndy Shevchenko return 0;
102495f3774SAndy Shevchenko }
103