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