add aic & intel ehci glue, add rtems osal

This commit is contained in:
sakumisu 2023-12-30 15:00:19 +08:00
parent 1492b8cca9
commit e58a78c070
4 changed files with 319 additions and 0 deletions

165
osal/usb_osal_rtems.c Normal file
View File

@ -0,0 +1,165 @@
/*
* Copyright (c) 2022, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef __rtems__
#include "usb_osal.h"
#include "usb_errno.h"
#include <rtems.h>
#define SYS_USB_MBOX_SIZE (sizeof(void *))
usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args)
{
rtems_id id = 0;
rtems_status_code res;
res = rtems_task_create(
rtems_build_name(name[0], name[1], name[2], name[3]),
prio,
stack_size,
RTEMS_PREEMPT,
0,
&id);
if (res != RTEMS_SUCCESSFUL) {
return NULL;
}
res = rtems_task_start(id, (rtems_task_entry)entry, (rtems_task_argument)args);
if (res != RTEMS_SUCCESSFUL) {
rtems_task_delete(id);
return NULL;
}
return (usb_osal_thread_t)id;
}
void usb_osal_thread_delete(usb_osal_thread_t thread)
{
rtems_task_delete(thread);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
rtems_id semaphore = 0;
rtems_status_code ret = rtems_semaphore_create(
rtems_build_name('U', 'S', 'B', 's'),
initial_count,
RTEMS_COUNTING_SEMAPHORE,
0,
&semaphore);
return semaphore;
}
void usb_osal_sem_delete(usb_osal_sem_t sem)
{
rtems_semaphore_delete(sem);
}
int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
{
rtems_status_code status;
status = rtems_semaphore_obtain(sem, RTEMS_WAIT, timeout);
return status == RTEMS_SUCCESSFUL ? 0 : -USB_ERR_TIMEOUT;
}
int usb_osal_sem_give(usb_osal_sem_t sem)
{
rtems_status_code status = rtems_semaphore_release(sem);
return (status == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
usb_osal_mutex_t usb_osal_mutex_create(void)
{
rtems_id mutex;
rtems_status_code ret = rtems_semaphore_create(
rtems_build_name('U', 'S', 'B', 'm'),
1,
RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_LOCAL,
0,
&mutex);
return mutex;
}
void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
{
rtems_semaphore_delete(mutex);
}
int usb_osal_mutex_take(usb_osal_mutex_t mutex)
{
return (rtems_semaphore_obtain(mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
int usb_osal_mutex_give(usb_osal_mutex_t mutex)
{
return (rtems_semaphore_release(mutex) == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
{
rtems_status_code ret;
rtems_id mailbox = 0;
ret = rtems_message_queue_create(
rtems_build_name('U', 'S', 'B', 'q'),
max_msgs,
SYS_USB_MBOX_SIZE,
RTEMS_DEFAULT_ATTRIBUTES,
&mailbox);
return mailbox;
}
int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
{
rtems_status_code ret;
ret = rtems_message_queue_send(mq, &addr, SYS_USB_MBOX_SIZE);
return (ret == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
{
size_t size;
rtems_status_code sc;
sc = rtems_message_queue_receive(
mq,
addr,
&size,
RTEMS_WAIT,
timeout);
return (sc == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}
uint32_t usb_osal_enter_critical_section(void)
{
rtems_interrupt_level pval;
#if RTEMS_SMP
rtems_recursive_mutex_lock(&sys_arch_lock);
#else
rtems_interrupt_disable(pval);
#endif
return pval;
}
void usb_osal_leave_critical_section(size_t flag)
{
#if RTEMS_SMP
rtems_recursive_mutex_unlock(&sys_arch_lock);
#else
rtems_interrupt_enable(flag);
#endif
}
void usb_osal_msleep(uint32_t delay)
{
rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(delay));
}
#endif

View File

@ -18,6 +18,14 @@
- Nuvoton all series
### Artinchip
- d13x, d21x
### Intel
Intel 6 Series Chipset and Intel C200 Series Chipset
## Before Use
Your should implement `usb_hc_low_level_init`.

91
port/ehci/usb_glue_aic.c Normal file
View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2022, Artinchip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <aic_core.h>
#include <aic_hal.h>
#include <hal_syscfg.h>
#include "usbh_core.h"
#include "usb_ehci_priv.h"
extern void USBH_IRQHandler(void);
void usb_hc_low_level_init(void)
{
uint32_t val;
/* set usb0 phy switch: Host/Device */
#ifdef AIC_USING_USB0_HOST
syscfg_usb_phy0_sw_host(1);
#endif
/* set phy type: UTMI/ULPI */
val = readl((volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x800));
#ifdef FPGA_BOARD_ARTINCHIP
/* fpga phy type = ULPI */
writel((val & ~0x1U), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x800));
#else
/* board phy type = UTMI */
writel((val | 0x1), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x800));
#endif
#if 0
/* Set AHB2STBUS_INSREG01
Set EHCI packet buffer IN/OUT threshold (in DWORDs)
Must increase the OUT threshold to avoid underrun. (FIFO size - 4)
*/
#ifdef FPGA_BOARD_ARTINCHIP
writel((32 | (127 << 16)), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x94));
#else
writel((32 | (32 << 16)), (volatile void *)(unsigned long)(CONFIG_USB_EHCI_HCCR_BASE+0x94));
#endif
#endif
/* enable clock */
hal_clk_enable(CONFIG_USB_EHCI_PHY_CLK);
hal_clk_enable(CONFIG_USB_EHCI_CLK);
aicos_udelay(300);
hal_reset_assert(CONFIG_USB_EHCI_PHY_RESET);
hal_reset_assert(CONFIG_USB_EHCI_RESET);
aicos_udelay(300);
hal_reset_deassert(CONFIG_USB_EHCI_PHY_RESET);
hal_reset_deassert(CONFIG_USB_EHCI_RESET);
aicos_udelay(300);
/* register interrupt callback */
aicos_request_irq(CONFIG_USB_EHCI_IRQ_NUM, (irq_handler_t)USBH_IRQHandler,
0, "usb_host_ehci", NULL);
aicos_irq_enable(CONFIG_USB_EHCI_IRQ_NUM);
}
uint8_t usbh_get_port_speed(const uint8_t port)
{
/* Defined by individual manufacturers */
uint32_t regval;
regval = EHCI_HCOR->portsc[port-1];
if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE)
return USB_SPEED_LOW;
if (regval & EHCI_PORTSC_PE)
return USB_SPEED_HIGH;
else
return USB_SPEED_FULL;
}
void usb_ehci_dcache_clean(uintptr_t addr, uint32_t len)
{
aicos_dcache_clean_range((size_t *)addr, len);
}
void usb_ehci_dcache_invalidate(uintptr_t addr, uint32_t len)
{
aicos_dcache_invalid_range((size_t *)addr, len);
}
void usb_ehci_dcache_clean_invalidate(uintptr_t addr, uint32_t len)
{
aicos_dcache_clean_invalid_range((size_t *)addr, len);
}

