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