summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2023-12-30 15:00:19 +0800
committersakumisu <[email protected]>2023-12-30 15:01:20 +0800
commite58a78c07020b35973d777a7cae34d5076d205c4 (patch)
tree305071ec07fb5f7df910502f9caab84efdc6b309
parent1492b8cca9ab8c014bf4a5ef38e4f2ec871bb858 (diff)
add aic & intel ehci glue, add rtems osal
-rw-r--r--osal/usb_osal_rtems.c165
-rw-r--r--port/ehci/README.md8
-rw-r--r--port/ehci/usb_glue_aic.c91
-rw-r--r--port/ehci/usb_glue_intel.c55
4 files changed, 319 insertions, 0 deletions
diff --git a/osal/usb_osal_rtems.c b/osal/usb_osal_rtems.c
new file mode 100644
index 00000000..701e4b7e
--- /dev/null
+++ b/osal/usb_osal_rtems.c
@@ -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 \ No newline at end of file
diff --git a/port/ehci/README.md b/port/ehci/README.md
index b5a87d2a..bccb2bc0 100644
--- a/port/ehci/README.md
+++ b/port/ehci/README.md
@@ -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`.
diff --git a/port/ehci/usb_glue_aic.c b/port/ehci/usb_glue_aic.c
new file mode 100644
index 00000000..dde38929
--- /dev/null
+++ b/port/ehci/usb_glue_aic.c
@@ -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);
+}
diff --git a/port/ehci/usb_glue_intel.c b/port/ehci/usb_glue_intel.c
new file mode 100644
index 00000000..b2264b15
--- /dev/null
+++ b/port/ehci/usb_glue_intel.c
@@ -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 \ No newline at end of file