1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
|
/*-
* Copyright (c) 2007-2008, Juniper Networks, Inc.
* Copyright (c) 2008, Michael Trimarchi <trimarchimichael@yahoo.it>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef USB_EHCI_H
#define USB_EHCI_H
//Charles
#ifndef BYTE
#define BYTE unsigned char
#endif
#ifndef WORD
#define WORD unsigned short
#endif
#ifndef DWORD
#define DWORD unsigned long
#endif
#define CONFIG_SYS_HZ 1000
#define BA_EHCI_PCI 0xD8007800 /* USB 2.0 EHCI USB Host Configuration Base Address */
#define BA_EHCI_REG 0xD8007900 /* USB 2.0 EHCI USB Host Register Base Address */
#define CapRegBase BA_EHCI_REG
#define OpRegBase (BA_EHCI_REG + 0x10)
#define USB_TEST_SUCCESS 0
#define USB_TEST_FAIL 1
#define USB_TEST_TIMEOUT 2
/* Basic Define*/
#define REG32 *(volatile unsigned int *)
#define REG16 *(volatile unsigned short *)
#define REG8 *(volatile unsigned char *)
#define REG_GET32(addr) ( REG32(addr) ) /* Read 32 bits Register */
#define REG_GET16(addr) ( REG16(addr) ) /* Read 16 bits Register */
#define REG_GET8(addr) ( REG8(addr) ) /* Read 8 bits Register */
#define REG_SET32(addr, val) ( REG32(addr) = (val) ) /* Write 32 bits Register */
#define REG_SET16(addr, val) ( REG16(addr) = (val) ) /* Write 16 bits Register */
#define REG_SET8(addr, val) ( REG8(addr) = (val) ) /* Write 8 bits Register */
#if !defined(CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS)
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 4
#endif
/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
#define DeviceRequest \
((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8)
#define DeviceOutRequest \
((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE) << 8)
#define InterfaceRequest \
((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
#define EndpointRequest \
((USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
#define EndpointOutRequest \
((USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE) << 8)
/*
* Register Space.
*/
struct ehci_hccr {
uint32_t cr_capbase;
#define HC_LENGTH(p) (((p) >> 0) & 0x00ff)
#define HC_VERSION(p) (((p) >> 16) & 0xffff)
uint32_t cr_hcsparams;
#define HCS_PPC(p) ((p) & (1 << 4))
#define HCS_INDICATOR(p) ((p) & (1 << 16)) /* Port indicators */
#define HCS_N_PORTS(p) (((p) >> 0) & 0xf)
uint32_t cr_hccparams;
uint8_t cr_hcsp_portrt[8];
} __attribute__ ((packed));
struct ehci_hcor {
uint32_t or_usbcmd;
#define CMD_PARK (1 << 11) /* enable "park" */
#define CMD_PARK_CNT(c) (((c) >> 8) & 3) /* how many transfers to park */
#define CMD_ASE (1 << 5) /* async schedule enable */
#define CMD_LRESET (1 << 7) /* partial reset */
#define CMD_IAAD (1 << 5) /* "doorbell" interrupt */
#define CMD_PSE (1 << 4) /* periodic schedule enable */
#define CMD_RESET (1 << 1) /* reset HC not bus */
#define CMD_RUN (1 << 0) /* start/stop HC */
uint32_t or_usbsts;
#define STD_ASS (1 << 15)
#define STS_HALT (1 << 12)
uint32_t or_usbintr;
#define INTR_UE (1 << 0) /* USB interrupt enable */
#define INTR_UEE (1 << 1) /* USB error interrupt enable */
#define INTR_PCE (1 << 2) /* Port change detect enable */
#define INTR_SEE (1 << 4) /* system error enable */
#define INTR_AAE (1 << 5) /* Interrupt on async adavance enable */
uint32_t or_frindex;
uint32_t or_ctrldssegment;
uint32_t or_periodiclistbase;
uint32_t or_asynclistaddr;
uint32_t _reserved_[9];
uint32_t or_configflag;
#define FLAG_CF (1 << 0) /* true: we'll support "high speed" */
uint32_t or_portsc[CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS];
uint32_t or_systune;
} __attribute__ ((packed));
#define USBMODE 0x68 /* USB Device mode */
#define USBMODE_SDIS (1 << 3) /* Stream disable */
#define USBMODE_BE (1 << 2) /* BE/LE endiannes select */
#define USBMODE_CM_HC (3 << 0) /* host controller mode */
#define USBMODE_CM_IDLE (0 << 0) /* idle state */
/* Interface descriptor */
struct usb_linux_interface_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned char bInterfaceNumber;
unsigned char bAlternateSetting;
unsigned char bNumEndpoints;
unsigned char bInterfaceClass;
unsigned char bInterfaceSubClass;
unsigned char bInterfaceProtocol;
unsigned char iInterface;
} __attribute__ ((packed));
/* Configuration descriptor information.. */
struct usb_linux_config_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short wTotalLength;
unsigned char bNumInterfaces;
unsigned char bConfigurationValue;
unsigned char iConfiguration;
unsigned char bmAttributes;
unsigned char MaxPower;
} __attribute__ ((packed));
#if defined CONFIG_EHCI_DESC_BIG_ENDIAN
#define ehci_readl(x) (*((volatile u32 *)(x)))
#define ehci_writel(a, b) (*((volatile u32 *)(a)) = ((volatile u32)b))
#else
#define ehci_readl(x) cpu_to_le32((*((volatile u32 *)(x))))
#define ehci_writel(a, b) (*((volatile u32 *)(a)) = \
cpu_to_le32(((volatile u32)b)))
#endif
#if defined CONFIG_EHCI_MMIO_BIG_ENDIAN
#define hc32_to_cpu(x) be32_to_cpu((x))
#define cpu_to_hc32(x) cpu_to_be32((x))
#else
#define hc32_to_cpu(x) le32_to_cpu((x))
#define cpu_to_hc32(x) cpu_to_le32((x))
#endif
#define EHCI_PS_WKOC_E (1 << 22) /* RW wake on over current */
#define EHCI_PS_WKDSCNNT_E (1 << 21) /* RW wake on disconnect */
#define EHCI_PS_WKCNNT_E (1 << 20) /* RW wake on connect */
#define EHCI_PS_PO (1 << 13) /* RW port owner */
#define EHCI_PS_PP (1 << 12) /* RW,RO port power */
#define EHCI_PS_LS (3 << 10) /* RO line status */
#define EHCI_PS_PR (1 << 8) /* RW port reset */
#define EHCI_PS_SUSP (1 << 7) /* RW suspend */
#define EHCI_PS_FPR (1 << 6) /* RW force port resume */
#define EHCI_PS_OCC (1 << 5) /* RWC over current change */
#define EHCI_PS_OCA (1 << 4) /* RO over current active */
#define EHCI_PS_PEC (1 << 3) /* RWC port enable change */
#define EHCI_PS_PE (1 << 2) /* RW port enable */
#define EHCI_PS_CSC (1 << 1) /* RWC connect status change */
#define EHCI_PS_CS (1 << 0) /* RO connect status */
#define EHCI_PS_CLEAR (EHCI_PS_OCC | EHCI_PS_PEC | EHCI_PS_CSC)
#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == (1 << 10))
/*
* Schedule Interface Space.
*
* IMPORTANT: Software must ensure that no interface data structure
* reachable by the EHCI host controller spans a 4K page boundary!
*
* Periodic transfers (i.e. isochronous and interrupt transfers) are
* not supported.
*/
/* Queue Element Transfer Descriptor (qTD). */
struct qTD {
/* this part defined by EHCI spec */
uint32_t qt_next; /* see EHCI 3.5.1 */
#define QT_NEXT_TERMINATE 1
uint32_t qt_altnext; /* see EHCI 3.5.2 */
uint32_t qt_token; /* see EHCI 3.5.3 */
uint32_t qt_buffer[5]; /* see EHCI 3.5.4 */
uint32_t qt_buffer_hi[5]; /* Appendix B */
/* pad struct for 32 byte alignment */
uint32_t unused[3];
};
/* Queue Head (QH). */
struct QH {
uint32_t qh_link;
#define QH_LINK_TERMINATE 1
#define QH_LINK_TYPE_ITD 0
#define QH_LINK_TYPE_QH 2
#define QH_LINK_TYPE_SITD 4
#define QH_LINK_TYPE_FSTN 6
uint32_t qh_endpt1;
uint32_t qh_endpt2;
uint32_t qh_curtd;
struct qTD qh_overlay;
/*
* Add dummy fill value to make the size of this struct
* aligned to 32 bytes
*/
uint8_t fill[16];
};
//Charles
typedef struct _HCSPARAMS {
DWORD N_Ports:4;
DWORD PortPowerControl:1;
DWORD Reserved1:2;
DWORD PortRouteRule:1;/*bit 7*/
DWORD NumberPortPerCC:4;/*bit 8-11*/
DWORD NumberOfCC:4;/*bit 12-15*/
DWORD PortIndicator:1;/*bit 16*/
DWORD Reserved2:3;/*bit 17-19*/
DWORD DebugPortNum:4;/*bit 20-23*/
DWORD Reserved3:8;/*bit 24-31*/
} __attribute__ ((packed)) HCSPARAMS, *pHCSPARAMS;
typedef struct _HCCPARAMS {
DWORD _64BitAddress:1;/*bit 0*/
DWORD ProgrammableFrameList:1;/*bit 1*/
DWORD Reserved1:2;/*bit 2-3*/
DWORD IsoScheduleThreshold:4;/*bit 4-7*/
DWORD Reserved2:24;/* bit 8-31*/
} __attribute__ ((packed)) HCCPARAMS, *pHCCPARAMS;
typedef struct _HostControllerCapability {
BYTE CapLength;/*byte 0*/
BYTE Reserved;/*byte 1*/
WORD HCIVersion;/*byte 2*/
HCSPARAMS HCSParams;/*byte 4*/
HCCPARAMS HCCParams;/*byte 8*/
BYTE PortRoute[15];/*byte c-1b*/
} HCCapability, *pHCCapability;
typedef struct _EHCICommand {
DWORD RunStop:1;/*bit 0*/
DWORD HCReset:1;/*bit 1*/
DWORD FrameListSize:2;/*bit 2-3*/
DWORD PeriodicEnable:1;/*bit 4*/
DWORD AsynchronousEnable:1;/*bit 5*/
DWORD IntOnAsyAdvDoorbell:1;/*bit 6*/
DWORD LightHCReset:1;/*bit 7*/
DWORD Reserved1:8;/*bit 8-15*/
DWORD InterruptThreshold:8;/*bit 16-23*/
DWORD Reserved2:8;/*bit 24-31*/
} __attribute__ ((packed)) EHCICommand, *pEHCICommand;
typedef struct _EHCIStatus {
DWORD USBInt:1;/* bit 0*/
DWORD USBErrInt:1;/* bit 1*/
DWORD PortChangeDetect:1;/* bit 2*/
DWORD FrameListRollover:1;/* bit 3*/
DWORD HostSysErr:1;/* bit 4*/
DWORD IntOnAsyncAdv:1;/* bit 5*/
DWORD Reserved1:6;/* bit 6-11*/
DWORD HCHalted:1;/* bit 12*/
DWORD Reclamation:1;/* bit 13*/
DWORD PeriodicSchStatus:1;/* bit 14*/
DWORD AsyncSchStatus:1;/* bit 15*/
DWORD Reserved2:16;/* bit 16-31*/
} __attribute__ ((packed)) EHCIStatus, *pEHCIStatus;
typedef struct _EHCIIntEnable {
DWORD USBIntEnable:1;/* bit 0*/
DWORD USBErrIntEnable:1;/* bit 1*/
DWORD PortChgIntEnable:1;/* bit 2*/
DWORD FrameListROEnable:1;/* bit 3*/
DWORD HostSysErrEnable:1;/* bit 4*/
DWORD IntOnAsyncAdvEnable:1;/* bit 5*/
DWORD Reserved:26;/* bit 6-31*/
} __attribute__ ((packed)) EHCIIntEnable, *pEHCIIntEnable;
typedef struct _EHCIConfigFlag {
DWORD ConfigFlag:1;/* bit 0*/
DWORD Reserved:31;/* bit 1-31*/
} __attribute__ ((packed)) EHCIConfigFlag, *pEHCIConfigFlag;
typedef struct _EHCIPortControlStatus {
DWORD CurrentConStatus:1;/* bit 0*/
DWORD ConnectStatusChg:1;/* bit 1*/
DWORD PortEnDisable:1;/* bit 2*/
DWORD PortEnDisChg:1;/* bit 3*/
DWORD OverCurrentActive:1;/* bit 4*/
DWORD OverCurrentChg:1;/* bit 5*/
DWORD ForcePortResume:1;/* bit 6*/
DWORD Suspend:1;/* bit 7*/
DWORD PortReset:1;/* bit 8*/
DWORD HighSpdDevice:1;/* bit 9*/
DWORD LineStatus:2;/* bit 10-11*/
DWORD PortPower:1;/* bit 12*/
DWORD PortOwer:1;/* bit 13*/
DWORD PortIndicatorControl:2;/* bit 14-15*/
DWORD PortTestControl:4;/* bit 16-19*/
DWORD WakeOnConEnable:1;/* bit 20*/
DWORD WakeOnDisconEnable:1;/* bit 21*/
DWORD WakeOnOverCurrentEnable:1;/* bit 22*/
DWORD Reserved:9;/* bit 23-31*/
} __attribute__ ((packed)) EHCIPortCtrlStatus, *pEHCIPortCtrlStatus;
typedef struct _EHCIOperationalReg {
EHCICommand CommandReg;/* byte 00*/
EHCIStatus StatusReg;/* byte 04*/
EHCIIntEnable IntEnableReg;/* byte 08*/
DWORD FrameIndex;/* byte 0c*/
DWORD CTRLSegment;/* byte 10*/
DWORD PeriodicBase;/* byte 14*/
DWORD AsyncBase;/* byte 18*/
DWORD Reserved[9];/* byte 1C-3F*/
EHCIConfigFlag ConfigFlag;/* byte 40*/
EHCIPortCtrlStatus Port[10];/* byte 44*/
} __attribute__ ((packed)) EHCIOPRegister, *pEHCIOPRegister;
/* Low level init functions */
int ehci_hcd_init(void);
int ehci_hcd_stop(void);
void ehci_config_port_owner(void);
int ehci_detect_device(void);
int ehci_enable_port(void);
unsigned char usb_ehci_initial(void);
unsigned char strtochar(unsigned char Value);
#define IRQ_UHDC 43
#define USB_PORT_A 1
#define USB_PORT_B 2
#define USB_PORT_C 4
#define USB_PORT_D 8
#ifdef USB_UHCI_DEBUG
int usb_display_td(struct qTD *td);
#endif
int usb_check_td(struct qTD *td);
int usb_check_bulk_td(struct qTD *td);
int parse_usb_param(char *name);
struct usb_operation_t {
unsigned char enable;
unsigned char port_num;
};
#endif /* USB_EHCI_H */
|