From 77bed3c28f9ae4abd3e4e9dab4fa57e0bd26ba04 Mon Sep 17 00:00:00 2001 From: songyanguang <345810377@qq.com> Date: Mon, 5 Aug 2024 20:47:51 +0800 Subject: [PATCH] Modify USB Device Initialization in xHCI code and Command TRB code to apply to XiZi AIOT. --- .../usb/components/port/xhci/usb_hc_xhci.c | 29 ++++++++--- .../drivers/usb/components/port/xhci/xhci.c | 50 ++++++++++++++++--- .../drivers/usb/components/port/xhci/xhci.h | 2 + 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/usb_hc_xhci.c b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/usb_hc_xhci.c index 88d74882e..57fea8451 100644 --- a/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/usb_hc_xhci.c +++ b/Ubiquitous/XiZi_AIoT/services/drivers/usb/components/port/xhci/usb_hc_xhci.c @@ -38,6 +38,10 @@ Modification: rewrite xhci functions to dock with USB core layer, so that the US 2. Date: 2024-06-24 Author: AIIT XUOS Lab Modification: rewrite xhci function usbh_get_port_speed to dock with USB core layer. + +3. Date: 2024-08-05 +Author: AIIT XUOS Lab +Modification: Modify USB Device Initialization in xHCI code to apply to XiZi AIOT. *************************************************/ #include "usb_hc_xhci.h" #include "usbh_hub.h" @@ -686,7 +690,7 @@ int xhci_usbh_roothub_control(struct usbh_bus *usb, struct usb_setup_packet *set return -EPIPE; } - portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); + portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) ); switch (setup->wValue) { case HUB_PORT_FEATURE_ENABLE: @@ -712,7 +716,7 @@ int xhci_usbh_roothub_control(struct usbh_bus *usb, struct usb_setup_packet *set uint32_t pclear = portsc & XHCI_PORTSC_RW_MASK; /* clear port status */ - writel(pclear, xhci->op + XHCI_OP_PORTSC ( port )); + writel(pclear, xhci->op_addr + XHCI_OP_PORTSC ( port )); break; case HUB_REQUEST_SET_FEATURE: @@ -740,7 +744,7 @@ int xhci_usbh_roothub_control(struct usbh_bus *usb, struct usb_setup_packet *set return -EPIPE; } - portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); + portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) ); status = 0; if (portsc & XHCI_PORTSC_CSC) @@ -750,7 +754,7 @@ int xhci_usbh_roothub_control(struct usbh_bus *usb, struct usb_setup_packet *set /* always clear all the status change bits */ uint32_t temp = portsc & ( XHCI_PORTSC_PRESERVE | XHCI_PORTSC_CHANGE ); - writel ( temp, xhci->op + XHCI_OP_PORTSC ( port ) ); + writel ( temp, xhci->op_addr + XHCI_OP_PORTSC ( port ) ); } if (portsc & XHCI_PORTSC_PEC) @@ -816,12 +820,23 @@ int xhci_usbh_roothub_control(struct usbh_bus *usb, struct usb_setup_packet *set return 0; } -// TODO: uint8_t xhci_usbh_get_port_speed(struct usbh_hub *hub, const uint8_t port) { - return 0; -} + USB_ASSERT(hub); + struct usbh_bus *usb = hub->usb; + USB_ASSERT(usb && usb->priv); + struct xhci_host *xhci = usb->priv; + if (hub->is_roothub) { + return xhci_root_speed(xhci, port); + } else { + struct usbh_hubport *roothub_port = usbh_root_hub_port(&(hub->child[port])); + /* TODO, hanlde TT for low-speed device on high-speed hub, but it doesn't matter, since + we haven't well handle hub yet */ + USB_ASSERT(roothub_port); + return xhci_root_speed(xhci, roothub_port->port); + } +} int xhci_usbh_ep_pipe_reconfigure(struct usbh_bus *usb, usbh_pipe_t pipe, uint8_t dev_addr, uint8_t mtu, uint8_t speed){ struct xhci_endpoint *ppipe = (struct xhci_endpoint *)pipe; 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 6f803b3a0..81d9c9cac 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 @@ -29,6 +29,10 @@ History: 1. Date: 2024-06-18 Author: AIIT XUOS Lab Modification: replant and redefine some xhci data structure, so that the cherryUSB can adapt to XiZi AIOT. + +2. Date: 2024-08-05 +Author: AIIT XUOS Lab +Modification: Modify Command TRB code to apply to XiZi AIOT. *************************************************/ #include "usbh_core.h" @@ -1265,7 +1269,7 @@ void xhci_remove ( struct xhci_host *xhci ) { * @ret rc Return status code */ int xhci_port_enable(struct xhci_host *xhci, uint32_t port) { - uint32_t portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); + uint32_t portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) ); /* double check if connected */ if (!(portsc & XHCI_PORTSC_CCS)) { @@ -1281,7 +1285,7 @@ int xhci_port_enable(struct xhci_host *xhci, uint32_t port) { case XHCI_PORTSC_PLS_POLLING: /* A USB2 port - perform device reset */ xhci_dump_port_status(port, portsc); - writel ((portsc | XHCI_PORTSC_PR), (xhci->op + XHCI_OP_PORTSC ( port ))); /* reset port */ + writel ((portsc | XHCI_PORTSC_PR), (xhci->op_addr + XHCI_OP_PORTSC ( port ))); /* reset port */ break; default: USB_LOG_ERR("PLS: %d \r\n", (portsc & XHCI_PORTSC_PLS_MASK)); @@ -1291,7 +1295,7 @@ int xhci_port_enable(struct xhci_host *xhci, uint32_t port) { /* Wait for device to complete reset and be enabled */ uint32_t end = 1000U, start = 0U; for (;;) { - portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); + portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) ); if (!(portsc & XHCI_PORTSC_CCS)) { /* USB 2.0 port would be disconnected after reset */ USB_LOG_INFO("USB 2.0 port disconnected during reset, need rescan \r\n"); @@ -1455,7 +1459,7 @@ static int xhci_port_psiv ( struct xhci_host *xhci, unsigned int port, return -ENOTSUP; /* Get protocol speed ID count */ - ports = readl ( xhci->cap + supported + XHCI_SUPPORTED_PORTS ); + ports = readl ( xhci->cap_addr + supported + XHCI_SUPPORTED_PORTS ); psic = XHCI_SUPPORTED_PORTS_PSIC ( ports ); /* Use the default mappings if applicable */ @@ -1474,7 +1478,7 @@ static int xhci_port_psiv ( struct xhci_host *xhci, unsigned int port, /* Iterate over PSI dwords looking for a match */ for ( i = 0 ; i < psic ; i++ ) { - psi = readl ( xhci->cap + supported + XHCI_SUPPORTED_PSI ( i )); + psi = readl ( xhci->cap_addr + supported + XHCI_SUPPORTED_PSI ( i )); mantissa = XHCI_SUPPORTED_PSI_MANTISSA ( psi ); exponent = XHCI_SUPPORTED_PSI_EXPONENT ( psi ); if ( xhci_speed_to_psi(speed) == XCHI_PSI ( mantissa, exponent ) ) { @@ -1505,7 +1509,7 @@ uint32_t xhci_root_speed ( struct xhci_host *xhci, uint8_t port ) { unsigned int protocol = xhci_port_protocol(xhci, port); /* Read port status */ - portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); + portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) ); USB_LOG_DBG("XHCI %s-%d status is 0x%08x, protocol 0x%x\n", xhci->name, port, portsc, protocol ); ccs = ( portsc & XHCI_PORTSC_CCS ); @@ -1616,7 +1620,7 @@ int xhci_event_wait(struct xhci_host *xhci, static inline void xhci_doorbell ( struct xhci_host *xhci, uint32_t slotid, uint32_t value ) { DSB(); BARRIER(); - writel ( value, xhci->db + slotid * XHCI_REG_DB_SIZE ); /* bit[7:0] db target, is ep_id */ + writel ( value, xhci->db_addr + slotid * XHCI_REG_DB_SIZE ); /* bit[7:0] db target, is ep_id */ } /** @@ -1793,14 +1797,25 @@ static int xhci_context ( struct xhci_host *xhci, struct xhci_slot *slot, size_t len; void *input; int rc; + uintptr_t input_vir; + uintptr_t input_phy; /* Allocate an input context */ len = xhci_input_context_offset ( xhci, XHCI_CTX_END ); +#if 0 input = usb_align(xhci_align ( len ), len); if ( ! input ) { rc = -ENOMEM; goto err_alloc; } +#endif + rc = naive_mmap(&input_vir, &input_phy, len, false); + if(rc != 0){ + USB_LOG_ERR("XHCI %s could not allocate xhci context\n", xhci->name ); + rc = -ENOMEM; + goto err_alloc; + } + input = input_vir; memset ( input, 0, len ); /* Populate input context */ @@ -1809,7 +1824,10 @@ static int xhci_context ( struct xhci_host *xhci, struct xhci_slot *slot, /* Construct command */ memset ( context, 0, sizeof ( *context ) ); context->type = type; +#if 0 context->input = CPU_TO_LE64 ( ( (uintptr_t)input ) ); +#endif + context->input = CPU_TO_LE64 ( ( (uintptr_t)input_phy ) ); context->slot = slot->id; /* Issue command and wait for completion */ @@ -1983,7 +2001,7 @@ static int xhci_port_slot_type ( struct xhci_host *xhci, unsigned int port ) { return -ENOTSUP; /* Get slot type */ - slot = readl ( xhci->cap + supported + XHCI_SUPPORTED_SLOT ); + slot = readl ( xhci->cap_addr + supported + XHCI_SUPPORTED_SLOT ); type = XHCI_SUPPORTED_SLOT_TYPE ( slot ); return type; @@ -2006,6 +2024,8 @@ int xhci_device_open ( struct xhci_host *xhci, struct xhci_endpoint *ep, int *sl int rc; int id; size_t len; + uintptr_t context_vir; + uintptr_t context_phy; /* Determine applicable slot type */ type = xhci_port_slot_type ( xhci, hport->port ); @@ -2043,16 +2063,30 @@ int xhci_device_open ( struct xhci_host *xhci, struct xhci_endpoint *ep, int *sl /* Allocate a device context */ len = xhci_device_context_offset ( xhci, XHCI_CTX_END ); +#if 0 slot->context = usb_align(xhci_align ( len ), len); if ( ! slot->context ) { rc = -ENOMEM; goto err_alloc_context; } +#endif + rc = naive_mmap(&context_addr, &context_phy, len, false); + if(rc != 0){ + USB_LOG_ERR("XHCI %s could not allocate xhci device context\n", xhci->name ); + rc = -ENOMEM; + goto err_alloc; + } + slot->context_vir = context_vir; + slot->context_phy = context_phy; + slot->context = (struct xhci_slot_context *)context_vir; memset ( slot->context, 0, len ); /* Set device context base address */ USB_ASSERT ( xhci->dcbaa.context[id] == 0 ); +#if 0 xhci->dcbaa.context[id] = CPU_TO_LE64 ( ( (uintptr_t)slot->context ) ); +#endif + xhci->dcbaa.context[id] = CPU_TO_LE64 ( ( (uintptr_t)slot->context_phy ) ); USB_LOG_DBG("XHCI %s slot %d device context [%08lx,%08lx)\n", xhci->name, slot->id, ( slot->context ), 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 4105f7b83..400ceef0d 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 @@ -799,6 +799,8 @@ struct xhci_slot { unsigned int id; /** Slot context */ struct xhci_slot_context *context; + uintptr_t context_vir; + uintptr_t context_phy; /** Route string */ unsigned int route;