Modify USB Device Initialization in xHCI code and Command TRB code to apply to XiZi AIOT.

This commit is contained in:
songyanguang 2024-08-05 20:47:51 +08:00
parent 2eba5a8071
commit 77bed3c28f
3 changed files with 66 additions and 15 deletions

View File

@ -38,6 +38,10 @@ Modification: rewrite xhci functions to dock with USB core layer, so that the US
2. Date: 2024-06-24 2. Date: 2024-06-24
Author: AIIT XUOS Lab Author: AIIT XUOS Lab
Modification: rewrite xhci function usbh_get_port_speed to dock with USB core layer. 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 "usb_hc_xhci.h"
#include "usbh_hub.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; return -EPIPE;
} }
portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) );
switch (setup->wValue) switch (setup->wValue)
{ {
case HUB_PORT_FEATURE_ENABLE: 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; uint32_t pclear = portsc & XHCI_PORTSC_RW_MASK;
/* clear port status */ /* clear port status */
writel(pclear, xhci->op + XHCI_OP_PORTSC ( port )); writel(pclear, xhci->op_addr + XHCI_OP_PORTSC ( port ));
break; break;
case HUB_REQUEST_SET_FEATURE: 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; return -EPIPE;
} }
portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) );
status = 0; status = 0;
if (portsc & XHCI_PORTSC_CSC) 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 */ /* always clear all the status change bits */
uint32_t temp = portsc & ( XHCI_PORTSC_PRESERVE | XHCI_PORTSC_CHANGE ); 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) 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; return 0;
} }
// TODO:
uint8_t xhci_usbh_get_port_speed(struct usbh_hub *hub, const uint8_t port) 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){ 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; struct xhci_endpoint *ppipe = (struct xhci_endpoint *)pipe;

View File

@ -29,6 +29,10 @@ History:
1. Date: 2024-06-18 1. Date: 2024-06-18
Author: AIIT XUOS Lab Author: AIIT XUOS Lab
Modification: replant and redefine some xhci data structure, so that the cherryUSB can adapt to XiZi AIOT. 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" #include "usbh_core.h"
@ -1265,7 +1269,7 @@ void xhci_remove ( struct xhci_host *xhci ) {
* @ret rc Return status code * @ret rc Return status code
*/ */
int xhci_port_enable(struct xhci_host *xhci, uint32_t port) { 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 */ /* double check if connected */
if (!(portsc & XHCI_PORTSC_CCS)) { 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: case XHCI_PORTSC_PLS_POLLING:
/* A USB2 port - perform device reset */ /* A USB2 port - perform device reset */
xhci_dump_port_status(port, portsc); 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; break;
default: default:
USB_LOG_ERR("PLS: %d \r\n", (portsc & XHCI_PORTSC_PLS_MASK)); 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 */ /* Wait for device to complete reset and be enabled */
uint32_t end = 1000U, start = 0U; uint32_t end = 1000U, start = 0U;
for (;;) { for (;;) {
portsc = readl ( xhci->op + XHCI_OP_PORTSC ( port ) ); portsc = readl ( xhci->op_addr + XHCI_OP_PORTSC ( port ) );
if (!(portsc & XHCI_PORTSC_CCS)) { if (!(portsc & XHCI_PORTSC_CCS)) {
/* USB 2.0 port would be disconnected after reset */ /* USB 2.0 port would be disconnected after reset */
USB_LOG_INFO("USB 2.0 port disconnected during reset, need rescan \r\n"); 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; return -ENOTSUP;
/* Get protocol speed ID count */ /* 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 ); psic = XHCI_SUPPORTED_PORTS_PSIC ( ports );
/* Use the default mappings if applicable */ /* 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 */ /* Iterate over PSI dwords looking for a match */
for ( i = 0 ; i < psic ; i++ ) { 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 ); mantissa = XHCI_SUPPORTED_PSI_MANTISSA ( psi );
exponent = XHCI_SUPPORTED_PSI_EXPONENT ( psi ); exponent = XHCI_SUPPORTED_PSI_EXPONENT ( psi );
if ( xhci_speed_to_psi(speed) == XCHI_PSI ( mantissa, exponent ) ) { 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); unsigned int protocol = xhci_port_protocol(xhci, port);
/* Read port status */ /* 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", USB_LOG_DBG("XHCI %s-%d status is 0x%08x, protocol 0x%x\n",
xhci->name, port, portsc, protocol ); xhci->name, port, portsc, protocol );
ccs = ( portsc & XHCI_PORTSC_CCS ); 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 ) { static inline void xhci_doorbell ( struct xhci_host *xhci, uint32_t slotid, uint32_t value ) {
DSB(); DSB();
BARRIER(); 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; size_t len;
void *input; void *input;
int rc; int rc;
uintptr_t input_vir;
uintptr_t input_phy;
/* Allocate an input context */ /* Allocate an input context */
len = xhci_input_context_offset ( xhci, XHCI_CTX_END ); len = xhci_input_context_offset ( xhci, XHCI_CTX_END );
#if 0
input = usb_align(xhci_align ( len ), len); input = usb_align(xhci_align ( len ), len);
if ( ! input ) { if ( ! input ) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_alloc; 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 ); memset ( input, 0, len );
/* Populate input context */ /* Populate input context */
@ -1809,7 +1824,10 @@ static int xhci_context ( struct xhci_host *xhci, struct xhci_slot *slot,
/* Construct command */ /* Construct command */
memset ( context, 0, sizeof ( *context ) ); memset ( context, 0, sizeof ( *context ) );
context->type = type; context->type = type;
#if 0
context->input = CPU_TO_LE64 ( ( (uintptr_t)input ) ); context->input = CPU_TO_LE64 ( ( (uintptr_t)input ) );
#endif
context->input = CPU_TO_LE64 ( ( (uintptr_t)input_phy ) );
context->slot = slot->id; context->slot = slot->id;
/* Issue command and wait for completion */ /* 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; return -ENOTSUP;
/* Get slot type */ /* 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 ); type = XHCI_SUPPORTED_SLOT_TYPE ( slot );
return type; return type;
@ -2006,6 +2024,8 @@ int xhci_device_open ( struct xhci_host *xhci, struct xhci_endpoint *ep, int *sl
int rc; int rc;
int id; int id;
size_t len; size_t len;
uintptr_t context_vir;
uintptr_t context_phy;
/* Determine applicable slot type */ /* Determine applicable slot type */
type = xhci_port_slot_type ( xhci, hport->port ); 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 */ /* Allocate a device context */
len = xhci_device_context_offset ( xhci, XHCI_CTX_END ); len = xhci_device_context_offset ( xhci, XHCI_CTX_END );
#if 0
slot->context = usb_align(xhci_align ( len ), len); slot->context = usb_align(xhci_align ( len ), len);
if ( ! slot->context ) { if ( ! slot->context ) {
rc = -ENOMEM; rc = -ENOMEM;
goto err_alloc_context; 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 ); memset ( slot->context, 0, len );
/* Set device context base address */ /* Set device context base address */
USB_ASSERT ( xhci->dcbaa.context[id] == 0 ); USB_ASSERT ( xhci->dcbaa.context[id] == 0 );
#if 0
xhci->dcbaa.context[id] = CPU_TO_LE64 ( ( (uintptr_t)slot->context ) ); 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", USB_LOG_DBG("XHCI %s slot %d device context [%08lx,%08lx)\n",
xhci->name, slot->id, ( slot->context ), xhci->name, slot->id, ( slot->context ),

View File

@ -799,6 +799,8 @@ struct xhci_slot {
unsigned int id; unsigned int id;
/** Slot context */ /** Slot context */
struct xhci_slot_context *context; struct xhci_slot_context *context;
uintptr_t context_vir;
uintptr_t context_phy;
/** Route string */ /** Route string */
unsigned int route; unsigned int route;