]> git.sur5r.net Git - freertos/blob
1a67a0ffd0ca77a7352f5617425bfd7dcbe6bdcd
[freertos] /
1 /******************************************************************************
2 *
3 * Copyright (C) 2015 Xilinx, Inc.  All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 *
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
30 *
31 ******************************************************************************/
32 /****************************************************************************/
33 /**
34 *
35 * @file xusbpsu.c
36 *
37 * <pre>
38 *
39 * MODIFICATION HISTORY:
40 *
41 * Ver   Who    Date     Changes
42 * ----- -----  -------- -----------------------------------------------------
43 * 1.00a bss    01/22/15 First release
44 * 1.00a bss    03/18/15 Added XUsbPsu_Wait_Clear_Timeout and
45 *                                               XUsbPsu_Wait_Set_Timeout functions
46 *
47 * </pre>
48 *
49 *****************************************************************************/
50
51 /***************************** Include Files ********************************/
52
53 #include "xusbpsu.h"
54
55 /************************** Constant Definitions *****************************/
56
57
58 /**************************** Type Definitions *******************************/
59
60
61 /***************** Macros (Inline Functions) Definitions *********************/
62
63
64 /************************** Function Prototypes ******************************/
65
66
67 /************************** Variable Definitions *****************************/
68
69 /*****************************************************************************/
70 /**
71 * Waits until a bit in a register is cleared or timeout occurs
72 *
73 * @param        InstancePtr is a pointer to the XUsbPsu instance to be worked on.
74 * @param        Offset is register offset.
75 * @param        BitMask is bit mask of required bit to be checked.
76 * @param        Timeout is the time to wait specified in micro seconds.
77 *
78 * @return
79 *                       - XST_SUCCESS when bit is cleared.
80 *                       - XST_FAILURE when timed out.
81 *
82 ******************************************************************************/
83 int XUsbPsu_Wait_Clear_Timeout(struct XUsbPsu *InstancePtr, u32 Offset,
84                                                                 u32 BitMask, u32 Timeout)
85 {
86         u32 RegVal;
87
88         do {
89                 RegVal = XUsbPsu_ReadReg(InstancePtr, Offset);
90                 if (!(RegVal & BitMask))
91                         break;
92                 Timeout--;
93                 if (!Timeout)
94                         return XST_FAILURE;
95                 usleep(1);
96         } while (1);
97
98         return XST_SUCCESS;
99 }
100
101 /*****************************************************************************/
102 /**
103 * Waits until a bit in a register is set or timeout occurs
104 *
105 * @param        InstancePtr is a pointer to the XUsbPsu instance to be worked on.
106 * @param        Offset is register offset.
107 * @param        BitMask is bit mask of required bit to be checked.
108 * @param        Timeout is the time to wait specified in micro seconds.
109 *
110 * @return
111 *                       - XST_SUCCESS when bit is set.
112 *                       - XST_FAILURE when timed out.
113 *
114 ******************************************************************************/
115 int XUsbPsu_Wait_Set_Timeout(struct XUsbPsu *InstancePtr, u32 Offset,
116                                                                 u32 BitMask, u32 Timeout)
117 {
118         u32 RegVal;
119
120         do {
121                 RegVal = XUsbPsu_ReadReg(InstancePtr, Offset);
122                 if (RegVal & BitMask)
123                         break;
124                 Timeout--;
125                 if (!Timeout)
126                         return XST_FAILURE;
127                 usleep(1);
128         } while (1);
129
130         return XST_SUCCESS;
131 }
132
133 /*****************************************************************************/
134 /**
135 * Sets mode of Core to USB Device/Host/OTG.
136 *
137 *
138 * @param        InstancePtr is a pointer to the XUsbPsu instance to be worked on.
139 * @param        Mode is mode to set
140 *                       - XUSBPSU_GCTL_PRTCAP_OTG
141 *                       - XUSBPSU_GCTL_PRTCAP_HOST
142 *                       - XUSBPSU_GCTL_PRTCAP_DEVICE
143 *
144 * @return       None
145 *
146 ******************************************************************************/
147 void XUsbPsu_SetMode(struct XUsbPsu *InstancePtr, u32 Mode)
148 {
149         u32 RegVal;
150
151         Xil_AssertVoid(InstancePtr != NULL);
152         Xil_AssertVoid(Mode <= XUSBPSU_GCTL_PRTCAP_OTG &&
153                                         Mode >= XUSBPSU_GCTL_PRTCAP_HOST);
154
155         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL);
156         RegVal &= ~(XUSBPSU_GCTL_PRTCAPDIR(XUSBPSU_GCTL_PRTCAP_OTG));
157         RegVal |= XUSBPSU_GCTL_PRTCAPDIR(Mode);
158         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal);
159 }
160
161 /*****************************************************************************/
162 /**
163 * Issues core PHY reset.
164 *
165 * @param        InstancePtr is a pointer to the XUsbPsu instance to be worked on.
166 *
167 * @return       None
168 *
169 ******************************************************************************/
170 void XUsbPsu_PhyReset(struct XUsbPsu *InstancePtr)
171 {
172         u32             RegVal;
173
174         Xil_AssertVoid(InstancePtr != NULL);
175
176         /* Before Resetting PHY, put Core in Reset */
177         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL);
178         RegVal |= XUSBPSU_GCTL_CORESOFTRESET;
179         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal);
180
181         /* Assert USB3 PHY reset */
182         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0));
183         RegVal |= XUSBPSU_GUSB3PIPECTL_PHYSOFTRST;
184         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0), RegVal);
185
186         /* Assert USB2 PHY reset */
187         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0));
188         RegVal |= XUSBPSU_GUSB2PHYCFG_PHYSOFTRST;
189         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0), RegVal);
190
191         usleep(XUSBPSU_PHY_TIMEOUT);
192
193         /* Clear USB3 PHY reset */
194         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0));
195         RegVal &= ~XUSBPSU_GUSB3PIPECTL_PHYSOFTRST;
196         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0), RegVal);
197
198         /* Clear USB2 PHY reset */
199         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0));
200         RegVal &= ~XUSBPSU_GUSB2PHYCFG_PHYSOFTRST;
201         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0), RegVal);
202
203         usleep(XUSBPSU_PHY_TIMEOUT);
204
205         /* After PHYs are stable we can take Core out of reset State */
206         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL);
207         RegVal &= ~XUSBPSU_GCTL_CORESOFTRESET;
208         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal);
209 }
210
211 /*****************************************************************************/
212 /**
213 * Sets up Event buffers so that events are written by Core.
214 *
215 * @param        InstancePtr is a pointer to the XUsbPsu instance to be worked on.
216 *
217 * @return       None
218 *
219 ******************************************************************************/
220 void XUsbPsu_EventBuffersSetup(struct XUsbPsu *InstancePtr)
221 {
222     struct XUsbPsu_EvtBuffer *Evt;
223
224         Xil_AssertVoid(InstancePtr != NULL);
225
226         Evt = &InstancePtr->Evt;
227         Evt->BuffAddr = (void *)InstancePtr->EventBuffer;
228
229         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRLO(0),
230                                                 (UINTPTR)InstancePtr->EventBuffer);
231         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRHI(0),
232                                                 ((UINTPTR)(InstancePtr->EventBuffer) >> 16) >> 16);
233         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTSIZ(0),
234                                         XUSBPSU_GEVNTSIZ_SIZE(sizeof(InstancePtr->EventBuffer)));
235         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0), 0);
236 }
237
238 /*****************************************************************************/
239 /**
240 * Resets Event buffer Registers to zero so that events are not written by Core.
241 *
242 * @param        InstancePtr is a pointer to the XUsbPsu instance to be worked on.
243 *
244 * @return       None
245 *
246 ******************************************************************************/
247 void XUsbPsu_EventBuffersReset(struct XUsbPsu *InstancePtr)
248 {
249
250         Xil_AssertVoid(InstancePtr != NULL);
251
252         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRLO(0), 0);
253         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRHI(0), 0);
254         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTSIZ(0),
255                         XUSBPSU_GEVNTSIZ_INTMASK | XUSBPSU_GEVNTSIZ_SIZE(0));
256         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0), 0);
257 }
258
259 /*****************************************************************************/
260 /**
261 * Reads data from Hardware Params Registers of Core.
262 *
263 * @param        InstancePtr is a pointer to the XUsbPsu instance to be worked on.
264 * @param        RegIndex is Register number to read
265 *                       - XUSBPSU_GHWPARAMS0
266 *                       - XUSBPSU_GHWPARAMS1
267 *                       - XUSBPSU_GHWPARAMS2
268 *                       - XUSBPSU_GHWPARAMS3
269 *                       - XUSBPSU_GHWPARAMS4
270 *                       - XUSBPSU_GHWPARAMS5
271 *                       - XUSBPSU_GHWPARAMS6
272 *                       - XUSBPSU_GHWPARAMS7
273 *
274 * @return       One of the GHWPARAMS RegValister contents.
275 *
276 ******************************************************************************/
277 u32 XUsbPsu_ReadHwParams(struct XUsbPsu *InstancePtr, u8 RegIndex)
278 {
279         u32 RegVal;
280
281         Xil_AssertNonvoid(InstancePtr != NULL);
282         Xil_AssertNonvoid(RegIndex >= XUSBPSU_GHWPARAMS0 &&
283                                 RegIndex <= XUSBPSU_GHWPARAMS7);
284
285         RegVal = XUsbPsu_ReadReg(InstancePtr, (XUSBPSU_GHWPARAMS0_OFFSET +
286                                                         (RegIndex * 4)));
287         return RegVal;
288 }
289
290 /*****************************************************************************/
291 /**
292 * Initializes Core.
293 *
294 * @param  InstancePtr is a pointer to the XUsbPsu instance to be worked on.
295 *
296 * @return
297 *               - XST_SUCCESS if initialization was successful
298 *               - XST_FAILURE if initialization was not successful
299 *
300 ******************************************************************************/
301 int XUsbPsu_CoreInit(struct XUsbPsu *InstancePtr)
302 {
303         u32             RegVal;
304         u32             Hwparams1;
305
306         Xil_AssertNonvoid(InstancePtr != NULL);
307
308         /* issue device SoftReset too */
309         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, XUSBPSU_DCTL_CSFTRST);
310
311         if (XUsbPsu_Wait_Clear_Timeout(InstancePtr, XUSBPSU_DCTL,
312                         XUSBPSU_DCTL_CSFTRST, 500) == XST_FAILURE) {
313                 /* timed out return failure */
314                 return XST_FAILURE;
315         }
316
317         XUsbPsu_PhyReset(InstancePtr);
318
319         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL);
320     RegVal &= ~XUSBPSU_GCTL_SCALEDOWN_MASK;
321     RegVal &= ~XUSBPSU_GCTL_DISSCRAMBLE;
322
323         Hwparams1 = XUsbPsu_ReadHwParams(InstancePtr, 1);
324
325         switch (XUSBPSU_GHWPARAMS1_EN_PWROPT(Hwparams1)) {
326     case XUSBPSU_GHWPARAMS1_EN_PWROPT_CLK:
327         RegVal &= ~XUSBPSU_GCTL_DSBLCLKGTNG;
328         break;
329     case XUSBPSU_GHWPARAMS1_EN_PWROPT_HIB:
330         /* enable hibernation here */
331         break;
332     default:
333         break;
334         }
335
336         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal);
337
338         return XST_SUCCESS;
339 }
340
341 /*****************************************************************************/
342 /**
343 * Enables an interrupt in Event Enable RegValister.
344 *
345 * @param  InstancePtr is a pointer to the XUsbPsu instance to be worked on
346 * @param  Mask is the OR of any Interrupt Enable Masks:
347 *               - XUSBPSU_DEVTEN_VNDRDEVTSTRCVEDEN
348 *               - XUSBPSU_DEVTEN_EVNTOVERFLOWEN
349 *               - XUSBPSU_DEVTEN_CMDCMPLTEN
350 *               - XUSBPSU_DEVTEN_ERRTICERREN
351 *               - XUSBPSU_DEVTEN_SOFEN
352 *               - XUSBPSU_DEVTEN_EOPFEN
353 *               - XUSBPSU_DEVTEN_HIBERNATIONREQEVTEN
354 *               - XUSBPSU_DEVTEN_WKUPEVTEN
355 *               - XUSBPSU_DEVTEN_ULSTCNGEN
356 *               - XUSBPSU_DEVTEN_CONNECTDONEEN
357 *               - XUSBPSU_DEVTEN_USBRSTEN
358 *               - XUSBPSU_DEVTEN_DISCONNEVTEN
359 *
360 * @return  None
361 *
362 ******************************************************************************/
363 void XUsbPsu_EnableIntr(struct XUsbPsu *InstancePtr, u32 Mask)
364 {
365     u32 RegVal;
366
367         Xil_AssertVoid(InstancePtr != NULL);
368
369     RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DEVTEN);
370     RegVal |= Mask;
371
372         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEVTEN, RegVal);
373 }
374
375 /*****************************************************************************/
376 /**
377 * Disables an interrupt in Event Enable RegValister.
378 *
379 * @param  InstancePtr is a pointer to the XUsbPsu instance to be worked on.
380 * @param  Mask is the OR of Interrupt Enable Masks
381 *               - XUSBPSU_DEVTEN_VNDRDEVTSTRCVEDEN
382 *               - XUSBPSU_DEVTEN_EVNTOVERFLOWEN
383 *               - XUSBPSU_DEVTEN_CMDCMPLTEN
384 *               - XUSBPSU_DEVTEN_ERRTICERREN
385 *               - XUSBPSU_DEVTEN_SOFEN
386 *               - XUSBPSU_DEVTEN_EOPFEN
387 *               - XUSBPSU_DEVTEN_HIBERNATIONREQEVTEN
388 *               - XUSBPSU_DEVTEN_WKUPEVTEN
389 *               - XUSBPSU_DEVTEN_ULSTCNGEN
390 *               - XUSBPSU_DEVTEN_CONNECTDONEEN
391 *               - XUSBPSU_DEVTEN_USBRSTEN
392 *               - XUSBPSU_DEVTEN_DISCONNEVTEN
393 *
394 * @return  None
395 *
396 ******************************************************************************/
397 void XUsbPsu_DisableIntr(struct XUsbPsu *InstancePtr, u32 Mask)
398 {
399         u32 RegVal;
400
401         Xil_AssertVoid(InstancePtr != NULL);
402
403         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DEVTEN);
404         RegVal &= ~Mask;
405         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEVTEN, RegVal);
406 }
407
408 /****************************************************************************/
409 /**
410 *
411 * This function does the following:
412 *       - initializes a specific XUsbPsu instance.
413 *       - sets up Event Buffer for Core to write events.
414 *       - Core Reset and PHY Reset.
415 *       - Sets core in Device Mode.
416 *       - Sets default speed as HIGH_SPEED.
417 *       - Sets Device Address to 0.
418 *       - Enables interrupts.
419 *
420 * @param        InstancePtr is a pointer to the XUsbPsu instance.
421 * @param        ConfigPtr points to the XUsbPsu device configuration structure.
422 * @param        BaseAddress is the device base address in the virtual memory
423 *                       address space. If the address translation is not used then the
424 *                       physical address is passed.
425 *                       Unexpected errors may occur if the address mapping is changed
426 *                       after this function is invoked.
427 *
428 * @return       XST_SUCCESS else XST_FAILURE
429 *
430 * @note         None.
431 *
432 *****************************************************************************/
433 int XUsbPsu_CfgInitialize(struct XUsbPsu *InstancePtr,
434                         XUsbPsu_Config *ConfigPtr, u32 BaseAddress)
435 {
436         int Ret;
437         u32 RegVal;
438         u32 IntrMask;
439
440         Xil_AssertNonvoid(InstancePtr != NULL);
441         Xil_AssertNonvoid(ConfigPtr   != NULL);
442
443         InstancePtr->ConfigPtr = ConfigPtr;
444
445         Ret = XUsbPsu_CoreInit(InstancePtr);
446         if (Ret) {
447                 return XST_FAILURE;
448         }
449
450         RegVal = XUsbPsu_ReadHwParams(InstancePtr, 3);
451         InstancePtr->NumInEps = XUSBPSU_NUM_IN_EPS(RegVal);
452         InstancePtr->NumOutEps = XUSBPSU_NUM_EPS(RegVal) - InstancePtr->NumInEps;
453
454         /* Map USB and Physical Endpoints */
455         XUsbPsu_InitializeEps(InstancePtr);
456
457         XUsbPsu_EventBuffersSetup(InstancePtr);
458
459         XUsbPsu_SetMode(InstancePtr, XUSBPSU_GCTL_PRTCAP_DEVICE);
460
461         XUsbPsu_SetSpeed(InstancePtr, XUSBPSU_DCFG_HIGHSPEED);
462
463         XUsbPsu_SetDeviceAddress(InstancePtr, 0);
464
465         return XST_SUCCESS;
466 }
467
468 /****************************************************************************/
469 /**
470 *
471 * Starts the controller so that Host can detect this device.
472 *
473 * @param        InstancePtr is a pointer to the XUsbPsu instance.
474 *
475 * @return       XST_SUCCESS else XST_FAILURE
476 *
477 * @note         None.
478 *
479 *****************************************************************************/
480 int XUsbPsu_Start(struct XUsbPsu *InstancePtr)
481 {
482         u32                     RegVal;
483
484         Xil_AssertNonvoid(InstancePtr != NULL);
485
486         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
487
488         RegVal |= XUSBPSU_DCTL_RUN_STOP;
489
490         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
491
492         if (XUsbPsu_Wait_Clear_Timeout(InstancePtr, XUSBPSU_DSTS,
493                         XUSBPSU_DSTS_DEVCTRLHLT, 500) == XST_FAILURE) {
494                 return XST_FAILURE;
495         }
496
497         return XST_SUCCESS;
498 }
499
500 /****************************************************************************/
501 /**
502 *
503 * Stops the controller so that Device disconnects from Host.
504 *
505 * @param        InstancePtr is a pointer to the XUsbPsu instance.
506 *
507 * @return       XST_SUCCESS else XST_FAILURE
508 *
509 * @note         None.
510 *
511 *****************************************************************************/
512 int XUsbPsu_Stop(struct XUsbPsu *InstancePtr)
513 {
514         u32                     RegVal;
515
516         Xil_AssertNonvoid(InstancePtr != NULL);
517
518         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
519         RegVal &= ~XUSBPSU_DCTL_RUN_STOP;
520
521         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
522
523         if (XUsbPsu_Wait_Set_Timeout(InstancePtr, XUSBPSU_DSTS,
524                         XUSBPSU_DSTS_DEVCTRLHLT, 500) == XST_FAILURE) {
525                 return XST_FAILURE;
526         }
527
528         return XST_SUCCESS;
529 }
530
531 /****************************************************************************/
532 /**
533  * Enables USB2 Test Modes
534  *
535  * @param       InstancePtr is a pointer to the XUsbPsu instance.
536  * @param       Mode is Test mode to set.
537  *
538  * @return      XST_SUCCESS else XST_FAILURE
539  *
540  * @note        None.
541  *
542  ****************************************************************************/
543 int XUsbPsu_SetTestMode(struct XUsbPsu *InstancePtr, int Mode)
544 {
545         u32             RegVal;
546
547         Xil_AssertNonvoid(InstancePtr != NULL);
548         Xil_AssertNonvoid(Mode >= TEST_J && Mode <= TEST_FORCE_ENABLE);
549
550         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
551         RegVal &= ~XUSBPSU_DCTL_TSTCTRL_MASK;
552
553         switch (Mode) {
554         case TEST_J:
555         case TEST_K:
556         case TEST_SE0_NAK:
557         case TEST_PACKET:
558         case TEST_FORCE_ENABLE:
559                 RegVal |= Mode << 1;
560                 break;
561         default:
562                 return XST_FAILURE;
563         }
564
565         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
566
567         return XST_SUCCESS;
568 }
569
570 /****************************************************************************/
571 /**
572  * Gets current State of USB Link
573  *
574  * @param       InstancePtr is a pointer to the XUsbPsu instance.
575  *
576  * @return      Link State
577  *
578  * @note        None.
579  *
580  ****************************************************************************/
581 u32 XUsbPsu_GetLinkState(struct XUsbPsu *InstancePtr)
582 {
583         u32             RegVal;
584
585         Xil_AssertNonvoid(InstancePtr != NULL);
586
587         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DSTS);
588
589         return XUSBPSU_DSTS_USBLNKST(RegVal);
590 }
591
592 /****************************************************************************/
593 /**
594  * Sets USB Link to a particular State
595  *
596  * @param       InstancePtr is a pointer to the XUsbPsu instance.
597  * @param       State is State of Link to set.
598  *
599  * @return      XST_SUCCESS else XST_FAILURE
600  *
601  * @note        None.
602  *
603  ****************************************************************************/
604 int XUsbPsu_SetLinkState(struct XUsbPsu *InstancePtr, u8 State)
605 {
606         u32             RegVal;
607
608         Xil_AssertNonvoid(InstancePtr != NULL);
609
610          /* Wait until device controller is ready. */
611         if (XUsbPsu_Wait_Clear_Timeout(InstancePtr, XUSBPSU_DSTS,
612                         XUSBPSU_DSTS_DCNRD, 500) == XST_FAILURE) {
613                 return XST_FAILURE;
614         }
615
616         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
617         RegVal &= ~XUSBPSU_DCTL_ULSTCHNGREQ_MASK;
618
619         RegVal |= XUSBPSU_DCTL_ULSTCHNGREQ(State);
620         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
621
622         return XST_SUCCESS;
623 }
624
625 /****************************************************************************/
626 /**
627 * Sets speed of the Core for connecting to Host
628 *
629 * @param        InstancePtr is a pointer to the XUsbPsu instance.
630 * @param        Speed is required speed
631 *                               - XUSBPSU_DCFG_HIGHSPEED
632 *                               - XUSBPSU_DCFG_FULLSPEED2
633 *                               - XUSBPSU_DCFG_LOWSPEED
634 *                               - XUSBPSU_DCFG_FULLSPEED1
635 *
636 * @return       None
637 *
638 * @note         None.
639 *
640 *****************************************************************************/
641 void XUsbPsu_SetSpeed(struct XUsbPsu *InstancePtr, u32 Speed)
642 {
643         u32     RegVal;
644
645         Xil_AssertVoid(InstancePtr != NULL);
646         Xil_AssertVoid(Speed >= XUSBPSU_DCFG_HIGHSPEED &&
647                         Speed <= XUSBPSU_DCFG_SUPERSPEED);
648
649         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCFG);
650         RegVal &= ~(XUSBPSU_DCFG_SPEED_MASK);
651         RegVal |= Speed;
652         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCFG, RegVal);
653 }
654
655 /****************************************************************************/
656 /**
657 * Sets Device Address of the Core
658 *
659 * @param        InstancePtr is a pointer to the XUsbPsu instance.
660 * @param        Addr is address to set.
661 *
662 * @return       XST_SUCCESS else XST_FAILURE
663 *
664 * @note None.
665 *
666 *****************************************************************************/
667 int XUsbPsu_SetDeviceAddress(struct XUsbPsu *InstancePtr, u16 Addr)
668 {
669         u32 RegVal;
670
671         Xil_AssertNonvoid(InstancePtr != NULL);
672         Xil_AssertNonvoid(Addr <= 127);
673
674         if (InstancePtr->State == XUSBPSU_STATE_CONFIGURED) {
675                 return XST_FAILURE;
676         }
677
678         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCFG);
679         RegVal &= ~(XUSBPSU_DCFG_DEVADDR_MASK);
680         RegVal |= XUSBPSU_DCFG_DEVADDR(Addr);
681         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCFG, RegVal);
682
683         if (Addr != 0)
684                 InstancePtr->State = XUSBPSU_STATE_ADDRESS;
685         else
686                 InstancePtr->State = XUSBPSU_STATE_DEFAULT;
687
688         return XST_FAILURE;
689 }