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