12e905c06SYann Gautier /* 2*6d1366e5SPatrick Delaunay * Copyright (c) 2024-2025, STMicroelectronics - All Rights Reserved 32e905c06SYann Gautier * 42e905c06SYann Gautier * SPDX-License-Identifier: BSD-3-Clause 52e905c06SYann Gautier */ 62e905c06SYann Gautier 7*6d1366e5SPatrick Delaunay #include <limits.h> 82e905c06SYann Gautier #include <stddef.h> 9*6d1366e5SPatrick Delaunay #include <string.h> 102e905c06SYann Gautier 11*6d1366e5SPatrick Delaunay #include <common/debug.h> 12*6d1366e5SPatrick Delaunay #include <drivers/st/usb_dwc3.h> 132e905c06SYann Gautier #include <drivers/usb_device.h> 142e905c06SYann Gautier 15*6d1366e5SPatrick Delaunay #include <platform_def.h> 16*6d1366e5SPatrick Delaunay #include <stm32cubeprogrammer.h> 17*6d1366e5SPatrick Delaunay #include <stm32mp_common.h> 182e905c06SYann Gautier #include <usb_dfu.h> 192e905c06SYann Gautier 20*6d1366e5SPatrick Delaunay /* String size (1 byte) + type (1 byte) + 24 UTF16 characters: 2 bytes each */ 21*6d1366e5SPatrick Delaunay #define SIZ_STRING_SERIAL U(24) 22*6d1366e5SPatrick Delaunay #define USB_SIZ_STRING_SERIAL (1U + 1U + (SIZ_STRING_SERIAL * 2U)) 23*6d1366e5SPatrick Delaunay #define USBD_MAX_STR_DESC_SIZ U(0x100) 24*6d1366e5SPatrick Delaunay #define USBD_VID U(0x0483) 25*6d1366e5SPatrick Delaunay #define USBD_PID U(0xDF11) 26*6d1366e5SPatrick Delaunay #define USBD_LANGID_STRING U(0x409) 27*6d1366e5SPatrick Delaunay #define USBD_MANUFACTURER_STRING "STMicroelectronics" 28*6d1366e5SPatrick Delaunay #define USBD_CONFIGURATION_STRING "DFU Config" 29*6d1366e5SPatrick Delaunay #define USBD_INTERFACE_STRING "DFU Interface" 30*6d1366e5SPatrick Delaunay 31*6d1366e5SPatrick Delaunay #define USB_DFU_ITF_NUM U(3) 32*6d1366e5SPatrick Delaunay 33*6d1366e5SPatrick Delaunay #define USB_DFU_CONFIG_DESC_SIZ USB_DFU_DESC_SIZ(USB_DFU_ITF_NUM) 34*6d1366e5SPatrick Delaunay 35*6d1366e5SPatrick Delaunay /* DFU devices */ 36*6d1366e5SPatrick Delaunay static struct usb_dfu_handle usb_dfu_handle; 37*6d1366e5SPatrick Delaunay 38*6d1366e5SPatrick Delaunay /* USB Standard Device Descriptor */ 39*6d1366e5SPatrick Delaunay static const uint8_t usb_stm32mp2_desc[USB_LEN_DEV_DESC] = { 40*6d1366e5SPatrick Delaunay USB_LEN_DEV_DESC, /* bLength */ 41*6d1366e5SPatrick Delaunay USB_DESC_TYPE_DEVICE, /* bDescriptorType */ 42*6d1366e5SPatrick Delaunay 0x00, /* bcdUSB */ 43*6d1366e5SPatrick Delaunay 0x02, /* version */ 44*6d1366e5SPatrick Delaunay 0x00, /* bDeviceClass */ 45*6d1366e5SPatrick Delaunay 0x00, /* bDeviceSubClass */ 46*6d1366e5SPatrick Delaunay 0x00, /* bDeviceProtocol */ 47*6d1366e5SPatrick Delaunay USB_MAX_EP0_SIZE, /* bMaxPacketSize */ 48*6d1366e5SPatrick Delaunay LOBYTE(USBD_VID), /* idVendor */ 49*6d1366e5SPatrick Delaunay HIBYTE(USBD_VID), /* idVendor */ 50*6d1366e5SPatrick Delaunay LOBYTE(USBD_PID), /* idVendor */ 51*6d1366e5SPatrick Delaunay HIBYTE(USBD_PID), /* idVendor */ 52*6d1366e5SPatrick Delaunay 0x00, /* bcdDevice rel. 2.00 */ 53*6d1366e5SPatrick Delaunay 0x02, 54*6d1366e5SPatrick Delaunay USBD_IDX_MFC_STR, /* Index of manufacturer string */ 55*6d1366e5SPatrick Delaunay USBD_IDX_PRODUCT_STR, /* Index of product string */ 56*6d1366e5SPatrick Delaunay USBD_IDX_SERIAL_STR, /* Index of serial number string */ 57*6d1366e5SPatrick Delaunay USBD_MAX_NUM_CONFIGURATION /* bNumConfigurations */ 58*6d1366e5SPatrick Delaunay }; /* USB_DeviceDescriptor */ 59*6d1366e5SPatrick Delaunay 60*6d1366e5SPatrick Delaunay /* USB Standard String Descriptor */ 61*6d1366e5SPatrick Delaunay static const uint8_t usb_stm32mp2_lang_id_desc[USB_LEN_LANGID_STR_DESC] = { 62*6d1366e5SPatrick Delaunay USB_LEN_LANGID_STR_DESC, 63*6d1366e5SPatrick Delaunay USB_DESC_TYPE_STRING, 64*6d1366e5SPatrick Delaunay LOBYTE(USBD_LANGID_STRING), 65*6d1366e5SPatrick Delaunay HIBYTE(USBD_LANGID_STRING), 66*6d1366e5SPatrick Delaunay }; 67*6d1366e5SPatrick Delaunay 68*6d1366e5SPatrick Delaunay /* USB Standard Device Descriptor */ 69*6d1366e5SPatrick Delaunay static const uint8_t usbd_stm32mp2_qualifier_desc[USB_LEN_DEV_QUALIFIER_DESC] = { 70*6d1366e5SPatrick Delaunay USB_LEN_DEV_QUALIFIER_DESC, 71*6d1366e5SPatrick Delaunay USB_DESC_TYPE_DEVICE_QUALIFIER, 72*6d1366e5SPatrick Delaunay 0x00, 73*6d1366e5SPatrick Delaunay 0x02, 74*6d1366e5SPatrick Delaunay 0x00, 75*6d1366e5SPatrick Delaunay 0x00, 76*6d1366e5SPatrick Delaunay 0x00, 77*6d1366e5SPatrick Delaunay 0x40, 78*6d1366e5SPatrick Delaunay 0x01, 79*6d1366e5SPatrick Delaunay 0x00, 80*6d1366e5SPatrick Delaunay }; 81*6d1366e5SPatrick Delaunay 82*6d1366e5SPatrick Delaunay /* USB serial number: build dynamically */ 83*6d1366e5SPatrick Delaunay static uint8_t usb_stm32mp2_serial[USB_SIZ_STRING_SERIAL + 1]; 84*6d1366e5SPatrick Delaunay 85*6d1366e5SPatrick Delaunay /* USB DFU device Configuration Descriptor */ 86*6d1366e5SPatrick Delaunay static const uint8_t usb_stm32mp2_config_desc[USB_DFU_CONFIG_DESC_SIZ] = { 87*6d1366e5SPatrick Delaunay 0x09, /* bLength: Configuration Descriptor size */ 88*6d1366e5SPatrick Delaunay USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ 89*6d1366e5SPatrick Delaunay USB_DFU_CONFIG_DESC_SIZ, /* wTotalLength: Bytes returned */ 90*6d1366e5SPatrick Delaunay 0x00, 0x01, /* bNumInterfaces: 1 interface */ 91*6d1366e5SPatrick Delaunay 0x01, /* bConfigurationValue: Configuration value */ 92*6d1366e5SPatrick Delaunay 0x02, /* iConfiguration: Index of string descriptor for configuration */ 93*6d1366e5SPatrick Delaunay 0xC0, /* bmAttributes: bus powered and Supprts Remote Wakeup */ 94*6d1366e5SPatrick Delaunay 0x32, /* MaxPower 100 mA: this current is used for detecting Vbus */ 95*6d1366e5SPatrick Delaunay 96*6d1366e5SPatrick Delaunay /* Descriptor of DFU interface 0 Alternate setting 0..N */ 97*6d1366e5SPatrick Delaunay USBD_DFU_IF_DESC(0), USBD_DFU_IF_DESC(1), USBD_DFU_IF_DESC(2), 98*6d1366e5SPatrick Delaunay /* DFU Functional Descriptor */ 99*6d1366e5SPatrick Delaunay 0x09, /* blength = 9 Bytes */ 100*6d1366e5SPatrick Delaunay DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor */ 101*6d1366e5SPatrick Delaunay DFU_BM_ATTRIBUTE, /* bmAttribute for DFU */ 102*6d1366e5SPatrick Delaunay 0xFF, /* DetachTimeOut = 255 ms */ 103*6d1366e5SPatrick Delaunay 0x00, 104*6d1366e5SPatrick Delaunay /* WARNING: In DMA mode the multiple MPS packets feature 105*6d1366e5SPatrick Delaunay * is still not supported ==> In this case, 106*6d1366e5SPatrick Delaunay * when using DMA USBD_DFU_XFER_SIZE should be set 107*6d1366e5SPatrick Delaunay * to 64 in usbd_conf.h 108*6d1366e5SPatrick Delaunay */ 109*6d1366e5SPatrick Delaunay TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte */ 110*6d1366e5SPatrick Delaunay ((USB_DFU_VERSION >> 0) & 0xFF), /* bcdDFUVersion */ 111*6d1366e5SPatrick Delaunay ((USB_DFU_VERSION >> 8) & 0xFF) 112*6d1366e5SPatrick Delaunay }; 113*6d1366e5SPatrick Delaunay 114*6d1366e5SPatrick Delaunay const char *const if_desc_string[USB_DFU_ITF_NUM] = { 115*6d1366e5SPatrick Delaunay "@DDR FIP /0x02/1*32Ke", "@FIP /0x03/1*16Me", "@virtual /0xF1/1*512Ba" 116*6d1366e5SPatrick Delaunay }; 117*6d1366e5SPatrick Delaunay 118*6d1366e5SPatrick Delaunay /* Buffer to build the unicode string provided to USB device stack */ 119*6d1366e5SPatrick Delaunay static uint8_t usb_str_dec[USBD_MAX_STR_DESC_SIZ]; 120*6d1366e5SPatrick Delaunay 121*6d1366e5SPatrick Delaunay /* 122*6d1366e5SPatrick Delaunay * Convert Ascii string into unicode one 123*6d1366e5SPatrick Delaunay * desc : descriptor buffer 124*6d1366e5SPatrick Delaunay * unicode : Formatted string buffer (unicode) 125*6d1366e5SPatrick Delaunay * len : descriptor length 126*6d1366e5SPatrick Delaunay */ 127*6d1366e5SPatrick Delaunay static void stm32mp2_get_string(const char *desc, uint8_t *unicode, 128*6d1366e5SPatrick Delaunay uint16_t *len) 1292e905c06SYann Gautier { 130*6d1366e5SPatrick Delaunay uint8_t idx = 0U; 131*6d1366e5SPatrick Delaunay 132*6d1366e5SPatrick Delaunay if (desc == NULL) { 133*6d1366e5SPatrick Delaunay return; 134*6d1366e5SPatrick Delaunay } 135*6d1366e5SPatrick Delaunay 136*6d1366e5SPatrick Delaunay *len = strlen(desc) * 2U + 2U; 137*6d1366e5SPatrick Delaunay unicode[idx++] = *len; 138*6d1366e5SPatrick Delaunay unicode[idx++] = USB_DESC_TYPE_STRING; 139*6d1366e5SPatrick Delaunay 140*6d1366e5SPatrick Delaunay while (*desc != '\0') { 141*6d1366e5SPatrick Delaunay unicode[idx++] = *desc++; 142*6d1366e5SPatrick Delaunay unicode[idx++] = 0x00U; 143*6d1366e5SPatrick Delaunay } 144*6d1366e5SPatrick Delaunay } 145*6d1366e5SPatrick Delaunay 146*6d1366e5SPatrick Delaunay /* 147*6d1366e5SPatrick Delaunay * Create the serial number string descriptor 148*6d1366e5SPatrick Delaunay */ 149*6d1366e5SPatrick Delaunay static void update_serial_num_string(void) 150*6d1366e5SPatrick Delaunay { 151*6d1366e5SPatrick Delaunay char serial_string[SIZ_STRING_SERIAL + 2U]; 152*6d1366e5SPatrick Delaunay /* serial number is set to 0 */ 153*6d1366e5SPatrick Delaunay uint32_t deviceserial[UID_WORD_NB] = { 0U, 0U, 0U }; 154*6d1366e5SPatrick Delaunay uint16_t length; 155*6d1366e5SPatrick Delaunay 156*6d1366e5SPatrick Delaunay if (stm32_get_uid_otp(deviceserial) != 0) { 157*6d1366e5SPatrick Delaunay return; 158*6d1366e5SPatrick Delaunay } 159*6d1366e5SPatrick Delaunay 160*6d1366e5SPatrick Delaunay /* build serial number with OTP value as in ROM code */ 161*6d1366e5SPatrick Delaunay snprintf(serial_string, sizeof(serial_string), "%08X%08X%08X", 162*6d1366e5SPatrick Delaunay deviceserial[0], deviceserial[1], deviceserial[2]); 163*6d1366e5SPatrick Delaunay 164*6d1366e5SPatrick Delaunay length = USB_SIZ_STRING_SERIAL; 165*6d1366e5SPatrick Delaunay stm32mp2_get_string(serial_string, usb_stm32mp2_serial, &length); 166*6d1366e5SPatrick Delaunay } 167*6d1366e5SPatrick Delaunay 168*6d1366e5SPatrick Delaunay /* 169*6d1366e5SPatrick Delaunay * Return Device Qualifier descriptor 170*6d1366e5SPatrick Delaunay * length : pointer data length 171*6d1366e5SPatrick Delaunay * return : pointer to descriptor buffer 172*6d1366e5SPatrick Delaunay */ 173*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_get_qualifier_desc(uint16_t *length) 174*6d1366e5SPatrick Delaunay { 175*6d1366e5SPatrick Delaunay *length = sizeof(usbd_stm32mp2_qualifier_desc); 176*6d1366e5SPatrick Delaunay 177*6d1366e5SPatrick Delaunay return (uint8_t *)usbd_stm32mp2_qualifier_desc; 178*6d1366e5SPatrick Delaunay } 179*6d1366e5SPatrick Delaunay 180*6d1366e5SPatrick Delaunay /* 181*6d1366e5SPatrick Delaunay * Return configuration descriptor 182*6d1366e5SPatrick Delaunay * length : pointer data length 183*6d1366e5SPatrick Delaunay * return : pointer to descriptor buffer 184*6d1366e5SPatrick Delaunay */ 185*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_get_config_desc(uint16_t *length) 186*6d1366e5SPatrick Delaunay { 187*6d1366e5SPatrick Delaunay *length = sizeof(usb_stm32mp2_config_desc); 188*6d1366e5SPatrick Delaunay 189*6d1366e5SPatrick Delaunay return (uint8_t *)usb_stm32mp2_config_desc; 190*6d1366e5SPatrick Delaunay } 191*6d1366e5SPatrick Delaunay 192*6d1366e5SPatrick Delaunay /* 193*6d1366e5SPatrick Delaunay * Returns the device descriptor. 194*6d1366e5SPatrick Delaunay * length: Pointer to data length variable 195*6d1366e5SPatrick Delaunay * return : Pointer to descriptor buffer 196*6d1366e5SPatrick Delaunay */ 197*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_device_desc(uint16_t *length) 198*6d1366e5SPatrick Delaunay { 199*6d1366e5SPatrick Delaunay *length = sizeof(usb_stm32mp2_desc); 200*6d1366e5SPatrick Delaunay 201*6d1366e5SPatrick Delaunay return (uint8_t *)usb_stm32mp2_desc; 202*6d1366e5SPatrick Delaunay } 203*6d1366e5SPatrick Delaunay 204*6d1366e5SPatrick Delaunay /* 205*6d1366e5SPatrick Delaunay * Returns the LangID string descriptor. 206*6d1366e5SPatrick Delaunay * length: Pointer to data length variable 207*6d1366e5SPatrick Delaunay * return : Pointer to descriptor buffer 208*6d1366e5SPatrick Delaunay */ 209*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_lang_id_desc(uint16_t *length) 210*6d1366e5SPatrick Delaunay { 211*6d1366e5SPatrick Delaunay *length = sizeof(usb_stm32mp2_lang_id_desc); 212*6d1366e5SPatrick Delaunay 213*6d1366e5SPatrick Delaunay return (uint8_t *)usb_stm32mp2_lang_id_desc; 214*6d1366e5SPatrick Delaunay } 215*6d1366e5SPatrick Delaunay 216*6d1366e5SPatrick Delaunay /* 217*6d1366e5SPatrick Delaunay * Returns the product string descriptor. 218*6d1366e5SPatrick Delaunay * length: Pointer to data length variable 219*6d1366e5SPatrick Delaunay * return : Pointer to descriptor buffer 220*6d1366e5SPatrick Delaunay */ 221*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_product_desc(uint16_t *length) 222*6d1366e5SPatrick Delaunay { 223*6d1366e5SPatrick Delaunay char name[STM32_SOC_NAME_SIZE]; 224*6d1366e5SPatrick Delaunay char product[128]; 225*6d1366e5SPatrick Delaunay uint32_t chip_id; 226*6d1366e5SPatrick Delaunay uint32_t chip_version; 227*6d1366e5SPatrick Delaunay 228*6d1366e5SPatrick Delaunay stm32mp_get_soc_name(name); 229*6d1366e5SPatrick Delaunay chip_id = stm32mp_get_chip_dev_id(); 230*6d1366e5SPatrick Delaunay chip_version = stm32mp_get_chip_version(); 231*6d1366e5SPatrick Delaunay 232*6d1366e5SPatrick Delaunay snprintf(product, sizeof(product), 233*6d1366e5SPatrick Delaunay "DFU @Device ID /0x%03X, @Revision ID /0x%04X, @Name /%s,", 234*6d1366e5SPatrick Delaunay chip_id, chip_version, name); 235*6d1366e5SPatrick Delaunay 236*6d1366e5SPatrick Delaunay stm32mp2_get_string(product, usb_str_dec, length); 237*6d1366e5SPatrick Delaunay 238*6d1366e5SPatrick Delaunay return usb_str_dec; 239*6d1366e5SPatrick Delaunay } 240*6d1366e5SPatrick Delaunay 241*6d1366e5SPatrick Delaunay /* 242*6d1366e5SPatrick Delaunay * Returns the manufacturer string descriptor. 243*6d1366e5SPatrick Delaunay * length: Pointer to data length variable 244*6d1366e5SPatrick Delaunay * return : Pointer to descriptor buffer 245*6d1366e5SPatrick Delaunay */ 246*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_manufacturer_desc(uint16_t *length) 247*6d1366e5SPatrick Delaunay { 248*6d1366e5SPatrick Delaunay stm32mp2_get_string(USBD_MANUFACTURER_STRING, usb_str_dec, length); 249*6d1366e5SPatrick Delaunay 250*6d1366e5SPatrick Delaunay return usb_str_dec; 251*6d1366e5SPatrick Delaunay } 252*6d1366e5SPatrick Delaunay 253*6d1366e5SPatrick Delaunay /* 254*6d1366e5SPatrick Delaunay * Returns the serial number string descriptor. 255*6d1366e5SPatrick Delaunay * length: Pointer to data length variable 256*6d1366e5SPatrick Delaunay * return : Pointer to descriptor buffer 257*6d1366e5SPatrick Delaunay */ 258*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_serial_desc(uint16_t *length) 259*6d1366e5SPatrick Delaunay { 260*6d1366e5SPatrick Delaunay *length = USB_SIZ_STRING_SERIAL; 261*6d1366e5SPatrick Delaunay 262*6d1366e5SPatrick Delaunay return (uint8_t *)usb_stm32mp2_serial; 263*6d1366e5SPatrick Delaunay } 264*6d1366e5SPatrick Delaunay 265*6d1366e5SPatrick Delaunay /* 266*6d1366e5SPatrick Delaunay * Returns the configuration string descriptor. 267*6d1366e5SPatrick Delaunay * length: Pointer to data length variable 268*6d1366e5SPatrick Delaunay * return : Pointer to descriptor buffer 269*6d1366e5SPatrick Delaunay */ 270*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_config_desc(uint16_t *length) 271*6d1366e5SPatrick Delaunay { 272*6d1366e5SPatrick Delaunay stm32mp2_get_string(USBD_CONFIGURATION_STRING, usb_str_dec, length); 273*6d1366e5SPatrick Delaunay 274*6d1366e5SPatrick Delaunay return usb_str_dec; 275*6d1366e5SPatrick Delaunay } 276*6d1366e5SPatrick Delaunay 277*6d1366e5SPatrick Delaunay /* 278*6d1366e5SPatrick Delaunay * Returns the interface string descriptor. 279*6d1366e5SPatrick Delaunay * length : Pointer to data length variable 280*6d1366e5SPatrick Delaunay * return : Pointer to descriptor buffer 281*6d1366e5SPatrick Delaunay */ 282*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_interface_desc(uint16_t *length) 283*6d1366e5SPatrick Delaunay { 284*6d1366e5SPatrick Delaunay stm32mp2_get_string(USBD_INTERFACE_STRING, usb_str_dec, length); 285*6d1366e5SPatrick Delaunay 286*6d1366e5SPatrick Delaunay return usb_str_dec; 287*6d1366e5SPatrick Delaunay } 288*6d1366e5SPatrick Delaunay 289*6d1366e5SPatrick Delaunay /* 290*6d1366e5SPatrick Delaunay * Manages the transfer of memory interfaces string descriptors. 291*6d1366e5SPatrick Delaunay * index: descriptor index 292*6d1366e5SPatrick Delaunay * length : pointer data length 293*6d1366e5SPatrick Delaunay * return : pointer to the descriptor table or NULL if the descriptor 294*6d1366e5SPatrick Delaunay * is not supported. 295*6d1366e5SPatrick Delaunay */ 296*6d1366e5SPatrick Delaunay static uint8_t *stm32mp2_get_usr_desc(uint8_t index, uint16_t *length) 297*6d1366e5SPatrick Delaunay { 298*6d1366e5SPatrick Delaunay if (index >= ARRAY_SIZE(if_desc_string)) { 2992e905c06SYann Gautier return NULL; 3002e905c06SYann Gautier } 3012e905c06SYann Gautier 302*6d1366e5SPatrick Delaunay stm32mp2_get_string(if_desc_string[index], usb_str_dec, length); 303*6d1366e5SPatrick Delaunay 304*6d1366e5SPatrick Delaunay return usb_str_dec; 305*6d1366e5SPatrick Delaunay } 306*6d1366e5SPatrick Delaunay 307*6d1366e5SPatrick Delaunay static const struct usb_desc dfu_desc = { 308*6d1366e5SPatrick Delaunay .get_device_desc = stm32mp2_device_desc, 309*6d1366e5SPatrick Delaunay .get_lang_id_desc = stm32mp2_lang_id_desc, 310*6d1366e5SPatrick Delaunay .get_manufacturer_desc = stm32mp2_manufacturer_desc, 311*6d1366e5SPatrick Delaunay .get_product_desc = stm32mp2_product_desc, 312*6d1366e5SPatrick Delaunay .get_configuration_desc = stm32mp2_config_desc, 313*6d1366e5SPatrick Delaunay .get_serial_desc = stm32mp2_serial_desc, 314*6d1366e5SPatrick Delaunay .get_interface_desc = stm32mp2_interface_desc, 315*6d1366e5SPatrick Delaunay .get_usr_desc = stm32mp2_get_usr_desc, 316*6d1366e5SPatrick Delaunay .get_config_desc = stm32mp2_get_config_desc, 317*6d1366e5SPatrick Delaunay .get_device_qualifier_desc = stm32mp2_get_qualifier_desc, 318*6d1366e5SPatrick Delaunay /* only HS is supported, as ROM code */ 319*6d1366e5SPatrick Delaunay .get_other_speed_config_desc = NULL, 320*6d1366e5SPatrick Delaunay }; 321*6d1366e5SPatrick Delaunay 322*6d1366e5SPatrick Delaunay static struct usb_handle usb_core_handle; 323*6d1366e5SPatrick Delaunay static struct pcd_handle pcd_handle; 324*6d1366e5SPatrick Delaunay static dwc3_handle_t dwc3_handle; 325*6d1366e5SPatrick Delaunay 326*6d1366e5SPatrick Delaunay struct usb_handle *usb_dfu_plat_init(void) 327*6d1366e5SPatrick Delaunay { 328*6d1366e5SPatrick Delaunay /* prepare USB Driver */ 329*6d1366e5SPatrick Delaunay pcd_handle.in_ep[0].maxpacket = USB_MAX_EP0_SIZE; 330*6d1366e5SPatrick Delaunay pcd_handle.out_ep[0].maxpacket = USB_MAX_EP0_SIZE; 331*6d1366e5SPatrick Delaunay usb_dwc3_init_driver(&usb_core_handle, &pcd_handle, &dwc3_handle, 332*6d1366e5SPatrick Delaunay (void *)USB_DWC3_BASE); 333*6d1366e5SPatrick Delaunay 334*6d1366e5SPatrick Delaunay /* keep the configuration from ROM code */ 335*6d1366e5SPatrick Delaunay usb_core_handle.ep0_state = USBD_EP0_DATA_IN; 336*6d1366e5SPatrick Delaunay usb_core_handle.dev_state = USBD_STATE_CONFIGURED; 337*6d1366e5SPatrick Delaunay 338*6d1366e5SPatrick Delaunay /* Update the serial number string descriptor from the unique ID */ 339*6d1366e5SPatrick Delaunay update_serial_num_string(); 340*6d1366e5SPatrick Delaunay 341*6d1366e5SPatrick Delaunay /* Prepare USB DFU stack */ 342*6d1366e5SPatrick Delaunay usb_dfu_register(&usb_core_handle, &usb_dfu_handle); 343*6d1366e5SPatrick Delaunay 344*6d1366e5SPatrick Delaunay /* Register DFU descriptor in USB stack */ 345*6d1366e5SPatrick Delaunay register_platform(&usb_core_handle, &dfu_desc); 346*6d1366e5SPatrick Delaunay 347*6d1366e5SPatrick Delaunay return &usb_core_handle; 348*6d1366e5SPatrick Delaunay } 349*6d1366e5SPatrick Delaunay 350*6d1366e5SPatrick Delaunay /* Link between USB alternate and STM32CubeProgramer phase */ 3512e905c06SYann Gautier uint8_t usb_dfu_get_phase(uint8_t alt) 3522e905c06SYann Gautier { 353*6d1366e5SPatrick Delaunay uint8_t ret; 354*6d1366e5SPatrick Delaunay 355*6d1366e5SPatrick Delaunay switch (alt) { 356*6d1366e5SPatrick Delaunay case 0: 357*6d1366e5SPatrick Delaunay ret = PHASE_DDR_FW; 358*6d1366e5SPatrick Delaunay break; 359*6d1366e5SPatrick Delaunay case 1: 360*6d1366e5SPatrick Delaunay ret = PHASE_SSBL; 361*6d1366e5SPatrick Delaunay break; 362*6d1366e5SPatrick Delaunay case 2: 363*6d1366e5SPatrick Delaunay ret = PHASE_CMD; 364*6d1366e5SPatrick Delaunay break; 365*6d1366e5SPatrick Delaunay default: 366*6d1366e5SPatrick Delaunay ret = PHASE_RESET; 367*6d1366e5SPatrick Delaunay break; 368*6d1366e5SPatrick Delaunay } 369*6d1366e5SPatrick Delaunay 370*6d1366e5SPatrick Delaunay return ret; 3712e905c06SYann Gautier } 372