2 Copyright © 2010-2013, The AROS Development Team. All rights reserved
6 #include <proto/exec.h>
10 #include <devices/usb_hub.h>
14 #ifdef AROS_USB30_CODE
16 #undef HiddPCIDeviceAttrBase
17 #define HiddPCIDeviceAttrBase (hd->hd_HiddPCIDeviceAB)
19 #define HiddAttrBase (hd->hd_HiddAB)
21 static AROS_INTH1(xhciResetHandler
, struct PCIController
*, hc
)
28 KPRINTF(1000, ("Halting HC failed, reset may result in undefined behavior!\n"));
33 /* Reset controller */
41 static AROS_INTH1(xhciCompleteInt
, struct PCIController
*, hc
)
45 KPRINTF(1, ("CompleteInt!\n"));
47 KPRINTF(1, ("CompleteDone\n"));
54 static AROS_INTH1(xhciIntCode
, struct PCIController
*, hc
)
58 // struct PCIDevice *base = hc->hc_Device;
59 // struct PCIUnit *unit = hc->hc_Unit;
63 intr
= opreg_readl(XHCI_USBSTS
);
64 if(intr
& XHCF_STS_EINT
) {
65 /* Clear (RW1C) Event Interrupt (EINT) */
66 opreg_writel(XHCI_USBSTS
, XHCF_STS_EINT
);
68 if (hc
->hc_Flags
& HCF_ONLINE
)
70 if(intr
& XHCF_STS_HSE
) {
71 KPRINTF(1000, ("Host System Error (HSE)!\n"));
74 if(intr
& XHCF_STS_PCD
) {
75 /* There are seven status change bits in the PORTSC register,
76 Connect Status Change (CSC)
77 Port Enabled/Disabled Change (PEC)
78 Warm Port Reset Change (WRC)
79 Over-current Change (OCC)
80 Port Reset Change (PRC)
81 Port Link State Change (PLC)
82 Port Config Error Change (CEC)
84 for (portn
= 1; portn
<= hc
->xhc_NumPorts
; portn
++) {
85 if (opreg_readl(XHCI_PORTSC(portn
)) & (XHCF_PS_CSC
|XHCF_PS_PEC
|XHCF_PS_OCC
|XHCF_PS_WRC
|XHCF_PS_PRC
|XHCF_PS_PLC
|XHCF_PS_CEC
)) {
86 KPRINTF(1000,("port %d changed\n", portn
));
91 if(intr
& XHCF_STS_SRE
) {
92 KPRINTF(1000, ("Host Controller Error (HCE)!\n"));
103 IPTR
xhciSearchExtCap(struct PCIController
*hc
, ULONG id
, IPTR extcap
) {
105 IPTR extcapoff
= (IPTR
) 0;
106 ULONG cnt
= XHCI_EXT_CAPS_MAX
;
108 KPRINTF(100,("search for ext cap with id(%ld)\n", id
));
111 KPRINTF(100, ("continue search from %p\n", extcap
));
112 extcap
= (IPTR
) XHCV_EXT_CAPS_NEXT(READMEM32_LE(extcap
));
114 extcap
= (IPTR
) hc
->xhc_capregbase
+ XHCV_xECP(capreg_readl(XHCI_HCCPARAMS
));
115 KPRINTF(100, ("search from the beginning %p\n", extcap
));
120 if((XHCV_EXT_CAPS_ID(READMEM32_LE(extcap
)) == id
)) {
121 KPRINTF(100, ("found matching ext cap %lx\n", extcap
));
122 return (IPTR
) extcap
;
126 KPRINTF(100, ("skipping ext cap with id(%ld)\n", XHCV_EXT_CAPS_ID(READMEM32_LE(extcap
))));
128 extcapoff
= (IPTR
) XHCV_EXT_CAPS_NEXT(READMEM32_LE(extcap
));
130 } while(cnt
& extcapoff
);
132 KPRINTF(100, ("not found!\n"));
136 BOOL
xhciHaltHC(struct PCIController
*hc
) {
138 struct PCIUnit
*hu
= hc
->hc_Unit
;
142 /* Halt the controller by clearing Run/Stop bit */
143 temp
= opreg_readl(XHCI_USBCMD
);
144 opreg_writel(XHCI_USBCMD
, (temp
& ~XHCF_CMD_RS
));
147 The xHC shall halt within 16 ms. after software clears the Run/Stop bit if certain conditions have been met.
148 The HCHalted (HCH) bit in the USBSTS register indicates when the xHC has finished its
149 pending pipelined transactions and has entered the stopped state.
151 timeout
= 250; //FIXME: arbitrary value of 2500ms
153 temp
= opreg_readl(XHCI_USBSTS
);
154 if( (temp
& XHCF_STS_HCH
) ) {
155 KPRINTF(1000, ("controller halted!\n"));
161 KPRINTF(1000, ("halt failed!\n"));
165 BOOL
xhciResetHC(struct PCIController
*hc
) {
167 struct PCIUnit
*hu
= hc
->hc_Unit
;
171 /* Reset controller by setting HCRST-bit */
172 temp
= opreg_readl(XHCI_USBCMD
);
173 opreg_writel(XHCI_USBCMD
, (temp
| XHCF_CMD_HCRST
));
176 Controller clears HCRST bit when reset is done, wait for it and the CNR-bit to be cleared
178 timeout
= 250; //FIXME: arbitrary value of 2500ms
180 temp
= opreg_readl(XHCI_USBCMD
);
181 if( !(temp
& XHCF_CMD_HCRST
) ) {
182 /* Wait for CNR-bit to clear */
183 timeout
= 250; //FIXME: arbitrary value of 2500ms
185 temp
= opreg_readl(XHCI_USBSTS
);
186 if( !(temp
& XHCF_STS_CNR
) ) {
187 KPRINTF(1000, ("reset succeeded!\n"));
197 KPRINTF(1000, ("reset failed!\n"));
201 BOOL
xhciInit(struct PCIController
*hc
, struct PCIUnit
*hu
) {
203 struct PCIDevice
*hd
= hu
->hu_Device
;
209 volatile APTR pciregbase
;
211 struct TagItem pciActivateMemAndBusmaster
[] =
213 { aHidd_PCIDevice_isIO
, FALSE
},
214 { aHidd_PCIDevice_isMEM
, TRUE
},
215 { aHidd_PCIDevice_isMaster
, TRUE
},
219 APTR T0
= AllocVecAligned(100,128,0);
223 /* Activate Mem and Busmaster as pciFreeUnit will disable them! (along with IO, but we don't have that...) */
224 OOP_SetAttrs(hc
->hc_PCIDeviceObject
, (struct TagItem
*) pciActivateMemAndBusmaster
);
226 OOP_GetAttr(hc
->hc_PCIDeviceObject
, aHidd_PCIDevice_Base0
, (APTR
) &pciregbase
);
227 // KPRINTF(1000, ("XHCI MMIO address space (%p)\n",pciregbase));
229 // Store capregbase in xhc_capregbase
230 hc
->xhc_capregbase
= (APTR
) pciregbase
;
231 KPRINTF(1000, ("xhc_capregbase (%p)\n",hc
->xhc_capregbase
));
233 // Store opregbase in xhc_opregbase
234 hc
->xhc_opregbase
= (APTR
) ((ULONG
) pciregbase
+ capreg_readb(XHCI_CAPLENGTH
));
235 KPRINTF(1000, ("xhc_opregbase (%p)\n",hc
->xhc_opregbase
));
237 // KPRINTF(1000, ("XHCI CAPLENGTH (%02x)\n", capreg_readb(XHCI_CAPLENGTH)));
238 // KPRINTF(1000, ("XHCI Version (%04x)\n", capreg_readw(XHCI_HCIVERSION)));
239 // KPRINTF(1000, ("XHCI HCSPARAMS1 (%08x)\n", capreg_readl(XHCI_HCSPARAMS1)));
240 // KPRINTF(1000, ("XHCI HCSPARAMS2 (%08x)\n", capreg_readl(XHCI_HCSPARAMS2)));
241 // KPRINTF(1000, ("XHCI HCSPARAMS3 (%08x)\n", capreg_readl(XHCI_HCSPARAMS3)));
242 // KPRINTF(1000, ("XHCI HCCPARAMS (%08x)\n", capreg_readl(XHCI_HCCPARAMS)));
245 This field defines the page size supported by the xHC implementation.
246 This xHC supports a page size of 2^(n+12) if bit n is Set. For example,
247 if bit 0 is set, the xHC supports 4k byte page sizes.
249 hc
->xhc_pagesize
= 1<<(AROS_LEAST_BIT_POS(opreg_readl(XHCI_PAGESIZE
)&0xffff)+12);
250 KPRINTF(1000, ("Pagesize = 0x%lx\n", hc
->xhc_pagesize
));
252 /* Testing scratchpad allocations */
253 //hc->xhc_scratchpads = 4;
254 hc
->xhc_scratchpads
= XHCV_SPB_Max(capreg_readl(XHCI_HCSPARAMS2
));
255 KPRINTF(1000, ("Max Scratchpad Buffers %lx\n",hc
->xhc_scratchpads
));
257 hc
->xhc_NumPorts
= XHCV_MaxPorts(capreg_readl(XHCI_HCSPARAMS1
));
258 KPRINTF(1000, ("MaxPorts %lx\n",hc
->xhc_NumPorts
));
261 We don't yeat know how many we have each of them, xhciParseSupProtocol takes care of that
263 hc
->xhc_NumPorts20
= 0;
264 hc
->xhc_NumPorts30
= 0;
267 Number of Device Slots (MaxSlots). This field specifies the maximum number of Device
268 Context Structures and Doorbell Array entries this host controller can support. Valid values are
269 in the range of 1 to 255. The value of ‘0’ is reserved, fail gracefully on it
271 hc
->xhc_maxslots
= (XHCV_MaxSlots(capreg_readl(XHCI_HCSPARAMS1
)) & XHCM_CONFIG_MaxSlotsEn
);
272 if(hc
->xhc_maxslots
== 0){
273 KPRINTF(1000, ("MaxSlots count is 0, failing!\n"));
277 KPRINTF(1000, ("MaxSlots %lx\n",hc
->xhc_maxslots
));
279 KPRINTF(1000, ("MaxIntrs %lx\n",XHCV_MaxIntrs(capreg_readl(XHCI_HCSPARAMS1
))));
281 /* 64 byte or 32 byte context data structures? */
282 if(capreg_readl(XHCI_HCCPARAMS
) & XHCF_CSZ
) {
283 hc
->xhc_contextsize64
=TRUE
;
286 /* xHCI Extended Capabilities, search for USB Legacy Support */
287 extcap
= xhciSearchExtCap(hc
, XHCI_EXT_CAPS_LEGACY
, 0);
290 temp
= READMEM32_LE(extcap
);
291 if( (temp
& XHCF_BIOSOWNED
) ){
292 KPRINTF(1000, ("controller owned by BIOS\n"));
294 /* Spec says "no more than a second", we give it a little more */
297 WRITEMEM32_LE(extcap
, (temp
| XHCF_OSOWNED
) );
299 temp
= READMEM32_LE(extcap
);
300 if( !(temp
& XHCF_BIOSOWNED
) ) {
301 KPRINTF(1000, ("BIOS gave up on XHCI. Pwned!\n"));
308 KPRINTF(1000, ("BIOS didn't release XHCI. Forcing and praying...\n"));
309 WRITEMEM32_LE(extcap
, (temp
& ~XHCF_BIOSOWNED
) );
314 /* XHCI spec says that there is at least one "Supported Protocol" capability, fail if none is found as this is used for port logic */
315 extcap
= xhciSearchExtCap(hc
, XHCI_EXT_CAPS_PROTOCOL
, 0);
317 KPRINTF(1000, ("Supported Protocol found!\n"));
318 xhciParseSupProtocol(hc
, extcap
);
320 /* Parse rest, if any...*/
322 extcap
= xhciSearchExtCap(hc
, XHCI_EXT_CAPS_PROTOCOL
, extcap
);
324 KPRINTF(1000, ("More Supported Protocols found!\n"));
325 xhciParseSupProtocol(hc
, extcap
);
329 KPRINTF(1000, ("No Supported Protocol found, failing!\n"));
334 If no USB2.0 ports were found but max port count is greater than USB3.0 count assume the overhead to be USB2.0
336 if( (hc
->xhc_NumPorts
< (hc
->xhc_NumPorts20
+ hc
->xhc_NumPorts30
)) ) {
337 KPRINTF(1000, ("Too many ports in Supported Protocol!\n"));
339 }else if ( (hc
->xhc_NumPorts
> (hc
->xhc_NumPorts20
+ hc
->xhc_NumPorts30
)) ) {
340 hc
->xhc_NumPorts20
= (hc
->xhc_NumPorts
- hc
->xhc_NumPorts30
);
343 KPRINTF(1000, ("Number of USB2.0 ports %ld\n", hc
->xhc_NumPorts20
));
344 KPRINTF(1000, ("Number of USB3.0 ports %ld\n", hc
->xhc_NumPorts30
));
347 if(xhciResetHC(hc
)) {
349 // for(cnt = 1; cnt <=hc->xhc_NumPorts; cnt++) {
350 // temp = opreg_readl(XHCI_PORTSC(cnt));
351 // KPRINTF(1000, ("Attached device's speed on port #%d is %d (PORTSC %lx)\n",cnt, XHCV_PS_SPEED(temp), temp ));
354 hc
->hc_PCIMemSize
= 1024; //Arbitrary number
356 /* CHECKME: Removed this memory allocation as it was not used in any way (at least for now) */
357 // memptr = HIDD_PCIDriver_AllocPCIMem(hc->hc_PCIDriverObject, hc->hc_PCIMemSize);
358 // hc->hc_PCIMem = (APTR) memptr;
359 hc
->hc_PCIMem
= NULL
;
363 // PhysicalAddress - VirtualAdjust = VirtualAddress
364 // VirtualAddress + VirtualAdjust = PhysicalAddress
365 // hc->hc_PCIVirtualAdjust = pciGetPhysical(hc, memptr) - (APTR)memptr;
366 // KPRINTF(10, ("VirtualAdjust 0x%08lx\n", hc->hc_PCIVirtualAdjust));
368 hc
->hc_CompleteInt
.is_Node
.ln_Type
= NT_INTERRUPT
;
369 hc
->hc_CompleteInt
.is_Node
.ln_Name
= "XHCI CompleteInt";
370 hc
->hc_CompleteInt
.is_Node
.ln_Pri
= 0;
371 hc
->hc_CompleteInt
.is_Data
= hc
;
372 hc
->hc_CompleteInt
.is_Code
= (VOID_FUNC
)xhciCompleteInt
;
375 hc
->hc_ResetInt
.is_Code
= (VOID_FUNC
)xhciResetHandler
;
376 hc
->hc_ResetInt
.is_Data
= hc
;
377 AddResetCallback(&hc
->hc_ResetInt
);
379 // add interrupt handler
380 hc
->hc_PCIIntHandler
.is_Node
.ln_Name
= "XHCI PCI (pciusb.device)";
381 hc
->hc_PCIIntHandler
.is_Node
.ln_Pri
= 5;
382 hc
->hc_PCIIntHandler
.is_Node
.ln_Type
= NT_INTERRUPT
;
383 hc
->hc_PCIIntHandler
.is_Code
= (VOID_FUNC
)xhciIntCode
;
384 hc
->hc_PCIIntHandler
.is_Data
= hc
;
385 PCIXAddInterrupt(hc
, &hc
->hc_PCIIntHandler
);
387 /* Clears (RW1C) Host System Error(HSE), Event Interrupt(EINT), Port Change Detect(PCD) and Save/Restore Error(SRE) */
388 temp
= opreg_readl(XHCI_USBSTS
);
389 opreg_writel(XHCI_USBSTS
, temp
);
391 /* After reset all notifications should be automatically disabled but ensure anyway */
392 opreg_writel(XHCI_DNCTRL
, 0);
394 /* Program the Max Device Slots Enabled (MaxSlotsEn) field */
396 Max Device Slots Enabled (MaxSlotsEn) – RW. Default = ‘0’. This field specifies the maximum
397 number of enabled Device Slots. Valid values are in the range of 0 to MaxSlots. Enabled Devices
398 Slots are allocated contiguously. e.g. A value of 16 specifies that Device Slots 1 to 16 are active.
399 A value of ‘0’ disables all Device Slots. A disabled Device Slot shall not respond to Doorbell
401 This field shall not be modified by software if the xHC is running (Run/Stop (R/S) = ‘1’).
403 opreg_writel(XHCI_CONFIG
, ((opreg_readl(XHCI_CONFIG
) & ~XHCM_CONFIG_MaxSlotsEn
) | hc
->xhc_maxslots
));
406 Device Context Base Address Array 2048, PAGESIZE, 64
408 hc
->xhc_dcbaa
= AllocVecAligned( ((hc
->xhc_maxslots
+ 1)*sizeof(UQUAD
)), 64, hc
->xhc_pagesize
);
409 if( !(hc
->xhc_dcbaa
) ){
410 KPRINTF(1000, ("Unable to allocate device context base array, failing!\n"));
414 if(hc
->xhc_scratchpads
) {
417 Scratchpad array is 64 byte aligned and can not cross page boundary
418 Scratchpad Buffer Array 248, PAGESIZE, 64
420 hc
->xhc_scratchpadarray
= AllocVecAligned( (hc
->xhc_scratchpads
*sizeof(UQUAD
) ), 64, hc
->xhc_pagesize
);
421 if( !(hc
->xhc_scratchpadarray
) ){
422 FreeVecAligned(hc
->xhc_dcbaa
);
423 KPRINTF(1000, ("Unable to allocate scratchpad buffer array, failing!\n"));
427 KPRINTF(1000, ("Allocated scratchpad buffer array at %p\n", hc
->xhc_scratchpadarray
));
429 for(temp
= 0; temp
<hc
->xhc_scratchpads
; temp
++){
432 A Scratchpad Buffer is a PAGESIZE block of system memory located on a PAGESIZE boundary
434 memptr
= AllocVecAligned(hc
->xhc_pagesize
, hc
->xhc_pagesize
, hc
->xhc_pagesize
);
436 //hc->xhc_scratchpadarray[temp] = (UQUAD) (0xDEADBEEF00000000 | (UQUAD) memptr);
437 hc
->xhc_scratchpadarray
[temp
] = (UQUAD
) memptr
;
438 /* CHECKME: Not really sure if the 32(or 64) bit address is stored correctly in the QUAD pointer list */
439 KPRINTF(1000, ("hc->xhc_scratchpadarray[%d] = %0lx:%0lx\n", temp
, (ULONG
) ((UQUAD
)(hc
->xhc_scratchpadarray
[temp
])>>32), (ULONG
) hc
->xhc_scratchpadarray
[temp
]));
441 for(temp
= 0; temp
<hc
->xhc_scratchpads
; temp
++){
442 if(hc
->xhc_scratchpadarray
[temp
]){
443 FreeVecAligned( (APTR
) hc
->xhc_scratchpadarray
[temp
] );
452 Host controller does not use scratchpads (This is the case OnMyHW™)
454 hc
->xhc_scratchpadarray
= NULL
;
458 KPRINTF(1000, ("Device context base array at %p\n", hc
->xhc_dcbaa
));
460 opreg_writeq(XHCI_DCBAAP
, (UQUAD
)hc
->xhc_dcbaa
);
462 /* FIXME: Allocate device context data structures and fill rest of the DCBAA array*/
464 hc
->xhc_dcbaa
[0] = (UQUAD
) hc
->xhc_scratchpadarray
;
466 /* Define the Command Ring Dequeue Pointer by programming the Command Ring Control Register */
468 /* Set Run/Stop(R/S), Interrupter Enable(INTE) and Host System Error Enable(HSEE) */
469 // opreg_writel(XHCI_USBCMD, (XHCF_CMD_RS | XHCF_CMD_INTE | XHCF_CMD_HSEE) );
471 KPRINTF(1000, ("xhciInit returns TRUE...\n"));
477 KPRINTF(1000, ("xhciInit returns FALSE...\n"));
481 void xhciFree(struct PCIController
*hc
, struct PCIUnit
*hu
) {
483 hc
= (struct PCIController
*) hu
->hu_Controllers
.lh_Head
;
484 while(hc
->hc_Node
.ln_Succ
)
486 switch(hc
->hc_HCIType
)
490 KPRINTF(1000, ("Shutting down XHCI %08lx\n", hc
));
494 KPRINTF(1000, ("Shutting down XHCI done.\n"));
499 hc
= (struct PCIController
*) hc
->hc_Node
.ln_Succ
;
503 void xhciParseSupProtocol(struct PCIController
*hc
, IPTR extcap
) {
507 temp1
= READMEM32_LE(extcap
);
508 KPRINTF(1000, ("Version %l.%l\n", XHCV_SPFD_RMAJOR(temp1
), XHCV_SPFD_RMINOR(temp1
) ));
510 temp2
= READMEM32_LE(extcap
+ XHCI_SPPORT
);
511 // KPRINTF(1000, ("CPO %ld\n", XHCV_SPPORT_CPO(temp2) ));
512 // KPRINTF(1000, ("CPCNT %ld\n", XHCV_SPPORT_CPCNT(temp2) ));
513 // KPRINTF(1000, ("PD %ld\n", XHCV_SPPORT_PD(temp2) ));
514 // KPRINTF(1000, ("PSIC %ld\n", XHCV_SPPORT_PSIC(temp2) ));
518 -We might not get at all "USB2 Supported Protocol", in that case make a wild assumption on # USB2.0 ports
519 -Check if the name string is "USB " (=0x20425355)
520 -Map USB specifications to their respective ports (USB2.0/USB3.0)
523 if(XHCV_SPFD_RMAJOR(temp1
) == 2) {
524 hc
->xhc_NumPorts20
= ((XHCV_SPPORT_CPCNT(temp2
) - XHCV_SPPORT_CPO(temp2
) + 1));
526 if(XHCV_SPFD_RMAJOR(temp1
) == 3) {
527 hc
->xhc_NumPorts30
= ((XHCV_SPPORT_CPCNT(temp2
) - XHCV_SPPORT_CPO(temp2
) + 1));