blob: fd18f1a76133aefec233b0a03f0de3fcc918beae [file] [log] [blame]
Amol Jadif3d5a892013-07-23 16:09:44 -07001/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28#include <debug.h>
29#include <reg.h>
30#include <bits.h>
31#include <string.h>
32#include <malloc.h>
33#include <stdlib.h>
34#include <arch/defines.h>
35#include <platform/timer.h>
36#include <platform/interrupts.h>
37#include <platform/irqs.h>
38#include <kernel/event.h>
39#include <usb30_dwc_hwio.h>
40#include <usb30_dwc.h>
41#include <usb30_dwc_hw.h>
42
43extern char* ss_link_state_lookup[20];
44extern char* hs_link_state_lookup[20];
45extern char* event_lookup_device[20];
46extern char* event_lookup_ep[20];
47extern char* dev_ctrl_state_lookup[20];
48extern char* ep_state_lookup[20];
49extern char* dev_state_lookup[20];
50extern char* speed_lookup[20];
51
52//#define DEBUG_USB
53
54#ifdef DEBUG_USB
55#define DBG(...) dprintf(ALWAYS, __VA_ARGS__)
56#else
57#define DBG(...)
58#endif
59
60#define ERR(...) dprintf(ALWAYS, __VA_ARGS__)
61
62/* This file provides interface to interact with DWC hardware. This code
63 * does not maintain any soft states. It programs the h/w as requested by the
64 * APIs.
65 */
66
67/* generic api to send endpoint command */
68static void dwc_ep_cmd(dwc_dev_t *dev, uint8_t ep_phy_num, dwc_ep_cmd_t *ep_cmd)
69{
70 if(REG_READ_FIELDI(dev, GUSB2PHYCFG, 0, SUSPENDUSB20))
71 {
72 /* this must be 0. see snps 6.3.2.5.8 */
73 ASSERT(0);
74 }
75
76 /* wait until previous command is in-active */
77 while( REG_READ_FIELDI(dev, DEPCMD, ep_phy_num, CMDACT) == 1);
78
79 /* clear cmd reg */
80 REG_WRITEI(dev, DEPCMD, ep_phy_num, 0);
81
82 /* write the command parameters */
83 REG_WRITEI(dev, DEPCMDPAR2, ep_phy_num, ep_cmd->param2);
84 REG_WRITEI(dev, DEPCMDPAR1, ep_phy_num, ep_cmd->param1);
85 REG_WRITEI(dev, DEPCMDPAR0, ep_phy_num, ep_cmd->param0);
86
87 /* command */
88 REG_WRITE_FIELDI(dev, DEPCMD, ep_phy_num, CMDTYP, ep_cmd->cmd);
89
90 if ((ep_cmd->cmd == DEPCMD_CMD_UPDATE_TRANSFER) ||
91 (ep_cmd->cmd == DEPCMD_CMD_END_TRANSFER) ||
92 (ep_cmd->cmd == DEPCMD_CMD_START_NEW_CONF))
93 {
94 /* set the transfer resource index */
95 REG_WRITE_FIELDI(dev,
96 DEPCMD,
97 ep_phy_num,
98 COMMANDPARAM,
99 ep_cmd->xfer_resource_index);
100 }
101
102 /* command interrupt can be set only if device is in running state. */
103 if(dwc_device_run_status(dev))
104 {
105 REG_WRITE_FIELDI(dev, DEPCMD, ep_phy_num, CMDIOC, 1);
106 }
107
108 DBG("\nEP CMD: ep = %d : 0x%05x "
109 "pram0 = 0x%08x param1 = 0x%08x param2 = 0x%08x",
110 ep_phy_num,
111 REG_READI(dev, DEPCMD, ep_phy_num) | (1 << 10),
112 ep_cmd->param0,
113 ep_cmd->param1,
114 ep_cmd->param2);
115
116 /* set active */
117 REG_WRITE_FIELDI(dev, DEPCMD, ep_phy_num, CMDACT, 1);
118
119 /* Wait until active bit is cleared.
120 * This does not necessarily mean that command is executed.
121 * It only means a new command can be issued.
122 * We get an interrupt when command execution is complete.
123 */
124 while( REG_READ_FIELDI(dev, DEPCMD, ep_phy_num, CMDACT) == 1);
125}
126
127/* send start transfer command to the specified ep.
128 * assumes the trb are already populated.
129 */
130void dwc_ep_cmd_start_transfer(dwc_dev_t *dev, uint8_t ep_phy_num)
131{
132 dwc_ep_cmd_t ep_cmd;
133 dwc_ep_t *ep = &dev->ep[DWC_EP_PHY_TO_INDEX(ep_phy_num)];
134
135 uint32_t td_addr_low = (uint32_t) ep->trb;
136 uint32_t td_addr_high = (uint32_t) 0x0;
137
138 /* transfer descriptor (aka TRB list) address must be on 16 byte boundary.*/
139 ASSERT((td_addr_low & 0xF) == 0);
140 ASSERT((td_addr_high & 0xF) == 0);
141
142 /* set command */
143 ep_cmd.cmd = DEPCMD_CMD_START_TRANSFER;
144
145 /* set params */
146 ep_cmd.param2 = 0;
147 ep_cmd.param1 = td_addr_low;
148 ep_cmd.param0 = td_addr_high;
149
150 dwc_ep_cmd(dev, ep_phy_num, &ep_cmd);
151
152 /* Note: On execution of this cmd, a ep command complete event occurs.
153 * this DEPEVT ep event returns a XferRscIdx - transfer resource
154 * index. That must be used to Update or End this transfer.
155 */
156 DBG("\n START_TRANSFER: new EP phy_num = %d state is = %s",
157 ep_phy_num, ep_state_lookup[ep->state]);
158}
159
160/* end transfer on a particular endpoint */
161void dwc_ep_cmd_end_transfer(dwc_dev_t *dev, uint8_t ep_phy_num)
162{
163 dwc_ep_cmd_t ep_cmd;
164
165 dwc_ep_t *ep = &dev->ep[DWC_EP_PHY_TO_INDEX(ep_phy_num)];
166
167 ep_cmd.cmd = 0;
168
169 /* set cmd and the resource index */
170 ep_cmd.cmd = DEPCMD_CMD_END_TRANSFER;
171 ep_cmd.xfer_resource_index = ep->resource_idx;
172
173 /* params */
174 ep_cmd.param2 = 0;
175 ep_cmd.param1 = 0;
176 ep_cmd.param0 = 0;
177
178 /* note: TRB status is not updated by the h/w when end transfer is issued.
179 * snps: 6.3.2.5.7
180 */
181 dwc_ep_cmd(dev, ep_phy_num, &ep_cmd);
182}
183
184/* set number of transfer resources to be used for the ep. */
185void dwc_ep_cmd_set_transfer_resource(dwc_dev_t *dev, uint8_t ep_phy_num)
186{
187 dwc_ep_cmd_t ep_cmd;
188
189 /* set command */
190 ep_cmd.cmd = DEPCMD_CMD_SET_TR_CONF;
191
192 ep_cmd.param2 = 0;
193 ep_cmd.param1 = 0;
194 ep_cmd.param0 = 1; /* number of transfer resources: always set to 1 */
195
196 dwc_ep_cmd(dev, ep_phy_num, &ep_cmd);
197}
198
199/* Configure end point in the core before starting to use it. The following
200 parameters need to be configured:
201 - usb ep number
202 - ep direction
203 - ep type
204 - mak pkt size
205 - burst size
206 - transfer events to be generated for this ep
207 - for IN ep, tx fifo to be used
208*/
209void dwc_ep_cmd_set_config(dwc_dev_t *dev, uint8_t index, uint8_t action)
210{
211 uint8_t ep_phy_num;
212 uint8_t ep_usb_num;
213 uint8_t ep_direction;
214 uint16_t max_pkt_size;
215 uint32_t burst_size;
216 uint8_t tx_fifo_num;
217
218 dwc_ep_t ep;
219 dwc_ep_cmd_t ep_cmd;
220 dwc_ep_type_t ep_type;
221
222 ep = dev->ep[index];
223
224 /* get the corresponding physical ep number */
225 ep_phy_num = ep.phy_num;
226 ep_usb_num = ep.number;
227 ep_direction = ep.dir;
228 ep_type = ep.type;
229 max_pkt_size = ep.max_pkt_size;
230 burst_size = ep.burst_size;
231 tx_fifo_num = ep.tx_fifo_num;
232
233 /* set command */
234 ep_cmd.cmd = DEPCMD_CMD_SET_EP_CONF;
235 ep_cmd.param2 = 0x0;
236 ep_cmd.param1 = 0x0;
237 ep_cmd.param0 = 0x0;
238
239 /* TODO: set bInterval according to ep value.
240 * ignored since it is not used for bulk.
241 */
242
243 /* map this usb ep to the ep_phy_num */
244 ep_cmd.param1 |= ep_usb_num << DEPCMDPAR1_USB_EP_NUM_BIT;
245 ep_cmd.param1 |= ep_direction << DEPCMDPAR1_USB_EP_DIR_BIT;
246
247 /* enable event generation */
248 ep_cmd.param1 |= BIT(DEPCMDPAR2_XFER_N_RDY_BIT);
249 ep_cmd.param1 |= BIT(DEPCMDPAR2_XFER_COMPLETE_BIT);
250
251 /* interrupt number: which event buffer to be used. */
252 ep_cmd.param1 |= 0;
253
254 /* action: 0 = initialize */
255 ep_cmd.param0 |= (action << DEPCMDPAR0_ACTION_BIT);
256 /* burst size */
257 ep_cmd.param0 |= (burst_size << DEPCMDPAR0_BURST_SIZE_BIT);
258
259 ep_cmd.param0 |= tx_fifo_num << DEPCMDPAR0_FIFO_NUM_BIT;
260 ep_cmd.param0 |= ep_type << DEPCMDPAR0_EP_TYPE_BIT;
261 ep_cmd.param0 |= max_pkt_size << DEPCMDPAR0_MAX_PKT_SIZE_BIT;
262
263 dwc_ep_cmd(dev, ep_phy_num, &ep_cmd);
264}
265
266/* send stall command to ep */
267void dwc_ep_cmd_stall(dwc_dev_t *dev, uint8_t ep_phy_num)
268{
269 dwc_ep_cmd_t ep_cmd;
270
271 /* set command */
272 ep_cmd.cmd = DEPCMD_CMD_SET_STALL;
273
274 ep_cmd.param2 = 0;
275 ep_cmd.param1 = 0;
276 ep_cmd.param0 = 0;
277
278 DBG("\nSTALLING.... ep_phy_num = %d\n", ep_phy_num);
279
280 dwc_ep_cmd(dev, ep_phy_num, &ep_cmd);
281}
282
283/* clear stall */
284void dwc_ep_cmd_clear_stall(dwc_dev_t *dev, uint8_t ep_phy_num)
285{
286 dwc_ep_cmd_t ep_cmd;
287
288 /* set command */
289 ep_cmd.cmd = DEPCMD_CMD_CLEAR_STALL;
290
291 ep_cmd.param2 = 0;
292 ep_cmd.param1 = 0;
293 ep_cmd.param0 = 0;
294
295 dwc_ep_cmd(dev, ep_phy_num, &ep_cmd);
296}
297
298/* send a start new config command */
299void dwc_ep_cmd_start_new_config(dwc_dev_t *dev,
300 uint8_t ep_phy_num,
301 uint8_t resource_idx)
302{
303 dwc_ep_cmd_t ep_cmd;
304
305 /* set command */
306 ep_cmd.cmd = DEPCMD_CMD_START_NEW_CONF;
307 ep_cmd.xfer_resource_index = resource_idx;
308
309 ep_cmd.param2 = 0;
310 ep_cmd.param1 = 0;
311 ep_cmd.param0 = 0;
312
313 dwc_ep_cmd(dev, ep_phy_num, &ep_cmd);
314}
315
316/******************** DWC Device related APIs *********************************/
317
318/* generic api to send device command */
319static void dwc_device_cmd(dwc_dev_t *dev, dwc_device_cmd_t *cmd)
320{
321 uint8_t active = REG_READ_FIELD(dev, DGCMD, CMDACT);
322
323 ASSERT(active);
324
325 REG_WRITE(dev, DGCMDPAR, cmd->param);
326 REG_WRITE_FIELD(dev, DGCMD, CMDTYP, cmd->cmd);
327
328 /* wait until active field is cleared. */
329 while(!REG_READ_FIELD(dev, DGCMD, CMDACT));
330
331 if(REG_READ_FIELD(dev, DGCMD, CMDSTATUS))
332 {
333 ERR("\n\n device command failed. \n\n");
334 ASSERT(0);
335 }
336}
337
338/* set periodic param */
339void dwc_device_set_periodic_param(dwc_dev_t *dev, uint32_t val)
340{
341 dwc_device_cmd_t cmd;
342
343 cmd.cmd = DWC_DEV_CMD_SET_PERIODIC_PARAMS_VAL;
344 cmd.param = val;
345
346 /* send device command to set period param value */
347 dwc_device_cmd(dev, &cmd);
348}
349
350/* set device address */
351void dwc_device_set_addr(dwc_dev_t *dev, uint16_t addr)
352{
353 REG_WRITE_FIELD(dev, DCFG, DEVADDR, addr);
354}
355
356/* reset device */
357void dwc_device_reset(dwc_dev_t *dev)
358{
359 /* start reset */
360 REG_WRITE_FIELD(dev, DCTL, CSFTRST, 1);
361
362 /* wait until done */
363 while(REG_READ_FIELD(dev, DCTL, CSFTRST));
364}
365
366/* Run/Stop device: 1 == run. 0 == stop */
367void dwc_device_run(dwc_dev_t *dev, uint8_t run)
368{
369 REG_WRITE_FIELD(dev, DCTL, RUN_STOP, run);
370}
371
372/* is device running? */
373uint8_t dwc_device_run_status(dwc_dev_t *dev)
374{
375 return REG_READ_FIELD(dev, DCTL, RUN_STOP);
376}
377
378/******************** Managing various events *********************************/
379/* event init:
380 program event buffer address, size and reset event count to 0.
381 */
382void dwc_event_init(dwc_dev_t *dev)
383{
384 /* snps 8.2.2 */
385
386 /* event buffer address */
387 REG_WRITEI(dev, GEVNTADRLO, 0, (uint32_t) dev->event_buf.buf);
388 REG_WRITEI(dev, GEVNTADRHI, 0, 0x0);
389
390 /* set buffer size. assuming interrupt is always needed on new event,
391 * bit 31 is not set.
392 */
393 REG_WRITEI(dev, GEVNTSIZ, 0, dev->event_buf.buf_size);
394
395 /* reset count */
396 REG_WRITEI(dev, GEVNTCOUNT, 0, 0x0);
397}
398
399/* event update index */
400static void dwc_event_update_index(uint16_t *index, uint16_t max_count)
401{
402 if(*index == max_count)
403 {
404 /* we have read the last entry. Need to roll over for next reading.*/
405 *index = 0;
406 }
407 else
408 {
409 *index += 1;
410 }
411}
412
413/* Returns next event from event queue and the size of event
414 * Event buffer is a circular buffer that the hardware populates when any of
415 * the enabled event occurs. An interrupt is generated if interrupt is enabled
416 * for that event.
417 * This api returns the next valid event from the event buffer and updates event
418 * buffer index.
419 * Most events are 4 byte long
420 * Note: caller must provide at least 12 bytes buffer in case the
421 * next event is the special 12 byte event.
422 */
423uint16_t dwc_event_get_next(dwc_dev_t *dev, uint32_t *event)
424{
425 uint16_t count;
426 uint16_t event_size = 0;
427 uint32_t *buf;
428
429 /* read the number of valid event data in event buffer. */
430 count = REG_READI(dev, GEVNTCOUNT, 0);
431
432 if(count == 0)
433 {
434 /* no events in buffer. */
435 return event_size;
436 }
437
438 /* each event is at least 4 bytes long.
439 * make sure there is at least one event to read.
440 */
441 ASSERT(count >= 4);
442
443 /* get event buffer for this device */
444 buf = dev->event_buf.buf;
445
446 /* invalidate cached event buf data */
447 arch_invalidate_cache_range((addr_t) (buf + dev->event_buf.index), 4);
448
449 /* read next event */
450 *event = buf[dev->event_buf.index];
451 event_size += 4;
452 dwc_event_update_index(&dev->event_buf.index, dev->event_buf.max_index);
453
454
455 /* is this buffer overflow event? */
456 if((DWC_EVENT_DEVICE_EVENT_ID(*event) == DWC_EVENT_DEVICE_EVENT_ID_BUFFER_OVERFLOW))
457 {
458 /* ouch... */
459 ERR("\n Event buffer is full. Need to increase size.\n");
460 ASSERT(0);
461 }
462
463 /* check for that special 12 byte event */
464 if( DWC_EVENT_IS_DEVICE_EVENT(*event) &
465 (DWC_EVENT_DEVICE_EVENT_ID(*event) == DWC_EVENT_DEVICE_EVENT_ID_VENDOR_DEVICE_TEST_LMP))
466 {
467 /* invalidate cached event buf data */
468 arch_invalidate_cache_range((addr_t) (buf + dev->event_buf.index), 4);
469
470 *(event + 1) = buf[dev->event_buf.index];
471 event_size += 4;
472 dwc_event_update_index(&dev->event_buf.index, dev->event_buf.buf_size);
473
474 /* invalidate cached event buf data */
475 arch_invalidate_cache_range((addr_t) (buf + dev->event_buf.index), 4);
476
477 *(event + 1) = buf[dev->event_buf.index];
478 event_size += 4;
479 dwc_event_update_index(&dev->event_buf.index, dev->event_buf.buf_size);
480 }
481
482 return event_size;
483}
484
485/* Lets h/w know that we have processed "count" bytes of data from event buffer
486 * and it can use that space for new events.
487 * This must be done only after the event is processed.
488 */
489void dwc_event_processed(dwc_dev_t *dev, uint16_t count)
490{
491 REG_WRITEI(dev, GEVNTCOUNT, 0, count);
492}
493
494/* enable device event generation:
495 * events - bit map of events defined in dwc_event_device_event_id_t
496 */
497void dwc_event_device_enable(dwc_dev_t *dev, uint32_t events)
498{
499 REG_WRITE(dev, DEVTEN, events);
500}
501
502/*************** Generic APIs affecting overall controller ********************/
503
504/* reset HS and SS PHY's digital interface: UTMI + PIPE3 */
505void dwc_phy_digital_reset(dwc_dev_t *dev)
506{
507 REG_WRITE_FIELDI(dev, GUSB2PHYCFG, 0, PHYSOFTRST, 1);
508 REG_WRITE_FIELDI(dev, GUSB3PIPECTL, 0, PHYSOFTRST, 1);
509
510 /* per HPG */
511 udelay(100);
512
513 REG_WRITE_FIELDI(dev, GUSB2PHYCFG, 0, PHYSOFTRST, 0);
514 REG_WRITE_FIELDI(dev, GUSB3PIPECTL, 0, PHYSOFTRST, 0);
515
516 /* per HPG */
517 udelay(100);
518}
519
520void dwc_usb2_phy_soft_reset(dwc_dev_t *dev)
521{
522 REG_WRITE_FIELDI(dev, GUSB2PHYCFG, 0, PHYSOFTRST, 1);
523
524 udelay(100);
525
526 REG_WRITE_FIELDI(dev, GUSB2PHYCFG, 0, PHYSOFTRST, 0);
527
528 udelay(100);
529}
530
531/* workaround_12 as described in HPG */
532void dwc_ss_phy_workaround_12(dwc_dev_t *dev)
533{
534 /* 12. */
535 REG_WRITEI(dev, GUSB3PIPECTL, 0, 0x30C0003);
536}
537
538/* AXI master config */
539void dwc_axi_master_config(dwc_dev_t *dev)
540{
541 uint32_t reg = 0;
542
543 reg = (DWC_GSBUSCFG0_INCR4BRSTENA_BMSK |
544 DWC_GSBUSCFG0_INCR8BRSTENA_BMSK |
545 DWC_GSBUSCFG0_INCR16BRSTENA_BMSK);
546
547 REG_WRITE(dev, GSBUSCFG0, reg);
548}
549
550/* read the controller id and version information */
551uint32_t dwc_coreid(dwc_dev_t *dev)
552{
553 return REG_READ(dev, GSNPSID);
554}
555
556/* read the current connection speed. */
557uint8_t dwc_connectspeed(dwc_dev_t *dev)
558{
559 return REG_READ_FIELD(dev, DSTS, CONNECTSPD);
560}
561
562/* disable all non-control EPs */
563void dwc_ep_disable_non_control(dwc_dev_t *dev)
564{
565 uint32_t reg = REG_READ(dev, DALEPENA);
566
567 /* clear all except the control IN and OUT ep */
568 reg &= 0x3;
569
570 REG_WRITE(dev, DALEPENA, reg);
571}
572
573/* disable a specific ep */
574void dwc_ep_disable(dwc_dev_t *dev, uint8_t ep_phy_num)
575{
576 uint32_t reg = REG_READ(dev, DALEPENA);
577
578 reg &= ~BIT(ep_phy_num);
579
580 REG_WRITE(dev, DALEPENA, reg);
581}
582
583/* enable a specific ep */
584void dwc_ep_enable(dwc_dev_t *dev, uint8_t ep_phy_num)
585{
586 uint32_t reg = REG_READ(dev, DALEPENA);
587
588 reg |= BIT(ep_phy_num);
589
590 REG_WRITE(dev, DALEPENA, reg);
591}
592
593/* global reset of controller.
594 * 1 == put in reset. 0 == out of reset
595 */
596void dwc_reset(dwc_dev_t *dev, uint8_t reset)
597{
598 /* snps databook table 6-11 indicates this field to be used only for debug
599 * purpose. use dctl.softreset instead for devide mode.
600 * but hpg 4.4.2. 8.a says use this.
601 */
602 REG_WRITE_FIELD(dev, GCTL, CORESOFTRESET, reset);
603
604 /* per HPG */
605 udelay(100);
606}
607
608/* initialize global control reg for device mode operation.
609 * sequence numbers are as described in HPG.
610 */
611void dwc_gctl_init(dwc_dev_t *dev)
612{
613 /* 16. */
614 /* a. default value is good for RAM clock */
615 /* b. default value is good for Disable Debug Attach */
616 REG_WRITE_FIELD(dev, GCTL, DEBUGATTACH, 0);
617
618 /* c & d: disable loopback/local loopback
619 * TODO: possibly for older version. no such fields in GCTL
620 */
621
622 /* e. no soft reset. */
623 REG_WRITE_FIELD(dev, GCTL, CORESOFTRESET, 0);
624
625 /* f. set port capability direction: device */
626 REG_WRITE_FIELD(dev, GCTL, PRTCAPDIR, 0x2);
627
628 /* g. set scale down value */
629 REG_WRITE_FIELD(dev, GCTL, FRMSCLDWN, 0x0);
630
631 /* h. enable multiple attempts for SS connection */
632 REG_WRITE_FIELD(dev, GCTL, U2RSTECN, 1);
633
634 /* i. set power down scale of snps phy */
635 REG_WRITE_FIELD(dev, GCTL, PWRDNSCALE, 0x2);
636
637 /* j. clear SOFITPSYNC bit */
638 REG_WRITE_FIELD(dev, GCTL, SOFITPSYNC, 0);
639}