blob: 3e7d458671824af0279e9cc86ad3ab112c423a17 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2 *
3 * (C)Copyright 2013 Marvell. All Rights Reserved.
4 *
5 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
6 * The copyright notice above does not evidence any actual or intended
7 * publication of such source code.
8 * This Module contains Proprietary Information of Marvell and should be
9 * treated as Confidential.
10 * The information in this file is provided for the exclusive use of the
11 * licensees of Marvell.
12 * Such users have the right to use, modify, and incorporate this code into
13 * products for purposes authorized by the license agreement provided they
14 * include this notice and the associated copyright notice with any such
15 * product.
16 * The information in this file is provided "AS IS" without warranty.
17 *
18 ******************************************************************************/
19
20
21#include "Typedef.h"
22#include "misc.h"
23#include "usb_descriptors.h"
24#include "usbdefs.h"
25#include "usb2_main.h"
26#include "usb2_enumeration.h"
27#include "usbapi.h"
28#include "snps_usb.h"
29#if BOOTROM
30#include "Bootrom.h"
31#endif
32
33//these are allocated in UsbDescriptors.c
34extern OPT_USB_DESCRIPTOR_LOADS USBDescriptors[NUM_USB_DESCRIPTORS];
35extern CHAR USB2DevQualDesc[];
36extern CHAR USB1ConfigDesc[];
37extern UINT_T USBStringIndexTable[MAX_USB_STRINGS];
38extern void USB2D_VendorRequest(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket);
39extern int DWC3_GET_CONN_SPEED(void);
40
41UINT usbstatus_value = 0x00000001;
42void USB2D_EnumerationHandler(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
43{
44 switch ((pSetupPacket->bmRequestType & 0x60) >> 5)
45 {
46 case STANDARD_REQ:
47 switch (pSetupPacket->bRequest)
48 {
49 case REQ_GET_STATUS:
50 USB2D_GetStatus(pDCProps, pSetupPacket);
51 break;
52// case REQ_CLEAR_FEATURE:
53// mvUsbCh9ClearFeature(handle, setup, &ci_otg_setupPacket);
54// break;
55// case REQ_SET_FEATURE:
56// mvUsbCh9SetFeature(handle, setup, &ci_otg_setupPacket);
57// break;
58 case REQ_SET_ADDRESS:
59 USB2D_SetAddress(pDCProps, pSetupPacket);
60 break;
61 case REQ_GET_DESCRIPTOR:
62 USB2D_GetDescriptor(pDCProps, pSetupPacket);
63 break;
64// case REQ_SET_DESCRIPTOR:
65// mvUsbCh9SetDescriptior(handle, setup, &ci_otg_setupPacket);
66// break;
67// case REQ_GET_CONFIGURATION:
68// mvUsbCh9GetConfig(handle, setup, &ci_otg_setupPacket);
69// break;
70 case REQ_SET_CONFIGURATION:
71 USB2D_SetConfig(pDCProps, pSetupPacket);
72 break;
73// case REQ_GET_INTERFACE:
74// mvUsbCh9GetInterface(handle, setup, &ci_otg_setupPacket);
75// break;
76// case REQ_SET_INTERFACE:
77// mvUsbCh9SetInterface(handle, setup, &ci_otg_setupPacket);
78// break;
79 default:
80 //unhandled descriptor. send a STALL PID
81 //TODO
82 DWC3_EP0_STALL_AND_RESTART(pDCProps);
83 break;
84 } // Endswitch
85 break;
86 case VENDOR_REQ:
87 USB2D_VendorRequest(pDCProps, pSetupPacket);
88 break;
89 default:
90 //unhandled descriptor. send a STALL PID
91 //TODO
92 DWC3_EP0_STALL_AND_RESTART(pDCProps);
93 break;
94 } //Endswitch
95}
96
97void USB2D_GetDescriptor(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
98{
99 UINT pktSize, stringLength, stringIndex;
100 UCHAR *payload = "UNHANDLED";
101
102 // Load the appropriate string depending on the descriptor requested
103 switch (pSetupPacket->wValue >> 8)
104 {
105 case DESC_TYPE_DEVICE:
106 pktSize = USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].DesSize;
107 payload = (UCHAR*)(USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].pDesPayload);
108 break;
109 case DESC_TYPE_CONFIG:
110 pktSize = USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize;
111 payload = (UCHAR*)(USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload);
112 break;
113 case DESC_TYPE_STRING:
114 stringIndex = ((pSetupPacket->wValue) & 0xFF);
115 // Bounds protection
116 if (stringIndex >= MAX_USB_STRINGS)
117 {
118 stringLength = (pSetupPacket->wLength);
119 if (stringLength > USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize)
120 pktSize = USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize;
121 else
122 pktSize = stringLength;
123 payload =(UCHAR*)(USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].pDesPayload);
124 break;
125 }
126 switch (USBStringIndexTable[stringIndex])
127 {
128 case USB_LANGUAGE_STRING_DESCRIPTOR:
129 case USB_MANUFACTURER_STRING_DESCRIPTOR:
130 case USB_PRODUCT_STRING_DESCRIPTOR:
131 case USB_SERIAL_STRING_DESCRIPTOR:
132 case USB_INTERFACE_STRING_DESCRIPTOR:
133 case USB_DEFAULT_STRING_DESCRIPTOR:
134 stringLength = (pSetupPacket->wLength);
135 if (stringLength > USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize)
136 pktSize = USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize;
137 else
138 pktSize = stringLength;
139 payload = (UCHAR*)(USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].pDesPayload);
140 break;
141 default:
142 //unhandled descriptor. set length to 0
143 pktSize = 0;
144 break;
145 }
146 break; // from DESC_TYPE_STRING
147 case DESC_TYPE_INTERFACE:
148 pktSize = USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].DesSize;
149 payload = (UCHAR*)(USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].pDesPayload);
150 break;
151 case DESC_TYPE_ENDPOINT:
152 pktSize = USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].DesSize;
153 payload = (UCHAR*)(USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].pDesPayload);
154 break;
155 case DESC_TYPE_QUALIFIER:
156 //getting this request means the host wants us to run at FULL speed...
157 pktSize = USB2DevQualDesc[0]; //bLength field
158 payload = (UCHAR*) USB2DevQualDesc;
159 //overwrite the CONFIG descriptor to point to the FULL speed version
160 USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize = (USB1ConfigDesc[2]) + (USB1ConfigDesc[3] << 8); //LSB + MSB
161 USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload = (UINT8_T *)USB1ConfigDesc;
162 break;
163 default:
164 //unhandled descriptor. set length to 0
165 pktSize = 0;
166 break;
167 } // Endswitch
168
169 //zero length means a valid descriptor was not found.
170 if(pktSize == 0)
171 { //unhandled descriptor. send a STALL PID
172 DWC3_EP0_STALL_AND_RESTART(pDCProps);
173 return;
174 }
175
176 pDCProps->ctrl_direction = USB_OUT;
177 //3 stages
178 pDCProps->ctrl_stages = 3;
179
180 //add EP0 TX dTD
181 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
182 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0,
183 USB_IN, (UINT)(payload), pktSize, DWC3_TRBCTL_CONTROL_DATA);
184
185#ifndef DWC3_ENABLE_XFERNOTREADY
186 //add EP0 RX dTD: size = 0, this is for the status OUT token
187 //USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_OUT,
188 // pDCProps->BufferSpace2, 0, DWC3_TRBCTL_CONTROL_STATUS3);
189#endif
190 return;
191}
192void USB2D_SetAddress(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
193{
194 UINT reg;
195
196 reg = DWC3_REG_READ(DWC3_DCFG);
197 reg &= ~(DWC3_DCFG_DEVADDR_MASK);
198 reg |= DWC3_DCFG_DEVADDR(pSetupPacket->wValue);
199 DWC3_REG_WRITE(DWC3_DCFG, reg);
200
201#ifndef DWC3_ENABLE_XFERNOTREADY
202 //send a zero length pckt to finish the Set Address
203 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN,
204 pDCProps->BufferSpace2, 0, DWC3_TRBCTL_CONTROL_STATUS2);
205#endif
206 pDCProps->ctrl_direction = USB_IN;
207 pDCProps->ctrl_stages = 2;
208
209 if (pSetupPacket->wValue)
210 pDCProps->dev_state = USB_STATE_ADDRESS;
211 else
212 pDCProps->dev_state = USB_STATE_DEFAULT;
213}
214
215void USB2D_GetStatus(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
216{
217 usbstatus_value = 0x00000001;
218 //Reply with a "Self Powered" status
219 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN,
220 (UINT)(&usbstatus_value), 2, DWC3_TRBCTL_CONTROL_DATA);
221
222 //add EP0 RX dTD: size = 0, this is for the status OUT token
223 //handled in DATA COMPLETE PHASE
224 //USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_OUT,
225 // pDCProps->BufferSpace2, 0, DWC3_TRBCTL_CONTROL_STATUS3);
226 pDCProps->ctrl_direction = USB_OUT;
227 pDCProps->ctrl_stages = 3;
228}
229
230void USB2D_SetConfig(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
231{
232 P_USBAPI_T p_usb;
233
234#ifndef DWC3_ENABLE_XFERNOTREADY
235 //send a zero length pckt to finish the Set Config
236 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN,
237 pDCProps->BufferSpace2, 0, DWC3_TRBCTL_CONTROL_STATUS2);
238#endif
239 pDCProps->ctrl_direction = USB_IN;
240 pDCProps->ctrl_stages = 2;
241
242#if BOOTROM
243 //bootrom: check DOWNLOAD DISABLE fuse before allowing EP1 and 2 to be setup
244 if(GetTBREnvStruct()->Fuses.bits.Download_Disable)
245 return;
246#endif
247
248 //set the packet size based on speed: HI 512, FULL 64
249 p_usb = GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum);
250 if(p_usb != NULL)
251 {
252#if 0
253 p_usb->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
254#endif
255 //TODO: set it as 512 even for full speed as the buffer in PM manager is 1024
256 if (USB_MODE_FS == DWC3_GET_CONN_SPEED())
257 p_usb->maxpacketsize = 64;
258 else
259 p_usb->maxpacketsize = 512;
260
261 //set the packet size based on speed: HI 512, FULL 64
262 //GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum)->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
263
264 //enable EP's based on the Config Table
265 USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_A, USB_OUT, USB_BULK);
266 USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_A, USB_IN, USB_BULK);
267 pDCProps->dev_state = USB_STATE_CONFIGURED;
268 //prime EP2 for Preamble
269 USB2D_EndpointTransmit( pDCProps,
270 USB_ENDPOINT_A,
271 USB_OUT,
272 (UINT)(pDCProps->BufferSpace),
273 p_usb->maxpacketsize);
274 }
275}
276
277
278//Vendor Request Setup Packet
279void USB2D_VendorRequest(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
280{
281 UCHAR * NoVendorString = "NoVendorString";
282 UINT pktSize, retval;
283 void * pPayload;
284
285 retval = FindVendorRequestInTIM (pSetupPacket->bRequest, pSetupPacket->bmRequestType, (UINT *)&pPayload, &pktSize);
286
287 if(retval != NoError)
288 {
289 pktSize = 15;//sizeof(ci2NoVendorString);
290 pPayload = NoVendorString;
291 }
292
293 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
294
295 //add EP0 TX dTD
296 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
297 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN,
298 (UINT)(pPayload), pktSize, DWC3_TRBCTL_CONTROL_DATA);
299
300 pDCProps->ctrl_direction = USB_OUT;
301 pDCProps->ctrl_stages = 3;
302 return;
303}
304
305
306