View File

@ -0,0 +1,55 @@
#ifdef __rtems__
#include <rtems.h>
#include <rtems/pci.h>
#include <bsp/irq.h>
#include "usbh_core.h"
uint32_t echi_base;
static int ehci_bus;
static int ehci_slot;
static int ehci_function;
static int ehci_vector;
extern void USBH_IRQHandler(void *para);
void ehci_pci_scan(int bus, int slot, int fun, int vector)
{
ehci_bus = bus;
ehci_slot = slot;
ehci_function = fun;
ehci_vector = vector;
pci_read_config_dword(bus, slot, fun, PCI_BASE_ADDRESS_0, &echi_base);
}
void usb_hc_low_level_init(void)
{
//set software own ehci
uint32_t legacy_val;
pci_write_config_dword(ehci_bus, ehci_slot, ehci_function, 0x68, 1 << 24);
pci_read_config_dword(ehci_bus, ehci_slot, ehci_function, 0x68, &legacy_val);
if ((legacy_val & 0x01010000) == 0x01000000)
printf("OS owned echi\n");
else
printf("BIOS owned echi\n");
rtems_status_code sc;
sc = rtems_interrupt_handler_install(
ehci_vector,
"USBirq",
RTEMS_INTERRUPT_SHARED,
USBH_IRQHandler,
(void *)0);
if (sc != RTEMS_SUCCESSFUL) {
printf("USB install isr falied,%s\n", rtems_status_text(sc));
return;
}
}
uint8_t usbh_get_port_speed(const uint8_t port)
{
printf("USB_SPEED_HIGH present\n");
return USB_SPEED_HIGH;
}
#endif