diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c index 09552e602..f4aa69518 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.c @@ -941,35 +941,83 @@ if ( ( rc = xhci_writeq ( xhci, ( cmds_phy | XHCI_CRCR_RCS ), static int xhci_event_alloc ( struct xhci_host *xhci ) { unsigned int count; size_t len; + uintptr_t evts_addr, evts_phy, eseg_addr, eseg_phy; int rc; /* Allocate event ring */ + len = sizeof(*xhci->evts); + rc = naive_mmap(&evts_addr, &evts_phy, len, false); + + if(rc != 0){ + USB_LOG_ERR("XHCI %s could not allocate Event RING\n", xhci->name ); + rc = -ENOMEM; + goto err_alloc_trb; + } + + +#if 0 xhci->evts = usb_align(XHCI_RING_SIZE, sizeof(*xhci->evts)); /* event ring */ if ( ! xhci->evts ) { rc = -ENOMEM; goto err_alloc_trb; } +#endif + xhci->evts_addr = evts_addr; + xhci->evts_phy = evts_phy; + xhci->evts = (struct xhci_ring *)evts_addr; memset(xhci->evts, 0U, sizeof(*xhci->evts)); /* Allocate event ring segment table */ + + len = sizeof(*xhci->eseg); + rc = naive_mmap(&eseg_addr, &eseg_phy, len, false); + if(rc != 0){ + USB_LOG_ERR("XHCI %s could not allocate Event Segment\n", xhci->name ); + rc = -ENOMEM; + goto err_alloc_segment; + } + +#if 0 xhci->eseg = usb_align(XHCI_ALIGMENT, sizeof(*xhci->eseg)); /* event segment */ if ( ! xhci->eseg ) { rc = -ENOMEM; goto err_alloc_segment; } +#endif + + xhci->eseg_addr = eseg_addr; + xhci->eseg_phy = eseg_phy; + + xhci->eseg = (struct xhci_er_seg *)eseg_addr; + memset(xhci->eseg, 0U, sizeof(*xhci->eseg)); xhci->eseg->base = CPU_TO_LE64 ( ( (uintptr_t)xhci->evts ) ); xhci->eseg->count = XHCI_RING_ITEMS; /* items of event ring TRB */ /* Program event ring registers */ - writel ( 1, xhci->run + XHCI_RUN_ERSTSZ ( 0 ) ); /* bit[15:0] event ring segment table size */ +// writel ( 1, xhci->run + XHCI_RUN_ERSTSZ ( 0 ) ); /* bit[15:0] event ring segment table size */ + + writel ( 1, xhci->run_addr + XHCI_RUN_ERSTSZ ( 0 ) ); /* bit[15:0] event ring segment table size */ + +#if 0 if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->evts ), xhci->run + XHCI_RUN_ERDP ( 0 ) ) ) != 0 ) /* bit[63:4] event ring dequeue pointer */ goto err_writeq_erdp; +#endif + if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->evts_phy ), + xhci->run_addr + XHCI_RUN_ERDP ( 0 ) ) ) != 0 ) /* bit[63:4] event ring dequeue pointer */ + goto err_writeq_erdp; + +#if 0 if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->eseg ), xhci->run + XHCI_RUN_ERSTBA ( 0 ) ) ) != 0 ) /* bit[63:6] event ring segment table base addr */ goto err_writeq_erstba; +#endif + + if ( ( rc = xhci_writeq ( xhci, (uintptr_t)( xhci->eseg_phy ), + xhci->run_addr + XHCI_RUN_ERSTBA ( 0 ) ) ) != 0 ) /* bit[63:6] event ring segment table base addr */ + goto err_writeq_erstba; xhci->evts->cs = 1; /* cycle state = 1 */ USB_LOG_DBG("XHCI %s event ring [%08lx,%08lx) table [%08lx,%08lx)\n", @@ -980,13 +1028,13 @@ static int xhci_event_alloc ( struct xhci_host *xhci ) { sizeof ( xhci->eseg[0] ) ) ); return 0; - xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERSTBA ( 0 ) ); + xhci_writeq ( xhci, 0, xhci->run_addr + XHCI_RUN_ERSTBA ( 0 ) ); err_writeq_erstba: - xhci_writeq ( xhci, 0, xhci->run + XHCI_RUN_ERDP ( 0 ) ); + xhci_writeq ( xhci, 0, xhci->run_addr + XHCI_RUN_ERDP ( 0 ) ); err_writeq_erdp: - usb_free ( xhci->eseg ); +// usb_free ( xhci->eseg ); err_alloc_segment: - usb_free ( xhci->evts ); +// usb_free ( xhci->evts ); err_alloc_trb: return rc; } diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.h b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.h index 93b36c792..4105f7b83 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.h +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/xhci.h @@ -900,7 +900,19 @@ struct xhci_host { uintptr_t cmds_phy; /** Event ring */ struct xhci_ring *evts; + /* + * evts_addr holds the virtual address of the event ring, meanwhile cvts_phy keeps the value that should be writen to Event Ring + * Dequeue Pointer Register (XHCI_RUN_ERDP). + */ + uintptr_t evts_addr; + uintptr_t evts_phy; struct xhci_er_seg *eseg; + /* + * eseg_addr holds the virtual address of the event segment, meanwhile cseg_phy keeps the value that should be writen to Event Ring + * Segment Table Size Register (XHCI_RUN_ERSTBA). + */ + uintptr_t eseg_addr; + uintptr_t eseg_phy; struct xhci_endpoint *cur_cmd_pipe; };