forked from yystopf/xiuos
Modify USB Device Initialization in xHCI code and Command TRB code to apply to XiZi AIOT.
This commit is contained in:
parent
2eba5a8071
commit
77bed3c28f
|
@ -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;
|
||||||
|
|
|
@ -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 ),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue