/* * Copyright (c) 2024, sakumisu * * SPDX-License-Identifier: Apache-2.0 */ #include "sys_driver.h" #include "gpio_driver.h" #include #include #include #include "bk_misc.h" #include "usbd_core.h" #include "usbh_core.h" #include "usb_musb_reg.h" #define USB_BASE_ADDR SOC_USB_REG_BASE #if (CONFIG_SOC_BK7271) #define REG_AHB2_USB_OTG_CFG (*((volatile unsigned char *)(USB_BASE_ADDR + 0x80))) #define REG_AHB2_USB_DMA_ENDP (*((volatile unsigned char *)(USB_BASE_ADDR + 0x84))) #define REG_AHB2_USB_VTH (*((volatile unsigned char *)(USB_BASE_ADDR + 0x88))) #define REG_AHB2_USB_GEN (*((volatile unsigned char *)(USB_BASE_ADDR + 0x8C))) #define REG_AHB2_USB_STAT (*((volatile unsigned char *)(USB_BASE_ADDR + 0x90))) #define REG_AHB2_USB_INT (*((volatile unsigned char *)(USB_BASE_ADDR + 0x94))) #define REG_AHB2_USB_RESET (*((volatile unsigned char *)(USB_BASE_ADDR + 0x98))) #define REG_AHB2_USB_DEV_CFG (*((volatile unsigned char *)(USB_BASE_ADDR + 0x9C))) #elif (CONFIG_SOC_BK7256XX) #define REG_AHB2_USB_OTG_CFG (*((volatile unsigned char *)(USB_BASE_ADDR + 0x280))) #define REG_AHB2_USB_DMA_ENDP (*((volatile unsigned char *)(USB_BASE_ADDR + 0x284))) #define REG_AHB2_USB_VTH (*((volatile unsigned char *)(USB_BASE_ADDR + 0x288))) #define REG_AHB2_USB_GEN (*((volatile unsigned char *)(USB_BASE_ADDR + 0x28C))) #define REG_AHB2_USB_STAT (*((volatile unsigned char *)(USB_BASE_ADDR + 0x290))) #define REG_AHB2_USB_INT (*((volatile unsigned char *)(USB_BASE_ADDR + 0x294))) #define REG_AHB2_USB_RESET (*((volatile unsigned char *)(USB_BASE_ADDR + 0x298))) #define REG_AHB2_USB_DEV_CFG (*((volatile unsigned char *)(USB_BASE_ADDR + 0x29C))) #elif (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX) #define REG_AHB2_USB_DEVICE_ID (*((volatile unsigned char *)(USB_BASE_ADDR + 0x280))) #define REG_AHB2_USB_VERSION_ID (*((volatile unsigned char *)(USB_BASE_ADDR + 0x284))) #define REG_AHB2_USB_GLOBAL_CTRL (*((volatile unsigned char *)(USB_BASE_ADDR + 0x288))) #define REG_AHB2_USB_DEVICE_STATUS (*((volatile unsigned char *)(USB_BASE_ADDR + 0x28c))) #define REG_AHB2_USB_OTG_CFG (*((volatile unsigned char *)(USB_BASE_ADDR + 0x290))) #define REG_AHB2_USB_DMA_ENDP (*((volatile unsigned char *)(USB_BASE_ADDR + 0x294))) #define REG_AHB2_USB_VTH (*((volatile unsigned char *)(USB_BASE_ADDR + 0x298))) #define REG_AHB2_USB_GEN (*((volatile unsigned char *)(USB_BASE_ADDR + 0x29C))) #define REG_AHB2_USB_STAT (*((volatile unsigned char *)(USB_BASE_ADDR + 0x2A0))) #define REG_AHB2_USB_INT (*((volatile unsigned char *)(USB_BASE_ADDR + 0x2A4))) #define REG_AHB2_USB_RESET (*((volatile unsigned char *)(USB_BASE_ADDR + 0x2A8))) #define REG_AHB2_USB_DEV_CFG (*((volatile unsigned char *)(USB_BASE_ADDR + 0x2AC))) #define REG_USB_USR_700 (*((volatile unsigned long *)(USB_BASE_ADDR + 0x700))) #define REG_USB_USR_704 (*((volatile unsigned long *)(USB_BASE_ADDR + 0x704))) #define REG_USB_USR_708 (*((volatile unsigned long *)(USB_BASE_ADDR + 0x708))) #define REG_USB_USR_70C (*((volatile unsigned long *)(USB_BASE_ADDR + 0x70C))) #define REG_USB_USR_710 (*((volatile unsigned long *)(USB_BASE_ADDR + 0x710))) #define REG_USB_USR_714 (*((volatile unsigned long *)(USB_BASE_ADDR + 0x714))) #define REG_USB_PHY_00 (*((volatile unsigned long *)(USB_BASE_ADDR + 0x400))) #define REG_USB_PHY_01 (*((volatile unsigned long *)(USB_BASE_ADDR + 0x404))) #endif #define USB_DP_CAPABILITY_VALUE (0xF) #define USB_DN_CAPABILITY_VALUE (0xF) #define NANENG_PHY_FC_REG01 (0x01 * 4) #define NANENG_PHY_FC_REG02 (0x02 * 4) #define NANENG_PHY_FC_REG03 (0x03 * 4) #define NANENG_PHY_FC_REG04 (0x04 * 4) #define NANENG_PHY_FC_REG05 (0x05 * 4) #define NANENG_PHY_FC_REG06 (0x06 * 4) #define NANENG_PHY_FC_REG07 (0x07 * 4) #define NANENG_PHY_FC_REG08 (0x08 * 4) #define NANENG_PHY_FC_REG09 (0x09 * 4) #define NANENG_PHY_FC_REG0A (0x0A * 4) #define NANENG_PHY_FC_REG0B (0x0B * 4) #define NANENG_PHY_FC_REG0C (0x0C * 4) #define NANENG_PHY_FC_REG0D (0x0D * 4) #define NANENG_PHY_FC_REG0E (0x0E * 4) #define NANENG_PHY_FC_REG0F (0x0F * 4) #define NANENG_PHY_FC_REG0F_BYTE 0x0F #define NANENG_PHY_FC_REG10 (0x10 * 4) #define NANENG_PHY_FC_REG11 (0x11 * 4) #define NANENG_PHY_FC_REG12 (0x12 * 4) #define NANENG_PHY_FC_REG13 (0x13 * 4) #define NANENG_PHY_FC_REG14 (0x14 * 4) #define NANENG_PHY_FC_REG15 (0x15 * 4) #define NANENG_PHY_FC_REG16 (0x16 * 4) #define NANENG_PHY_FC_REG17 (0x17 * 4) #define NANENG_PHY_FC_REG18 (0x18 * 4) #define NANENG_PHY_FC_REG19 (0x19 * 4) #define NANENG_PHY_FC_REG1A (0x1A * 4) #define NANENG_PHY_FC_REG1B (0x1B * 4) #define NANENG_PHY_FC_REG1C (0x1C * 4) #define NANENG_PHY_FC_REG1D (0x1D * 4) #define NANENG_PHY_FC_REG1E (0x1E * 4) #define NANENG_PHY_FC_REG1F (0x1F * 4) #if CONFIG_USBDEV_EP_NUM != 8 #error beken chips only support 8 endpoints #endif #if CONFIG_USBHOST_PIPE_NUM != 8 #error beken chips only support 8 pipes #endif // clang-format off static struct musb_fifo_cfg musb_device_table[] = { { .ep_num = 0, .style = FIFO_TXRX, .maxpacket = 64, }, { .ep_num = 1, .style = FIFO_TX, .maxpacket = 1024, }, { .ep_num = 1, .style = FIFO_RX, .maxpacket = 1024, }, { .ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 2, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 3, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 3, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 4, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 4, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 5, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 5, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 6, .style = FIFO_TXRX, .maxpacket = 512, }, { .ep_num = 7, .style = FIFO_TXRX, .maxpacket = 512, } }; static struct musb_fifo_cfg musb_host_table[] = { { .ep_num = 0, .style = FIFO_TXRX, .maxpacket = 64, }, { .ep_num = 1, .style = FIFO_TX, .maxpacket = 1024, }, { .ep_num = 1, .style = FIFO_RX, .maxpacket = 1024, }, { .ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 2, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 3, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 3, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 4, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 4, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 5, .style = FIFO_TX, .maxpacket = 512, }, { .ep_num = 5, .style = FIFO_RX, .maxpacket = 512, }, { .ep_num = 6, .style = FIFO_TXRX, .maxpacket = 512, }, { .ep_num = 7, .style = FIFO_TXRX, .maxpacket = 512, } }; // clang-format on uint8_t usbd_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) { *cfg = musb_device_table; return sizeof(musb_device_table) / sizeof(musb_device_table[0]); } uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg) { *cfg = musb_host_table; return sizeof(musb_host_table) / sizeof(musb_host_table[0]); } uint32_t usb_get_musb_ram_size(void) { return 8192; } extern void USBD_IRQHandler(uint8_t busid); void USBD_IRQ(void) { USBD_IRQHandler(0); } static void bk_analog_layer_usb_sys_related_ops(uint32_t usb_mode, bool ops) { extern void delay(INT32 num); #if 0 sys_drv_usb_analog_phy_en(ops, NULL); sys_drv_usb_analog_speed_en(ops, NULL); sys_drv_usb_analog_ckmcu_en(ops, NULL); #endif if (ops) { sys_drv_usb_clock_ctrl(true, NULL); delay(100); #if 0 sys_drv_usb_analog_deepsleep_en(false); #endif sys_drv_usb_analog_dp_capability(USB_DP_CAPABILITY_VALUE); sys_drv_usb_analog_dn_capability(USB_DN_CAPABILITY_VALUE); if (!sys_hal_psram_ldo_status()) { sys_drv_psram_ldo_enable(1); } sys_drv_usb_analog_phy_en(1, NULL); if (usb_mode == 0) { REG_USB_USR_708 = 0x0; REG_USB_USR_710 &= ~(0x1 << 7); delay(100); REG_USB_USR_710 |= (0x1 << 15); //REG_USB_USR_710 |= (0x1<<14); REG_USB_USR_710 |= (0x1 << 16); REG_USB_USR_710 |= (0x1 << 17); REG_USB_USR_710 |= (0x1 << 18); REG_USB_USR_710 |= (0x1 << 19); REG_USB_USR_710 &= ~(0x1 << 20); REG_USB_USR_710 |= (0x1 << 21); REG_USB_USR_710 |= (0x0 << 0); REG_USB_USR_710 |= (0x1 << 5); REG_USB_USR_710 |= (0x1 << 6); REG_USB_USR_710 |= (0x1 << 9); REG_USB_USR_710 |= (0x1 << 10); REG_USB_USR_710 |= (0x1 << 1); REG_USB_USR_710 |= (0x1 << 7); REG_USB_USR_708 = 0x1; #if 0 REG_USB_PHY_00 = 0x08; REG_USB_PHY_01 = 0x02; REG_USB_USR_710 |= (0x1<< 8); while(1){ reg = REG_USB_USR_70C; if(reg & 0x100){ USB_DRIVER_LOGI("SelfTest Fin!\r\n"); USB_DRIVER_LOGI("test end!\r\n"); break; } else { USB_DRIVER_LOGI("70c_reg:0x%x\r\n", reg); delay(10000); } } REG_USB_PHY_00 &= ~0x08; REG_USB_PHY_01 &= ~0x02; REG_USB_USR_710 &= ~(0x1<< 8); #endif } else { REG_USB_USR_710 |= (0x1 << 15); REG_USB_USR_710 |= (0x1 << 14); REG_USB_USR_710 |= (0x1 << 16); REG_USB_USR_710 |= (0x1 << 17); REG_USB_USR_710 |= (0x1 << 18); REG_USB_USR_710 |= (0x1 << 19); REG_USB_USR_710 &= ~(0x1 << 20); REG_USB_USR_710 |= (0x1 << 21); REG_USB_USR_710 |= (0x0 << 0); REG_USB_USR_710 |= (0x1 << 5); REG_USB_USR_710 |= (0x1 << 6); REG_USB_USR_710 |= (0x1 << 9); REG_USB_USR_710 |= (0x1 << 10); REG_USB_USR_710 |= (0x1 << 7); REG_USB_USR_708 = 0x1; } } else { sys_drv_usb_analog_phy_en(0, NULL); sys_drv_usb_clock_ctrl(false, NULL); } } void usb_dc_low_level_init(void) { #if CONFIG_SYS_CPU0 bk_pm_module_vote_sleep_ctrl(PM_SLEEP_MODULE_NAME_USB_1, 0x0, 0x0); #endif bk_analog_layer_usb_sys_related_ops(1, true); bk_gpio_set_output_high(CONFIG_USB_VBAT_CONTROL_GPIO_ID); bk_pm_module_vote_cpu_freq(PM_DEV_ID_USB_1, PM_CPU_FRQ_120M); sys_hal_usb_analog_phy_en(true); sys_drv_usb_clock_ctrl(true, NULL); sys_drv_int_enable(USB_INTERRUPT_CTRL_BIT); bk_int_isr_register(INT_SRC_USB, USBD_IRQ, NULL); bk_int_set_priority(INT_SRC_USB, 2); } void usb_dc_low_level_deinit(void) { bk_pm_module_vote_cpu_freq(PM_DEV_ID_USB_1, PM_CPU_FRQ_DEFAULT); sys_hal_usb_analog_phy_en(false); sys_drv_usb_clock_ctrl(false, NULL); sys_drv_int_disable(USB_INTERRUPT_CTRL_BIT); bk_int_isr_unregister(INT_SRC_USB); bk_analog_layer_usb_sys_related_ops(1, false); sys_drv_dev_clk_pwr_up(CLK_PWR_ID_USB_1, CLK_PWR_CTRL_PWR_DOWN); } extern void USBH_IRQHandler(uint8_t busid); void USBH_IRQ(void) { USBH_IRQHandler(0); } #define NANENG_PHY_CFG 1 #define USB_PHY_BASE (SOC_USB_REG_BASE + 0x400) #define HWREG(x) \ (*((volatile uint32_t *)(x))) #define HWREGH(x) \ (*((volatile uint16_t *)(x))) #define HWREGB(x) \ (*((volatile uint8_t *)(x))) void usb_hc_low_level_init(struct usbh_bus *bus) { #if CONFIG_SYS_CPU0 bk_pm_module_vote_sleep_ctrl(PM_SLEEP_MODULE_NAME_USB_1, 0x0, 0x0); #endif bk_analog_layer_usb_sys_related_ops(0, true); bk_gpio_set_output_high(CONFIG_USB_VBAT_CONTROL_GPIO_ID); #if NANENG_PHY_CFG //NANENG_PHY_CFG_HSRX_TEST HWREGB(USB_PHY_BASE + NANENG_PHY_FC_REG0F) |= (0x1 << 4); //disconnect value 640mv HWREGB(USB_PHY_BASE + NANENG_PHY_FC_REG0B) = 0x7C; #endif bk_int_isr_register(INT_SRC_USB, USBH_IRQ, NULL); sys_drv_int_enable(USB_INTERRUPT_CTRL_BIT); } void usb_hc_low_level_deinit(struct usbh_bus *bus) { sys_drv_int_disable(USB_INTERRUPT_CTRL_BIT); bk_int_isr_unregister(INT_SRC_USB); sys_drv_dev_clk_pwr_up(CLK_PWR_ID_USB_1, CLK_PWR_CTRL_PWR_DOWN); bk_analog_layer_usb_sys_related_ops(0, false); }