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
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;

View File

@ -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 ),

View File

@ -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;