diff --git a/port/dwc2/usb_glue_kendryte.c b/port/dwc2/usb_glue_kendryte.c new file mode 100644 index 00000000..699a55cb --- /dev/null +++ b/port/dwc2/usb_glue_kendryte.c @@ -0,0 +1,157 @@ +/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include "usbd_core.h" +#include "usbh_core.h" + +#define DEFAULT_USB_HCLK_FREQ_MHZ 200 + +uint32_t SystemCoreClock = (DEFAULT_USB_HCLK_FREQ_MHZ * 1000 * 1000); +uintptr_t g_usb_otg0_base = (uintptr_t)0x91500000UL; +uintptr_t g_usb_otg1_base = (uintptr_t)0x91540000UL; + +static void sysctl_reset_hw_done(volatile uint32_t *reset_reg, uint8_t reset_bit, uint8_t done_bit) +{ + *reset_reg |= (1 << done_bit); /* clear done bit */ + rt_thread_mdelay(1); + + *reset_reg |= (1 << reset_bit); /* set reset bit */ + rt_thread_mdelay(1); + /* check done bit */ + while (*reset_reg & (1 << done_bit) == 0) + ; +} + +#define USB_IDPULLUP0 (1 << 4) +#define USB_DMPULLDOWN0 (1 << 8) +#define USB_DPPULLDOWN0 (1 << 9) + +#ifdef PKG_CHERRYUSB_HOST +static void usb_hc_interrupt_cb(int irq, void *arg_pv) +{ + extern void USBH_IRQHandler(uint8_t busid); + USBH_IRQHandler((uint8_t)(uintptr_t)arg_pv); +} + +void usb_hc_low_level_init(struct usbh_bus *bus) +{ + uint32_t *hs_reg; + uint32_t usb_ctl3; + + if (bus->hcd.hcd_id == 0) { + sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28); + + hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000); + usb_ctl3 = *hs_reg | USB_IDPULLUP0; + + *hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0); + + rt_iounmap(hs_reg); + + rt_hw_interrupt_install(173, usb_hc_interrupt_cb, NULL, "usbh0"); + rt_hw_interrupt_umask(173); + + } else { + sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29); + + hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000); + usb_ctl3 = *hs_reg | USB_IDPULLUP0; + + *hs_reg = usb_ctl3 | (USB_DMPULLDOWN0 | USB_DPPULLDOWN0); + + rt_iounmap(hs_reg); + + rt_hw_interrupt_install(174, usb_hc_interrupt_cb, 1, "usbh1"); + rt_hw_interrupt_umask(174); + } +} + +void usb_hc_low_level_deinit(struct usbh_bus *bus) +{ + if (bus->hcd.hcd_id == 0) { + rt_hw_interrupt_mask(173); + } else { + rt_hw_interrupt_mask(174); + } +} + +uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) +{ + return 0; +} +#endif + +#ifdef PKG_CHERRYUSB_DEVICE +static void usb_dc_interrupt_cb(int irq, void *arg_pv) +{ + extern void USBD_IRQHandler(uint8_t busid); + USBD_IRQHandler(0); +} + +#ifdef CHERRYUSB_DEVICE_USING_USB0 +void usb_dc_low_level_init(void) +{ + sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 0, 28); + uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x7C), 0x1000); + *hs_reg = 0x37; + rt_iounmap(hs_reg); + + rt_hw_interrupt_install(173, usb_dc_interrupt_cb, NULL, "usbd"); + rt_hw_interrupt_umask(173); +} + +void usb_dc_low_level_deinit(void) +{ + rt_hw_interrupt_mask(173); +} +#else +void usb_dc_low_level_init(void) +{ + sysctl_reset_hw_done((volatile uint32_t *)0x9110103c, 1, 29); + uint32_t *hs_reg = (uint32_t *)rt_ioremap((void *)(0x91585000 + 0x9C), 0x1000); + *hs_reg = 0x37; + rt_iounmap(hs_reg); + + rt_hw_interrupt_install(174, usb_dc_interrupt_cb, NULL, "usbd"); + rt_hw_interrupt_umask(174); +} + +void usb_dc_low_level_deinit(void) +{ + rt_hw_interrupt_mask(174); +} +#endif +uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) +{ + return 0; +} + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + /* implement later */ +} +#endif \ No newline at end of file