diff options
author | Shangbing Hu <shangbing.hu@mediatek.com> | 2016-07-12 10:18:28 +0800 |
---|---|---|
committer | Shangbing Hu <shangbing.hu@mediatek.com> | 2016-07-12 10:18:28 +0800 |
commit | 2ceb2f927bf03ae52d2addcbcc751306cc9944ea (patch) | |
tree | f9ab6873b64ebdfddf2fdb0cac8663cac97faa76 | |
parent | 971af533fb2cd63fcad0762398b94614e875b5ec (diff) |
[ALPS02220149] usb: mt6755 usb driver porting
[Detail]
add mu3d and mu3phy folder.
mu3d is Mediatek USB3.0 MAC
mu3phy is Mediatek USB3.0 PHY
[Solution]
CONFIG_USB_MU3D_DRV=y to enable SSUSB mac driver
CONFIG_MU3_PHY=y to enable SSUSB phy driver
[Feature] USB 3.0 Device
MTK-Commit-Id: b4d01b987dff4344dc6aa1734a4a711651199228
Change-Id: Ia505a9f8058c9ee83c39299eb42a2a5b1fdd8967
Signed-off-by: Shangbing Hu <shangbing.hu@mediatek.com>
CR-Id: ALPS02220149
44 files changed, 26178 insertions, 0 deletions
diff --git a/drivers/misc/mediatek/Kconfig b/drivers/misc/mediatek/Kconfig index 094090ca5b98..9425fa16d981 100644 --- a/drivers/misc/mediatek/Kconfig +++ b/drivers/misc/mediatek/Kconfig @@ -106,6 +106,8 @@ source "drivers/misc/mediatek/partition/Kconfig" source "drivers/misc/mediatek/sysenv/Kconfig" source "drivers/misc/mediatek/mtprof/Kconfig" source "drivers/misc/mediatek/usb20/Kconfig" +source "drivers/misc/mediatek/mu3d/Kconfig" +source "drivers/misc/mediatek/mu3phy/Kconfig" source "drivers/misc/mediatek/gpio/Kconfig" source "drivers/misc/mediatek/cmdq/Kconfig" source "drivers/misc/mediatek/smi/Kconfig" diff --git a/drivers/misc/mediatek/Makefile b/drivers/misc/mediatek/Makefile index 7f6286b75861..05920f4d291d 100644 --- a/drivers/misc/mediatek/Makefile +++ b/drivers/misc/mediatek/Makefile @@ -41,6 +41,8 @@ obj-$(CONFIG_MTK_RTC) += rtc/ obj-$(CONFIG_MTK_PMIC) += power/ obj-$(CONFIG_MTK_PMIC_WRAP) += pmic_wrap/ obj-$(CONFIG_USB_MTK_HDRC) += usb20/ +obj-$(CONFIG_USB_MU3D_DRV) += mu3d/ +obj-$(CONFIG_MU3_PHY) += mu3phy/ obj-$(CONFIG_MTK_GPIO) += gpio/ obj-$(CONFIG_SECURITY_SELINUX) += selinux_warning/ obj-$(CONFIG_MTK_MEM) += mem/ diff --git a/drivers/misc/mediatek/mu3d/Kconfig b/drivers/misc/mediatek/mu3d/Kconfig new file mode 100644 index 000000000000..0f36c97a333c --- /dev/null +++ b/drivers/misc/mediatek/mu3d/Kconfig @@ -0,0 +1,38 @@ +# +# MediaTek USB 3.0 Controller Driver +# + +config USBIF_COMPLIANCE + tristate "MediaTek MUSB U3 USBIF COMPLIANCE" + default n + ---help--- + This selects the MediaTek USB-IF Compliance Test Program. + MediaTek I2C bus adapter is the base for some other I2C client, eg: touch, sensors. + If you want to verify USB-IF COMPLIANCE, say Y. + If unsure, say N. + +config USB_MU3D_PIO_ONLY + tristate "MediaTek MUSB Gadget support EP0 PIO mode" + default n + ---help--- + Say Y here if you want to disable USB DMA function. + All data is copied between memory and FIFO by the CPU. + DMA controllers are ignored. + If unsure, say N. + +config USB_MU3D_DRV + tristate "MediaTek SSUSB MAC Driver support" + default n + ---help--- + This selects the MediaTek USB MAC driver. + Say Y here if your system using Mediatek USB3.0 IP. + It supports super-speed, high-speed and full-speed. + If unsure, say N. + +config USB_MU3D_DVT + tristate "MediaTek SSUSB DVT support" + default n + ---help--- + Say Y here if your system using Mediatek USB3.0 IP + and would like to do verification program. + If unsure, say N. diff --git a/drivers/misc/mediatek/mu3d/Makefile b/drivers/misc/mediatek/mu3d/Makefile new file mode 100644 index 000000000000..68595da586fc --- /dev/null +++ b/drivers/misc/mediatek/mu3d/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_USB_MU3D_DRV) += drv/ +obj-$(CONFIG_USB_MU3D_DRV) += hal/ +obj-$(CONFIG_USB_MU3D_DVT) += test_drv/ diff --git a/drivers/misc/mediatek/mu3d/drv/Makefile b/drivers/misc/mediatek/mu3d/drv/Makefile new file mode 100644 index 000000000000..a85d32420d62 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/Makefile @@ -0,0 +1,12 @@ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/mu3d/drv \ + -I$(srctree)/drivers/misc/mediatek/mu3d/hal \ + -I$(srctree)/drivers/misc/mediatek/mu3phy \ + -I$(srctree)/drivers/misc/mediatek/mu3phy/$(CONFIG_MTK_PLATFORM) + +ccflags-y += -DUSE_SSUSB_QMU + +obj-y := musb_hdrc.o +musb_hdrc-y := musb_core.o +musb_hdrc-y += musb_gadget_ep0.o musb_gadget.o +musb_hdrc-y += musb_init.o ssusb_qmu.o mt_usb.o +musb_hdrc-$(CONFIG_DEBUG_FS) += musb_debugfs.o diff --git a/drivers/misc/mediatek/mu3d/drv/mt_usb.c b/drivers/misc/mediatek/mu3d/drv/mt_usb.c new file mode 100644 index 000000000000..cdcefa3d60c0 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/mt_usb.c @@ -0,0 +1,621 @@ +/* + * MUSB OTG controller driver for Blackfin Processors + * + * Copyright 2006-2008 Analog Devices Inc. + * + * Enter bugs at http://blackfin.uclinux.org/ + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/workqueue.h> +#include <linux/usb/gadget.h> +/*#include "mach/emi_mpu.h"*/ + +#include "mu3d_hal_osal.h" +#include "musb_core.h" +#ifdef CONFIG_MTK_UART_USB_SWITCH +#include "mtk-phy-asic.h" +/*#include <mach/mt_typedefs.h>*/ +#endif + +#if defined(FOR_BRING_UP) || !defined(CONFIG_MTK_SMART_BATTERY) +static inline void BATTERY_SetUSBState(int usb_state) +{ +}; +static inline CHARGER_TYPE mt_get_charger_type(void) +{ + return STANDARD_HOST; +}; +static inline bool upmu_is_chr_det(void) +{ + return true; +}; +static inline u32 upmu_get_rgs_chrdet(void) +{ + return 1; +}; +#endif + +unsigned int cable_mode = CABLE_MODE_NORMAL; +#ifdef CONFIG_MTK_UART_USB_SWITCH +u32 port_mode = PORT_MODE_USB; +u32 sw_tx = 0; +u32 sw_rx = 0; +u32 sw_uart_path = 0; +#endif + +/* ================================ */ +/* connect and disconnect functions */ +/* ================================ */ +bool mt_usb_is_device(void) +{ +#if !defined(CONFIG_MTK_FPGA) && defined(CONFIG_MTK_XHCI) + bool tmp = mtk_is_host_mode(); + + os_printk(K_INFO, "%s mode\n", tmp ? "HOST" : "DEV"); + return !tmp; +#else + return true; +#endif +} + +enum status { INIT, ON, OFF }; +#ifdef CONFIG_USBIF_COMPLIANCE +static enum status connection_work_dev_status = INIT; +void init_connection_work(void) +{ + connection_work_dev_status = INIT; +} +#endif + +#ifndef CONFIG_USBIF_COMPLIANCE + +struct timespec connect_timestamp = { 0, 0 }; + +void set_connect_timestamp(void) +{ + connect_timestamp = CURRENT_TIME; + pr_debug("set timestamp = %llu\n", timespec_to_ns(&connect_timestamp)); +} + +void clr_connect_timestamp(void) +{ + connect_timestamp.tv_sec = 0; + connect_timestamp.tv_nsec = 0; + pr_debug("clr timestamp = %llu\n", timespec_to_ns(&connect_timestamp)); +} + +struct timespec get_connect_timestamp(void) +{ + pr_debug("get timestamp = %llu\n", timespec_to_ns(&connect_timestamp)); + return connect_timestamp; +} +#endif + +void connection_work(struct work_struct *data) +{ + struct musb *musb = container_of(to_delayed_work(data), struct musb, connection_work); +#ifndef CONFIG_USBIF_COMPLIANCE + static enum status connection_work_dev_status = INIT; +#endif +#ifdef CONFIG_MTK_UART_USB_SWITCH + if (!usb_phy_check_in_uart_mode()) { +#endif + bool is_usb_cable = usb_cable_connected(); + bool cmode_effect_on = false; + CHARGER_TYPE chg_type = mt_get_charger_type(); + + if (fake_CDP && chg_type == STANDARD_HOST) { + os_printk(K_INFO, "%s, fake to type 2\n", __func__); + chg_type = CHARGING_HOST; + } + os_printk(K_NOTICE, "%s type=%d\n", __func__, chg_type); + if ((musb->usb_mode == CABLE_MODE_HOST_ONLY && chg_type == STANDARD_HOST) + || musb->usb_mode == CABLE_MODE_CHRG_ONLY) + cmode_effect_on = true; +#ifdef CONFIG_MTK_KERNEL_POWER_OFF_CHARGING + if (g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT + || g_boot_mode == LOW_POWER_OFF_CHARGING_BOOT) { + if (chg_type == STANDARD_HOST) + cmode_effect_on = true; + + } +#endif + os_printk(K_INFO, "%s type=%d, cmode_effect_on=%d, usb_mode:%d\n", + __func__, chg_type, cmode_effect_on, musb->usb_mode); + +#ifndef CONFIG_MTK_FPGA + if (!mt_usb_is_device()) { + connection_work_dev_status = OFF; + usb_fake_powerdown(musb->is_clk_on); + musb->is_clk_on = 0; + os_printk(K_INFO, "%s, Host mode. directly return\n", __func__); + return; + } +#endif + + os_printk(K_INFO, "%s musb %s, cable %s\n", __func__, + ((connection_work_dev_status == + 0) ? "INIT" : ((connection_work_dev_status == 1) ? "ON" : "OFF")), + (is_usb_cable ? "IN" : "OUT")); + + if ((is_usb_cable == true) && (connection_work_dev_status != ON) + && (!cmode_effect_on)) { + + connection_work_dev_status = ON; +#ifndef CONFIG_USBIF_COMPLIANCE + set_connect_timestamp(); +#endif + + if (!wake_lock_active(&musb->usb_wakelock)) + wake_lock(&musb->usb_wakelock); + + /* FIXME: Should use usb_udc_start() & usb_gadget_connect(), like usb_udc_softconn_store(). + * But have no time to think how to handle. However i think it is the correct way.*/ + musb_start(musb); + + os_printk(K_INFO, "%s ----Connect----\n", __func__); + } else if (((is_usb_cable == false) && (connection_work_dev_status != OFF)) + || (cmode_effect_on)) { + + connection_work_dev_status = OFF; +#ifndef CONFIG_USBIF_COMPLIANCE + clr_connect_timestamp(); +#endif + + /*FIXME: we should use usb_gadget_disconnect() & usb_udc_stop(). like usb_udc_softconn_store(). + * But have no time to think how to handle. However i think it is the correct way.*/ + musb_stop(musb); + + if (wake_lock_active(&musb->usb_wakelock)) + wake_unlock(&musb->usb_wakelock); + + os_printk(K_INFO, "%s ----Disconnect----\n", __func__); + } else { + /* This if-elseif is to set wakelock when booting with USB cable. + * Because battery driver does _NOT_ notify at this codition.*/ + /* if( (is_usb_cable == true) && !wake_lock_active(&musb->usb_wakelock)) { */ + /* os_printk(K_INFO, "%s Boot wakelock\n", __func__); */ + /* wake_lock(&musb->usb_wakelock); */ + /* } else if( (is_usb_cable == false) && wake_lock_active(&musb->usb_wakelock)) { */ + /* os_printk(K_INFO, "%s Boot unwakelock\n", __func__); */ + /* wake_unlock(&musb->usb_wakelock); */ + /* } */ + + os_printk(K_INFO, "%s directly return\n", __func__); + } +#ifdef CONFIG_MTK_UART_USB_SWITCH + } else { +#if 0 + usb_fake_powerdown(musb->is_clk_on); + musb->is_clk_on = 0; +#else + os_printk(K_INFO, "%s, in UART MODE!!!\n", __func__); +#endif + } +#endif +} + +bool mt_usb_is_ready(void) +{ + os_printk(K_INFO, "USB is ready or not\n"); +#ifdef NEVER + if (!mtk_musb || !mtk_musb->is_ready) + return false; + else + return true; +#endif /* NEVER */ + return true; +} + +void mt_usb_connect(void) +{ + os_printk(K_INFO, "%s+\n", __func__); + if (_mu3d_musb) { + struct delayed_work *work; + + work = &_mu3d_musb->connection_work; + + schedule_delayed_work_on(0, work, 0); + } else { + os_printk(K_INFO, "%s musb_musb not ready\n", __func__); + } + os_printk(K_INFO, "%s-\n", __func__); +} +EXPORT_SYMBOL_GPL(mt_usb_connect); + +void mt_usb_disconnect(void) +{ + os_printk(K_INFO, "%s+\n", __func__); + + if (_mu3d_musb) { + struct delayed_work *work; + + work = &_mu3d_musb->connection_work; + + schedule_delayed_work_on(0, work, 0); + } else { + os_printk(K_INFO, "%s musb_musb not ready\n", __func__); + } + os_printk(K_INFO, "%s-\n", __func__); +} +EXPORT_SYMBOL_GPL(mt_usb_disconnect); + +bool usb_cable_connected(void) +{ +#ifndef CONFIG_MTK_FPGA + CHARGER_TYPE chg_type = CHARGER_UNKNOWN; +#ifdef CONFIG_POWER_EXT + chg_type = mt_get_charger_type(); + os_printk(K_INFO, "%s ext-chrdet=%d type=%d\n", __func__, upmu_get_rgs_chrdet(), chg_type); + if (upmu_get_rgs_chrdet() && (chg_type == STANDARD_HOST)) + return true; +#else + if (upmu_is_chr_det()) { + chg_type = mt_get_charger_type(); + os_printk(K_INFO, "%s type=%d\n", __func__, chg_type); + if (chg_type == STANDARD_HOST || chg_type == CHARGING_HOST) + return true; + } +#endif + os_printk(K_INFO, "%s no USB Host detect!\n", __func__); + return false; +#else + os_printk(K_INFO, "%s [FPGA] always true\n", __func__); + return true; +#endif +} +EXPORT_SYMBOL_GPL(usb_cable_connected); + +#ifdef NEVER +void musb_platform_reset(struct musb *musb) +{ + u16 swrst = 0; + void __iomem *mbase = musb->mregs; + + swrst = musb_readw(mbase, MUSB_SWRST); + swrst |= (MUSB_SWRST_DISUSBRESET | MUSB_SWRST_SWRST); + musb_writew(mbase, MUSB_SWRST, swrst); +} +#endif /* NEVER */ + +void usb_check_connect(void) +{ + os_printk(K_INFO, "usb_check_connect\n"); + +#ifndef CONFIG_MTK_FPGA + if (usb_cable_connected()) + mt_usb_connect(); +#endif + +} + +void musb_sync_with_bat(struct musb *musb, int usb_state) +{ + os_printk(K_INFO, "musb_sync_with_bat\n"); + +#ifndef CONFIG_MTK_FPGA +#if defined(CONFIG_MTK_SMART_BATTERY) + BATTERY_SetUSBState(usb_state); +#ifndef FOR_BRING_UP + wake_up_bat(); +#endif +#endif +#endif + +} +EXPORT_SYMBOL_GPL(musb_sync_with_bat); + +/*--FOR INSTANT POWER ON USAGE--------------------------------------------------*/ +static inline struct musb *dev_to_musb(struct device *dev) +{ + return dev_get_drvdata(dev); +} + +const char *const usb_mode_str[CABLE_MODE_MAX] = { "CHRG_ONLY", "NORMAL", "HOST_ONLY" }; + +ssize_t musb_cmode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + if (!dev) { + os_printk(K_ERR, "dev is null!!\n"); + return 0; + } + return sprintf(buf, "%d\n", cable_mode); +} + +ssize_t musb_cmode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int cmode; + struct musb *musb = dev_to_musb(dev); + + if (!dev) { + os_printk(K_ERR, "dev is null!!\n"); + return count; + } else if (1 == sscanf(buf, "%ud", &cmode)) { + os_printk(K_INFO, "%s %s --> %s\n", __func__, usb_mode_str[cable_mode], + usb_mode_str[cmode]); + + if (cmode >= CABLE_MODE_MAX) + cmode = CABLE_MODE_NORMAL; + + if (cable_mode != cmode) { + if (cmode == CABLE_MODE_CHRG_ONLY) { /* IPO shutdown, disable USB */ + if (musb) { + musb->usb_mode = CABLE_MODE_CHRG_ONLY; + mt_usb_disconnect(); + } + } else if (cmode == CABLE_MODE_HOST_ONLY) { + if (musb) { + musb->usb_mode = CABLE_MODE_HOST_ONLY; + mt_usb_disconnect(); + } + } else { /* IPO bootup, enable USB */ + if (musb) { + musb->usb_mode = CABLE_MODE_NORMAL; + mt_usb_connect(); + } + } + cable_mode = cmode; + } + } + return count; +} + +#ifdef CONFIG_MTK_UART_USB_SWITCH +ssize_t musb_portmode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + if (!dev) { + pr_debug("dev is null!!\n"); + return 0; + } + + if (usb_phy_check_in_uart_mode()) + port_mode = PORT_MODE_UART; + else + port_mode = PORT_MODE_USB; + + if (port_mode == PORT_MODE_USB) + pr_debug("\nUSB Port mode -> USB\n"); + else if (port_mode == PORT_MODE_UART) + pr_debug("\nUSB Port mode -> UART\n"); + + uart_usb_switch_dump_register(); + + return scnprintf(buf, PAGE_SIZE, "%d\n", port_mode); +} + +ssize_t musb_portmode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int portmode; + + if (!dev) { + pr_debug("dev is null!!\n"); + return count; + } else if (1 == sscanf(buf, "%ud", &portmode)) { + pr_debug("\nUSB Port mode: current => %d (port_mode), change to => %d (portmode)\n", + port_mode, portmode); + if (portmode >= PORT_MODE_MAX) + portmode = PORT_MODE_USB; + + if (port_mode != portmode) { + if (portmode == PORT_MODE_USB) { /* Changing to USB Mode */ + pr_debug("USB Port mode -> USB\n"); + usb_phy_switch_to_usb(); + } else if (portmode == PORT_MODE_UART) { /* Changing to UART Mode */ + pr_debug("USB Port mode -> UART\n"); + usb_phy_switch_to_uart(); + } + uart_usb_switch_dump_register(); + port_mode = portmode; + } + } + return count; +} + +ssize_t musb_tx_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 var; + u8 var2; + + if (!dev) { + pr_debug("dev is null!!\n"); + return 0; + } + + var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDTM1 + 0x2)); + var2 = (var >> 3) & ~0xFE; + pr_debug("[MUSB]addr: 0x6E (TX), value: %x - %x\n", var, var2); + + sw_tx = var; + + return scnprintf(buf, PAGE_SIZE, "%x\n", var2); +} + +ssize_t musb_tx_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int val; + u8 var; + u8 var2; + + if (!dev) { + pr_debug("dev is null!!\n"); + return count; + } else if (1 == sscanf(buf, "%ud", &val)) { + pr_debug("\n Write TX : %d\n", val); + +#ifdef CONFIG_MTK_FPGA + var = USB_PHY_Read_Register8(U3D_U2PHYDTM1 + 0x2); +#else + var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDTM1 + 0x2)); +#endif + + if (val == 0) + var2 = var & ~(1 << 3); + else + var2 = var | (1 << 3); + +#ifdef CONFIG_MTK_FPGA + USB_PHY_Write_Register8(var2, U3D_U2PHYDTM1 + 0x2); + var = USB_PHY_Read_Register8(U3D_U2PHYDTM1 + 0x2); +#else + /* U3PhyWriteField32(U3D_USBPHYDTM1+0x2, + E60802_RG_USB20_BC11_SW_EN_OFST, E60802_RG_USB20_BC11_SW_EN, 0); */ + /* Jeremy TODO 0320 */ + var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDTM1 + 0x2)); +#endif + + var2 = (var >> 3) & ~0xFE; + + pr_debug + ("[MUSB]addr: U3D_U2PHYDTM1 (0x6E) TX [AFTER WRITE], value after: %x - %x\n", + var, var2); + sw_tx = var; + } + return count; +} + +ssize_t musb_rx_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 var; + u8 var2; + + if (!dev) { + pr_debug("dev is null!!\n"); + return 0; + } +#ifdef CONFIG_MTK_FPGA + var = USB_PHY_Read_Register8(U3D_U2PHYDMON1 + 0x3); +#else + var = U3PhyReadReg8((u3phy_addr_t) (U3D_U2PHYDMON1 + 0x3)); +#endif + var2 = (var >> 7) & ~0xFE; + pr_debug("[MUSB]addr: U3D_U2PHYDMON1 (0x77) (RX), value: %x - %x\n", var, var2); + sw_rx = var; + + return scnprintf(buf, PAGE_SIZE, "%x\n", var2); +} + +ssize_t musb_uart_path_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 var = 0; + + if (!dev) { + pr_debug("dev is null!!\n"); + return 0; + } + + var = DRV_Reg8(ap_uart0_base + 0xB0); + pr_debug("[MUSB]addr: (UART0) 0xB0, value: %x\n\n", DRV_Reg8(ap_uart0_base + 0xB0)); + sw_uart_path = var; + + return scnprintf(buf, PAGE_SIZE, "%x\n", var); +} +#endif + +#ifdef NEVER +#ifdef CONFIG_MTK_FPGA +static struct i2c_client *usb_i2c_client; +static const struct i2c_device_id usb_i2c_id[] = { {"mtk-usb", 0}, {} }; + +static struct i2c_board_info usb_i2c_dev __initdata = { I2C_BOARD_INFO("mtk-usb", 0x60) }; + + +void USB_PHY_Write_Register8(UINT8 var, UINT8 addr) +{ + char buffer[2]; + + buffer[0] = addr; + buffer[1] = var; + i2c_master_send(usb_i2c_client, &buffer, 2); +} + +UINT8 USB_PHY_Read_Register8(UINT8 addr) +{ + UINT8 var; + + i2c_master_send(usb_i2c_client, &addr, 1); + i2c_master_recv(usb_i2c_client, &var, 1); + return var; +} + +static int usb_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + + pr_debug("[MUSB]usb_i2c_probe, start\n"); + + usb_i2c_client = client; + + /* disable usb mac suspend */ + DRV_WriteReg8(USB_SIF_BASE + 0x86a, 0x00); + + /* usb phy initial sequence */ + USB_PHY_Write_Register8(0x00, 0xFF); + USB_PHY_Write_Register8(0x04, 0x61); + USB_PHY_Write_Register8(0x00, 0x68); + USB_PHY_Write_Register8(0x00, 0x6a); + USB_PHY_Write_Register8(0x6e, 0x00); + USB_PHY_Write_Register8(0x0c, 0x1b); + USB_PHY_Write_Register8(0x44, 0x08); + USB_PHY_Write_Register8(0x55, 0x11); + USB_PHY_Write_Register8(0x68, 0x1a); + + + pr_debug("[MUSB]addr: 0xFF, value: %x\n", USB_PHY_Read_Register8(0xFF)); + pr_debug("[MUSB]addr: 0x61, value: %x\n", USB_PHY_Read_Register8(0x61)); + pr_debug("[MUSB]addr: 0x68, value: %x\n", USB_PHY_Read_Register8(0x68)); + pr_debug("[MUSB]addr: 0x6a, value: %x\n", USB_PHY_Read_Register8(0x6a)); + pr_debug("[MUSB]addr: 0x00, value: %x\n", USB_PHY_Read_Register8(0x00)); + pr_debug("[MUSB]addr: 0x1b, value: %x\n", USB_PHY_Read_Register8(0x1b)); + pr_debug("[MUSB]addr: 0x08, value: %x\n", USB_PHY_Read_Register8(0x08)); + pr_debug("[MUSB]addr: 0x11, value: %x\n", USB_PHY_Read_Register8(0x11)); + pr_debug("[MUSB]addr: 0x1a, value: %x\n", USB_PHY_Read_Register8(0x1a)); + + + pr_debug("[MUSB]usb_i2c_probe, end\n"); + return 0; + +} + +static int usb_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info) +{ + strcpy(info->type, "mtk-usb"); + return 0; +} + +static int usb_i2c_remove(struct i2c_client *client) +{ + return 0; +} + + +struct i2c_driver usb_i2c_driver = { + .probe = usb_i2c_probe, + .remove = usb_i2c_remove, + .detect = usb_i2c_detect, + .driver = { + .name = "mtk-usb", + }, + .id_table = usb_i2c_id, +}; + +int add_usb_i2c_driver(void) +{ + int ret = 0; + + i2c_register_board_info(0, &usb_i2c_dev, 1); + if (i2c_add_driver(&usb_i2c_driver) != 0) { + pr_debug("[MUSB]usb_i2c_driver initialization failed!!\n"); + ret = -1; + } else + pr_debug("[MUSB]usb_i2c_driver initialization succeed!!\n"); + + return ret; +} +#endif /* End of CONFIG_MTK_FPGA */ +#endif /* NEVER */ diff --git a/drivers/misc/mediatek/mu3d/drv/musb_core.c b/drivers/misc/mediatek/mu3d/drv/musb_core.c new file mode 100644 index 000000000000..8fa640a2356e --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_core.c @@ -0,0 +1,2956 @@ +/* + * MUSB OTG driver core code + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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. + * + */ + +/* + * Inventra (Multipoint) Dual-Role Controller Driver for Linux. + * + * This consists of a Host Controller Driver (HCD) and a peripheral + * controller driver implementing the "Gadget" API; OTG support is + * in the works. These are normal Linux-USB controller drivers which + * use IRQs and have no dedicated thread. + * + * This version of the driver has only been used with products from + * Texas Instruments. Those products integrate the Inventra logic + * with other DMA, IRQ, and bus modules, as well as other logic that + * needs to be reflected in this driver. + * + * + * NOTE: the original Mentor code here was pretty much a collection + * of mechanisms that don't seem to have been fully integrated/working + * for *any* Linux kernel version. This version aims at Linux 2.6.now, + * Key open issues include: + * + * - Lack of host-side transaction scheduling, for all transfer types. + * The hardware doesn't do it; instead, software must. + * + * This is not an issue for OTG devices that don't support external + * hubs, but for more "normal" USB hosts it's a user issue that the + * "multipoint" support doesn't scale in the expected ways. That + * includes DaVinci EVM in a common non-OTG mode. + * + * * Control and bulk use dedicated endpoints, and there's as + * yet no mechanism to either (a) reclaim the hardware when + * peripherals are NAKing, which gets complicated with bulk + * endpoints, or (b) use more than a single bulk endpoint in + * each direction. + * + * RESULT: one device may be perceived as blocking another one. + * + * * Interrupt and isochronous will dynamically allocate endpoint + * hardware, but (a) there's no record keeping for bandwidth; + * (b) in the common case that few endpoints are available, there + * is no mechanism to reuse endpoints to talk to multiple devices. + * + * RESULT: At one extreme, bandwidth can be overcommitted in + * some hardware configurations, no faults will be reported. + * At the other extreme, the bandwidth capabilities which do + * exist tend to be severely undercommitted. You can't yet hook + * up both a keyboard and a mouse to an external USB hub. + */ +/* Sanity CR check in */ +/* + * This gets many kinds of configuration information: + * - Kconfig for everything user-configurable + * - platform_device for addressing, irq, and platform_data + * - platform_data is mostly for board-specific informarion + * (plus recentrly, SOC or family details) + * + * Most of the conditional compilation will (someday) vanish. + */ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/kobject.h> +#include <linux/prefetch.h> +#include <linux/platform_device.h> +#include <linux/io.h> + +#ifdef CONFIG_USBIF_COMPLIANCE +#include <linux/proc_fs.h> +#include <asm/uaccess.h> +#include <linux/seq_file.h> +#include <mach/system.h> +#endif + +#include <mt-plat/mt_chip.h> +#include "musb_core.h" +#include "mu3d_hal_osal.h" +#include "mu3d_hal_usb_drv.h" +#include "mu3d_hal_hw.h" +#include "ssusb_qmu.h" + +#ifdef CONFIG_MTK_UART_USB_SWITCH +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#define AP_UART0_COMPATIBLE_NAME "mediatek,AP_UART0" +#endif + +#define TA_WAIT_BCON(m) max_t(int, (m)->a_wait_bcon, OTG_TIME_A_WAIT_BCON) + + +#define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" +#define DRIVER_DESC "Inventra Dual-Role USB Controller Driver" + +#define MUSB_VERSION "6.0" + +#define DRIVER_INFO DRIVER_DESC ", v" MUSB_VERSION + +const char musb_driver_name[] = MUSB_DRIVER_NAME; + +struct musb *_mu3d_musb = NULL; + +u32 debug_level = K_ALET | K_CRIT | K_ERR | K_WARNIN | K_NOTICE | K_INFO; +u32 fake_CDP = 0; + +module_param(debug_level, int, 0644); +MODULE_PARM_DESC(debug_level, "Debug Print Log Lvl"); +module_param(fake_CDP, int, 0644); + +#ifdef EP_PROFILING +u32 is_prof = 1; + +module_param(is_prof, int, 0644); +MODULE_PARM_DESC(is_prof, "profiling each EP"); +#endif + +MODULE_DESCRIPTION(DRIVER_INFO); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" MUSB_DRIVER_NAME); + +#define U3D_FIFO_START_ADDRESS 0 + +void __iomem *u3_base; +void __iomem *u3_sif_base; +void __iomem *u3_sif2_base; +void __iomem *ap_uart0_base; + +#ifdef CONFIG_MTK_FPGA +void __iomem *i2c1_base; +#endif + +/*-------------------------------------------------------------------------*/ + +static inline struct musb *dev_to_musb(struct device *dev) +{ + return dev_get_drvdata(dev); +} + +/*-------------------------------------------------------------------------*/ + +#if 0 +/* #ifndef CONFIG_BLACKFIN */ +static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset) +{ + void __iomem *addr = otg->io_priv; + int i = 0; + u8 r; + u8 power; + + /* Make sure the transceiver is not in low power mode */ + power = musb_readb(addr, MUSB_POWER); + power &= ~MUSB_POWER_SUSPENDM; + musb_writeb(addr, MUSB_POWER, power); + + /* REVISIT: musbhdrc_ulpi_an.pdf recommends setting the + * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM. + */ + + musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8) offset); + musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR); + + while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) + & MUSB_ULPI_REG_CMPLT)) { + i++; + if (i == 10000) + return -ETIMEDOUT; + + } + r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); + r &= ~MUSB_ULPI_REG_CMPLT; + musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); + + return musb_readb(addr, MUSB_ULPI_REG_DATA); +} + +static int musb_ulpi_write(struct otg_transceiver *otg, u32 offset, u32 data) +{ + void __iomem *addr = otg->io_priv; + int i = 0; + u8 r = 0; + u8 power; + + /* Make sure the transceiver is not in low power mode */ + power = musb_readb(addr, MUSB_POWER); + power &= ~MUSB_POWER_SUSPENDM; + musb_writeb(addr, MUSB_POWER, power); + + musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8) offset); + musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8) data); + musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ); + + while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) + & MUSB_ULPI_REG_CMPLT)) { + i++; + if (i == 10000) + return -ETIMEDOUT; + } + + r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); + r &= ~MUSB_ULPI_REG_CMPLT; + musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); + + return 0; +} +#else +#define musb_ulpi_read NULL +#define musb_ulpi_write NULL +#endif + +/* + * Load an endpoint's FIFO + */ +void musb_write_fifo(struct musb_hw_ep *hw_ep, u16 len, const u8 *src) +{ + unsigned int residue; + unsigned int temp; + + /* QMU GPD address --> CPU DMA address */ + void __iomem *fifo = (void __iomem *)(uintptr_t) USB_FIFO(hw_ep->epnum); + + os_printk(K_DEBUG, "%s epnum=%d, len=%d, buf=%p\n", __func__, hw_ep->epnum, len, src); + + residue = len; + + while (residue > 0) { + + if (residue == 1) { + temp = ((*src) & 0xFF); + /* os_writeb(fifo, temp); */ + writeb(temp, fifo); + src += 1; + residue -= 1; + } else if (residue == 2) { + temp = ((*src) & 0xFF) + (((*(src + 1)) << 8) & 0xFF00); + /* os_writew(fifo, temp); */ + writew(temp, fifo); + src += 2; + residue -= 2; + } else if (residue == 3) { + temp = ((*src) & 0xFF) + (((*(src + 1)) << 8) & 0xFF00); + /* os_writew(fifo, temp); */ + writew(temp, fifo); + src += 2; + + temp = ((*src) & 0xFF); + /* os_writeb(fifo, temp); */ + writeb(temp, fifo); + src += 1; + residue -= 3; + } else { + temp = ((*src) & 0xFF) + (((*(src + 1)) << 8) & 0xFF00) + + (((*(src + 2)) << 16) & 0xFF0000) + (((*(src + 3)) << 24) & 0xFF000000); + /* os_writel(fifo, temp); */ + writel(temp, fifo); + src += 4; + residue -= 4; + } + } +} + +/* + * Unload an endpoint's FIFO + */ +void musb_read_fifo(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) +{ + u16 residue; + unsigned int temp; + + /* QMU GPD address --> CPU DMA address */ + void __iomem *fifo = (void __iomem *)(uintptr_t) USB_FIFO(hw_ep->epnum); + + os_printk(K_DEBUG, "%s %cX ep%d fifo %p count %d buf %p\n", + __func__, 'R', hw_ep->epnum, fifo, len, dst); + + residue = len; + + while (residue > 0) { + + temp = os_readl(fifo); + + /*Store the first byte */ + *dst = temp & 0xFF; + + /*Store the 2nd byte, If have */ + if (residue > 1) + *(dst + 1) = (temp >> 8) & 0xFF; + + /*Store the 3rd byte, If have */ + if (residue > 2) + *(dst + 2) = (temp >> 16) & 0xFF; + + /*Store the 4th byte, If have */ + if (residue > 3) + *(dst + 3) = (temp >> 24) & 0xFF; + + if (residue > 4) { + dst = dst + 4; + residue = residue - 4; + } else { + residue = 0; + } + } + +} + + + +/*-------------------------------------------------------------------------*/ + +/* for high speed test mode; see USB 2.0 spec 7.1.20 */ +static const u8 musb_test_packet[53] = { + /* implicit SYNC then DATA0 to start */ + + /* JKJKJKJK x9 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* JJKKJJKK x8 */ + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + /* JJJJKKKK x8 */ + 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, + /* JJJJJJJKKKKKKK x8 */ + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* JJJJJJJK x8 */ + 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, + /* JKKKKKKK x10, JK */ + 0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e + /* implicit CRC16 then EOP to end */ +}; + +void musb_load_testpacket(struct musb *musb) +{ + u32 maxp; + + maxp = musb->endpoints->max_packet_sz_tx; + mu3d_hal_write_fifo(0, sizeof(musb_test_packet), (u8 *) musb_test_packet, maxp); +} + +/*-------------------------------------------------------------------------*/ + +/* + * Handles OTG hnp timeouts, such as b_ase0_brst + */ +void musb_otg_timer_func(unsigned long data) +{ + struct musb *musb = (struct musb *)data; + unsigned long flags; + + spin_lock_irqsave(&musb->lock, flags); + switch (musb->xceiv->state) { + case OTG_STATE_B_WAIT_ACON: + dev_dbg(musb->controller, "HNP: b_wait_acon timeout; back to b_peripheral\n"); + musb_g_disconnect(musb); + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->is_active = 0; + break; + case OTG_STATE_A_SUSPEND: + case OTG_STATE_A_WAIT_BCON: + dev_dbg(musb->controller, "HNP: %s timeout\n", + usb_otg_state_string(musb->xceiv->state)); + musb_platform_set_vbus(musb, 0); + musb->xceiv->state = OTG_STATE_A_WAIT_VFALL; + break; + default: + dev_dbg(musb->controller, "HNP: Unhandled mode %s\n", + usb_otg_state_string(musb->xceiv->state)); + } + musb->ignore_disconnect = 0; + spin_unlock_irqrestore(&musb->lock, flags); +} + +/* + * Stops the HNP transition. Caller must take care of locking. + */ +void musb_hnp_stop(struct musb *musb) +{ + struct usb_hcd *hcd = musb_to_hcd(musb); + u32 reg; + + dev_dbg(musb->controller, "HNP: stop from %s\n", usb_otg_state_string(musb->xceiv->state)); + + switch (musb->xceiv->state) { + case OTG_STATE_A_PERIPHERAL: + musb_g_disconnect(musb); + dev_dbg(musb->controller, "HNP: back to %s\n", + usb_otg_state_string(musb->xceiv->state)); + break; + case OTG_STATE_B_HOST: + dev_dbg(musb->controller, "HNP: Disabling HR\n"); + hcd->self.is_b_host = 0; + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + MUSB_DEV_MODE(musb); + /* reg = musb_readb(mbase, MUSB_POWER); */ + reg = os_readl(U3D_POWER_MANAGEMENT); + reg |= SUSPENDM_ENABLE; + os_writel(U3D_POWER_MANAGEMENT, reg); + /* REVISIT: Start SESSION_REQUEST here? */ + break; + default: + dev_dbg(musb->controller, "HNP: Stopping in unknown state %s\n", + usb_otg_state_string(musb->xceiv->state)); + } + + /* + * When returning to A state after HNP, avoid hub_port_rebounce(), + * which cause occasional OPT A "Did not receive reset after connect" + * errors. + */ + musb->port1_status &= ~(USB_PORT_STAT_C_CONNECTION << 16); +} + +/* + * Interrupt Service Routine to record USB "global" interrupts. + * Since these do not happen often and signify things of + * paramount importance, it seems OK to check them individually; + * the order of the tests is specified in the manual + * + * @param musb instance pointer + * @param int_usb register contents + * @param devctl + * @param power + */ + +static irqreturn_t musb_stage0_irq(struct musb *musb, u32 int_usb, u8 devctl, u8 power) +{ + struct usb_otg *otg = musb->xceiv->otg; + irqreturn_t handled = IRQ_NONE; + + dev_notice(musb->controller, "<== Power=%02x, DevCtl=%02x, int_usb=0x%x\n", power, devctl, + int_usb); + + /* in host mode, the peripheral may issue remote wakeup. + * in peripheral mode, the host may resume the link. + * spurious RESUME irqs happen too, paired with SUSPEND. + */ + if (int_usb & RESUME_INTR) { + handled = IRQ_HANDLED; + dev_notice(musb->controller, "RESUME (%s)\n", + usb_otg_state_string(musb->xceiv->state)); + + /* We implement device mode only. */ + switch (musb->xceiv->state) { + case OTG_STATE_A_SUSPEND: + /* possibly DISCONNECT is upcoming */ + musb->xceiv->state = OTG_STATE_A_HOST; + usb_hcd_resume_root_hub(musb_to_hcd(musb)); + break; + case OTG_STATE_B_WAIT_ACON: + case OTG_STATE_B_PERIPHERAL: + /* disconnect while suspended? we may + * not get a disconnect irq... + */ + if ((devctl & USB_DEVCTL_VBUSVALID) + != (3 << USB_DEVCTL_VBUS_OFFSET) + ) { + musb->int_usb |= DISCONN_INTR; + musb->int_usb &= ~SUSPEND_INTR; + break; + } + musb_g_resume(musb); + break; + case OTG_STATE_B_IDLE: + musb->int_usb &= ~SUSPEND_INTR; + break; + default: + WARNING("bogus %s RESUME (%s)\n", + "peripheral", usb_otg_state_string(musb->xceiv->state)); + } + } + + /* see manual for the order of the tests */ + if (int_usb & SESSION_REQ_INTR) { + if ((devctl & USB_DEVCTL_VBUSMASK) == USB_DEVCTL_VBUSVALID + && (devctl & USB_DEVCTL_BDEVICE)) { + dev_dbg(musb->controller, "SessReq while on B state\n"); + return IRQ_HANDLED; + } + + dev_notice(musb->controller, "SESSION_REQUEST (%s)\n", + usb_otg_state_string(musb->xceiv->state)); + + /* IRQ arrives from ID pin sense or (later, if VBUS power + * is removed) SRP. responses are time critical: + * - turn on VBUS (with silicon-specific mechanism) + * - go through A_WAIT_VRISE + * - ... to A_WAIT_BCON. + * a_wait_vrise_tmout triggers VBUS_ERROR transitions + */ + /* os_writel(mregs + MAC_DEVICE_CONTROL, devctl & USB_DEVCTL_SESSION); */ + musb->ep0_stage = MUSB_EP0_START; + musb->xceiv->state = OTG_STATE_A_IDLE; + MUSB_HST_MODE(musb); + musb_platform_set_vbus(musb, 1); + + handled = IRQ_HANDLED; + } + + if (int_usb & VBUSERR_INTR) { + int ignore = 0; + + /* During connection as an A-Device, we may see a short + * current spikes causing voltage drop, because of cable + * and peripheral capacitance combined with vbus draw. + * (So: less common with truly self-powered devices, where + * vbus doesn't act like a power supply.) + * + * Such spikes are short; usually less than ~500 usec, max + * of ~2 msec. That is, they're not sustained overcurrent + * errors, though they're reported using VBUSERROR irqs. + * + * Workarounds: (a) hardware: use self powered devices. + * (b) software: ignore non-repeated VBUS errors. + * + * REVISIT: do delays from lots of DEBUG_KERNEL checks + * make trouble here, keeping VBUS < 4.4V ? + */ + switch (musb->xceiv->state) { + case OTG_STATE_A_HOST: + /* recovery is dicey once we've gotten past the + * initial stages of enumeration, but if VBUS + * stayed ok at the other end of the link, and + * another reset is due (at least for high speed, + * to redo the chirp etc), it might work OK... + */ + case OTG_STATE_A_WAIT_BCON: + case OTG_STATE_A_WAIT_VRISE: + if (musb->vbuserr_retry) { + musb->vbuserr_retry--; + ignore = 1; + devctl |= USB_DEVCTL_SESSION; + /* os_writel(mregs + MAC_DEVICE_CONTROL, devctl & USB_DEVCTL_SESSION); */ + } else { + musb->port1_status |= + USB_PORT_STAT_OVERCURRENT | (USB_PORT_STAT_C_OVERCURRENT << 16); + } + break; + default: + break; + } + + dev_notice(musb->controller, "VBUS_ERROR in %s (%02x, %s), retry #%d, port1 %08x\n", + usb_otg_state_string(musb->xceiv->state), devctl, ({ + char *s; + + switch (devctl & + USB_DEVCTL_VBUSMASK) { + case 0 << USB_DEVCTL_VBUS_OFFSET: + s = "<SessEnd"; break; case 1 << USB_DEVCTL_VBUS_OFFSET: + s = "<AValid"; break; case 2 << USB_DEVCTL_VBUS_OFFSET: + s = "<VBusValid"; + break; + /* case 3 << MUSB_DEVCTL_VBUS_SHIFT: */ + default: + s = "VALID"; break; }; + s; } + ), VBUSERR_RETRY_COUNT - musb->vbuserr_retry, musb->port1_status); + + /* go through A_WAIT_VFALL then start a new session */ + if (!ignore) + musb_platform_set_vbus(musb, 0); + handled = IRQ_HANDLED; + } + + if (int_usb & SUSPEND_INTR) { + dev_notice(musb->controller, "SUSPEND (%s) devctl %02x power %02x\n", + usb_otg_state_string(musb->xceiv->state), devctl, power); + handled = IRQ_HANDLED; + + switch (musb->xceiv->state) { + case OTG_STATE_A_PERIPHERAL: + /* We also come here if the cable is removed, since + * this silicon doesn't report ID-no-longer-grounded. + * + * We depend on T(a_wait_bcon) to shut us down, and + * hope users don't do anything dicey during this + * undesired detour through A_WAIT_BCON. + */ + musb_hnp_stop(musb); + usb_hcd_resume_root_hub(musb_to_hcd(musb)); + /* musb_root_disconnect(musb); //I don't port virthub now. */ + musb_platform_try_idle(musb, jiffies + + msecs_to_jiffies(musb->a_wait_bcon + ? : OTG_TIME_A_WAIT_BCON)); + + break; + case OTG_STATE_B_IDLE: + if (!musb->is_active) + break; + case OTG_STATE_B_PERIPHERAL: + musb_g_suspend(musb); + musb->is_active = is_otg_enabled(musb) + && otg->gadget->b_hnp_enable; + if (musb->is_active) { + musb->xceiv->state = OTG_STATE_B_WAIT_ACON; + dev_dbg(musb->controller, "HNP: Setting timer for b_ase0_brst\n"); + mod_timer(&musb->otg_timer, jiffies + + msecs_to_jiffies(OTG_TIME_B_ASE0_BRST)); + } + break; + case OTG_STATE_A_WAIT_BCON: + if (musb->a_wait_bcon != 0) + musb_platform_try_idle(musb, jiffies + + msecs_to_jiffies(musb->a_wait_bcon)); + break; + case OTG_STATE_A_HOST: + musb->xceiv->state = OTG_STATE_A_SUSPEND; + musb->is_active = is_otg_enabled(musb) + && otg->host->b_hnp_enable; + break; + case OTG_STATE_B_HOST: + /* Transition to B_PERIPHERAL, see 6.8.2.6 p 44 */ + dev_dbg(musb->controller, "REVISIT: SUSPEND as B_HOST\n"); + break; + default: + /* "should not happen" */ + musb->is_active = 0; + break; + } + } + + if (int_usb & CONN_INTR) { + struct usb_hcd *hcd = musb_to_hcd(musb); + u32 int_en = 0; + + handled = IRQ_HANDLED; + musb->is_active = 1; + + musb->ep0_stage = MUSB_EP0_START; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_START\n"); + + /* flush endpoints when transitioning from Device Mode */ + if (is_peripheral_active(musb)) { + /* REVISIT HNP; */ + /* just force disconnect */ + } + /* musb_writew(musb->mregs, MUSB_INTRTXE, musb->epmask); */ + /* musb_writew(musb->mregs, MUSB_INTRRXE, musb->epmask & 0xfffe); */ +#ifdef USE_SSUSB_QMU + /*Only Enable EP0 Tx interrupt */ + os_writel(U3D_EPIESR, os_readl(U3D_EPIESR) | EP0ISR); +#else + /*Enable EP0 Tx and EPn Tx/Rx interrupt */ + os_printk(K_DEBUG, "Enable EP0 & EPn interrupt =%x\n", + musb->epmask | ((musb->epmask << 16) & EPRISR)); + os_writel(U3D_EPIESR, musb->epmask | ((musb->epmask << 16) & EPRISR)); +#endif + int_en = + SUSPEND_INTR_EN | RESUME_INTR_EN | RESET_INTR_EN | CONN_INTR_EN | + DISCONN_INTR_EN; + + os_writel(U3D_COMMON_USB_INTR_ENABLE, int_en); + + /* musb_writeb(musb->mregs, MUSB_INTRUSBE, 0xf7); */ + + musb->port1_status &= ~(USB_PORT_STAT_LOW_SPEED + | USB_PORT_STAT_HIGH_SPEED | USB_PORT_STAT_ENABLE); + musb->port1_status |= USB_PORT_STAT_CONNECTION | (USB_PORT_STAT_C_CONNECTION << 16); + + /* high vs full speed is just a guess until after reset */ + if (devctl & USB_DEVCTL_LS_DEV) + musb->port1_status |= USB_PORT_STAT_LOW_SPEED; + + /* indicate new connection to OTG machine */ + switch (musb->xceiv->state) { + case OTG_STATE_B_PERIPHERAL: + if (int_usb & SUSPEND_INTR) { + dev_dbg(musb->controller, "HNP: SUSPEND+CONNECT, now b_host\n"); + int_usb &= ~SUSPEND_INTR; + goto b_host; + } else + dev_dbg(musb->controller, "CONNECT as b_peripheral???\n"); + break; + case OTG_STATE_B_WAIT_ACON: + dev_dbg(musb->controller, "HNP: CONNECT, now b_host\n"); +b_host: + musb->xceiv->state = OTG_STATE_B_HOST; + hcd->self.is_b_host = 1; + musb->ignore_disconnect = 0; + del_timer(&musb->otg_timer); + break; + default: + if ((devctl & USB_DEVCTL_VBUSVALID) + == (3 << USB_DEVCTL_VBUS_OFFSET)) { + musb->xceiv->state = OTG_STATE_A_HOST; + hcd->self.is_b_host = 0; + } + break; + } + + /* poke the root hub */ + MUSB_HST_MODE(musb); + if (hcd->status_urb) + usb_hcd_poll_rh_status(hcd); + else + usb_hcd_resume_root_hub(hcd); + + dev_notice(musb->controller, "CONNECT (%s) devctl %02x\n", + usb_otg_state_string(musb->xceiv->state), devctl); + } + + if ((int_usb & DISCONN_INTR) && !musb->ignore_disconnect) { + dev_notice(musb->controller, "DISCONNECT (%s) as %s, devctl %02x\n", + usb_otg_state_string(musb->xceiv->state), MUSB_MODE(musb), devctl); + handled = IRQ_HANDLED; + + switch (musb->xceiv->state) { + case OTG_STATE_A_HOST: + case OTG_STATE_A_SUSPEND: + usb_hcd_resume_root_hub(musb_to_hcd(musb)); +/* musb_root_disconnect(musb); */ + if (musb->a_wait_bcon != 0 && is_otg_enabled(musb)) + musb_platform_try_idle(musb, jiffies + + msecs_to_jiffies(musb->a_wait_bcon)); + break; + case OTG_STATE_B_HOST: + /* REVISIT this behaves for "real disconnect" + * cases; make sure the other transitions from + * from B_HOST act right too. The B_HOST code + * in hnp_stop() is currently not used... + */ + /* musb_root_disconnect(musb); //I don't port virthub now. */ + musb_to_hcd(musb)->self.is_b_host = 0; + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + MUSB_DEV_MODE(musb); + musb_g_disconnect(musb); + break; + case OTG_STATE_A_PERIPHERAL: + musb_hnp_stop(musb); + /* musb_root_disconnect(musb); //I don't port virthub now. */ + /* FALLTHROUGH */ + case OTG_STATE_B_WAIT_ACON: + /* FALLTHROUGH */ + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_IDLE: + musb_g_disconnect(musb); + break; + default: + WARNING("unhandled DISCONNECT transition (%s)\n", + usb_otg_state_string(musb->xceiv->state)); + break; + } + } + + /* mentor saves a bit: bus reset and babble share the same irq. + * only host sees babble; only peripheral sees bus reset. + */ + if (int_usb & RESET_INTR) { + handled = IRQ_HANDLED; + + mu3d_hal_pdn_ip_port(1, 0, 1, 1); + + if (1) { /* device mode */ + dev_notice(musb->controller, "BUS RESET as %s\n", + usb_otg_state_string(musb->xceiv->state)); + os_printk(K_INFO, "BUS RESET\n"); + switch (musb->xceiv->state) { + case OTG_STATE_A_SUSPEND: + /* We need to ignore disconnect on suspend + * otherwise tusb 2.0 won't reconnect after a + * power cycle, which breaks otg compliance. + */ + musb->ignore_disconnect = 1; + musb_g_reset(musb); + /* FALLTHROUGH */ + case OTG_STATE_A_WAIT_BCON: /* OPT TD.4.7-900ms */ + /* never use invalid T(a_wait_bcon) */ + dev_dbg(musb->controller, "HNP: in %s, %d msec timeout\n", + usb_otg_state_string(musb->xceiv->state), + TA_WAIT_BCON(musb)); + mod_timer(&musb->otg_timer, jiffies + + msecs_to_jiffies(TA_WAIT_BCON(musb))); + break; + case OTG_STATE_A_PERIPHERAL: + musb->ignore_disconnect = 0; + del_timer(&musb->otg_timer); + musb_g_reset(musb); + break; + case OTG_STATE_B_WAIT_ACON: + dev_dbg(musb->controller, "HNP: RESET (%s), to b_peripheral\n", + usb_otg_state_string(musb->xceiv->state)); + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb_g_reset(musb); + break; + case OTG_STATE_B_IDLE: + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + /* FALLTHROUGH */ + case OTG_STATE_B_PERIPHERAL: + musb_g_reset(musb); + break; + default: + dev_dbg(musb->controller, "Unhandled BUS RESET as %s\n", + usb_otg_state_string(musb->xceiv->state)); + } + } + } + + schedule_work(&musb->irq_work); + + return handled; +} + +#ifdef EP_PROFILING +#define POLL_INTERVAL 10 + +unsigned int ep_prof[8][2]; + +static void ep_prof_work(struct work_struct *data) +{ + struct musb *musb = container_of(to_delayed_work(data), struct musb, ep_prof_work); + + int i; + int tx = 0; + int rx = 0; + bool is_print = false; + + for (i = 1; i < 9; i++) { + if ((ep_prof[i - 1][0] != 0) || (ep_prof[i - 1][1] != 0)) { + os_printk(K_INFO, "[%d]T%d,R%d", i, ep_prof[i - 1][0], ep_prof[i - 1][1]); + tx += ep_prof[i - 1][0]; + rx += ep_prof[i - 1][1]; + is_print = true; + } + ep_prof[i - 1][0] = ep_prof[i - 1][1] = 0; + } + + if (is_print) + os_printk(K_INFO, "T%d,R%d\n", tx, rx); + + schedule_delayed_work(&musb->ep_prof_work, msecs_to_jiffies(POLL_INTERVAL * 1000)); +} +#endif + +static void musb_restore_context(struct musb *musb); +static void musb_save_context(struct musb *musb); + + +/*-------------------------------------------------------------------------*/ +/* +* Program the HDRC to start (enable interrupts, dma, etc.). +*/ +void musb_start(struct musb *musb) +{ + u8 devctl = (u8) os_readl(U3D_DEVICE_CONTROL); + + dev_dbg(musb->controller, "<== devctl %02x\n", devctl); + + os_printk(K_INFO, "%s\n", __func__); + + if (musb->is_clk_on == 0) { +#ifndef CONFIG_MTK_FPGA + /* Recovert PHY. And turn on CLK. */ + usb_phy_recover(musb->is_clk_on); + musb->is_clk_on = 1; + + /* USB 2.0 slew rate calibration */ + u3phy_ops->u2_slew_rate_calibration(u3phy); +#endif + + /* disable IP reset and power down, disable U2/U3 ip power down */ + _ex_mu3d_hal_ssusb_en(); + + /* USB PLL Force settings */ +#ifdef CONFIG_PROJECT_PHY + usb20_pll_settings(false, false); +#endif + + /* reset U3D all dev module. */ + mu3d_hal_rst_dev(); + + /* + * SW workaround of SSUSB device mode fake disable interrupt + * 1. Clear SSUSB_U3_PORT_DIS @ _ex_mu3d_hal_ssusb_en() + * 2. Wait SSUSB_U3_MAC_RST_B_STS change to 1. @ mu3d_hal_check_clk_sts() + * 3. Delay 50us + * 4. Clear U3 interrupt @ mu3d_hal_check_clk_sts() + * Recommended value : 50us + */ + udelay(20); + + musb_restore_context(musb); + } + + /*Enable Level 1 interrupt (BMU, QMU, MAC3, DMA, MAC2, EPCTL) */ + os_writel(U3D_LV1IESR, 0xFFFFFFFF); + + /* Initialize the default interrupts */ + _ex_mu3d_hal_system_intr_en(); + +#ifdef USB_GADGET_SUPERSPEED + /* HS/FS detected by HW */ + /* USB2.0 controller will negotiate for HS mode when the device is reset by the host */ + os_writel(U3D_POWER_MANAGEMENT, (os_readl(U3D_POWER_MANAGEMENT) | HS_ENABLE)); + + /* set LPM remote wake up enable by HW */ + os_writel(U3D_POWER_MANAGEMENT, (os_readl(U3D_POWER_MANAGEMENT) | LPM_HRWE)); + os_writel(U3D_USB2_EPCTL_LPM, (L1_EXIT_EP0_CHK | L1_EXIT_EP_IN_CHK | L1_EXIT_EP_OUT_CHK)); + os_writel(U3D_USB2_EPCTL_LPM_FC_CHK, + (L1_EXIT_EP0_FC_CHK | L1_EXIT_EP_IN_FC_CHK | L1_EXIT_EP_OUT_FC_CHK)); + +#ifdef CONFIG_USBIF_COMPLIANCE + /* Accept LGO_U1/U2 at beginning */ + os_writel(U3D_LINK_POWER_CONTROL, + os_readl(U3D_LINK_POWER_CONTROL) | SW_U1_ACCEPT_ENABLE | SW_U2_ACCEPT_ENABLE); + + /* 3us timeout for PENDING HP */ + os_writel(U3D_LINK_HP_TIMER, (os_readl(U3D_LINK_HP_TIMER) & ~(PHP_TIMEOUT_VALUE)) | 0x6); + + /* set vbus force enable */ + os_setmsk(U3D_MISC_CTRL, (VBUS_FRC_EN | VBUS_ON)); +#endif + + /* device responses to u3_exit from host automatically */ + os_writel(U3D_LTSSM_CTRL, os_readl(U3D_LTSSM_CTRL) & ~SOFT_U3_EXIT_EN); + +#else +#ifdef USB_GADGET_DUALSPEED + /* HS/FS detected by HW */ + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) | HS_ENABLE); +#else + /* FS only */ + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) & ~HS_ENABLE); +#endif + /* disable U3 port */ + mu3d_hal_u3dev_dis(); +#endif + +#ifndef CONFIG_MTK_FPGA + /*if (mt_get_chip_hw_code() == 0x6595) */ + { + os_printk(K_INFO, "%s Set Clock to 62.4MHz+\n", __func__); + /* sys_ck = OSC 124.8MHz/2 = 62.4MHz */ + os_setmsk(U3D_SSUSB_SYS_CK_CTRL, SSUSB_SYS_CK_DIV2_EN); + /* U2 MAC sys_ck = ceil(62.4) = 63 */ + os_writelmsk(U3D_USB20_TIMING_PARAMETER, 63, TIME_VALUE_1US); +#ifdef SUPPORT_U3 + /* U3 MAC sys_ck = ceil(62.4) = 63 */ + os_writelmsk(U3D_TIMING_PULSE_CTRL, 63, CNT_1US_VALUE); +#endif + os_printk(K_INFO, "%s Set Clock to 62.4MHz-\n", __func__); + } +#endif + + os_writel(U3D_LINK_RESET_INFO, os_readl(U3D_LINK_RESET_INFO) & ~WTCHRP); + + /* U2/U3 detected by HW */ + os_writel(U3D_DEVICE_CONF, 0); + + musb->is_active = 1; + + musb_platform_enable(musb); + +#ifdef EP_PROFILING + if (is_prof != 0) + schedule_delayed_work(&musb->ep_prof_work, msecs_to_jiffies(POLL_INTERVAL * 1000)); +#endif + + if (musb->softconnect) + mu3d_hal_u3dev_en(); +} + + +static void musb_generic_disable(void) +{ + /*Disable interrupts */ + mu3d_hal_initr_dis(); + + /*Clear all interrupt status */ + mu3d_hal_clear_intr(); +} + +/* + * 1. Disable U2 & U3 function + * 2. Notify disconnect event to upper + */ +static void gadget_stop(struct musb *musb) +{ + /* Disable U2 detect */ + mu3d_hal_u3dev_dis(); + mu3d_hal_u2dev_disconn(); + + /* notify gadget driver */ + if (musb->g.speed != USB_SPEED_UNKNOWN) { + if (musb->gadget_driver && musb->gadget_driver->disconnect) + musb->gadget_driver->disconnect(&musb->g); + musb->g.speed = USB_SPEED_UNKNOWN; + } +} + +/* + * Make the HDRC stop (disable interrupts, etc.); + * reversible by musb_start + * called on gadget driver unregister + * with controller locked, irqs blocked + * acts as a NOP unless some role activated the hardware + */ +void musb_stop(struct musb *musb) +{ + os_printk(K_INFO, "musb_stop\n"); + + /* stop IRQs, timers, ... */ + musb_platform_disable(musb); + musb_generic_disable(); + + /*Added by M */ + gadget_stop(musb); + musb->is_active = 0; + /*Added by M */ +#ifndef CONFIG_USBIF_COMPLIANCE + cancel_delayed_work_sync(&musb->check_ltssm_work); +#endif + + dev_dbg(musb->controller, "HDRC disabled\n"); + + if (musb->active_ep == 0) + schedule_work(&musb->suspend_work); + + /* Move to suspend work queue */ +#ifdef NEVER + /* + * Note: When reset the SSUSB IP, All MAC regs can _NOT_ be accessed and be reset to the default value. + * So save the MUST-SAVED reg in the context structure before set SSUSB_IP_SW_RST. + */ + musb_save_context(musb); + + /* Set SSUSB_IP_SW_RST to avoid power leakage */ +#ifdef CONFIG_MTK_UART_USB_SWITCH + if (!in_uart_mode) + os_setmsk(U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); +#else + os_setmsk(U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); +#endif + +#ifndef CONFIG_MTK_FPGA + /* Let PHY enter savecurrent mode. And turn off CLK. */ + usb_phy_savecurrent(musb->is_clk_on); + musb->is_clk_on = 0; +#endif +#endif /* NEVER */ + + /* FIXME + * - mark host and/or peripheral drivers unusable/inactive + * - disable DMA (and enable it in HdrcStart) + * - make sure we can musb_start() after musb_stop(); with + * OTG mode, gadget driver module rmmod/modprobe cycles that + * - ... + */ + musb_platform_try_idle(musb, 0); +} + +static void musb_shutdown(struct platform_device *pdev) +{ + struct musb *musb = dev_to_musb(&pdev->dev); + unsigned long flags; + + pm_runtime_get_sync(musb->controller); + spin_lock_irqsave(&musb->lock, flags); + musb_platform_disable(musb); + musb_generic_disable(); + spin_unlock_irqrestore(&musb->lock, flags); + +#ifndef CONFIG_USBIF_COMPLIANCE + if (!is_otg_enabled(musb) && is_host_enabled(musb)) + usb_remove_hcd(musb_to_hcd(musb)); +#endif + + os_writel(U3D_DEVICE_CONTROL, 0); + musb_platform_exit(musb); + + pm_runtime_put(musb->controller); + /* FIXME power down */ +} + + +/*-------------------------------------------------------------------------*/ + +/* + * The silicon either has hard-wired endpoint configurations, or else + * "dynamic fifo" sizing. The driver has support for both, though at this + * writing only the dynamic sizing is very well tested. Since we switched + * away from compile-time hardware parameters, we can no longer rely on + * dead code elimination to leave only the relevant one in the object file. + * + * We don't currently use dynamic fifo setup capability to do anything + * more than selecting one of a bunch of predefined configurations. + */ +#if defined(CONFIG_USB_MUSB_TUSB6010) \ + || defined(CONFIG_USB_MUSB_TUSB6010_MODULE) \ + || defined(CONFIG_USB_MUSB_OMAP2PLUS) \ + || defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE) \ + || defined(CONFIG_USB_MUSB_AM35X) \ + || defined(CONFIG_USB_MUSB_AM35X_MODULE) + +#ifdef CONFIG_USBIF_COMPLIANCE +static ushort fifo_mode = 4; +#else +static ushort __initdata fifo_mode = 4; +#endif + +#elif defined(CONFIG_USB_MUSB_UX500) \ + || defined(CONFIG_USB_MUSB_UX500_MODULE) + +#ifdef CONFIG_USBIF_COMPLIANCE +static ushort fifo_mode = 5; +#else +static ushort __initdata fifo_mode = 5; +#endif + +#else + +#ifdef CONFIG_USBIF_COMPLIANCE +static ushort fifo_mode = 2; +#else +static ushort __initdata fifo_mode = 2; +#endif + +#endif + +/* "modprobe ... fifo_mode=1" etc */ +module_param(fifo_mode, ushort, 0); +MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration"); + +/* + * tables defining fifo_mode values. define more if you like. + * for host side, make sure both halves of ep1 are set up. + */ + +/* mode 0 - fits in 2KB */ +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb_fifo_cfg mode_0_cfg[] = { +#else +static struct musb_fifo_cfg mode_0_cfg[] __initdata = { +#endif + {.hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512,}, + {.hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256,}, + {.hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256,}, +}; + +/* mode 1 - fits in 4KB */ +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb_fifo_cfg mode_1_cfg[] = { +#else +static struct musb_fifo_cfg mode_1_cfg[] __initdata = { +#endif + {.hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE,}, + {.hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE,}, + {.hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE,}, + {.hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256,}, + {.hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256,}, +}; + +/* mode 2 - fits in 4KB */ +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb_fifo_cfg mode_2_cfg[] = { +#else +static struct musb_fifo_cfg mode_2_cfg[] __initdata = { +#endif + {.hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256,}, + {.hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256,}, +}; + +/* mode 3 - fits in 4KB */ +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb_fifo_cfg mode_3_cfg[] = { +#else +static struct musb_fifo_cfg mode_3_cfg[] __initdata = { +#endif + {.hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE,}, + {.hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE,}, + {.hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 3, .style = FIFO_RXTX, .maxpacket = 256,}, + {.hw_ep_num = 4, .style = FIFO_RXTX, .maxpacket = 256,}, +}; + +/* mode 4 - fits in 16KB */ +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb_fifo_cfg mode_4_cfg[] = { +#else +static struct musb_fifo_cfg mode_4_cfg[] __initdata = { +#endif + {.hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 5, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 5, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 6, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 6, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 7, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 7, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 8, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 9, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 9, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 256,}, + {.hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 64,}, + {.hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 256,}, + {.hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 64,}, + {.hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 256,}, + {.hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 64,}, + {.hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 4096,}, + {.hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024,}, + {.hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024,}, +}; + +/* mode 5 - fits in 8KB */ +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb_fifo_cfg mode_5_cfg[] = { +#else +static struct musb_fifo_cfg mode_5_cfg[] __initdata = { +#endif + {.hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 5, .style = FIFO_TX, .maxpacket = 512,}, + {.hw_ep_num = 5, .style = FIFO_RX, .maxpacket = 512,}, + {.hw_ep_num = 6, .style = FIFO_TX, .maxpacket = 32,}, + {.hw_ep_num = 6, .style = FIFO_RX, .maxpacket = 32,}, + {.hw_ep_num = 7, .style = FIFO_TX, .maxpacket = 32,}, + {.hw_ep_num = 7, .style = FIFO_RX, .maxpacket = 32,}, + {.hw_ep_num = 8, .style = FIFO_TX, .maxpacket = 32,}, + {.hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 32,}, + {.hw_ep_num = 9, .style = FIFO_TX, .maxpacket = 32,}, + {.hw_ep_num = 9, .style = FIFO_RX, .maxpacket = 32,}, + {.hw_ep_num = 10, .style = FIFO_TX, .maxpacket = 32,}, + {.hw_ep_num = 10, .style = FIFO_RX, .maxpacket = 32,}, + {.hw_ep_num = 11, .style = FIFO_TX, .maxpacket = 32,}, + {.hw_ep_num = 11, .style = FIFO_RX, .maxpacket = 32,}, + {.hw_ep_num = 12, .style = FIFO_TX, .maxpacket = 32,}, + {.hw_ep_num = 12, .style = FIFO_RX, .maxpacket = 32,}, + {.hw_ep_num = 13, .style = FIFO_RXTX, .maxpacket = 512,}, + {.hw_ep_num = 14, .style = FIFO_RXTX, .maxpacket = 1024,}, + {.hw_ep_num = 15, .style = FIFO_RXTX, .maxpacket = 1024,}, +}; + +void ep0_setup(struct musb *musb, struct musb_hw_ep *hw_ep0, const struct musb_fifo_cfg *cfg) +{ + os_printk(K_INFO, "ep0_setup maxpacket: %d\n", cfg->maxpacket); + + hw_ep0->fifoaddr_rx = 0; + hw_ep0->fifoaddr_tx = 0; + hw_ep0->is_shared_fifo = true; + hw_ep0->fifo = (void __iomem *)(uintptr_t) MUSB_FIFO_OFFSET(0); /* QMU GPD address --> CPU DMA address */ + + /* for U2 */ + hw_ep0->max_packet_sz_tx = cfg->maxpacket; + hw_ep0->max_packet_sz_rx = cfg->maxpacket; + + /* Defines the maximum amount of data that can be transferred through EP0 in a single operation. */ + os_writelmskumsk(U3D_EP0CSR, hw_ep0->max_packet_sz_tx, EP0_MAXPKTSZ0, EP0_W1C_BITS); + + /* Enable EP0 interrupt */ + os_writel(U3D_EPIESR, os_readl(U3D_EPIESR) | EP0ISR); +} + +/* + * configure a fifo; for non-shared endpoints, this may be called + * once for a tx fifo and once for an rx fifo. + * + * returns negative errno or offset for next fifo. + */ +#ifdef CONFIG_USBIF_COMPLIANCE +static int fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, const struct musb_fifo_cfg *cfg, + u16 offset) +#else +static int __init +fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, const struct musb_fifo_cfg *cfg, u16 offset) +#endif +{ + u16 maxpacket = cfg->maxpacket; + /* u16 c_off = offset >> 3; */ + u16 ret_offset = 0; + u32 maxpreg = 0; + u8 mult = 0; + + /* calculate mult. added for ssusb. */ + if (maxpacket > 1024) { + maxpreg = 1024; + mult = (maxpacket / 1024) - 1; + } else { + maxpreg = maxpacket; + /* set EP0 TX/RX slot to 3 by default */ + /* REVISIT-J: WHY? CHECK! */ + /* if (hw_ep->epnum == 1) */ + /* mult = 3; */ + } + + /*REVISIT-J: WHY? CHECK! EP1 as BULK EP */ + /* EP0 reserved endpoint for control, bidirectional; + * EP1 reserved for bulk, two unidirection halves. + */ + if (hw_ep->epnum == 1) + musb->bulk_ep = hw_ep; + /* REVISIT error check: be sure ep0 can both rx and tx ... */ + if ((cfg->style == FIFO_TX) || (cfg->style == FIFO_RXTX)) { + hw_ep->max_packet_sz_tx = maxpreg; + hw_ep->mult_tx = mult; + + hw_ep->fifoaddr_tx = musb->txfifoadd_offset; + if (maxpacket == 1023) + musb->txfifoadd_offset += (1024 * (hw_ep->mult_tx + 1)); + else + musb->txfifoadd_offset += (maxpacket * (hw_ep->mult_tx + 1)); + ret_offset = musb->txfifoadd_offset; + } + + if ((cfg->style == FIFO_RX) || (cfg->style == FIFO_RXTX)) { + hw_ep->max_packet_sz_rx = maxpreg; + hw_ep->mult_rx = mult; + + hw_ep->fifoaddr_rx = musb->rxfifoadd_offset; + if (maxpacket == 1023) + musb->rxfifoadd_offset += (1024 * (hw_ep->mult_rx + 1)); + else + musb->rxfifoadd_offset += (maxpacket * (hw_ep->mult_rx + 1)); + ret_offset = musb->rxfifoadd_offset; + } + + /* NOTE rx and tx endpoint irqs aren't managed separately, + * which happens to be ok + */ + musb->epmask |= (1 << hw_ep->epnum); + + return ret_offset; + +} + + +struct musb_fifo_cfg ep0_cfg_u3 = { + .style = FIFO_RXTX, .maxpacket = 512, +}; + +struct musb_fifo_cfg ep0_cfg_u2 = { + .style = FIFO_RXTX, .maxpacket = 64, +}; + +#ifdef CONFIG_USBIF_COMPLIANCE +static int ep_config_from_table(struct musb *musb) +#else +static int __init ep_config_from_table(struct musb *musb) +#endif +{ + const struct musb_fifo_cfg *cfg; + unsigned i, n; + int offset = 0; + struct musb_hw_ep *hw_ep = musb->endpoints; + + if (musb->config->fifo_cfg) { + cfg = musb->config->fifo_cfg; + n = musb->config->fifo_cfg_size; + os_printk(K_DEBUG, "%s: usb pre-cfg fifo_mode cfg=%p sz=%d\n", musb_driver_name, + cfg, n); + goto done; + } + + switch (fifo_mode) { + default: + fifo_mode = 0; + /* FALLTHROUGH */ + case 0: + cfg = mode_0_cfg; + n = ARRAY_SIZE(mode_0_cfg); + break; + case 1: + cfg = mode_1_cfg; + n = ARRAY_SIZE(mode_1_cfg); + break; + case 2: + cfg = mode_2_cfg; + n = ARRAY_SIZE(mode_2_cfg); + break; + case 3: + cfg = mode_3_cfg; + n = ARRAY_SIZE(mode_3_cfg); + break; + case 4: + cfg = mode_4_cfg; + n = ARRAY_SIZE(mode_4_cfg); + break; + case 5: + cfg = mode_5_cfg; + n = ARRAY_SIZE(mode_5_cfg); + break; + } + + os_printk(K_INFO, "%s: setup fifo_mode %d\n", musb_driver_name, fifo_mode); + + +done: +#ifdef USB_GADGET_SUPERSPEED /* SS */ + /* use SS EP0 as default; it may be changed later */ + os_printk(K_INFO, "%s ep_config_from_table ep0_cfg_u3\n", __func__); + ep0_setup(musb, hw_ep, &ep0_cfg_u3); +#else /* HS, FS */ + os_printk(K_INFO, "%s ep_config_from_table ep0_cfg_u2\n", __func__); + ep0_setup(musb, hw_ep, &ep0_cfg_u2); +#endif + /* assert(offset > 0) */ + + /* NOTE: for RTL versions >= 1.400 EPINFO and RAMINFO would + * be better than static musb->config->num_eps and DYN_FIFO_SIZE... + */ + + for (i = 0; i < n; i++) { + u8 epn = cfg->hw_ep_num; + + if (epn >= musb->config->num_eps) { + os_printk(K_ERR, "%s: invalid ep %d\n", musb_driver_name, epn); + return -EINVAL; + } + offset = fifo_setup(musb, hw_ep + epn, cfg++, offset); + if (offset < 0) { + os_printk(K_ERR, "%s: mem overrun, ep %d\n", musb_driver_name, epn); + return -EINVAL; + } + epn++; + musb->nr_endpoints = max(epn, musb->nr_endpoints); + } + + os_printk(K_INFO, "%s: %d/%d max ep, %d/%d memory\n", + musb_driver_name, + n + 1, musb->config->num_eps * 2 - 1, + offset, (1 << (musb->config->ram_bits + 2))); + + if (!musb->bulk_ep) { + pr_debug("%s: missing bulk\n", musb_driver_name); + return -EINVAL; + } + + return 0; +} + + +/* + * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false + * @param musb the controller + */ +static int ep_config_from_hw(struct musb *musb) +{ + u8 epnum = 0; + struct musb_hw_ep *hw_ep; + void __iomem *mbase = musb->mregs; + int ret = 0; + + dev_dbg(musb->controller, "<== static silicon ep config\n"); + + /* FIXME pick up ep0 maxpacket size */ + + for (epnum = 1; epnum < musb->config->num_eps; epnum++) { + musb_ep_select(mbase, epnum); + hw_ep = musb->endpoints + epnum; + + ret = musb_read_fifosize(musb, hw_ep, epnum); + if (ret < 0) + break; + + /* FIXME set up hw_ep->{rx,tx}_double_buffered */ + + /* pick an RX/TX endpoint for bulk */ + if (hw_ep->max_packet_sz_tx < 512 || hw_ep->max_packet_sz_rx < 512) + continue; + + /* REVISIT: this algorithm is lazy, we should at least + * try to pick a double buffered endpoint. + */ + if (musb->bulk_ep) + continue; + musb->bulk_ep = hw_ep; + } + + if (!musb->bulk_ep) { + pr_debug("%s: missing bulk\n", musb_driver_name); + return -EINVAL; + } + + return 0; +} + + +enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, }; + +/* Initialize MUSB (M)HDRC part of the USB hardware subsystem; + * configure endpoints, or take their config from silicon + */ +#ifdef CONFIG_USBIF_COMPLIANCE +static int musb_core_init(u16 musb_type, struct musb *musb) +#else +static int __init musb_core_init(u16 musb_type, struct musb *musb) +#endif +{ + /* u8 reg; */ + /* char *type; */ + /* char aInfo[90], aRevision[32], aDate[12]; */ + void __iomem *mbase = musb->mregs; + int status = 0; + int i; + + /*TODO: We can change musb_read_hwvers() api to mtu3d version! */ +#ifdef NEVER + /* log core options (read using indexed model) */ + reg = musb_read_configdata(mbase); + + strcpy(aInfo, (reg & MUSB_CONFIGDATA_UTMIDW) ? "UTMI-16" : "UTMI-8"); + if (reg & MUSB_CONFIGDATA_DYNFIFO) { + strcat(aInfo, ", dyn FIFOs"); + musb->dyn_fifo = true; + } + if (reg & MUSB_CONFIGDATA_MPRXE) { + strcat(aInfo, ", bulk combine"); + musb->bulk_combine = true; + } + if (reg & MUSB_CONFIGDATA_MPTXE) { + strcat(aInfo, ", bulk split"); + musb->bulk_split = true; + } + if (reg & MUSB_CONFIGDATA_HBRXE) { + strcat(aInfo, ", HB-ISO Rx"); + musb->hb_iso_rx = true; + } + if (reg & MUSB_CONFIGDATA_HBTXE) { + strcat(aInfo, ", HB-ISO Tx"); + musb->hb_iso_tx = true; + } + if (reg & MUSB_CONFIGDATA_SOFTCONE) + strcat(aInfo, ", SoftConn"); + + pr_debug("%s: ConfigData=0x%02x (%s)\n", musb_driver_name, reg, aInfo); + + aDate[0] = 0; + if (MUSB_CONTROLLER_MHDRC == musb_type) { + musb->is_multipoint = 1; + type = "M"; + } else { + musb->is_multipoint = 0; + type = ""; +#ifndef CONFIG_USB_OTG_BLACKLIST_HUB + pr_err("%s: kernel must blacklist external hubs\n", musb_driver_name); +#endif + } + + /* log release info */ + musb->hwvers = musb_read_hwvers(mbase); + snprintf(aRevision, 32, "%d.%d%s", MUSB_HWVERS_MAJOR(musb->hwvers), + MUSB_HWVERS_MINOR(musb->hwvers), (musb->hwvers & MUSB_HWVERS_RC) ? "RC" : ""); + pr_debug("%s: %sHDRC RTL version %s %s\n", musb_driver_name, type, aRevision, aDate); + +#endif /* NEVER */ + musb->hwvers = os_readl(U3D_SSUSB_HW_ID); + + os_printk(K_INFO, "%s: HDC version %d\n", musb_driver_name, musb->hwvers); + + /* add for U3D */ + musb->txfifoadd_offset = U3D_FIFO_START_ADDRESS; + musb->rxfifoadd_offset = U3D_FIFO_START_ADDRESS; + + os_printk(K_INFO, "%s EPnFIFOSz Tx=%x, Rx=%x\n", __func__, os_readl(U3D_CAP_EPNTXFFSZ), + os_readl(U3D_CAP_EPNRXFFSZ)); + os_printk(K_INFO, "%s EPnNum Tx=%x, Rx=%d\n", __func__, os_readl(U3D_CAP_EPINFO) & 0x1F, + (os_readl(U3D_CAP_EPINFO) >> 8) & 0x1F); + + if (os_readl(U3D_CAP_EPNTXFFSZ) && os_readl(U3D_CAP_EPNRXFFSZ)) + musb->dyn_fifo = true; + else +#ifdef CONFIG_MTK_UART_USB_SWITCH + musb->dyn_fifo = true; +#else + musb->dyn_fifo = false; +#endif + + /* discover endpoint configuration */ + musb->nr_endpoints = 1; + musb->epmask = 1; + + /* status = ep_config_from_table(musb); */ + if (musb->dyn_fifo) + status = ep_config_from_table(musb); + else + status = ep_config_from_hw(musb); + + if (status < 0) + return status; + + /* finish init, and print endpoint config */ + for (i = 0; i < musb->nr_endpoints; i++) { + struct musb_hw_ep *hw_ep = musb->endpoints + i; + + hw_ep->fifo = (void __iomem *)(uintptr_t) MUSB_FIFO_OFFSET(i); +#ifdef CONFIG_USB_MUSB_TUSB6010 + hw_ep->fifo_async = musb->async + 0x400 + MUSB_FIFO_OFFSET(i); + hw_ep->fifo_sync = musb->sync + 0x400 + MUSB_FIFO_OFFSET(i); + hw_ep->fifo_sync_va = musb->sync_va + 0x400 + MUSB_FIFO_OFFSET(i); + + if (i == 0) + hw_ep->conf = mbase - 0x400 + TUSB_EP0_CONF; + else + hw_ep->conf = mbase + 0x400 + (((i - 1) & 0xf) << 2); +#endif + + /* change data structure for ssusb */ + hw_ep->addr_txcsr0 = (void __iomem *)(uintptr_t) SSUSB_EP_TXCR0_OFFSET(i, 0); + hw_ep->addr_txcsr1 = (void __iomem *)(uintptr_t) SSUSB_EP_TXCR1_OFFSET(i, 0); + hw_ep->addr_txcsr2 = (void __iomem *)(uintptr_t) SSUSB_EP_TXCR2_OFFSET(i, 0); + hw_ep->addr_rxcsr0 = (void __iomem *)(uintptr_t) SSUSB_EP_RXCR0_OFFSET(i, 0); + hw_ep->addr_rxcsr1 = (void __iomem *)(uintptr_t) SSUSB_EP_RXCR1_OFFSET(i, 0); + hw_ep->addr_rxcsr2 = (void __iomem *)(uintptr_t) SSUSB_EP_RXCR2_OFFSET(i, 0); + hw_ep->addr_rxcsr3 = (void __iomem *)(uintptr_t) SSUSB_EP_RXCR3_OFFSET(i, 0); + + hw_ep->target_regs = musb_read_target_reg_base(i, mbase); + hw_ep->rx_reinit = 1; + hw_ep->tx_reinit = 1; + + if (hw_ep->max_packet_sz_tx) { + dev_dbg(musb->controller, + "%s: hw_ep %d%s, %smax %d\n", + musb_driver_name, i, + hw_ep->is_shared_fifo ? "shared" : "tx", + "", hw_ep->max_packet_sz_tx); + } + if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) { + dev_dbg(musb->controller, + "%s: hw_ep %d%s, %smax %d\n", + musb_driver_name, i, "rx", "", hw_ep->max_packet_sz_rx); + } + if (!(hw_ep->max_packet_sz_tx || hw_ep->max_packet_sz_rx)) + dev_dbg(musb->controller, "hw_ep %d not configured\n", i); + } + +#ifdef USE_SSUSB_QMU + /* Allocate GBD and BD */ + _ex_mu3d_hal_alloc_qmu_mem(musb->controller); + /* Iniital QMU */ + _ex_mu3d_hal_init_qmu(); + + musb_save_context(musb); +#endif + + return 0; +} + +/* + * handle all the irqs defined by the HDRC core. for now we expect: other + * irq sources (phy, dma, etc) will be handled first, musb->int_* values + * will be assigned, and the irq will already have been acked. + * + * called in irq context with spinlock held, irqs blocked + */ +irqreturn_t musb_interrupt(struct musb *musb) +{ + irqreturn_t retval = IRQ_NONE; + u8 devctl, power = 0; +#ifndef USE_SSUSB_QMU + u32 reg = 0, ep_num = 0; +#endif + +#ifdef POWER_SAVING_MODE + if (!(os_readl(U3D_SSUSB_U2_CTRL_0P) & SSUSB_U2_PORT_PDN)) { + devctl = (u8) os_readl(U3D_DEVICE_CONTROL); + power = (u8) os_readl(U3D_POWER_MANAGEMENT); + } else { + devctl = 0; + power = 0; + musb->int_usb = 0; + } +#else + devctl = (u8) os_readl(U3D_DEVICE_CONTROL); + power = (u8) os_readl(U3D_POWER_MANAGEMENT); +#endif + + /* dev_dbg(musb->controller, "** IRQ %s usb%04x tx%04x rx%04x\n", */ + os_printk(K_DEBUG, "IRQ %s usb%04x tx%04x rx%04x\n", + (devctl & USB_DEVCTL_HOSTMODE) ? "host" : "peripheral", + musb->int_usb, musb->int_tx, musb->int_rx); + + /* the core can interrupt us for multiple reasons; docs have + * a generic interrupt flowchart to follow + */ + if (musb->int_usb) + retval |= musb_stage0_irq(musb, musb->int_usb, devctl, power); + + /* "stage 1" is handling endpoint irqs */ + + /* handle endpoint 0 first */ + if (musb->int_tx & 1) + retval |= musb_g_ep0_irq(musb); + +#ifndef USE_SSUSB_QMU + /* RX on endpoints 1-15 */ + reg = musb->int_rx >> 1; + ep_num = 1; + while (reg) { + if (reg & 1) { + /* musb_ep_select(musb->mregs, ep_num); */ + /* REVISIT just retval = ep->rx_irq(...) */ + retval = IRQ_HANDLED; + musb_g_rx(musb, ep_num); + } + + reg >>= 1; + ep_num++; + } + + /* TX on endpoints 1-15 */ + reg = musb->int_tx >> 1; + ep_num = 1; + while (reg) { + if (reg & 1) { + /* musb_ep_select(musb->mregs, ep_num); */ + /* REVISIT just retval |= ep->tx_irq(...) */ + retval = IRQ_HANDLED; + musb_g_tx(musb, ep_num); + } + reg >>= 1; + ep_num++; + } +#endif + + return retval; +} +EXPORT_SYMBOL_GPL(musb_interrupt); + +#ifndef CONFIG_USB_MU3D_PIO_ONLY +static bool use_dma = 1; + +/* "modprobe ... use_dma=0" etc */ +module_param(use_dma, bool, 0); +MODULE_PARM_DESC(use_dma, "enable/disable use of DMA"); + +void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) +{ + u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL); + + /* called with controller lock already held */ + + if (!epnum) { +#ifndef CONFIG_USB_TUSB_OMAP_DMA + if (!is_cppi_enabled()) { + /* endpoint 0 */ + if (devctl & MUSB_DEVCTL_HM) + /* Do nothing, MUSB does _NOT_ support host */ + /* musb_h_ep0_irq(musb); */ + os_printk(K_DEBUG, "Call musb_h_ep0_irq(), AYKM???!!!\n"); + else + musb_g_ep0_irq(musb); + } +#endif + } else { + /* endpoints 1..15 */ + if (transmit) { + if (devctl & MUSB_DEVCTL_HM) { + if (is_host_capable()) + /* Do nothing, MUSB does _NOT_ support host */ + /* musb_host_tx(musb, epnum); */ + os_printk(K_DEBUG, "Call musb_host_tx(), AYKM???!!!\n"); + } else { + if (is_peripheral_capable()) + musb_g_tx(musb, epnum); + } + } else { + /* receive */ + if (devctl & MUSB_DEVCTL_HM) { + if (is_host_capable()) + /* Do nothing, MUSB does _NOT_ support host */ + /* musb_host_tx(musb, epnum); */ + os_printk(K_DEBUG, "Call musb_host_tx(), AYKM???!!!\n"); + } else { + if (is_peripheral_capable()) + musb_g_rx(musb, epnum); + } + } + } +} + +#else +#define use_dma 0 +#endif + +/*-------------------------------------------------------------------------*/ + +#ifdef CONFIG_SYSFS + +static ssize_t musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct musb *musb = dev_to_musb(dev); + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&musb->lock, flags); + ret = sprintf(buf, "%s\n", usb_otg_state_string(musb->xceiv->state)); + spin_unlock_irqrestore(&musb->lock, flags); + + return ret; +} + +static ssize_t +musb_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) +{ + struct musb *musb = dev_to_musb(dev); + unsigned long flags; + int status; + + spin_lock_irqsave(&musb->lock, flags); + if (sysfs_streq(buf, "host")) + status = musb_platform_set_mode(musb, MUSB_HOST); + else if (sysfs_streq(buf, "peripheral")) + status = musb_platform_set_mode(musb, MUSB_PERIPHERAL); + else if (sysfs_streq(buf, "otg")) + status = musb_platform_set_mode(musb, MUSB_OTG); + else + status = -EINVAL; + spin_unlock_irqrestore(&musb->lock, flags); + + return (status == 0) ? n : status; +} + +static DEVICE_ATTR(mode, 0644, musb_mode_show, musb_mode_store); + +static ssize_t +musb_vbus_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) +{ + struct musb *musb = dev_to_musb(dev); + unsigned long flags; + unsigned long val; + + /*if (sscanf(buf, "%lu", &val) < 1) {*/ + if (kstrtol(buf, 10, &val) < 1) { + dev_err(dev, "Invalid VBUS timeout ms value\n"); + return -EINVAL; + } + + spin_lock_irqsave(&musb->lock, flags); + /* force T(a_wait_bcon) to be zero/unlimited *OR* valid */ + musb->a_wait_bcon = val ? max_t(int, val, OTG_TIME_A_WAIT_BCON) : 0; + if (musb->xceiv->state == OTG_STATE_A_WAIT_BCON) + musb->is_active = 0; + musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(val)); + spin_unlock_irqrestore(&musb->lock, flags); + + return n; +} + +static ssize_t musb_vbus_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct musb *musb = dev_to_musb(dev); + unsigned long flags; + unsigned long val; + int vbus; + + spin_lock_irqsave(&musb->lock, flags); + val = musb->a_wait_bcon; + /* FIXME get_vbus_status() is normally #defined as false... + * and is effectively TUSB-specific. + */ + vbus = musb_platform_get_vbus_status(musb); + spin_unlock_irqrestore(&musb->lock, flags); + + return sprintf(buf, "Vbus %s, timeout %lu msec\n", vbus ? "on" : "off", val); +} + +static DEVICE_ATTR(vbus, 0644, musb_vbus_show, musb_vbus_store); + +/* Gadget drivers can't know that a host is connected so they might want + * to start SRP, but users can. This allows userspace to trigger SRP. + */ +static ssize_t +musb_srp_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) +{ + struct musb *musb = dev_to_musb(dev); + unsigned short srp; + + /*if (sscanf(buf, "%hu", &srp) != 1 || (srp != 1)) {*/ + if (kstrtol(buf, 10, (long *)&srp) != 1 || (srp != 1)) { + dev_err(dev, "SRP: Value must be 1\n"); + return -EINVAL; + } + + if (srp == 1) + musb_g_wakeup(musb); + + return n; +} + +static DEVICE_ATTR(srp, 0644, NULL, musb_srp_store); +DEVICE_ATTR(cmode, 0664, musb_cmode_show, musb_cmode_store); + +#ifdef CONFIG_MTK_UART_USB_SWITCH +DEVICE_ATTR(portmode, 0664, musb_portmode_show, musb_portmode_store); +DEVICE_ATTR(tx, 0664, musb_tx_show, musb_tx_store); +DEVICE_ATTR(rx, 0444, musb_rx_show, NULL); +DEVICE_ATTR(uartpath, 0444, musb_uart_path_show, NULL); +#endif + +static struct attribute *musb_attributes[] = { + &dev_attr_mode.attr, + &dev_attr_vbus.attr, + &dev_attr_srp.attr, + &dev_attr_cmode.attr, +#ifdef CONFIG_MTK_UART_USB_SWITCH + &dev_attr_portmode.attr, + &dev_attr_tx.attr, + &dev_attr_rx.attr, + &dev_attr_uartpath.attr, +#endif + NULL +}; + +static const struct attribute_group musb_attr_group = { + .attrs = musb_attributes, +}; + +#endif /* sysfs */ + +static void musb_save_context(struct musb *musb) +{ + int i; + + for (i = 0; i < musb->config->num_eps; ++i) { + os_printk(K_DEBUG, "%s EP%d\n", __func__, i); +#ifdef USE_SSUSB_QMU + /* Save TXQ/RXQ starting address. Those would be reset to 0 after reset SSUSB IP. */ + musb->context.index_regs[i].txqmuaddr = os_readl(USB_QMU_TQSAR(i + 1)); + os_printk(K_DEBUG, "%s TQSAR[%d]=%x\n", __func__, i, + musb->context.index_regs[i].txqmuaddr); + musb->context.index_regs[i].rxqmuaddr = os_readl(USB_QMU_RQSAR(i + 1)); + os_printk(K_DEBUG, "%s RQSAR[%d]=%x\n", __func__, i, + musb->context.index_regs[i].rxqmuaddr); +#endif + } +} + +static void musb_restore_context(struct musb *musb) +{ + int i; + + for (i = 0; i < musb->config->num_eps; ++i) { +#ifdef USE_SSUSB_QMU + os_writel(USB_QMU_TQSAR(i + 1), musb->context.index_regs[i].txqmuaddr); + os_writel(USB_QMU_RQSAR(i + 1), musb->context.index_regs[i].rxqmuaddr); + os_printk(K_DEBUG, "%s TQSAR[%d]=%x\n", __func__, i, + os_readl(USB_QMU_TQSAR(i + 1))); + os_printk(K_DEBUG, "%s TQSAR[%d]=%x\n", __func__, i, + os_readl(USB_QMU_RQSAR(i + 1))); +#endif + } +} + +static void musb_suspend_work(struct work_struct *data) +{ + struct musb *musb = container_of(data, struct musb, suspend_work); + + os_printk(K_INFO, "%s active_ep=%d, clk_on=%d\n", __func__, musb->active_ep, + musb->is_clk_on); + + if (musb->is_clk_on == 1 + && (!usb_cable_connected() || (musb->usb_mode != CABLE_MODE_NORMAL))) { + +#ifdef EP_PROFILING + cancel_delayed_work_sync(&musb->ep_prof_work); +#endif + /* + * Note: musb_save_context() _MUST_ be called _BEFORE_ setting SSUSB_IP_SW_RST. + * Because when setting SSUSB_IP_SW_RST to reset the SSUSB IP, + * All MAC regs can _NOT_ be read and be reset to the default value. + * So save the MUST-SAVED reg in the context structure. + */ + musb_save_context(musb); + + /* Set SSUSB_IP_SW_RST to avoid power leakage */ + os_setmsk(U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); + +#ifndef CONFIG_MTK_FPGA + /* Let PHY enter savecurrent mode. And turn off CLK. */ + usb_phy_savecurrent(musb->is_clk_on); + musb->is_clk_on = 0; +#endif + } +} + +/* Only used to provide driver mode change events */ +static void musb_irq_work(struct work_struct *data) +{ + struct musb *musb = container_of(data, struct musb, irq_work); + static int old_state; + + os_printk(K_INFO, "%s [%d]=[%d]\n", __func__, musb->xceiv->state, old_state); + + if (musb->xceiv->state != old_state) { + old_state = musb->xceiv->state; + sysfs_notify(&musb->controller->kobj, NULL, "mode"); + } + +} + +const struct hc_driver musb_hc_driver = { + .description = "musb-hcd", + .product_desc = "MUSB HDRC host driver", + .hcd_priv_size = sizeof(struct musb), + .flags = HCD_USB2 | HCD_MEMORY, +}; + +/* -------------------------------------------------------------------------- + * Init support + */ +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb *allocate_instance(struct device *dev, + struct musb_hdrc_config *config, void __iomem *mbase) +#else +static struct musb *__init +allocate_instance(struct device *dev, struct musb_hdrc_config *config, void __iomem *mbase) +#endif +{ + struct musb *musb; + struct musb_hw_ep *ep; + int epnum; + struct usb_hcd *hcd; + + hcd = usb_create_hcd(&musb_hc_driver, dev, dev_name(dev)); + if (!hcd) + return NULL; + /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */ + + musb = hcd_to_musb(hcd); + INIT_LIST_HEAD(&musb->control); + INIT_LIST_HEAD(&musb->in_bulk); + INIT_LIST_HEAD(&musb->out_bulk); + + hcd->uses_new_polling = 1; + hcd->has_tt = 1; + + musb->vbuserr_retry = VBUSERR_RETRY_COUNT; + musb->a_wait_bcon = OTG_TIME_A_WAIT_BCON; + dev_set_drvdata(dev, musb); + musb->mregs = mbase; + musb->ctrl_base = mbase; + musb->nIrq = -ENODEV; + musb->config = config; + BUG_ON(musb->config->num_eps > MUSB_C_NUM_EPS); + for (epnum = 0, ep = musb->endpoints; epnum < musb->config->num_eps; epnum++, ep++) { + ep->musb = musb; + ep->epnum = epnum; + } + + musb->controller = dev; + + /* added for ssusb: */ + /* musb->xceiv = kzalloc(sizeof(struct otg_transceiver), GFP_KERNEL); */ + /* memset(musb->xceiv, 0, sizeof(struct otg_transceiver)); */ + /* musb->xceiv->state = OTG_STATE_B_IDLE; //initial its value */ + + return musb; +} + +static void musb_free(struct musb *musb) +{ + /* this has multiple entry modes. it handles fault cleanup after + * probe(), where things may be partially set up, as well as rmmod + * cleanup after everything's been de-activated. + */ + +#ifdef CONFIG_SYSFS + sysfs_remove_group(&musb->controller->kobj, &musb_attr_group); +#endif + + musb_gadget_cleanup(musb); + + if (musb->nIrq >= 0) { + if (musb->irq_wake) + disable_irq_wake(musb->nIrq); + free_irq(musb->nIrq, musb); + } +#ifdef USE_SSUSB_QMU + tasklet_kill(&musb->qmu_done); + tasklet_kill(&musb->error_recovery); +#endif + + cancel_work_sync(&musb->irq_work); + cancel_delayed_work_sync(&musb->connection_work); + /* cancel_delayed_work_sync(&musb->check_ltssm_work); */ + cancel_work_sync(&musb->suspend_work); + +#ifdef USE_SSUSB_QMU + _ex_mu3d_hal_free_qmu_mem(musb->controller); +#endif +/* + if (is_dma_capable() && musb->dma_controller) { + struct dma_controller *c = musb->dma_controller; + + (void) c->stop(c); + dma_controller_destroy(c); + } +*/ + wake_lock_destroy(&musb->usb_wakelock); + + /* added for ssusb: */ +#ifdef CONFIG_USBIF_COMPLIANCE + /* kfree(musb->xceiv); //free the instance allocated in allocate_instance */ + /* musb->xceiv = NULL; */ + /* kfree(musb); */ +#else + /*i add these, need to test */ + usb_put_hcd(musb_to_hcd(musb)); + + kfree(musb->xceiv); /* free the instance allocated in allocate_instance */ + musb->xceiv = NULL; + + kfree(musb); +#endif + +} + +/* + * Perform generic per-controller initialization. + * + * @pDevice: the controller (already clocked, etc) + * @nIrq: irq + * @mregs: virtual address of controller registers, + * not yet corrected for platform-specific offsets + */ +#ifdef CONFIG_USBIF_COMPLIANCE +static int musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) +#else +static int __init musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) +#endif +{ + int status; + struct musb *musb; + struct musb_hdrc_platform_data *plat = dev->platform_data; + struct usb_hcd *hcd; + + /* The driver might handle more features than the board; OK. + * Fail when the board needs a feature that's not enabled. + */ + + os_printk(K_INFO, "[MU3D]%s\n", __func__); + + if (!plat) { + dev_err(dev, "no platform_data?\n"); + status = -ENODEV; + goto fail0; + } + + /* allocate */ + musb = allocate_instance(dev, plat->config, ctrl); + if (!musb) { + status = -ENOMEM; + goto fail0; + } + /* pm_runtime_use_autosuspend(musb->controller); */ + /* pm_runtime_set_autosuspend_delay(musb->controller, 200); */ + /* pm_runtime_enable(musb->controller); */ + + spin_lock_init(&musb->lock); + musb->board_mode = plat->mode; + musb->board_set_power = plat->set_power; + musb->min_power = plat->min_power; + musb->ops = plat->platform_ops; + musb->usb_mode = CABLE_MODE_NORMAL; + + _mu3d_musb = musb; + + wake_lock_init(&musb->usb_wakelock, WAKE_LOCK_SUSPEND, "USB.lock"); + + INIT_DELAYED_WORK(&musb->connection_work, connection_work); + + INIT_DELAYED_WORK(&musb->check_ltssm_work, check_ltssm_work); + +#ifndef CONFIG_USBIF_COMPLIANCE + INIT_DELAYED_WORK(&musb->reconnect_work, reconnect_work); +#endif + +#ifdef EP_PROFILING + INIT_DELAYED_WORK(&musb->ep_prof_work, ep_prof_work); +#endif + + /* The musb_platform_init() call: + * - adjusts musb->mregs and musb->isr if needed, + * - may initialize an integrated tranceiver + * - initializes musb->xceiv, usually by otg_get_transceiver() + * - stops powering VBUS + * + * There are various transceiver configurations. Blackfin, + * DaVinci, TUSB60x0, and others integrate them. OMAP3 uses + * external/discrete ones in various flavors (twl4030 family, + * isp1504, non-OTG, etc) mostly hooking up through ULPI. + */ + /*move to musb_init.c */ + /*musb->isr = generic_interrupt; */ + status = musb_platform_init(musb); + if (status < 0) + goto fail1; + + if (!musb->isr) { + status = -ENODEV; + goto fail3; + } + /* pm_runtime_get_sync(musb->controller); */ + + /* ideally this would be abstracted in platform setup */ +#ifdef USE_SSUSB_QMU + if (!is_dma_capable()) +#else + if (!is_dma_capable() || !musb->dma_controller) +#endif + dev->dma_mask = NULL; + + /* be sure interrupts are disabled before connecting ISR */ + musb_platform_disable(musb); + musb_generic_disable(); + + /* setup musb parts of the core (especially endpoints) */ + status = musb_core_init(plat->config->multipoint + ? MUSB_CONTROLLER_MHDRC : MUSB_CONTROLLER_HDRC, musb); + if (status < 0) + goto fail3; + + /* REVISIT-J: Do _NOT_ support OTG functionality */ + /* setup_timer(&musb->otg_timer, musb_otg_timer_func, (unsigned long) musb); */ + + /* Init IRQ workqueue before request_irq */ + INIT_WORK(&musb->irq_work, musb_irq_work); + + INIT_WORK(&musb->suspend_work, musb_suspend_work); + +#ifdef USE_SSUSB_QMU + tasklet_init(&musb->qmu_done, qmu_done_tasklet, (unsigned long)musb); + tasklet_init(&musb->error_recovery, qmu_error_recovery, (unsigned long)musb); +#endif + + /* attach to the IRQ */ + if (request_irq(nIrq, musb->isr, IRQF_TRIGGER_LOW, dev_name(dev), musb)) { + dev_err(dev, "request_irq %d failed!\n", nIrq); + status = -ENODEV; + goto fail3; + } + musb->nIrq = nIrq; + /* FIXME this handles wakeup irqs wrong */ + if (enable_irq_wake(nIrq) == 0) { + musb->irq_wake = 1; + device_init_wakeup(dev, 1); + } else { + musb->irq_wake = 0; + } + + /* host side needs more setup */ +#ifndef CONFIG_USBIF_COMPLIANCE + if (is_host_enabled(musb)) { + hcd = musb_to_hcd(musb); + otg_set_host(musb->xceiv->otg, &hcd->self); + + if (is_otg_enabled(musb)) + hcd->self.otg_port = 1; + + musb->xceiv->otg->host = &hcd->self; + hcd->power_budget = 2 * (plat->power ? : 250); + + /* program PHY to use external vBus if required */ + if (plat->extvbus) { + u8 busctl = musb_read_ulpi_buscontrol(musb->mregs); + + busctl |= MUSB_ULPI_USE_EXTVBUS; + musb_write_ulpi_buscontrol(musb->mregs, busctl); + } + } +#endif + + MUSB_DEV_MODE(musb); + musb->xceiv->otg->default_a = 0; + musb->xceiv->state = OTG_STATE_B_IDLE; + + status = musb_gadget_setup(musb); + + if (status < 0) + goto fail3; + + status = musb_init_debugfs(musb); + if (status < 0) + goto fail4; + +#ifdef CONFIG_SYSFS + status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); + if (status) + goto fail5; +#endif + + pm_runtime_put(musb->controller); + + dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({ + char *s; + + switch (musb->board_mode) { + case MUSB_HOST: + s = "Host"; break; case MUSB_PERIPHERAL: + s = "Peripheral"; break; default: + s = "OTG"; break; }; s; } + ), ctrl, (is_dma_capable() && musb->dma_controller) + ? "DMA" : "PIO", musb->nIrq); + + return 0; + +fail5: + musb_exit_debugfs(musb); + +fail4: + if (!is_otg_enabled(musb) && is_host_enabled(musb)) + usb_remove_hcd(musb_to_hcd(musb)); + else + musb_gadget_cleanup(musb); + +fail3: + if (musb->irq_wake) + device_init_wakeup(dev, 0); + musb_platform_exit(musb); + +fail1: + dev_err(musb->controller, "musb_init_controller failed with status %d\n", status); + + musb_free(musb); + +fail0: + + return status; + +} + +#define USB3_BASE_REGS_ADDR_RES_NAME "ssusb_base" +#define USB3_SIF_REGS_ADDR_RES_NAME "ssusb_sif" +#define USB3_SIF2_REGS_ADDR_RES_NAME "ssusb_sif2" + +static void __iomem *acquire_reg_base(struct platform_device *pdev, const char *res_name) +{ + struct resource *iomem; + void __iomem *base = NULL; + + iomem = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); + if (!iomem) { + pr_err("Can't get resource for %s\n", res_name); + goto end; + } + + base = ioremap(iomem->start, resource_size(iomem)); + if (!(uintptr_t) base) { + pr_err("Can't remap %s\n", res_name); + goto end; + } + os_printk(K_INFO, "%s=0x%lx\n", res_name, (uintptr_t) (base)); +end: + return base; +} + +/*-------------------------------------------------------------------------*/ + +/* all implementations (PCI bridge to FPGA, VLYNQ, etc) should just + * bridge to a platform device; this driver then suffices. + */ +#ifdef CONFIG_USBIF_COMPLIANCE +static int mu3d_normal_driver_on; + +static int musb_probe(struct platform_device *pdev) +#else +static int __init musb_probe(struct platform_device *pdev) +#endif +{ + struct device *dev = &pdev->dev; + int irq = platform_get_irq_byname(pdev, MUSB_DRIVER_NAME); + int status = 0; +#ifdef CONFIG_MTK_UART_USB_SWITCH + struct device_node *ap_uart0_node = NULL; +#endif + if (irq <= 0) + return -ENODEV; + + os_printk(K_INFO, "[MU3D]musb_probe irq=%d\n", irq); + + u3_base = acquire_reg_base(pdev, USB3_BASE_REGS_ADDR_RES_NAME); + if (!u3_base) + goto exit_regs; + + u3_sif_base = acquire_reg_base(pdev, USB3_SIF_REGS_ADDR_RES_NAME); + if (!u3_sif_base) + goto exit_regs; + + u3_sif2_base = acquire_reg_base(pdev, USB3_SIF2_REGS_ADDR_RES_NAME); + if (!u3_sif2_base) + goto exit_regs; + +#ifdef CONFIG_MTK_UART_USB_SWITCH + ap_uart0_node = of_find_compatible_node(NULL, NULL, AP_UART0_COMPATIBLE_NAME); + + if (ap_uart0_node == NULL) { + os_printk(K_ERR, "USB get ap_uart0_node failed\n"); + if (ap_uart0_base) + iounmap(ap_uart0_base); + ap_uart0_base = 0; + } else { + ap_uart0_base = of_iomap(ap_uart0_node, 0); + } +#endif + +#ifdef CONFIG_MTK_FPGA + /*i2c1_base = ioremap(0x11008000, 0x1000); */ + i2c1_base = ioremap(0x11009000, 0x1000); + if (!(i2c1_base)) { + pr_err("Can't remap I2C1 BASE\n"); + status = -ENOMEM; + } + os_printk(K_INFO, "I2C1 BASE=0x%lx\n", (uintptr_t) (i2c1_base)); +#endif + + status = musb_init_controller(dev, irq, u3_base); + if (status < 0) + goto exit_regs; + + return status; + +exit_regs: + if (u3_base) + iounmap(u3_base); + if (u3_sif_base) + iounmap(u3_sif_base); + if (u3_sif2_base) + iounmap(u3_sif2_base); + u3_base = 0; + u3_sif_base = 0; + u3_sif2_base = 0; + + return status; +} + +static int musb_remove(struct platform_device *pdev) +{ + struct musb *musb = dev_to_musb(&pdev->dev); + void __iomem *ctrl_base = musb->ctrl_base; + + /* this gets called on rmmod. + * - Host mode: host may still be active + * - Peripheral mode: peripheral is deactivated (or never-activated) + * - OTG mode: both roles are deactivated (or never-activated) + */ + +#ifdef CONFIG_SYSFS /* USBIF */ + sysfs_remove_group(&musb->controller->kobj, &musb_attr_group); +#endif + pm_runtime_get_sync(musb->controller); + musb_exit_debugfs(musb); + musb_shutdown(pdev); + + pm_runtime_put(musb->controller); + musb_free(musb); + _mu3d_musb = NULL; +#ifndef CONFIG_USBIF_COMPLIANCE + /* USB IF share resource with mu3d nor drv, so do not unmap it in IF case */ + iounmap(ctrl_base); +#endif + device_init_wakeup(&pdev->dev, 0); + + return 0; +} + +/* + * MU3D driver does _NOT_ use PM to control USB power state. + * When cable disconnected and all EPs are disabled, turn off all the clock and powers. + * Turn on all the clock and powers until the cable exists. + */ +#ifdef NEVER /* CONFIG_PM */ + +/*Do _NOT_ use the original save and restore context functions*/ +#ifdef NEVER +static void musb_save_context(struct musb *musb) +{ + int i; + void __iomem *musb_base = musb->mregs; + void __iomem *epio; + + if (is_host_enabled(musb)) { + musb->context.frame = musb_readw(musb_base, MUSB_FRAME); + musb->context.testmode = musb_readb(musb_base, MUSB_TESTMODE); + musb->context.busctl = musb_read_ulpi_buscontrol(musb->mregs); + } + musb->context.power = musb_readb(musb_base, MUSB_POWER); + musb->context.intrtxe = musb_readw(musb_base, MUSB_INTRTXE); + musb->context.intrrxe = musb_readw(musb_base, MUSB_INTRRXE); + musb->context.intrusbe = musb_readb(musb_base, MUSB_INTRUSBE); + musb->context.index = musb_readb(musb_base, MUSB_INDEX); + musb->context.devctl = musb_readb(musb_base, MUSB_DEVCTL); + + for (i = 0; i < musb->config->num_eps; ++i) { + struct musb_hw_ep *hw_ep; + + hw_ep = &musb->endpoints[i]; + if (!hw_ep) + continue; + + epio = hw_ep->regs; + if (!epio) + continue; + + musb->context.index_regs[i].txmaxp = musb_readw(epio, MUSB_TXMAXP); + musb->context.index_regs[i].txcsr = musb_readw(epio, MUSB_TXCSR); + musb->context.index_regs[i].rxmaxp = musb_readw(epio, MUSB_RXMAXP); + musb->context.index_regs[i].rxcsr = musb_readw(epio, MUSB_RXCSR); + + if (musb->dyn_fifo) { + musb->context.index_regs[i].txfifoadd = musb_read_txfifoadd(musb_base); + musb->context.index_regs[i].rxfifoadd = musb_read_rxfifoadd(musb_base); + musb->context.index_regs[i].txfifosz = musb_read_txfifosz(musb_base); + musb->context.index_regs[i].rxfifosz = musb_read_rxfifosz(musb_base); + } + if (is_host_enabled(musb)) { + musb->context.index_regs[i].txtype = musb_readb(epio, MUSB_TXTYPE); + musb->context.index_regs[i].txinterval = musb_readb(epio, MUSB_TXINTERVAL); + musb->context.index_regs[i].rxtype = musb_readb(epio, MUSB_RXTYPE); + musb->context.index_regs[i].rxinterval = musb_readb(epio, MUSB_RXINTERVAL); + + musb->context.index_regs[i].txfunaddr = musb_read_txfunaddr(musb_base, i); + musb->context.index_regs[i].txhubaddr = musb_read_txhubaddr(musb_base, i); + musb->context.index_regs[i].txhubport = musb_read_txhubport(musb_base, i); + + musb->context.index_regs[i].rxfunaddr = musb_read_rxfunaddr(musb_base, i); + musb->context.index_regs[i].rxhubaddr = musb_read_rxhubaddr(musb_base, i); + musb->context.index_regs[i].rxhubport = musb_read_rxhubport(musb_base, i); + } + } +} + +static void musb_restore_context(struct musb *musb) +{ + int i; + void __iomem *musb_base = musb->mregs; + void __iomem *ep_target_regs; + void __iomem *epio; + + if (is_host_enabled(musb)) { + musb_writew(musb_base, MUSB_FRAME, musb->context.frame); + musb_writeb(musb_base, MUSB_TESTMODE, musb->context.testmode); + musb_write_ulpi_buscontrol(musb->mregs, musb->context.busctl); + } + musb_writeb(musb_base, MUSB_POWER, musb->context.power); + musb_writew(musb_base, MUSB_INTRTXE, musb->context.intrtxe); + musb_writew(musb_base, MUSB_INTRRXE, musb->context.intrrxe); + musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe); + musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl); + + for (i = 0; i < musb->config->num_eps; ++i) { + struct musb_hw_ep *hw_ep; + + hw_ep = &musb->endpoints[i]; + if (!hw_ep) + continue; + + epio = hw_ep->regs; + if (!epio) + continue; + + musb_writew(epio, MUSB_TXMAXP, musb->context.index_regs[i].txmaxp); + musb_writew(epio, MUSB_TXCSR, musb->context.index_regs[i].txcsr); + musb_writew(epio, MUSB_RXMAXP, musb->context.index_regs[i].rxmaxp); + musb_writew(epio, MUSB_RXCSR, musb->context.index_regs[i].rxcsr); + + if (musb->dyn_fifo) { + musb_write_txfifosz(musb_base, musb->context.index_regs[i].txfifosz); + musb_write_rxfifosz(musb_base, musb->context.index_regs[i].rxfifosz); + musb_write_txfifoadd(musb_base, musb->context.index_regs[i].txfifoadd); + musb_write_rxfifoadd(musb_base, musb->context.index_regs[i].rxfifoadd); + } + + if (is_host_enabled(musb)) { + musb_writeb(epio, MUSB_TXTYPE, musb->context.index_regs[i].txtype); + musb_writeb(epio, MUSB_TXINTERVAL, musb->context.index_regs[i].txinterval); + musb_writeb(epio, MUSB_RXTYPE, musb->context.index_regs[i].rxtype); + musb_writeb(epio, MUSB_RXINTERVAL, musb->context.index_regs[i].rxinterval); + musb_write_txfunaddr(musb_base, i, musb->context.index_regs[i].txfunaddr); + musb_write_txhubaddr(musb_base, i, musb->context.index_regs[i].txhubaddr); + musb_write_txhubport(musb_base, i, musb->context.index_regs[i].txhubport); + + ep_target_regs = musb_read_target_reg_base(i, musb_base); + + musb_write_rxfunaddr(ep_target_regs, musb->context.index_regs[i].rxfunaddr); + musb_write_rxhubaddr(ep_target_regs, musb->context.index_regs[i].rxhubaddr); + musb_write_rxhubport(ep_target_regs, musb->context.index_regs[i].rxhubport); + } + } + musb_writeb(musb_base, MUSB_INDEX, musb->context.index); +} +#endif /* NEVER */ + +static void musb_save_context(struct musb *musb) +{ + int i; + +#ifdef CONFIG_USB_MU3D_DRV + /* + * U3D_EPIER(Endpoint 0 interrupt enable.) and U3D_EP0CSR(EP0 MaxP Size) + * would be configured at + * #U2: RESET Signal -> musb_g_reset() -> musb_conifg_ep0() -> ep0_setup() + * #U3: ENTER_U0_INTR -> musb_conifg_ep0() -> ep0_setup() + * U3D_EPIER(Endpoint N interrupt enable.) at PIO mode + * would be configured when PC sends USB_REQ_SET_CONFIGURATION. + */ + /* + musb->context.intr_ep = os_readl(U3D_EPIER); + musb->context.ep0_csr = os_readl(U3D_EP0CSR); + */ +#ifdef USE_SSUSB_QMU + /* + * QGCSR(RXQ/TXQ Enable) and QIER0(QMU Done Interrupt Enable) + * would be configured at mu3d_hal_ep_enable() when PC sends USB_REQ_SET_CONFIGURATION + * USB_REQ_SET_CONFIGURATION -> set_config() -> f->set_alt() -> usb_ep_enable() -> musb_gadget_enable() + * So do _NOT_ have to save those value. + */ + /* + musb->context.qmu_crs = os_readl(U3D_QGCSR); + musb->context.intr_qmu_done = os_readl(U3D_QIER0); + */ +#endif +#endif /* CONFIG_USB_MU3D_DRV */ + for (i = 0; i < musb->config->num_eps; ++i) { + os_printk(K_DEBUG, "%s EP%d\n", __func__, i); +#ifdef CONFIG_USB_MU3D_DRV + /* + * Each TX/RX EP CSR would be configured at mu3d_hal_ep_enable() when PC sends USB_REQ_SET_CONFIGURATION + */ + /* + musb->context.index_regs[i].txcsr0 = USB_ReadCsr32(U3D_TX1CSR0, i+1); + musb->context.index_regs[i].txcsr1 = USB_ReadCsr32(U3D_TX1CSR1, i+1); + musb->context.index_regs[i].txcsr2 = USB_ReadCsr32(U3D_TX1CSR2, i+1); + musb->context.index_regs[i].rxcsr0 = USB_ReadCsr32(U3D_RX1CSR0, i+1); + musb->context.index_regs[i].rxcsr1 = USB_ReadCsr32(U3D_RX1CSR1, i+1); + musb->context.index_regs[i].rxcsr2 = USB_ReadCsr32(U3D_RX1CSR2, i+1); + */ +#ifdef USE_SSUSB_QMU + /* Save TXQ/RXQ starting address. Those would be reset to 0 after reset SSUSB IP. */ + musb->context.index_regs[i].txqmuaddr = os_readl(USB_QMU_TQSAR(i + 1)); + os_printk(K_DEBUG, "%s TQSAR[%d]=%x\n", __func__, i, + musb->context.index_regs[i].txqmuaddr); + musb->context.index_regs[i].rxqmuaddr = os_readl(USB_QMU_RQSAR(i + 1)); + os_printk(K_DEBUG, "%s RQSAR[%d]=%x\n", __func__, i, + musb->context.index_regs[i].rxqmuaddr); +#endif +#endif /* CONFIG_USB_MU3D_DRV */ + } +} + +static void musb_restore_context(struct musb *musb) +{ + int i; + +#ifdef CONFIG_USB_MU3D_DRV + /* + os_writel(U3D_EPIESR, musb->context.intr_ep); + os_writel(U3D_EP0CSR, musb->context.ep0_csr); + */ +#ifdef USE_SSUSB_QMU + /* + os_writel(U3D_QGCSR, musb->context.qmu_crs); + os_writel(U3D_QIESR0, musb->context.intr_qmu_done); + */ +#endif +#endif /* CONFIG_USB_MU3D_DRV */ + + for (i = 0; i < musb->config->num_eps; ++i) { +#ifdef CONFIG_USB_MU3D_DRV + /* + USB_WriteCsr32(U3D_TX1CSR0, i+1, musb->context.index_regs[i].txcsr0); + USB_WriteCsr32(U3D_TX1CSR1, i+1, musb->context.index_regs[i].txcsr1); + USB_WriteCsr32(U3D_TX1CSR2, i+1, musb->context.index_regs[i].txcsr2); + USB_WriteCsr32(U3D_RX1CSR0, i+1, musb->context.index_regs[i].rxcsr0); + USB_WriteCsr32(U3D_RX1CSR1, i+1, musb->context.index_regs[i].rxcsr1); + USB_WriteCsr32(U3D_RX1CSR2, i+1, musb->context.index_regs[i].rxcsr2); + */ +#ifdef USE_SSUSB_QMU + os_writel(USB_QMU_TQSAR(i + 1), musb->context.index_regs[i].txqmuaddr); + os_writel(USB_QMU_RQSAR(i + 1), musb->context.index_regs[i].rxqmuaddr); + os_printk(K_INFO, "%s TQSAR[%d]=%x\n", __func__, i, os_readl(USB_QMU_TQSAR(i + 1))); + os_printk(K_INFO, "%s TQSAR[%d]=%x\n", __func__, i, os_readl(USB_QMU_RQSAR(i + 1))); +#endif +#endif /* CONFIG_USB_MU3D_DRV */ + } +} + +static int musb_suspend_noirq(struct device *dev) +{ + struct musb *musb = dev_to_musb(dev); + + os_printk(K_INFO, "%s\n", __func__); + /* + * Note: musb_save_context() _MUST_ be called _BEFORE_ mtu3d_suspend_noirq(). + * Because when mtu3d_suspend_noirq() resets the SSUSB IP, All MAC regs can _NOT_ be read and be reset to + * the default value. So save the MUST-SAVED reg in the context structure. + */ + musb_save_context(musb); + + /* Set SSUSB_IP_SW_RST to avoid power leakage */ + os_setmsk(U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); + +#ifndef CONFIG_MTK_FPGA + /* Let PHY enter savecurrent mode. And turn off CLK. */ + usb_phy_savecurrent(musb->is_clk_on); + musb->is_clk_on = 0; +#endif + + + return 0; +} + +static int musb_resume_noirq(struct device *dev) +{ + struct musb *musb = dev_to_musb(dev); + + os_printk(K_INFO, "%s\n", __func__); + +#ifndef CONFIG_MTK_FPGA + /* Recovert PHY. And turn on CLK. */ + usb_phy_recover(musb->is_clk_on); + musb->is_clk_on = 1; + + /* USB 2.0 slew rate calibration */ + u3phy_ops->u2_slew_rate_calibration(u3phy); +#endif + + /* disable IP reset and power down, disable U2/U3 ip power down */ + _ex_mu3d_hal_ssusb_en(); + + /* reset U3D all dev module. */ + mu3d_hal_rst_dev(); + + musb_restore_context(musb); + + return 0; +} + +static const struct dev_pm_ops musb_dev_pm_ops = { + .suspend_noirq = musb_suspend_noirq, + .resume_noirq = musb_resume_noirq, +}; + +#define MUSB_DEV_PM_OPS (&musb_dev_pm_ops) + +#else /* NEVER */ + +/* These suspend/Resume function deal with UART switch related recover only */ +#ifdef CONFIG_MTK_UART_USB_SWITCH +#define MUSB_DEV_PM_OPS (&musb_dev_pm_ops) +static int musb_suspend_noirq(struct device *dev) +{ + os_printk(K_INFO, "%s: for CONFIG_MTK_UART_USB_SWITCH: in_uart_mode: %d\n", __func__, + in_uart_mode); + + return 0; +} + +static int musb_resume_noirq(struct device *dev) +{ + os_printk(K_INFO, "%s: for CONFIG_MTK_UART_USB_SWITCH: in_uart_mode: %d\n", __func__, + in_uart_mode); + + if (in_uart_mode == true) + usb_phy_switch_to_uart(); + + return 0; +} + +static const struct dev_pm_ops musb_dev_pm_ops = { + .suspend_noirq = musb_suspend_noirq, + .resume_noirq = musb_resume_noirq, +}; +#else +#define MUSB_DEV_PM_OPS NULL +#endif /* CONFIG_MTK_UART_USB_SWITCH */ +#endif /* NEVER */ + +static struct platform_driver musb_driver = { + .driver = { + .name = (char *)musb_driver_name, + .bus = &platform_bus_type, + .owner = THIS_MODULE, + .pm = MUSB_DEV_PM_OPS, + }, + .probe = musb_probe, + .remove = musb_remove, + .shutdown = musb_shutdown, +}; + +/*-------------------------------------------------------------------------*/ +#ifdef CONFIG_USBIF_COMPLIANCE +static int musb_mu3d_proc_show(struct seq_file *seq, void *v) +{ + seq_printf(seq, "musb_mu3d_proc_show, mu3d is %d (on:1, off:0)\n", mu3d_normal_driver_on); + return 0; +} + +static int musb_mu3d_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_mu3d_proc_show, inode->i_private); +} + +static ssize_t musb_mu3d_proc_write(struct file *file, const char __user *buf, size_t length, + loff_t *ppos) +{ + int ret; + char msg[32]; + int result; + int status; + struct device *dev; + int irq; + struct resource *iomem; + void __iomem *base; + struct musb *musb; + void __iomem *ctrl_base; + + if (length >= sizeof(msg)) { + os_printk(K_ERR, "musb_mu3d_proc_write length error, the error len is %d\n", + (unsigned int)length); + return -EINVAL; + } + if (copy_from_user(msg, buf, length)) + return -EFAULT; + + msg[length] = 0; + + os_printk(K_DEBUG, "musb_mu3d_proc_write: %s, current driver on/off: %d\n", msg, + mu3d_normal_driver_on); + + if ((msg[0] == '1') && (mu3d_normal_driver_on == 0)) { + os_printk(K_DEBUG, "registe mu3d driver ===>\n"); + init_connection_work(); + init_check_ltssm_work(); + platform_driver_register(&musb_driver); + mu3d_normal_driver_on = 1; + Charger_Detect_En(true); + os_printk(K_DEBUG, "registe mu3d driver <===\n"); + } else if ((msg[0] == '0') && (mu3d_normal_driver_on == 1)) { + os_printk(K_DEBUG, "unregiste mu3d driver ===>\n"); + mu3d_normal_driver_on = 0; + Charger_Detect_En(false); + platform_driver_unregister(&musb_driver); + os_printk(K_DEBUG, "unregiste mu3d driver <===\n"); + } else { + /* kernel_restart(NULL); */ + /* arch_reset(0, NULL); */ + os_printk(K_ERR, "musb_mu3d_proc_write , set reboot !\n"); + /* os_printk(K_ERR, "musb_mu3d_proc_write write faile !\n"); */ + } + return length; +} + +static const struct file_operations mu3d_proc_fops = { + .owner = THIS_MODULE, + .open = musb_mu3d_proc_open, + .write = musb_mu3d_proc_write, + .read = seq_read, + .llseek = seq_lseek, + +}; + +static int __init musb_init(void) +{ + struct proc_dir_entry *prEntry; + int ret = 0; + + if (usb_disabled()) + return 0; + + pr_info("%s: version " MUSB_VERSION ", ?dma?, otg (peripheral+host)\n", musb_driver_name); + + /* USBIF */ + prEntry = proc_create("mu3d_driver_init", 0666, NULL, &mu3d_proc_fops); + + if (prEntry) + os_printk(K_ERR, "create the mu3d init proc OK!\n"); + else + os_printk(K_ERR, "[ERROR] create the mu3d init proc FAIL\n"); + + /* set MU3D up at boot up */ + ret = platform_driver_register(&musb_driver); + mu3d_normal_driver_on = 1; + Charger_Detect_En(true); + + return ret; +} +module_init(musb_init); + +static void __exit musb_cleanup(void) +{ + os_printk(K_ERR, "musb_cleanup\n"); + if (mu3d_normal_driver_on == 1) + platform_driver_unregister(&musb_driver); + + return 0; +} +module_exit(musb_cleanup); +#else + +static int __init musb_init(void) +{ + if (usb_disabled()) + return 0; + + pr_info("%s: version " MUSB_VERSION ", ?dma?, otg (peripheral+host)\n", musb_driver_name); + return platform_driver_register(&musb_driver); +} +module_init(musb_init); + +static void __exit musb_cleanup(void) +{ + platform_driver_unregister(&musb_driver); +} +module_exit(musb_cleanup); +#endif diff --git a/drivers/misc/mediatek/mu3d/drv/musb_core.h b/drivers/misc/mediatek/mu3d/drv/musb_core.h new file mode 100644 index 000000000000..fefd5df34756 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_core.h @@ -0,0 +1,804 @@ +/* + * MUSB OTG driver defines + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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. + * + */ + +#ifndef __MUSB_CORE_H__ +#define __MUSB_CORE_H__ + +#include <linux/slab.h> +#include <linux/list.h> +#include <linux/interrupt.h> +#include <linux/errno.h> +#include <linux/timer.h> +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/usb/ch9.h> +#include <linux/usb/gadget.h> +#include <linux/usb.h> +#include <linux/usb/otg.h> +#include <linux/usb/musb.h> +#include <linux/wakelock.h> +#include <linux/workqueue.h> +/*#include <mt-plat/battery_common.h>*/ +#include <mt-plat/charging.h> + +struct musb; +struct musb_hw_ep; +struct musb_ep; + +#ifdef CONFIG_MTK_KERNEL_POWER_OFF_CHARGING +#include <mach/mt_boot_common.h> +extern BOOTMODE g_boot_mode; +#endif +extern u32 fake_CDP; + +extern struct musb *_mu3d_musb; + + +/* Helper defines for struct musb->hwvers */ +#define MUSB_HWVERS_MAJOR(x) ((x >> 10) & 0x1f) +#define MUSB_HWVERS_MINOR(x) (x & 0x3ff) +#define MUSB_HWVERS_RC 0x8000 +#define MUSB_HWVERS_1300 0x52C +#define MUSB_HWVERS_1400 0x590 +#define MUSB_HWVERS_1800 0x720 +#define MUSB_HWVERS_1900 0x784 +#define MUSB_HWVERS_2000 0x800 + +#include "musb_debug.h" +#include "musb_dma.h" + +#include "musb_io.h" +#include "musb_regs.h" /* We don't want to use original musb registers any more. */ + +#include "musb_gadget.h" +#include <linux/usb/hcd.h> + +#define USB_GADGET_SUPERSPEED +#define EP_PROFILING + +#define MUSB_DRIVER_NAME "musb-hdrc" + +#define is_peripheral_enabled(musb) ((musb)->board_mode != MUSB_HOST) +#define is_host_enabled(musb) ((musb)->board_mode != MUSB_PERIPHERAL) +#define is_otg_enabled(musb) ((musb)->board_mode == MUSB_OTG) + +/* NOTE: otg and peripheral-only state machines start at B_IDLE. + * OTG or host-only go to A_IDLE when ID is sensed. + */ +#define is_peripheral_active(m) (!(m)->is_host) +#define is_host_active(m) ((m)->is_host) + +#ifndef CONFIG_HAVE_CLK +/* Dummy stub for clk framework */ +#define clk_get(dev, id) NULL +#define clk_put(clock) do {} while (0) +#define clk_enable(clock) do {} while (0) +#define clk_disable(clock) do {} while (0) +#endif + +#ifdef CONFIG_PROC_FS +#include <linux/fs.h> +#define MUSB_CONFIG_PROC_FS +#endif + +static inline struct usb_hcd *musb_to_hcd(struct musb *musb) +{ + return container_of((void *)musb, struct usb_hcd, hcd_priv); +} + +static inline struct musb *hcd_to_musb(struct usb_hcd *hcd) +{ + return (struct musb *)(hcd->hcd_priv); +} + +/****************************** PERIPHERAL ROLE *****************************/ + +#define is_peripheral_capable() (1) + +extern irqreturn_t musb_g_ep0_irq(struct musb *); +extern void musb_g_tx(struct musb *, u8); +extern void musb_g_rx(struct musb *, u8); +extern void musb_g_reset(struct musb *); +extern void musb_g_suspend(struct musb *); +extern void musb_g_resume(struct musb *); +extern void musb_g_wakeup(struct musb *); +extern void musb_g_disconnect(struct musb *); + +/****************************** HOST ROLE ***********************************/ + +#define is_host_capable() (1) + +extern irqreturn_t musb_h_ep0_irq(struct musb *); +extern void musb_host_tx(struct musb *, u8); +extern void musb_host_rx(struct musb *, u8); + +/****************************** CONSTANTS ********************************/ + +#ifndef MUSB_C_NUM_EPS +#define MUSB_C_NUM_EPS ((u8)9) +#endif + +#ifndef MUSB_MAX_END0_PACKET +#define MUSB_MAX_END0_PACKET ((u16)MUSB_EP0_FIFOSIZE) +#endif + +/* USB working mode */ +typedef enum { + CABLE_MODE_CHRG_ONLY = 0, + CABLE_MODE_NORMAL, + CABLE_MODE_HOST_ONLY, + CABLE_MODE_MAX +} CABLE_MODE; + +typedef enum { + USB_SUSPEND = 0, + USB_UNCONFIGURED, + USB_CONFIGURED +} usb_state_enum; + +/* host side ep0 states */ +enum musb_h_ep0_state { + MUSB_EP0_IDLE, + MUSB_EP0_START, /* expect ack of setup */ + MUSB_EP0_IN, /* expect IN DATA */ + MUSB_EP0_OUT, /* expect ack of OUT DATA */ + MUSB_EP0_STATUS, /* expect ack of STATUS */ +} __packed; + +/* peripheral side ep0 states */ +enum musb_g_ep0_state { + MUSB_EP0_STAGE_IDLE, /* idle, waiting for SETUP */ + MUSB_EP0_STAGE_SETUP, /* received SETUP */ + MUSB_EP0_STAGE_TX, /* IN data */ + MUSB_EP0_STAGE_RX, /* OUT data */ + MUSB_EP0_STAGE_STATUSIN, /* (after OUT data) */ + MUSB_EP0_STAGE_STATUSOUT, /* (after IN data) */ + MUSB_EP0_STAGE_ACKWAIT, /* after zlp, before statusin */ +} __packed; + +/* + * OTG protocol constants. See USB OTG 1.3 spec, + * sections 5.5 "Device Timings" and 6.6.5 "Timers". + */ +#define OTG_TIME_A_WAIT_VRISE 100 /* msec (max) */ +#define OTG_TIME_A_WAIT_BCON 1100 /* min 1 second */ +#define OTG_TIME_A_AIDL_BDIS 200 /* min 200 msec */ +#define OTG_TIME_B_ASE0_BRST 100 /* min 3.125 ms */ + + +/*************************** REGISTER ACCESS ********************************/ + +/* Endpoint registers (other than dynfifo setup) can be accessed either + * directly with the "flat" model, or after setting up an index register. + */ + +#if defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_SOC_OMAP2430) \ + || defined(CONFIG_SOC_OMAP3430) || defined(CONFIG_BLACKFIN) \ + || defined(CONFIG_ARCH_OMAP4) +/* REVISIT indexed access seemed to + * misbehave (on DaVinci) for at least peripheral IN ... + */ +#define MUSB_FLAT_REG +#endif + +/* TUSB mapping: "flat" plus ep0 special cases */ +#if defined(CONFIG_USB_TUSB6010) +#define musb_ep_select(_mbase, _epnum) \ + musb_writeb((_mbase), MUSB_INDEX, (_epnum)) +#define MUSB_EP_OFFSET MUSB_TUSB_OFFSET + +/* "flat" mapping: each endpoint has its own i/o address */ +#elif defined(MUSB_FLAT_REG) +#define musb_ep_select(_mbase, _epnum) (((void)(_mbase)), ((void)(_epnum))) +#define MUSB_EP_OFFSET MUSB_FLAT_OFFSET + +/* "indexed" mapping: INDEX register controls register bank select */ +#else +#define musb_ep_select(_mbase, _epnum) \ + musb_writeb((_mbase), MUSB_INDEX, (_epnum)) +#define MUSB_EP_OFFSET MUSB_INDEXED_OFFSET +#endif + + + + +#define SSUSB_EP_TXCR0_OFFSET(_epnum, _offset) \ + (U3D_TX1CSR0 + ((_epnum - 1)*0x10) + (_offset)) + +#define SSUSB_EP_TXCR1_OFFSET(_epnum, _offset) \ + (U3D_TX1CSR1 + ((_epnum - 1)*0x10) + (_offset)) + +#define SSUSB_EP_TXCR2_OFFSET(_epnum, _offset) \ + (U3D_TX1CSR2 + ((_epnum - 1)*0x10) + (_offset)) + +#define SSUSB_EP_TXMAXP_OFFSET(_epnum, _offset) \ + (U3D_TX1CSR0 + ((_epnum - 1)*0x10) + (_offset)) + +#define SSUSB_EP_RXCR0_OFFSET(_epnum, _offset) \ + (U3D_RX1CSR0 + ((_epnum - 1)*0x10) + (_offset)) + +#define SSUSB_EP_RXCR1_OFFSET(_epnum, _offset) \ + (U3D_RX1CSR1 + ((_epnum - 1)*0x10) + (_offset)) + +#define SSUSB_EP_RXCR2_OFFSET(_epnum, _offset) \ + (U3D_RX1CSR2 + ((_epnum - 1)*0x10) + (_offset)) + +#define SSUSB_EP_RXCR3_OFFSET(_epnum, _offset) \ + (U3D_RX1CSR3 + ((_epnum - 1)*0x10) + (_offset)) + + + +/****************************** FUNCTIONS ********************************/ + +#define MUSB_HST_MODE(_musb)\ + { (_musb)->is_host = true; } +#define MUSB_DEV_MODE(_musb) \ + { (_musb)->is_host = false; } + +#define test_devctl_hst_mode(_x) \ + (musb_readb((_x)->mregs, MUSB_DEVCTL)&MUSB_DEVCTL_HM) + +#define MUSB_MODE(musb) ((musb)->is_host ? "Host" : "Peripheral") + +/******************************** TYPES *************************************/ + +/** + * struct musb_platform_ops - Operations passed to musb_core by HW glue layer + * @init: turns on clocks, sets up platform-specific registers, etc + * @exit: undoes @init + * @set_mode: forcefully changes operating mode + * @try_ilde: tries to idle the IP + * @vbus_status: returns vbus status if possible + * @set_vbus: forces vbus status + * @adjust_channel_params: pre check for standard dma channel_program func + */ +struct musb_platform_ops { + int (*init)(struct musb *musb); + int (*exit)(struct musb *musb); + + void (*enable)(struct musb *musb); + void (*disable)(struct musb *musb); + + int (*set_mode)(struct musb *musb, u8 mode); + void (*try_idle)(struct musb *musb, unsigned long timeout); + + int (*vbus_status)(struct musb *musb); + void (*set_vbus)(struct musb *musb, int on); + + int (*adjust_channel_params)(struct dma_channel *channel, + u16 packet_sz, u8 *mode, dma_addr_t *dma_addr, u32 *len); +}; + +/* + * struct musb_hw_ep - endpoint hardware (bidirectional) + * + * Ordered slightly for better cacheline locality. + */ +struct musb_hw_ep { + struct musb *musb; + void __iomem *fifo; + void __iomem *regs; + + /* For ssusb+ */ + void __iomem *addr_txcsr0; + void __iomem *addr_txcsr1; + void __iomem *addr_txcsr2; + /* void __iomem *addr_txmaxpktsz; */ + + void __iomem *addr_rxcsr0; + void __iomem *addr_rxcsr1; + void __iomem *addr_rxcsr2; + void __iomem *addr_rxcsr3; + void __iomem *addr_rxmaxpktsz; + /* For ssusb- */ + +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) + void __iomem *conf; +#endif + + /* index in musb->endpoints[] */ + u8 epnum; + + /* hardware configuration, possibly dynamic */ + bool is_shared_fifo; + /* bool tx_double_buffered; */ + /* bool rx_double_buffered; */ + u16 max_packet_sz_tx; + u16 max_packet_sz_rx; + + /* For ssusb+ */ + u32 fifoaddr_tx; + u32 fifoaddr_rx; + + u8 mult_tx; + u8 mult_rx; + + u8 interval_tx; + u8 interval_rx; + /* For ssusb- */ + + struct dma_channel *tx_channel; + struct dma_channel *rx_channel; + +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) + /* TUSB has "asynchronous" and "synchronous" dma modes */ + dma_addr_t fifo_async; + dma_addr_t fifo_sync; + void __iomem *fifo_sync_va; +#endif + + void __iomem *target_regs; + + /* currently scheduled peripheral endpoint */ + struct musb_qh *in_qh; + struct musb_qh *out_qh; + + u8 rx_reinit; + u8 tx_reinit; + + /* peripheral side */ + struct musb_ep ep_in; /* TX */ + struct musb_ep ep_out; /* RX */ +}; + +static inline struct musb_request *next_in_request(struct musb_hw_ep *hw_ep) +{ + return next_request(&hw_ep->ep_in); +} + +static inline struct musb_request *next_out_request(struct musb_hw_ep *hw_ep) +{ + return next_request(&hw_ep->ep_out); +} + +#ifdef NEVER +struct musb_csr_regs { + /* FIFO registers */ + u16 txmaxp, txcsr, rxmaxp, rxcsr; + u16 rxfifoadd, txfifoadd; + u8 txtype, txinterval, rxtype, rxinterval; + u8 rxfifosz, txfifosz; + u8 txfunaddr, txhubaddr, txhubport; + u8 rxfunaddr, rxhubaddr, rxhubport; +}; + +struct musb_context_registers { + + u8 power; + u16 intrtxe, intrrxe; + u8 intrusbe; + u16 frame; + u8 index, testmode; + + u8 devctl, busctl, misc; + + struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; +}; +#endif /* NEVER */ + +#ifdef CONFIG_USB_MU3D_DRV +struct musb_csr_regs { + /* FIFO registers */ + /* u32 txcsr0, txcsr1, txcsr2; */ + /* u32 rxcsr0, rxcsr1, rxcsr2; */ +#ifdef USE_SSUSB_QMU + u32 txqmuaddr, rxqmuaddr; +#endif + /* u16 txmaxp, txcsr, rxmaxp, rxcsr; */ + /* u16 rxfifoadd, txfifoadd; */ + /* u8 txtype, txinterval, rxtype, rxinterval; */ + /* u8 rxfifosz, txfifosz; */ + + /* u8 txfunaddr, txhubaddr, txhubport; */ + /* u8 rxfunaddr, rxhubaddr, rxhubport; */ +}; + +struct musb_context_registers { + + /* u8 power; */ + /* u16 intrtxe, intrrxe; */ + /* u8 intrusbe; */ + /* u16 frame; */ + /* u8 index, testmode; */ + + /* u8 devctl, busctl, misc; */ + /* u32 intr_ep; */ + /* u32 ep0_csr; */ + /* u32 qmu_crs, intr_qmu_done; */ + struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; +}; +#endif + +/* + * struct musb - Driver instance data. + */ +struct musb { + /* device lock */ + spinlock_t lock; + + const struct musb_platform_ops *ops; + struct musb_context_registers context; + + irqreturn_t (*isr)(int, void *); + struct work_struct irq_work; + u32 hwvers; + +/* this hub status bit is reserved by USB 2.0 and not seen by usbcore */ +#define MUSB_PORT_STAT_RESUME (1 << 31) + + u32 port1_status; + + unsigned long rh_timer; + + enum musb_h_ep0_state ep0_stage; + + /* bulk traffic normally dedicates endpoint hardware, and each + * direction has its own ring of host side endpoints. + * we try to progress the transfer at the head of each endpoint's + * queue until it completes or NAKs too much; then we try the next + * endpoint. + */ + struct musb_hw_ep *bulk_ep; + + struct list_head control; /* of musb_qh */ + struct list_head in_bulk; /* of musb_qh */ + struct list_head out_bulk; /* of musb_qh */ + + struct timer_list otg_timer; + struct notifier_block nb; + + struct dma_controller *dma_controller; + + struct device *controller; + void __iomem *ctrl_base; + void __iomem *mregs; + +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) + dma_addr_t async; + dma_addr_t sync; + void __iomem *sync_va; +#endif + + /* passed down from chip/board specific irq handlers */ + u32 int_usb; + u16 int_rx; + u16 int_tx; + + struct usb_phy *xceiv; + + int nIrq; + unsigned irq_wake:1; + + struct musb_hw_ep endpoints[MUSB_C_NUM_EPS]; +#define control_ep endpoints + +#define VBUSERR_RETRY_COUNT 3 + u16 vbuserr_retry; + u16 epmask; + u8 nr_endpoints; + + u8 board_mode; /* enum musb_mode */ + int (*board_set_power)(int state); + + u8 min_power; /* vbus for periph, in mA/2 */ + + bool is_host; + + int a_wait_bcon; /* VBUS timeout in msecs */ + unsigned long idle_timeout; /* Next timeout in jiffies */ + + /* active means connected and not suspended */ + unsigned is_active:1; + + unsigned is_multipoint:1; + unsigned ignore_disconnect:1; /* during bus resets */ + + unsigned hb_iso_rx:1; /* high bandwidth iso rx? */ + unsigned hb_iso_tx:1; /* high bandwidth iso tx? */ + unsigned dyn_fifo:1; /* dynamic FIFO supported? */ + + unsigned bulk_split:1; +#define can_bulk_split(musb, type) \ + (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_split) + + unsigned bulk_combine:1; +#define can_bulk_combine(musb, type) \ + (((type) == USB_ENDPOINT_XFER_BULK) && (musb)->bulk_combine) + + /* is_suspended means USB B_PERIPHERAL suspend */ + unsigned is_suspended:1; + + /* may_wakeup means remote wakeup is enabled */ + unsigned may_wakeup:1; + + /* is_self_powered is reported in device status and the + * config descriptor. is_bus_powered means B_PERIPHERAL + * draws some VBUS current; both can be true. + */ + unsigned is_self_powered:1; + unsigned is_bus_powered:1; + + unsigned set_address:1; + unsigned test_mode:1; + unsigned softconnect:1; + + u8 address; + u8 test_mode_nr; + u32 ackpend; /* ep0 *//*We don't maintain Max Packet size in it. */ + enum musb_g_ep0_state ep0_state; + struct usb_gadget g; /* the gadget */ + struct usb_gadget_driver *gadget_driver; /* its driver */ + + /* + * FIXME: Remove this flag. + * + * This is only added to allow Blackfin to work + * with current driver. For some unknown reason + * Blackfin doesn't work with double buffering + * and that's enabled by default. + * + * We added this flag to forcefully disable double + * buffering until we get it working. + */ + unsigned double_buffer_not_ok:1; + + struct musb_hdrc_config *config; + +#ifdef MUSB_CONFIG_PROC_FS + struct proc_dir_entry *proc_entry; +#endif + + u32 txfifoadd_offset; + u32 rxfifoadd_offset; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_root; +#endif + + unsigned is_clk_on; + unsigned usb_mode; + unsigned active_ep; + struct work_struct suspend_work; + struct wake_lock usb_wakelock; + struct delayed_work connection_work; + struct delayed_work check_ltssm_work; +#ifndef CONFIG_USBIF_COMPLIANCE + struct delayed_work reconnect_work; +#endif +#ifdef EP_PROFILING + struct delayed_work ep_prof_work; +#endif + +#ifdef USE_SSUSB_QMU + struct tasklet_struct qmu_done; + u32 qmu_done_intr; + + struct tasklet_struct error_recovery; + u32 error_wQmuVal; + u32 error_wErrVal; +#endif +}; + +static inline struct musb *gadget_to_musb(struct usb_gadget *g) +{ + return container_of(g, struct musb, g); +} + +#ifdef CONFIG_BLACKFIN +static inline int musb_read_fifosize(struct musb *musb, struct musb_hw_ep *hw_ep, u8 epnum) +{ + musb->nr_endpoints++; + musb->epmask |= (1 << epnum); + + if (epnum < 5) { + hw_ep->max_packet_sz_tx = 128; + hw_ep->max_packet_sz_rx = 128; + } else { + hw_ep->max_packet_sz_tx = 1024; + hw_ep->max_packet_sz_rx = 1024; + } + hw_ep->is_shared_fifo = false; + + return 0; +} + +static inline void musb_configure_ep0(struct musb *musb) +{ + musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; + musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; + musb->endpoints[0].is_shared_fifo = true; +} + +#else + +static inline int musb_read_fifosize(struct musb *musb, struct musb_hw_ep *hw_ep, u8 epnum) +{ + void __iomem *mbase = musb->mregs; + u8 reg = 0; + + /* read from core using indexed model */ + reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE)); + /* 0's returned when no more endpoints */ + if (!reg) + return -ENODEV; + + musb->nr_endpoints++; + musb->epmask |= (1 << epnum); + + hw_ep->max_packet_sz_tx = 1 << (reg & 0x0f); + + /* shared TX/RX FIFO? */ + if ((reg & 0xf0) == 0xf0) { + hw_ep->max_packet_sz_rx = hw_ep->max_packet_sz_tx; + hw_ep->is_shared_fifo = true; + } else { + hw_ep->max_packet_sz_rx = 1 << ((reg & 0xf0) >> 4); + hw_ep->is_shared_fifo = false; + } + + return 0; +} + +static inline void musb_configure_ep0(struct musb *musb) +{ + musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; + musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; + musb->endpoints[0].is_shared_fifo = true; +} +#endif /* CONFIG_BLACKFIN */ + + +/***************************** Glue it together *****************************/ + +extern const char musb_driver_name[]; + +extern void musb_start(struct musb *musb); +extern void musb_stop(struct musb *musb); + +extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src); +extern void musb_read_fifo(struct musb_hw_ep *ep, u16 len, u8 *dst); + +extern void musb_load_testpacket(struct musb *); + +extern irqreturn_t musb_interrupt(struct musb *); + +extern void musb_hnp_stop(struct musb *musb); + +static inline void musb_platform_set_vbus(struct musb *musb, int is_on) +{ + if (musb->ops->set_vbus) + musb->ops->set_vbus(musb, is_on); +} + +static inline void musb_platform_enable(struct musb *musb) +{ + if (musb->ops->enable) + musb->ops->enable(musb); +} + +static inline void musb_platform_disable(struct musb *musb) +{ + if (musb->ops->disable) + musb->ops->disable(musb); +} + +static inline int musb_platform_set_mode(struct musb *musb, u8 mode) +{ + if (!musb->ops->set_mode) + return 0; + + return musb->ops->set_mode(musb, mode); +} + +static inline void musb_platform_try_idle(struct musb *musb, unsigned long timeout) +{ + if (musb->ops->try_idle) + musb->ops->try_idle(musb, timeout); +} + +static inline int musb_platform_get_vbus_status(struct musb *musb) +{ + if (!musb->ops->vbus_status) + return 0; + + return musb->ops->vbus_status(musb); +} + +static inline int musb_platform_init(struct musb *musb) +{ + if (!musb->ops->init) + return -EINVAL; + + return musb->ops->init(musb); +} + +static inline int musb_platform_exit(struct musb *musb) +{ + if (!musb->ops->exit) + return -EINVAL; + + return musb->ops->exit(musb); +} + +extern bool usb_cable_connected(void); +extern void usb_phy_savecurrent(unsigned int clk_on); +extern void usb_phy_recover(unsigned int clk_on); +extern void usb_fake_powerdown(unsigned int clk_on); +extern void connection_work(struct work_struct *data); +extern void check_ltssm_work(struct work_struct *data); + +#ifndef CONFIG_USBIF_COMPLIANCE +extern void reconnect_work(struct work_struct *data); +extern struct timespec get_connect_timestamp(void); +#else /*CONFIG_USBIF_COMPLIANCE */ +extern void init_connection_work(void); +extern void init_check_ltssm_work(void); +extern void Charger_Detect_En(bool enable); +#endif /*CONFIG_USBIF_COMPLIANCE */ + + +extern void musb_sync_with_bat(struct musb *musb, int usb_state); + + +#ifdef CONFIG_MTK_UART_USB_SWITCH +extern bool in_uart_mode; +extern ssize_t musb_portmode_show(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t musb_portmode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); +extern ssize_t musb_tx_show(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t musb_tx_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); +extern ssize_t musb_rx_show(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t musb_uart_path_show(struct device *dev, struct device_attribute *attr, char *buf); +extern bool usb_phy_check_in_uart_mode(void); +extern void usb_phy_switch_to_uart(void); +#endif /*CONFIG_MTK_UART_USB_SWITCH */ + + +extern ssize_t musb_cmode_show(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t musb_cmode_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); + +extern void usb20_pll_settings(bool host, bool forceOn); + +#if defined(FOR_BRING_UP) || !defined(CONFIG_MTK_SMART_BATTERY) +/* implement static function in mt_usb.c */ +#else +extern bool upmu_is_chr_det(void); +extern u32 upmu_get_rgs_chrdet(void); +#endif + +#endif /* __MUSB_CORE_H__ */ diff --git a/drivers/misc/mediatek/mu3d/drv/musb_debug.h b/drivers/misc/mediatek/mu3d/drv/musb_debug.h new file mode 100644 index 000000000000..d11f583d8830 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_debug.h @@ -0,0 +1,56 @@ +/* + * MUSB OTG driver debug defines + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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. + * + */ + +#ifndef __MUSB_LINUX_DEBUG_H__ +#define __MUSB_LINUX_DEBUG_H__ + +#define WARNING(fmt, args...) pr_debug("%s %d: " fmt, __func__, __LINE__, ## args) +#define INFO(fmt, args...) pr_debug("%s %d: " fmt, __func__, __LINE__, ## args) +#define ERR(fmt, args...) pr_err("%s %d: " fmt, __func__, __LINE__, ## args) + +#ifdef CONFIG_DEBUG_FS +int musb_init_debugfs(struct musb *musb); +void musb_exit_debugfs(struct musb *musb); +#else +static inline int musb_init_debugfs(struct musb *musb) +{ + return 0; +} + +static inline void musb_exit_debugfs(struct musb *musb) +{ +} +#endif + +#endif /*__MUSB_LINUX_DEBUG_H__ */ diff --git a/drivers/misc/mediatek/mu3d/drv/musb_debugfs.c b/drivers/misc/mediatek/mu3d/drv/musb_debugfs.c new file mode 100644 index 000000000000..a67569a6ac40 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_debugfs.c @@ -0,0 +1,621 @@ +/* + * MUSB OTG driver debugfs support + * + * Copyright 2010 Nokia Corporation + * Contact: Felipe Balbi <felipe.balbi@nokia.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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 <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/debugfs.h> +#include <linux/seq_file.h> + +#include <asm/uaccess.h> + +#include "musb_core.h" +#include "musb_debug.h" +#include "mu3d_hal_phy.h" +#include "mu3d_hal_usb_drv.h" +#include "mu3d_hal_hw.h" +#include "mu3d_hal_qmu_drv.h" + + +struct musb_register_map { + char *name; + unsigned offset; + unsigned size; +}; + +static const struct musb_register_map musb_regmap[] = { + {"FAddr", 0x00, 8}, + {"Power", 0x01, 8}, + {"Frame", 0x0c, 16}, + {"Index", 0x0e, 8}, + {"Testmode", 0x0f, 8}, + {"TxMaxPp", 0x10, 16}, + {"TxCSRp", 0x12, 16}, + {"RxMaxPp", 0x14, 16}, + {"RxCSR", 0x16, 16}, + {"RxCount", 0x18, 16}, + {"ConfigData", 0x1f, 8}, + {"DevCtl", 0x60, 8}, + {"MISC", 0x61, 8}, + {"TxFIFOsz", 0x62, 8}, + {"RxFIFOsz", 0x63, 8}, + {"TxFIFOadd", 0x64, 16}, + {"RxFIFOadd", 0x66, 16}, + {"VControl", 0x68, 32}, + {"HWVers", 0x6C, 16}, + {"EPInfo", 0x78, 8}, + {"RAMInfo", 0x79, 8}, + {"LinkInfo", 0x7A, 8}, + {"VPLen", 0x7B, 8}, + {"HS_EOF1", 0x7C, 8}, + {"FS_EOF1", 0x7D, 8}, + {"LS_EOF1", 0x7E, 8}, + {"SOFT_RST", 0x7F, 8}, + {"DMA_CNTLch0", 0x204, 16}, + {"DMA_ADDRch0", 0x208, 32}, + {"DMA_COUNTch0", 0x20C, 32}, + {"DMA_CNTLch1", 0x214, 16}, + {"DMA_ADDRch1", 0x218, 32}, + {"DMA_COUNTch1", 0x21C, 32}, + {"DMA_CNTLch2", 0x224, 16}, + {"DMA_ADDRch2", 0x228, 32}, + {"DMA_COUNTch2", 0x22C, 32}, + {"DMA_CNTLch3", 0x234, 16}, + {"DMA_ADDRch3", 0x238, 32}, + {"DMA_COUNTch3", 0x23C, 32}, + {"DMA_CNTLch4", 0x244, 16}, + {"DMA_ADDRch4", 0x248, 32}, + {"DMA_COUNTch4", 0x24C, 32}, + {"DMA_CNTLch5", 0x254, 16}, + {"DMA_ADDRch5", 0x258, 32}, + {"DMA_COUNTch5", 0x25C, 32}, + {"DMA_CNTLch6", 0x264, 16}, + {"DMA_ADDRch6", 0x268, 32}, + {"DMA_COUNTch6", 0x26C, 32}, + {"DMA_CNTLch7", 0x274, 16}, + {"DMA_ADDRch7", 0x278, 32}, + {"DMA_COUNTch7", 0x27C, 32}, + {} /* Terminating Entry */ +}; + +static int musb_regdump_show(struct seq_file *s, void *unused) +{ + struct musb *musb = s->private; + unsigned i; + + seq_puts(s, "MUSB (M)HDRC Register Dump\n"); + + for (i = 0; i < ARRAY_SIZE(musb_regmap); i++) { + switch (musb_regmap[i].size) { + case 8: + seq_printf(s, "%-12s: %02x\n", musb_regmap[i].name, + musb_readb(musb->mregs, musb_regmap[i].offset)); + break; + case 16: + seq_printf(s, "%-12s: %04x\n", musb_regmap[i].name, + musb_readw(musb->mregs, musb_regmap[i].offset)); + break; + case 32: + seq_printf(s, "%-12s: %08x\n", musb_regmap[i].name, + musb_readl(musb->mregs, musb_regmap[i].offset)); + break; + } + } + + return 0; +} + +static int musb_regdump_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_regdump_show, inode->i_private); +} + +static const struct file_operations musb_regdump_fops = { + .open = musb_regdump_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int musb_test_mode_show(struct seq_file *s, void *unused) +{ + struct musb *musb = s->private; + unsigned test; + + test = musb_readb(musb->mregs, MUSB_TESTMODE); + + if (test & FORCE_HOST) + seq_puts(s, "force host\n"); + + if (test & FIFO_ACCESS) + seq_puts(s, "fifo access\n"); + + if (test & FORCE_FS) + seq_puts(s, "force full-speed\n"); + + if (test & FORCE_HS) + seq_puts(s, "force high-speed\n"); + + if (test & TEST_PACKET_MODE) + seq_puts(s, "test packet\n"); + + if (test & TEST_K_MODE) + seq_puts(s, "test K\n"); + + if (test & TEST_J_MODE) + seq_puts(s, "test J\n"); + + if (test & TEST_SE0_NAK_MODE) + seq_puts(s, "test SE0 NAK\n"); + + return 0; +} + +static int musb_test_mode_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_test_mode_show, inode->i_private); +} + +static ssize_t musb_test_mode_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct musb *musb = s->private; + u8 test = 0; + char buf[18]; + + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "force host", 9)) + test = FORCE_HOST; + + if (!strncmp(buf, "fifo access", 11)) + test = FIFO_ACCESS; + + if (!strncmp(buf, "force full-speed", 15)) + test = FORCE_FS; + + if (!strncmp(buf, "force high-speed", 15)) + test = FORCE_HS; + + if (!strncmp(buf, "test packet", 10)) { + test = TEST_PACKET_MODE; + musb_load_testpacket(musb); + } + + if (!strncmp(buf, "test K", 6)) + test = TEST_K_MODE; + + if (!strncmp(buf, "test J", 6)) + test = TEST_J_MODE; + + if (!strncmp(buf, "test SE0 NAK", 12)) + test = TEST_SE0_NAK_MODE; + + musb_writeb(musb->mregs, MUSB_TESTMODE, test); + + return count; +} + +static const struct file_operations musb_test_mode_fops = { + .open = musb_test_mode_open, + .write = musb_test_mode_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +#ifdef USE_SSUSB_QMU + +static int musb_usb_reg_show(struct seq_file *s, void *unused) +{ + int i; + + for (i = 1; i < 9; ++i) { + unsigned int *addr = 0; + uintptr_t tmp; + + seq_printf(s, "EP[%d] CSR0=%08x, CSR1=%08x, CSR2=%08x\n", i, + (unsigned int)USB_ReadCsr32(U3D_TX1CSR0, i), + (unsigned int)USB_ReadCsr32(U3D_TX1CSR1, i), + (unsigned int)USB_ReadCsr32(U3D_TX1CSR2, i)); + + seq_printf(s, "TxQ CPR=%08x, CSR=%08x\n", + (unsigned int)os_readl(USB_QMU_TQCPR(i)), + (unsigned int)os_readl(USB_QMU_TQCSR(i))); + + tmp = (uintptr_t) os_readl(USB_QMU_TQCPR(i)); /* QMU GPD address --> CPU DMA address */ + + if (tmp != 0) { + /* addr = (unsigned int *)phys_to_virt(tmp); */ + addr = (unsigned int *)gpd_phys_to_virt((void *)tmp, USB_TX, i); + + /*seq_printf(s, "GPD[%08x] %08x, %08x, %08x, %08x\n", + addr, (*(unsigned int*)addr), + (*(unsigned int*)(addr+1)), + (*(unsigned int*)(addr+2)), + (*(unsigned int*)(addr+3))); */ + + seq_printf(s, "GPD[%p] HWO=%d, BPD=%d, Next_GPD=%lx, DataBuffer=%lx, BufferLen=%d\n", + addr, (u32) TGPD_GET_FLAG(addr), + (u32) TGPD_GET_FORMAT(addr), (uintptr_t) TGPD_GET_NEXT(addr), + (uintptr_t) TGPD_GET_DATA(addr), (u32) TGPD_GET_BUF_LEN(addr)); + } + + seq_printf(s, "EP[%d] CSR0=%08x, CSR1=%08x, CSR2=%08x, CSR3=%08x\n", i, + (unsigned int)USB_ReadCsr32(U3D_RX1CSR0, i), + (unsigned int)USB_ReadCsr32(U3D_RX1CSR1, i), + (unsigned int)USB_ReadCsr32(U3D_RX1CSR2, i), + (unsigned int)USB_ReadCsr32(U3D_RX1CSR3, i)); + + seq_printf(s, "RxQ CPR=%08x, CSR=%08x, LDPR=%08x\n", + (unsigned int)os_readl(USB_QMU_RQCPR(i)), + (unsigned int)os_readl(USB_QMU_RQCSR(i)), + (unsigned int)os_readl(USB_QMU_RQLDPR(i))); + + tmp = (uintptr_t) os_readl(USB_QMU_RQCPR(i)); + + if (tmp != 0) { + /* addr = (unsigned int *)phys_to_virt(tmp); */ + addr = (unsigned int *)gpd_phys_to_virt((void *)tmp, USB_RX, i); + + /*seq_printf(s, "GPD[%08x] %08x, %08x, %08x, %08x\n", + addr, (*(unsigned int*)addr), + (*(unsigned int*)(addr+1)), + (*(unsigned int*)(addr+2)), + (*(unsigned int*)(addr+3))); */ + + seq_printf(s, "GPD[%p] HWO=%d, Next_GPD=%lx ,DataBufLen=%d, DataBuf=%lx, RecvLen=%d, Endpoint=%d\n", + addr, (u32) TGPD_GET_FLAG(addr), (uintptr_t) TGPD_GET_NEXT(addr), + (u32) TGPD_GET_DataBUF_LEN(addr), + (uintptr_t) TGPD_GET_DATA(addr), (u32) TGPD_GET_BUF_LEN(addr), + (u32) TGPD_GET_EPaddr(addr)); + } + + seq_puts(s, "---------------\n\n"); + } + + return 0; +} + +static int musb_usb_reg_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_usb_reg_show, inode->i_private); +} + +static ssize_t musb_usb_reg_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + char buf[18]; + char dir; + int ep; + + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + if (sscanf(buf, "resume %c %d", &dir, &ep) == 2) { + pr_debug("%s %c %d\n", __func__, dir, ep); + + if (dir == 'R' || dir == 'r') { + pr_debug("%s resume EP[%d]-R\n", __func__, ep); + os_writel(USB_QMU_RQCSR(ep), QMU_Q_RESUME); + /* mu3d_hal_resume_qmu(ep, USB_RX); */ + } else { + pr_debug("%s resume EP[%d]-T\n", __func__, ep); + os_writel(USB_QMU_TQCSR(ep), QMU_Q_RESUME); + /* mu3d_hal_resume_qmu(ep, USB_TX); */ + } + } + return count; +} + + +static const struct file_operations musb_usb_reg_fops = { + .open = musb_usb_reg_open, + .write = musb_usb_reg_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +#ifdef CONFIG_MTK_FPGA +static int musb_scan_phase_show(struct seq_file *s, void *unused) +{ + seq_puts(s, "#echo scan l=[0|1] d=[0~3] > scan_phase\n"); + seq_puts(s, "#echo linkup[0|1] > scan_phase\n"); + + return 0; +} + + +static int musb_scan_phase(struct seq_file *s, int latch, int driving) +{ + struct musb *musb = s->private; + + disable_irq(musb->nIrq); + + os_printk(K_INFO, "Init PHY\n"); + u3phy_ops->init(u3phy); + + os_printk(K_INFO, "Plug in the USB cable 3\n"); + mdelay(1000); + os_printk(K_INFO, "Plug in the USB cable 2\n"); + mdelay(1000); + os_printk(K_INFO, "Plug in the USB cable 1\n"); + mdelay(1000); + + os_printk(K_INFO, "PHY SCAN latch=%d, drivind=%d\n", latch, driving); + mu3d_hal_phy_scan(latch, driving); + seq_puts(s, "Finish--\n"); + + return 0; +} + +static int musb_scan_phase_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_scan_phase_show, inode->i_private); +} + +static ssize_t musb_scan_phase_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + char buf[18]; + + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + if (!strncmp(buf, "linkup1", 7)) { + int status = RET_SUCCESS; + int cnt = 10; + + mu3d_hal_link_up(1); + mdelay(500); + do { + if ((os_readl(U3D_LINK_STATE_MACHINE) & LTSSM) != STATE_U0_STATE) { + status = RET_FAIL; + break; + } + mdelay(50); + } while (cnt--); + + if (status != RET_SUCCESS) + pr_debug("&&&&&& LINK UP FAIL !!&&&&&&\n"); + else + pr_debug("&&&&&& LINK UP PASS !!&&&&&&\n"); + + } + + if (!strncmp(buf, "linkup0", 7)) { + int status = RET_SUCCESS; + int cnt = 10; + + mu3d_hal_link_up(0); + mdelay(500); + do { + if ((os_readl(U3D_LINK_STATE_MACHINE) & LTSSM) != STATE_U0_STATE) { + status = RET_FAIL; + break; + } + mdelay(50); + } while (cnt--); + + if (status != RET_SUCCESS) + os_printk(K_INFO, "&&&&&& LINK UP FAIL !!&&&&&&\n"); + else + os_printk(K_INFO, "&&&&&& LINK UP PASS !!&&&&&&\n"); + } + + if (strncmp(buf, "scan", 4) == 0) { + unsigned latch, driving; + + if (sscanf(buf, "scan l=%u d=%u", &latch, &driving) == 2) { + os_printk(K_INFO, "%s latch=%d, driving=%d\n", __func__, latch, driving); + musb_scan_phase(s, latch, driving); + } else { + os_printk(K_INFO, "%s Can not match\n", __func__); + } + } + + return count; +} + +static const struct file_operations musb_scan_phase_fops = { + .open = musb_scan_phase_open, + .write = musb_scan_phase_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int musb_phy_reg_show(struct seq_file *s, void *unused) +{ + seq_printf(s, + "#echo w/w8/w32 [ADDR] [VAL] > phy_reg (ex: #echo w 0x2000e4 0x1 > phy_reg)\n"); + seq_puts(s, "#echo r/r8/r32 [ADDR] > phy_reg (ex: #echo r32 0x2000e4 > phy_reg)\n"); + + return 0; +} + +static int musb_phy_reg_open(struct inode *inode, struct file *file) +{ + return single_open(file, musb_phy_reg_show, inode->i_private); +} + +static ssize_t musb_phy_rege_write(struct file *file, + const char __user *ubuf, size_t count, loff_t *ppos) +{ + /* warning: unused variable 's' [-Wunused-variable] */ + /* struct seq_file *s = file->private_data; */ + char buf[18]; + + memset(buf, 0x00, sizeof(buf)); + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + if (!strncmp(buf, "w", 1)) { + unsigned int address = 0; + unsigned int value = 0; + + if (sscanf(buf, "w32 0x%x 0x%x", &address, &value) == 2) { + value = value & 0xff; + os_printk(K_INFO, "%s write32 address=0x%x, value=0x%x\n", __func__, + address, value); + U3PhyWriteReg32(address, value); + mdelay(10); + value = U3PhyReadReg32(address); + os_printk(K_INFO, "%s result=0x%x\n", __func__, value); + } else if (sscanf(buf, "w8 0x%x 0x%x", &address, &value) == 2) { + value = value & 0xff; + os_printk(K_INFO, "%s write8 address=0x%x, value=0x%x\n", __func__, address, + value); + U3PhyWriteReg8(address, value); + mdelay(10); + value = U3PhyReadReg8(address); + os_printk(K_INFO, "%s result=0x%x\n", __func__, value); + } else if (sscanf(buf, "w 0x%x 0x%x", &address, &value) == 2) { + value = value & 0xff; + pr_debug("%s write address=0x%x, value=0x%x\n", __func__, address, value); + _U3Write_Reg(address, value); + mdelay(10); + value = _U3Read_Reg(address); + os_printk(K_INFO, "%s result=0x%x\n", __func__, value); + } else { + os_printk(K_INFO, "%s Can not match\n", __func__); + } + } + + if (!strncmp(buf, "r", 1)) { + unsigned int address = 0; + unsigned int value = 0; + + if (sscanf(buf, "r32 0x%x", &address) == 1) { + os_printk(K_INFO, "%s read32 address=0x%x\n", __func__, address); + value = U3PhyReadReg32(address); + os_printk(K_INFO, "%s result=0x%x\n", __func__, value); + } else if (sscanf(buf, "r8 0x%x", &address) == 1) { + os_printk(K_INFO, "%s read8 address=0x%x\n", __func__, address); + value = U3PhyReadReg8(address); + os_printk(K_INFO, "%s result=0x%x\n", __func__, value); + } else if (sscanf(buf, "r 0x%x", &address) == 1) { + os_printk(K_INFO, "%s read address=0x%x\n", __func__, address); + value = _U3Read_Reg(address); + os_printk(K_INFO, "%s result=0x%x\n", __func__, value); + } else { + os_printk(K_INFO, "%s Can not match\n", __func__); + } + } +#endif + + return count; +} + +static const struct file_operations musb_phy_reg_fops = { + .open = musb_phy_reg_open, + .write = musb_phy_rege_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +int musb_init_debugfs(struct musb *musb) +{ + struct dentry *root; + struct dentry *file; + int ret; + + root = debugfs_create_dir(dev_name(musb->controller), NULL); + if (!root) { + ret = -ENOMEM; + goto err0; + } + + file = debugfs_create_file("regdump", S_IRUGO, root, musb, &musb_regdump_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } + + file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, musb, &musb_test_mode_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } +#ifdef USE_SSUSB_QMU + file = debugfs_create_file("usb_reg", S_IRUGO | S_IWUSR, root, musb, &musb_usb_reg_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } +#endif + +#ifdef CONFIG_MTK_FPGA + file = debugfs_create_file("scan_phase", S_IRUGO | S_IWUSR, + root, musb, &musb_scan_phase_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } + + file = debugfs_create_file("phy_reg", S_IRUGO | S_IWUSR, root, musb, &musb_phy_reg_fops); + if (!file) { + ret = -ENOMEM; + goto err1; + } +#endif + + musb->debugfs_root = root; + + return 0; + +err1: + debugfs_remove_recursive(root); + +err0: + return ret; +} + +void /* __init_or_exit */ musb_exit_debugfs(struct musb *musb) +{ + debugfs_remove_recursive(musb->debugfs_root); +} diff --git a/drivers/misc/mediatek/mu3d/drv/musb_dma.h b/drivers/misc/mediatek/mu3d/drv/musb_dma.h new file mode 100644 index 000000000000..0d6bff2ad883 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_dma.h @@ -0,0 +1,180 @@ +/* + * MUSB OTG driver DMA controller abstraction + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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. + * + */ + +#ifndef __MUSB_DMA_H__ +#define __MUSB_DMA_H__ + +struct musb_hw_ep; + +/* + * DMA Controller Abstraction + * + * DMA Controllers are abstracted to allow use of a variety of different + * implementations of DMA, as allowed by the Inventra USB cores. On the + * host side, usbcore sets up the DMA mappings and flushes caches; on the + * peripheral side, the gadget controller driver does. Responsibilities + * of a DMA controller driver include: + * + * - Handling the details of moving multiple USB packets + * in cooperation with the Inventra USB core, including especially + * the correct RX side treatment of short packets and buffer-full + * states (both of which terminate transfers). + * + * - Knowing the correlation between dma channels and the + * Inventra core's local endpoint resources and data direction. + * + * - Maintaining a list of allocated/available channels. + * + * - Updating channel status on interrupts, + * whether shared with the Inventra core or separate. + */ + +#define DMA_ADDR_INVALID (~(dma_addr_t)0) + +#ifndef CONFIG_USB_MU3D_PIO_ONLY +#define is_dma_capable() (1) +#else +#define is_dma_capable() (0) +#endif + +#ifdef CONFIG_USB_TI_CPPI_DMA +#define is_cppi_enabled() 1 +#else +#define is_cppi_enabled() 0 +#endif + +#ifdef CONFIG_USB_TUSB_OMAP_DMA +#define tusb_dma_omap() 1 +#else +#define tusb_dma_omap() 0 +#endif + +/* Anomaly 05000456 - USB Receive Interrupt Is Not Generated in DMA Mode 1 + * Only allow DMA mode 1 to be used when the USB will actually generate the + * interrupts we expect. + */ +#ifdef CONFIG_BLACKFIN +#undef USE_MODE1 +#if !ANOMALY_05000456 +#define USE_MODE1 +#endif +#endif + +/* + * DMA channel status ... updated by the dma controller driver whenever that + * status changes, and protected by the overall controller spinlock. + */ +enum dma_channel_status { + /* unallocated */ + MUSB_DMA_STATUS_UNKNOWN, + /* allocated ... but not busy, no errors */ + MUSB_DMA_STATUS_FREE, + /* busy ... transactions are active */ + MUSB_DMA_STATUS_BUSY, + /* transaction(s) aborted due to ... dma or memory bus error */ + MUSB_DMA_STATUS_BUS_ABORT, + /* transaction(s) aborted due to ... core error or USB fault */ + MUSB_DMA_STATUS_CORE_ABORT +}; + +struct dma_controller; + +/** + * struct dma_channel - A DMA channel. + * @private_data: channel-private data + * @max_len: the maximum number of bytes the channel can move in one + * transaction (typically representing many USB maximum-sized packets) + * @actual_len: how many bytes have been transferred + * @status: current channel status (updated e.g. on interrupt) + * @desired_mode: true if mode 1 is desired; false if mode 0 is desired + * + * channels are associated with an endpoint for the duration of at least + * one usb transfer. + */ +struct dma_channel { + void *private_data; + /* FIXME not void* private_data, but a dma_controller * */ + size_t max_len; + size_t actual_len; + enum dma_channel_status status; + bool desired_mode; +}; + +/* + * dma_channel_status - return status of dma channel + * @c: the channel + * + * Returns the software's view of the channel status. If that status is BUSY + * then it's possible that the hardware has completed (or aborted) a transfer, + * so the driver needs to update that status. + */ +static inline enum dma_channel_status dma_channel_status(struct dma_channel *c) +{ + return (is_dma_capable() && c) ? c->status : MUSB_DMA_STATUS_UNKNOWN; +} + +/** + * struct dma_controller - A DMA Controller. + * @start: call this to start a DMA controller; + * return 0 on success, else negative errno + * @stop: call this to stop a DMA controller + * return 0 on success, else negative errno + * @channel_alloc: call this to allocate a DMA channel + * @channel_release: call this to release a DMA channel + * @channel_abort: call this to abort a pending DMA transaction, + * returning it to FREE (but allocated) state + * + * Controllers manage dma channels. + */ +struct dma_controller { + int (*start)(struct dma_controller *); + int (*stop)(struct dma_controller *); + struct dma_channel *(*channel_alloc)(struct dma_controller *, + struct musb_hw_ep *, u8 is_tx); + void (*channel_release)(struct dma_channel *); + int (*channel_program)(struct dma_channel *channel, + u16 maxpacket, u8 mode, dma_addr_t dma_addr, u32 length); + int (*channel_abort)(struct dma_channel *); + int (*is_compatible)(struct dma_channel *channel, u16 maxpacket, void *buf, u32 length); +}; + +/* called after channel_program(), may indicate a fault */ +extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit); + + +extern struct dma_controller *__init dma_controller_create(struct musb *, void __iomem *); + +extern void dma_controller_destroy(struct dma_controller *); + +#endif /* __MUSB_DMA_H__ */ diff --git a/drivers/misc/mediatek/mu3d/drv/musb_gadget.c b/drivers/misc/mediatek/mu3d/drv/musb_gadget.c new file mode 100644 index 000000000000..1fc585c533a7 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_gadget.c @@ -0,0 +1,2030 @@ +/* + * MUSB OTG driver peripheral support + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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 <linux/kernel.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/module.h> +#include <linux/smp.h> +#include <linux/spinlock.h> +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/slab.h> + +#include "musb_core.h" +#include "mu3d_hal_osal.h" +#include "mu3d_hal_qmu_drv.h" +#include "mu3d_hal_usb_drv.h" +#include "mu3d_hal_hw.h" +#include "ssusb_qmu.h" +#include "musb_gadget.h" + +/* MUSB PERIPHERAL status 3-mar-2006: + * + * - EP0 seems solid. It passes both USBCV and usbtest control cases. + * Minor glitches: + * + * + remote wakeup to Linux hosts work, but saw USBCV failures; + * in one test run (operator error?) + * + endpoint halt tests -- in both usbtest and usbcv -- seem + * to break when dma is enabled ... is something wrongly + * clearing SENDSTALL? + * + * - Mass storage behaved ok when last tested. Network traffic patterns + * (with lots of short transfers etc) need retesting; they turn up the + * worst cases of the DMA, since short packets are typical but are not + * required. + * + * - TX/IN + * + both pio and dma behave in with network and g_zero tests + * + no cppi throughput issues other than no-hw-queueing + * + failed with FLAT_REG (DaVinci) + * + seems to behave with double buffering, PIO -and- CPPI + * + with gadgetfs + AIO, requests got lost? + * + * - RX/OUT + * + both pio and dma behave in with network and g_zero tests + * + dma is slow in typical case (short_not_ok is clear) + * + double buffering ok with PIO + * + double buffering *FAILS* with CPPI, wrong data bytes sometimes + * + request lossage observed with gadgetfs + * + * - ISO not tested ... might work, but only weakly isochronous + * + * - Gadget driver disabling of softconnect during bind() is ignored; so + * drivers can't hold off host requests until userspace is ready. + * (Workaround: they can turn it off later.) + * + * - PORTABILITY (assumes PIO works): + * + DaVinci, basically works with cppi dma + * + OMAP 2430, ditto with mentor dma + * + TUSB 6010, platform-specific dma in the works + */ + +/* ----------------------------------------------------------------------- */ + +#define is_buffer_mapped(req) (is_dma_capable() && \ + (req->map_state != UN_MAPPED)) + +/* Maps the buffer to dma */ + +static inline void map_dma_buffer(struct musb_request *request, + struct musb *musb, struct musb_ep *musb_ep) +{ +#ifndef USE_SSUSB_QMU + int compatible = true; + struct dma_controller *dma = musb->dma_controller; +#endif + + unsigned length; + + length = ALIGN(request->request.length, dma_get_cache_alignment()); + + request->map_state = UN_MAPPED; + +#ifndef USE_SSUSB_QMU + if (!is_dma_capable() || !musb_ep->dma) + return; + + /* Check if DMA engine can handle this request. + * DMA code must reject the USB request explicitly. + * Default behaviour is to map the request. + */ + if (dma->is_compatible) + compatible = dma->is_compatible(musb_ep->dma, + musb_ep->packet_sz, request->request.buf, + request->request.length); + if (!compatible) + return; + +#endif + if (request->request.dma == DMA_ADDR_INVALID) { + request->request.dma = dma_map_single(musb->controller, + request->request.buf, + length, + request->tx + ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + request->map_state = MUSB_MAPPED; + } else { + dma_sync_single_for_device(musb->controller, + request->request.dma, + length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + request->map_state = PRE_MAPPED; + } +} + +/* Unmap the buffer from dma and maps it back to cpu */ +static inline void unmap_dma_buffer(struct musb_request *request, struct musb *musb) +{ + unsigned length; + + length = ALIGN(request->request.length, dma_get_cache_alignment()); + + if (!is_buffer_mapped(request)) + return; + + if (request->request.dma == DMA_ADDR_INVALID) { + dev_vdbg(musb->controller, "not unmapping a never mapped buffer\n"); + return; + } + if (request->map_state == MUSB_MAPPED) { + dma_unmap_single(musb->controller, + request->request.dma, + length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + request->request.dma = DMA_ADDR_INVALID; + } else { /* PRE_MAPPED */ + dma_sync_single_for_cpu(musb->controller, + request->request.dma, + length, request->tx ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + } + request->map_state = UN_MAPPED; +} + +/* + * Immediately complete a request. + * + * @param request the request to complete + * @param status the status to complete the request with + * Context: controller locked, IRQs blocked. + */ +void musb_g_giveback(struct musb_ep *ep, + struct usb_request *request, + int status) __releases(ep->musb->lock) __acquires(ep->musb->lock) +{ + struct musb_request *req; + struct musb *musb; + int busy = ep->busy; + + if (unlikely(list_empty(&ep->req_list))) { + os_printk(K_ERR, "ep->req_list is empty:%s\n", ep->end_point.name); + return; + } + + req = to_musb_request(request); + + list_del(&req->list); + if (req->request.status == -EINPROGRESS) + req->request.status = status; + musb = req->musb; + + ep->busy = 1; + spin_unlock(&musb->lock); + unmap_dma_buffer(req, musb); + if (request->status == 0) + /* dev_dbg(musb->controller, "%s done request %p, %d/%d\n", */ + os_printk(K_DEBUG, "%s done request %p, %d/%d\n", + ep->end_point.name, request, req->request.actual, req->request.length); + else + /* dev_dbg(musb->controller, "%s request %p, %d/%d fault %d\n", */ + os_printk(K_DEBUG, "%s request %p, %d/%d fault %d\n", + ep->end_point.name, request, + req->request.actual, req->request.length, request->status); + + os_printk(K_DEBUG, "*************** musb_g_giveback : %p, #%d\n", request, + req->request.actual); + req->request.complete(&req->ep->end_point, &req->request); + spin_lock(&musb->lock); + ep->busy = busy; +} + +/* ----------------------------------------------------------------------- */ + +/* + * Abort requests queued to an endpoint using the status. Synchronous. + * caller locked controller and blocked irqs, and selected this ep. + */ +static void nuke(struct musb_ep *ep, const int status) +{ + struct musb_request *req = NULL; + + os_printk(K_INFO, "%s status=%d %s-%s\n", __func__, status, ep->end_point.name, + (ep->is_in ? "IN" : "OUT")); + + ep->busy = 1; + +#ifdef USE_SSUSB_QMU + _ex_mu3d_hal_flush_qmu(ep->hw_ep->epnum, (ep->is_in ? USB_TX : USB_RX)); + /* mu3d_hal_start_qmu(ep->musb->mregs, ep->hw_ep->epnum, (ep->is_in? USB_TX: USB_RX)); */ +#endif + + while (!list_empty(&ep->req_list)) { + req = list_first_entry(&ep->req_list, struct musb_request, list); + musb_g_giveback(ep, &req->request, status); + os_printk(K_INFO, "%s call musb_g_giveback() EP is %s\n", __func__, + ep->end_point.name); + } +} + +/* ----------------------------------------------------------------------- */ + +/* Data transfers - pure PIO, pure DMA, or mixed mode */ + +/* + * This assumes the separate CPPI engine is responding to DMA requests + * from the usb core ... sequenced a bit differently from mentor dma. + */ + +static inline int max_ep_writesize(struct musb *musb, struct musb_ep *ep) +{ + if (can_bulk_split(musb, ep->type)) + return ep->hw_ep->max_packet_sz_tx; + else + return ep->packet_sz; +} + + +#ifdef CONFIG_USB_INVENTRA_DMA + +/* Peripheral tx (IN) using Mentor DMA works as follows: + Only mode 0 is used for transfers <= wPktSize, + mode 1 is used for larger transfers, + + One of the following happens: + - Host sends IN token which causes an endpoint interrupt + -> TxAvail + -> if DMA is currently busy, exit. + -> if queue is non-empty, txstate(). + + - Request is queued by the gadget driver. + -> if queue was previously empty, txstate() + + txstate() + -> start + /\ -> setup DMA + | (data is transferred to the FIFO, then sent out when + | IN token(s) are recd from Host. + | -> DMA interrupt on completion + | calls TxAvail. + | -> stop DMA, ~DMAENAB, + | -> set TxPktRdy for last short pkt or zlp + | -> Complete Request + | -> Continue next request (call txstate) + |___________________________________| + + * Non-Mentor DMA engines can of course work differently, such as by + * upleveling from irq-per-packet to irq-per-buffer. + */ + +#endif + +#ifndef USE_SSUSB_QMU + +/* + * An endpoint is transmitting data. This can be called either from + * the IRQ routine or from ep.queue() to kickstart a request on an + * endpoint. + * + * Context: controller locked, IRQs blocked, endpoint selected + */ +static void txstate(struct musb *musb, struct musb_request *req) +{ + u8 epnum = req->epnum; + struct musb_ep *musb_ep; + struct usb_request *request; + u16 fifo_count = 0; + u32 txcsr0 = 0, maxp; + int use_dma = 0; + + os_printk(K_DEBUG, "%s\n", __func__); + + musb_ep = req->ep; + + /* we shouldn't get here while DMA is active ... but we do ... */ + if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { + dev_dbg(musb->controller, "dma pending...\n"); + return; + } + + /* read TXCSR before */ + txcsr0 = os_readl(musb->endpoints[epnum].addr_txcsr0); + request = &req->request; + fifo_count = min(max_ep_writesize(musb, musb_ep), (int)(request->length - request->actual)); + + if (txcsr0 & TX_TXPKTRDY) + return; + + if (txcsr0 & TX_SENDSTALL) + return; + + if (!use_dma) { + /* + * Unmap the dma buffer back to cpu if dma channel + * programming fails + */ + unmap_dma_buffer(req, musb); + + maxp = musb_ep->packet_sz; + + mu3d_hal_write_fifo(epnum, fifo_count, (u8 *) (request->buf + request->actual), + maxp); + request->actual += fifo_count; + + os_printk(K_DEBUG, "%s actual=%d, fifo_count=%d\n", __func__, request->actual, + fifo_count); + +#if 0 + musb_write_fifo(musb_ep->hw_ep, fifo_count, + (u8 *) (request->buf + request->actual)); + request->actual += fifo_count; + txcsr0 &= TX_W1C_BITS; + txcsr0 |= TX_TXPKTRDY; + os_writel(musb->endpoints[epnum].addr_txcsr0, txcsr0); +#endif + } +} + +#endif +/* + * FIFO state update (e.g. data ready). + * Called from IRQ, with controller locked. + */ +void musb_g_tx(struct musb *musb, u8 epnum) +{ + u32 txcsr0; + struct musb_request *req; + struct usb_request *request; + struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_in; + struct dma_channel *dma; + + req = next_request(musb_ep); + request = &req->request; + + txcsr0 = os_readl(musb->endpoints[epnum].addr_txcsr0); + + dma = is_dma_capable() ? musb_ep->dma : NULL; + if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { + /* + * SHOULD NOT HAPPEN... has with CPPI though, after + * changing SENDSTALL (and other cases); harmless? + */ + dev_dbg(musb->controller, "%s dma still busy?\n", musb_ep->end_point.name); + return; + } + + if (request) { + /* + * First, maybe a terminating short packet. Some DMA + * engines might handle this by themselves. + */ + if ((request->zero && request->length && (request->length % musb_ep->packet_sz == 0) + && (request->actual == request->length)) + ) { + /* + * On DMA completion, FIFO may not be + * available yet... + */ + if (txcsr0 & TX_TXPKTRDY) + return; + + dev_dbg(musb->controller, "sending zero pkt\n"); + /* os_writel(musb->endpoints[epnum].addr_txcsr0, (txcsr0 & TX_W1C_BITS) | TX_TXPKTRDY); */ + writel((txcsr0 & TX_W1C_BITS) | TX_TXPKTRDY, + musb->endpoints[epnum].addr_txcsr0); + request->zero = 0; + } + + if (request->actual == request->length) { + musb_g_giveback(musb_ep, request, 0); + req = musb_ep->desc ? next_request(musb_ep) : NULL; + if (!req) { + dev_dbg(musb->controller, "%s idle now\n", musb_ep->end_point.name); + return; + } + } +#ifdef USE_SSUSB_QMU + /* txstate_qmu(musb, req); */ +#else + txstate(musb, req); +#endif + } +} + +/* ------------------------------------------------------------ */ + +#ifdef CONFIG_USB_INVENTRA_DMA + +/* Peripheral rx (OUT) using Mentor DMA works as follows: + - Only mode 0 is used. + + - Request is queued by the gadget class driver. + -> if queue was previously empty, rxstate() + + - Host sends OUT token which causes an endpoint interrupt + /\ -> RxReady + | -> if request queued, call rxstate + | /\ -> setup DMA + | | -> DMA interrupt on completion + | | -> RxReady + | | -> stop DMA + | | -> ack the read + | | -> if data recd = max expected + | | by the request, or host + | | sent a short packet, + | | complete the request, + | | and start the next one. + | |_____________________________________| + | else just wait for the host + | to send the next OUT token. + |__________________________________________________| + + * Non-Mentor DMA engines can of course work differently. + */ + +#endif + +/* + * Context: controller locked, IRQs blocked, endpoint selected + */ +static void rxstate(struct musb *musb, struct musb_request *req) +{ + const u8 epnum = req->epnum; + struct usb_request *request = &req->request; + struct musb_ep *musb_ep; + u16 fifo_count; + unsigned len = 0; + u32 rxcsr0 = os_readl(musb->endpoints[epnum].addr_rxcsr0); + struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; + + musb_ep = &hw_ep->ep_out; + + fifo_count = musb_ep->packet_sz; + + /* We shouldn't get here while DMA is active, but we do... */ + if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) { + dev_dbg(musb->controller, "DMA pending...\n"); + return; + } + + os_printk(K_DEBUG, "epnum=%d, rxcsr addr=%lX, rxcsr0=%X\n", epnum, + (uintptr_t) (musb->endpoints[epnum].addr_rxcsr0), rxcsr0); + + if (rxcsr0 & RX_SENDSTALL) + return; + + if (rxcsr0 & RX_RXPKTRDY) { + fifo_count = (USB_ReadCsr32(U3D_RX1CSR3, epnum) >> EP_RX_COUNT_OFST); + if (request->actual < request->length) { + len = request->length - request->actual; + fifo_count = min_t(unsigned, len, fifo_count); + /* fifo_count = mu3d_hal_read_fifo( epnum, (request->buf + request->actual)); */ + musb_read_fifo(&musb->endpoints[epnum], fifo_count, + (request->buf + request->actual)); + request->actual += fifo_count; + + /* ack the read! */ +#ifdef AUTOCLEAR + if (!fifo_count) { + USB_WriteCsr32(U3D_RX1CSR0, epnum, + USB_ReadCsr32(U3D_RX1CSR0, epnum) | RX_RXPKTRDY); + } +#else + USB_WriteCsr32(U3D_RX1CSR0, epnum, + USB_ReadCsr32(U3D_RX1CSR0, epnum) | RX_RXPKTRDY); +#endif + } + } + + os_printk(K_DEBUG, "%s length=%d, actual=%d, fifo_count=%d\n", __func__, request->length, + request->actual, fifo_count); + os_printk(K_DEBUG, "%s len=%d, packet_sz=%d\n", __func__, len, musb_ep->packet_sz); + + /* reach the end or short packet detected */ + if (request->actual == request->length || fifo_count < musb_ep->packet_sz) + musb_g_giveback(musb_ep, request, 0); + + +#ifdef NEVER + /* Check other slot is empty */ + rxcsr0 = os_readl(musb->endpoints[epnum].addr_rxcsr0); + os_printk(K_DEBUG, "rxcsr0 fifoempty=0x%x\n", rxcsr0 & RX_FIFOEMPTY); + if (!(rxcsr0 & RX_FIFOEMPTY)) { + os_printk(K_DEBUG, "==READ AGAIN!!!==\n"); + musb_g_rx(musb, epnum); + } +#endif /* NEVER */ +} + +/* + * Data ready for a request; called from IRQ + */ +void musb_g_rx(struct musb *musb, u8 epnum) +{ + u32 rxcsr0; + struct musb_request *req; + struct usb_request *request; + struct musb_ep *musb_ep; + struct dma_channel *dma; + struct musb_hw_ep *hw_ep = &musb->endpoints[epnum]; + + musb_ep = &hw_ep->ep_out; + + req = next_request(musb_ep); + if (!req) + return; + + request = &req->request; + + rxcsr0 = os_readl(musb->endpoints[epnum].addr_rxcsr0); + + if (rxcsr0 & RX_SENTSTALL) { + + /* EPN needs to continuous sending STALL until host set clear_feature to clear the status. */ + + /* musb_writew(epio, MUSB_RXCSR, csr); */ + + /*SENTSTALL is W1C. So write again to clear it.*/ + /* os_writel(musb->endpoints[epnum].addr_rxcsr0, (rxcsr0 & RX_W1C_BITS) | RX_SENTSTALL); */ + writel((rxcsr0 & RX_W1C_BITS) | RX_SENTSTALL, musb->endpoints[epnum].addr_rxcsr0); + + return; + } + + + dma = is_dma_capable() ? musb_ep->dma : NULL; + + /* Analyze request */ + rxstate(musb, req); +} + +/* ------------------------------------------------------------ */ + +static int musb_gadget_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) +{ + unsigned long flags; + struct musb_ep *musb_ep; + struct musb_hw_ep *hw_ep; + struct musb *musb; + void __iomem *mbase; + u8 epnum = 0; + unsigned maxp = 0; + int status = -EINVAL; + TRANSFER_TYPE type = USB_CTRL; + USB_DIR dir = USB_TX; + + + if (!ep || !desc) + return -EINVAL; + + os_printk(K_INFO, "musb_gadget_enable %s\n", ep->name); + + musb_ep = to_musb_ep(ep); + hw_ep = musb_ep->hw_ep; + musb = musb_ep->musb; + mbase = musb->mregs; + epnum = hw_ep->epnum; + + if (!musb->is_active) + return -EINVAL; + + spin_lock_irqsave(&musb->lock, flags); + + if (musb_ep->desc) { + status = -EBUSY; + goto fail; + } + musb_ep->type = usb_endpoint_type(desc); + + /* check direction and (later) maxpacket size against endpoint */ + if (usb_endpoint_num(desc) != epnum) + goto fail; + + /* REVISIT this rules out high bandwidth periodic transfers */ + maxp = le16_to_cpu(desc->wMaxPacketSize); + if (maxp & ~0x07ff) + goto fail; + + musb_ep->packet_sz = maxp; + + os_printk(K_DEBUG, "U3D_EPIER=0x%X\n", os_readl(U3D_EPIER)); + + /* enable the interrupts for the endpoint, set the endpoint + * packet size (or fail), set the mode, clear the fifo + */ + if (usb_endpoint_dir_in(desc)) { /* TX */ + + +#ifndef USE_SSUSB_QMU + u32 int_txe = os_readl(U3D_EPIER); +#endif + if (hw_ep->is_shared_fifo) + musb_ep->is_in = 1; + if (!musb_ep->is_in) + goto fail; + + if (maxp > hw_ep->max_packet_sz_tx) + goto fail; + +#ifndef USE_SSUSB_QMU + os_printk(K_DEBUG, "epnum=%d, int_txe=0x%x, EPIER=0x%x+\n", epnum, int_txe, + os_readl(U3D_EPIER)); + int_txe |= (1 << epnum); + os_writel(U3D_EPIESR, int_txe); + os_printk(K_DEBUG, "epnum=%d, int_txe=0x%x, EPIER=0x%x-\n", epnum, int_txe, + os_readl(U3D_EPIER)); +#endif + dir = USB_TX; + + switch (musb_ep->type) { + case USB_ENDPOINT_XFER_BULK: + type = USB_BULK; + break; + case USB_ENDPOINT_XFER_ISOC: + type = USB_ISO; + break; + case USB_ENDPOINT_XFER_INT: + type = USB_INTR; + break; + } + } else { +#ifndef USE_SSUSB_QMU + u32 int_rxe = os_readl(U3D_EPIER); +#endif + if (hw_ep->is_shared_fifo) + musb_ep->is_in = 0; + if (musb_ep->is_in) + goto fail; + + if (maxp > hw_ep->max_packet_sz_rx) { + dev_dbg(musb->controller, "packet size beyond hardware FIFO size\n"); + goto fail; + } +#ifndef USE_SSUSB_QMU + os_printk(K_DEBUG, "int_rxe=0x%x, EPIER=0x%x+\n", int_rxe, os_readl(U3D_EPIER)); + int_rxe |= (BIT16 << epnum); + os_writel(U3D_EPIESR, int_rxe); + os_printk(K_DEBUG, "int_rxe=0x%x, EPIER=0x%x-\n", int_rxe, os_readl(U3D_EPIER)); +#endif + dir = USB_RX; + + switch (musb_ep->type) { + case USB_ENDPOINT_XFER_BULK: + type = USB_BULK; + break; + case USB_ENDPOINT_XFER_ISOC: + type = USB_ISO; + break; + case USB_ENDPOINT_XFER_INT: + type = USB_INTR; + break; + } + + } + + /* + * At PIO with 2 slot(double buffer), the host transfers 512 + N bytes. + * 512 would fill the 1st slot. And the rest of N bytes will put into + * the 2nd slot. The interrupt is coming. The driver reads the data + * stored at the 1st slot. Then driver expects the next interrupt to + * read the data at the 2nd slot. But the interrupt does not show up! + * Designer says maybe the interrupt the driver handles is the interrupt + * come from the 2nd slot. the system does not fast enough. So the later + * one and the previous one merge to one interrupt. + * So at FPGA stage and PIO, just use _ONE_ slot. + */ +#ifdef USE_SSUSB_QMU + _ex_mu3d_hal_ep_enable(epnum, dir, type, maxp, 0, MAX_SLOT, 0, 0); +#else + /*TODO: Check support mulitslots on real ship */ + _ex_mu3d_hal_ep_enable(epnum, dir, type, maxp, 0, 0, 0, 0); +#endif + +#ifdef USE_SSUSB_QMU + mu3d_hal_start_qmu(epnum, dir); +#endif + /* NOTE: all the I/O code _should_ work fine without DMA, in case + * for some reason you run out of channels here. + */ + if (is_dma_capable() && musb->dma_controller) { + struct dma_controller *c = musb->dma_controller; + + musb_ep->dma = c->channel_alloc(c, hw_ep, (desc->bEndpointAddress & USB_DIR_IN)); + } else + musb_ep->dma = NULL; + + musb_ep->desc = desc; + musb_ep->busy = 0; + musb_ep->wedged = 0; + status = 0; + + musb->active_ep++; + os_printk(K_INFO, "[U3D]%s active_ep=%d\n", __func__, musb->active_ep); + + /* pr_debug("%s periph: enabled %s for %s %s, %smaxpacket %d\n", */ + os_printk(K_INFO, "[U3D]%s periph: enabled %s for %s %s, %smaxpacket %d\n", + musb_driver_name, musb_ep->end_point.name, ({ + char *s; + + switch (musb_ep->type) { + case USB_ENDPOINT_XFER_BULK: + s = "bulk"; + break; + case USB_ENDPOINT_XFER_INT: + s = "int"; + break; + default: + s = "iso"; + break; + }; + s; + }), + musb_ep->is_in ? "IN" : "OUT", musb_ep->dma ? "dma, " : "", musb_ep->packet_sz); + + schedule_work(&musb->irq_work); + +fail: + spin_unlock_irqrestore(&musb->lock, flags); + + return status; +} + +/* + * Disable an endpoint flushing all requests queued. + */ +static int musb_gadget_disable(struct usb_ep *ep) +{ + unsigned long flags; + struct musb *musb; + u8 epnum; + struct musb_ep *musb_ep; + int status = 0; + + os_printk(K_INFO, "%s %s\n", __func__, ep->name); + + musb_ep = to_musb_ep(ep); + musb = musb_ep->musb; + epnum = musb_ep->current_epnum; + + spin_lock_irqsave(&musb->lock, flags); + +#ifdef USE_SSUSB_QMU + /* zero the endpoint sizes */ + if (musb_ep->is_in) + os_writelmskumsk(musb->endpoints[epnum].addr_rxcsr0, 0, TX_TXMAXPKTSZ, TX_W1C_BITS); + else + os_writelmskumsk(musb->endpoints[epnum].addr_rxcsr0, 0, RX_RXMAXPKTSZ, RX_W1C_BITS); +#else + /* zero the endpoint sizes */ + if (musb_ep->is_in) { /* TX */ + u32 int_txe = os_readl(U3D_EPIER); + + int_txe &= ~(1 << epnum); + os_writel(U3D_EPIESR, int_txe); + os_writelmskumsk(musb->endpoints[epnum].addr_rxcsr0, 0, TX_TXMAXPKTSZ, TX_W1C_BITS); + } else { + u32 int_rxe = os_readl(U3D_EPIER); + + int_rxe &= ~(BIT16 << epnum); + os_writel(U3D_EPIESR, int_rxe); + os_writelmskumsk(musb->endpoints[epnum].addr_rxcsr0, 0, RX_RXMAXPKTSZ, RX_W1C_BITS); + } +#endif + musb_ep->desc = NULL; + + /* abort all pending DMA and requests */ + nuke(musb_ep, -ESHUTDOWN); + + mu3d_hal_unfigured_ep_num(epnum, (musb_ep->is_in ? USB_TX : USB_RX)); + + schedule_work(&musb->irq_work); + + musb->active_ep--; + os_printk(K_INFO, "[U3D]%s active_ep=%d\n", __func__, musb->active_ep); + + if (musb->active_ep == 0 && musb->is_active == 0) + schedule_work(&musb->suspend_work); + + spin_unlock_irqrestore(&(musb->lock), flags); + + dev_dbg(musb->controller, "%s\n", musb_ep->end_point.name); + + return status; +} + +/* + * Allocate a request for an endpoint. + * Reused by ep0 code. + */ +struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) +{ + struct musb_ep *musb_ep = to_musb_ep(ep); + /*struct musb *musb = musb_ep->musb;*/ + struct musb_request *request = NULL; + + request = kzalloc(sizeof(struct musb_request), gfp_flags); + if (!request) { + /*WARNING:OOM_MESSAGE: Possible unnecessary 'out of memory' message*/ + /*dev_dbg(musb->controller, "not enough memory\n");*/ + return NULL; + } + + request->request.dma = DMA_ADDR_INVALID; + request->epnum = musb_ep->current_epnum; + request->ep = musb_ep; + + return &request->request; +} + +/* + * Free a request + * Reused by ep0 code. + */ +void musb_free_request(struct usb_ep *ep, struct usb_request *req) +{ + kfree(to_musb_request(req)); +} + +static LIST_HEAD(buffers); + +struct free_record { + struct list_head list; + struct device *dev; + unsigned bytes; + dma_addr_t dma; +}; + +/* + * Context: controller locked, IRQs blocked. + */ +void musb_ep_restart(struct musb *musb, struct musb_request *req) +{ + /* + * We don't do anything if QMU because QMU is already + * waiting there when musb_gadget_queue(). + */ +#ifndef USE_SSUSB_QMU + /* dev_dbg(musb->controller, "<== %s request %p len %u on hw_ep%d\n", */ + os_printk(K_DEBUG, "%s %s request %p len %u on hw_ep%d\n", + __func__, req->tx ? "TX/IN" : "RX/OUT", + &req->request, req->request.length, req->epnum); + + if (req->tx) + txstate(musb, req); + else + rxstate(musb, req); +#endif +} + + +static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) +{ + struct musb_ep *musb_ep; + struct musb_request *request; + struct musb *musb; + int status = 0; + unsigned long lockflags; + + if (!ep || !req) + return -EINVAL; + if (!req->buf) + return -ENODATA; + + musb_ep = to_musb_ep(ep); + musb = musb_ep->musb; + + request = to_musb_request(req); + request->musb = musb; + + if (request->ep != musb_ep) + return -EINVAL; + + os_printk(K_DEBUG, "%s %s, req=%p, len#%d\n", __func__, ep->name, req, + request->request.length); + + /* request is mine now... */ + request->request.actual = 0; + request->request.status = -EINPROGRESS; + request->epnum = musb_ep->current_epnum; + request->tx = musb_ep->is_in; + +#ifdef CONFIG_MTK_LM_MODE + /* + * Do NOT map the buffer when the request length is 0 on 4GB env. + * But the request is still set as MUSB_MAPPED for triggering ZLP. + */ + if (request->tx && (request->request.length == 0)) + request->map_state = MUSB_MAPPED; + else + map_dma_buffer(request, musb, musb_ep); +#else + map_dma_buffer(request, musb, musb_ep); +#endif + + + spin_lock_irqsave(&musb->lock, lockflags); + + /* don't queue if the ep is down */ + if (!musb_ep->desc) { + dev_dbg(musb->controller, "req %p queued to %s while ep %s\n", + req, ep->name, "disabled"); + status = -ESHUTDOWN; + goto cleanup; + } + + /* add request to the list */ + list_add_tail(&request->list, &musb_ep->req_list); + +#ifdef EP_PROFILING + if (is_prof != 0) + ep_prof[request->epnum - 1][request->tx ? 0 : 1] += request->request.length; +#endif + +#ifdef USE_SSUSB_QMU +#ifdef CONFIG_MTK_LM_MODE + if ((request->request.dma != DMA_ADDR_INVALID) || (request->map_state != UN_MAPPED)) { +#else + if (request->request.dma != DMA_ADDR_INVALID) { +#endif + qmu_printk(K_DEBUG, "%s %s EP%d, len=%d, maxp=%d request=%p\n", + request->tx ? "[TX]" : "[RX]", __func__, request->epnum, + request->request.length, ep->maxpacket, request); + if (request->tx) { + request->request.actual = request->request.length; + if (request->request.length > 0) { + u32 txcsr; + + _ex_mu3d_hal_insert_transfer_gpd(request->epnum, USB_TX, + request->request.dma, + request->request.length, true, + true, false, + ((request->request.zero == + 1) ? 1 : 0), ep->maxpacket); + + /*Enable Tx_DMAREQEN */ + txcsr = USB_ReadCsr32(U3D_TX1CSR0, request->epnum) | TX_DMAREQEN; + + mb(); + + USB_WriteCsr32(U3D_TX1CSR0, request->epnum, txcsr); + + mu3d_hal_resume_qmu(request->epnum, USB_TX); + + } else if (request->request.length == 0) { + /* If there is only ZLP in the reqeest list. Just send ZLP directly */ + int utime = 1000000; /* 1 sec */ + /* Send ZLP by setting TXPKTRDY */ + u32 val = 0; + + qmu_printk(K_DEBUG, "[TX]" "Send ZLP\n"); + if (wait_for_value_us + (USB_END_OFFSET(request->epnum, U3D_TX1CSR0), TX_FIFOEMPTY, + TX_FIFOEMPTY, 1, utime) == RET_SUCCESS) { + qmu_printk(K_DEBUG, "Tx[%d] 0x%x\n", request->epnum, + USB_ReadCsr32(U3D_TX1CSR0, request->epnum)); + } else { + qmu_printk(K_CRIT, + "Tx[%d] Fail to send ZLP 0x%x, utime %d, skip and wait until QMU Done\n", + request->epnum, USB_ReadCsr32(U3D_TX1CSR0, + request->epnum), + utime); + goto cleanup; + } + + /*Disable Tx_DMAREQEN */ + val = USB_ReadCsr32(U3D_TX1CSR0, request->epnum) & ~TX_DMAREQEN; + + mb(); + + USB_WriteCsr32(U3D_TX1CSR0, request->epnum, val); + + val = USB_ReadCsr32(U3D_TX1CSR0, request->epnum) | TX_TXPKTRDY; + + mb(); + + USB_WriteCsr32(U3D_TX1CSR0, request->epnum, val); + + qmu_printk(K_DEBUG, + "[TX] Give back ZLP of EP%d. actual:%d, length:%d %p\n", + request->epnum, request->request.actual, + request->request.length, request); + + /* call giveback directlly? no need to wait tx completed? */ + musb_g_giveback(musb_ep, &(request->request), 0); + } + } else { + _ex_mu3d_hal_insert_transfer_gpd(request->epnum, USB_RX, + request->request.dma, + request->request.length, true, true, false, + (musb_ep->type == + USB_ENDPOINT_XFER_ISOC ? 0 : 1), + ep->maxpacket); + mu3d_hal_resume_qmu(request->epnum, USB_RX); + } + } +#endif + /* it this is the head of the queue, start i/o ... */ + if (!musb_ep->busy && &request->list == musb_ep->req_list.next) + musb_ep_restart(musb, request); + +cleanup: + spin_unlock_irqrestore(&musb->lock, lockflags); + return status; +} + +static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request) +{ + struct musb_ep *musb_ep = to_musb_ep(ep); + struct musb_request *req = to_musb_request(request); + struct musb_request *r; + unsigned long flags; + int status = 0; + struct musb *musb = musb_ep->musb; + + if (!ep || !request || to_musb_request(request)->ep != musb_ep) + return -EINVAL; + + os_printk(K_INFO, "%s : request 0x%p\n", __func__, request); + + spin_lock_irqsave(&musb->lock, flags); + + list_for_each_entry(r, &musb_ep->req_list, list) { + if (r == req) + break; + } + if (r != req) { + dev_dbg(musb->controller, "request %p not queued to %s\n", request, ep->name); + status = -EINVAL; + goto done; + } + + /* if the hardware doesn't have the request, easy ... */ + if (musb_ep->req_list.next != &req->list || musb_ep->busy) + musb_g_giveback(musb_ep, request, -ECONNRESET); + + /* ... else abort the dma transfer ... */ + +#ifdef USE_SSUSB_QMU + else { + _ex_mu3d_hal_flush_qmu(musb_ep->hw_ep->epnum, (musb_ep->is_in ? USB_TX : USB_RX)); + + musb_g_giveback(musb_ep, request, -ECONNRESET); + + /* only start qmu, don't need to reset EP */ + /* mu3d_hal_restart_qmu(musb_ep->hw_ep->epnum, (musb_ep->is_in? USB_TX: USB_RX)); */ + mu3d_hal_start_qmu(musb_ep->hw_ep->epnum, (musb_ep->is_in ? USB_TX : USB_RX)); + + status = 0; + } +#else + else if (is_dma_capable() && musb_ep->dma) { + struct dma_controller *c = musb->dma_controller; + + if (c->channel_abort) + status = c->channel_abort(musb_ep->dma); + else + status = -EBUSY; + if (status == 0) + musb_g_giveback(musb_ep, request, -ECONNRESET); + } else { + /* NOTE: by sticking to easily tested hardware/driver states, + * we leave counting of in-flight packets imprecise. + */ + musb_g_giveback(musb_ep, request, -ECONNRESET); + } +#endif +done: + spin_unlock_irqrestore(&musb->lock, flags); + return status; +} + +/* + * Set or clear the halt bit of an endpoint. A halted enpoint won't tx/rx any + * data but will queue requests. + * + * exported to ep0 code + */ +static int musb_gadget_set_halt(struct usb_ep *ep, int value) +{ + struct musb_ep *musb_ep = to_musb_ep(ep); + u8 epnum = musb_ep->current_epnum; + struct musb *musb = musb_ep->musb; + void __iomem *mbase; + unsigned long flags; + u32 txcsr0 = 0, rxcsr0 = 0; + struct musb_request *request; + int status = 0; + + if (!ep) + return -EINVAL; + mbase = musb->mregs; + + os_printk(K_DEBUG, "musb_gadget_set_halt : %s...", ep->name); + spin_lock_irqsave(&musb->lock, flags); + + if (USB_ENDPOINT_XFER_ISOC == musb_ep->type) { + status = -EINVAL; + goto done; + } + + + request = next_request(musb_ep); + if (value) { + if (request) { + dev_dbg(musb->controller, "request in progress, cannot halt %s\n", + ep->name); + status = -EAGAIN; + goto done; + } + /* Cannot portably stall with non-empty FIFO */ + if (musb_ep->is_in) { + txcsr0 = os_readl(musb->endpoints[epnum].addr_txcsr0); + if (!(txcsr0 & TX_FIFOEMPTY)) { + dev_dbg(musb->controller, "FIFO busy, cannot halt %s\n", ep->name); + status = -EAGAIN; + goto done; + } + } + } else + musb_ep->wedged = 0; + + /* set/clear the stall and toggle bits */ + dev_dbg(musb->controller, "%s: %s stall\n", ep->name, value ? "set" : "clear"); + if (musb_ep->is_in) { /* TX */ + txcsr0 = os_readl(musb->endpoints[epnum].addr_txcsr0) & TX_W1C_BITS; + + if (value) { /* set */ + txcsr0 |= TX_SENDSTALL; + /* os_writel(musb->endpoints[epnum].addr_txcsr0, txcsr0); */ + writel(txcsr0, musb->endpoints[epnum].addr_txcsr0); + } else { /* clear */ + /* we need to also clear SENTSTALL to let the EP work normaly. */ + txcsr0 = (txcsr0 & (~TX_SENDSTALL)) | TX_SENTSTALL; + /* os_writel(musb->endpoints[epnum].addr_txcsr0, txcsr0); */ + writel(txcsr0, musb->endpoints[epnum].addr_txcsr0); + + /* reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) | (BIT16 << epnum)); + /* reset reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) & ~(BIT16 << epnum)); + + /* We cannot flush QMU now, because the MSC gadget will not re-submit + * the CBW request after clear halt. */ + /* _ex_mu3d_hal_flush_qmu(epnum, USB_TX); */ + /* mu3d_hal_restart_qmu(epnum, USB_TX); */ + } + + } else { + rxcsr0 = os_readl(musb->endpoints[epnum].addr_rxcsr0) & RX_W1C_BITS; + + if (value) { /* set stall */ + rxcsr0 &= RX_W1C_BITS; + rxcsr0 |= RX_SENDSTALL; + /* os_writel(musb->endpoints[epnum].addr_rxcsr0, rxcsr0); */ + writel(rxcsr0, musb->endpoints[epnum].addr_rxcsr0); + } else { /* clear stall */ + /* we need to also clear SENTSTALL to let the EP work normaly. */ + rxcsr0 = (rxcsr0 & (~RX_SENDSTALL)) | RX_SENTSTALL; + /* os_writel(musb->endpoints[epnum].addr_rxcsr0, rxcsr0); */ + writel(rxcsr0, musb->endpoints[epnum].addr_rxcsr0); + /* reset RX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) | (1 << epnum)); + /* reset reset RX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) & (~(1 << epnum))); + /* We cannot flush QMU now, because the MSC gadget will not re-submit + * the CBW request after clear halt. */ + /* _ex_mu3d_hal_flush_qmu(epnum, USB_RX); */ + /* mu3d_hal_restart_qmu(epnum, USB_RX); */ + } + } + + + /* maybe start the first request in the queue */ + if (!musb_ep->busy && !value && request) { + dev_dbg(musb->controller, "restarting the request\n"); + musb_ep_restart(musb, request); + } + +done: + spin_unlock_irqrestore(&musb->lock, flags); + return status; +} + +/* + * Sets the halt feature with the clear requests ignored + */ +static int musb_gadget_set_wedge(struct usb_ep *ep) +{ + struct musb_ep *musb_ep = to_musb_ep(ep); + + if (!ep) + return -EINVAL; + + musb_ep->wedged = 1; + + return usb_ep_set_halt(ep); +} + +static int musb_gadget_fifo_status(struct usb_ep *ep) +{ + struct musb_ep *musb_ep = to_musb_ep(ep); + int retval = -EINVAL; + + if (musb_ep->desc && !musb_ep->is_in) { + struct musb *musb = musb_ep->musb; + int epnum = musb_ep->current_epnum; + unsigned long flags; + + spin_lock_irqsave(&musb->lock, flags); + + /* FIXME return zero unless RXPKTRDY is set */ + retval = os_readl(musb->endpoints[epnum].addr_rxcsr3) >> 16; + + spin_unlock_irqrestore(&musb->lock, flags); + } + return retval; +} + +static void musb_gadget_fifo_flush(struct usb_ep *ep) +{ + struct musb_ep *musb_ep = to_musb_ep(ep); + struct musb *musb = musb_ep->musb; + u8 epnum = musb_ep->current_epnum; + unsigned long flags; +#ifndef USE_SSUSB_QMU /* we don't enable EP interrupts in QMU mode. */ + u32 int_txe; +#endif + u32 txcsr0 = 0; + + spin_lock_irqsave(&musb->lock, flags); + + /* disable interrupts */ +#ifndef USE_SSUSB_QMU /* we don't enable EP interrupts in QMU mode. */ + int_txe = os_readl(U3D_EPIER); + os_writel(U3D_EPIECR, ~(int_txe) | (1 << epnum)); /* set clear register */ +#endif + + if (musb_ep->is_in) { /* TX */ + +#ifdef USE_SSUSB_QMU + _ex_mu3d_hal_flush_qmu(epnum, USB_TX); + mu3d_hal_restart_qmu(epnum, USB_TX); + +#endif + txcsr0 = os_readl(musb->endpoints[epnum].addr_txcsr0); + + if (!(txcsr0 & TX_FIFOEMPTY)) { + os_printk(K_DEBUG, "%s RESET\n", ep->name); + /* reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) | (BIT16 << epnum)); + /* reset reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) & ~(BIT16 << epnum)); + + /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */ + } + + } else { +#ifdef USE_SSUSB_QMU + _ex_mu3d_hal_flush_qmu(epnum, USB_RX); + mu3d_hal_restart_qmu(epnum, USB_RX); +#endif + os_printk(K_DEBUG, "%s RESET\n", ep->name); + /* os_writew(musb->endpoints[epnum].addr_rxcsr0, rxcsr0 | USB_RXCSR_FLUSHFIFO); */ + /* os_writew(musb->endpoints[epnum].addr_rxcsr0, rxcsr0 & (~USB_RXCSR_FLUSHFIFO)); */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) | (1 << epnum)); /* reset RX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) & (~(1 << epnum))); /* reset reset RX EP */ + + } + + /* re-enable interrupt */ +#ifndef USE_SSUSB_QMU + os_writel(U3D_EPIESR, int_txe); +#endif + spin_unlock_irqrestore(&musb->lock, flags); +} + +static const struct usb_ep_ops musb_ep_ops = { + .enable = musb_gadget_enable, + .disable = musb_gadget_disable, + .alloc_request = musb_alloc_request, + .free_request = musb_free_request, + .queue = musb_gadget_queue, + .dequeue = musb_gadget_dequeue, + .set_halt = musb_gadget_set_halt, + .set_wedge = musb_gadget_set_wedge, + .fifo_status = musb_gadget_fifo_status, + .fifo_flush = musb_gadget_fifo_flush +}; + +/* ----------------------------------------------------------------------- */ + +static int musb_gadget_get_frame(struct usb_gadget *gadget) +{ + return (int)os_readl(U3D_USB20_FRAME_NUM); +} + +static int musb_gadget_wakeup(struct usb_gadget *gadget) +{ + struct musb *musb = gadget_to_musb(gadget); + unsigned long flags; + int status = -EINVAL; + u8 devctl; + int retries; + + spin_lock_irqsave(&musb->lock, flags); + os_printk(K_DEBUG, "musb_gadget_wakeup\n"); + + switch (musb->xceiv->state) { + case OTG_STATE_B_PERIPHERAL: + /* NOTE: OTG state machine doesn't include B_SUSPENDED; + * that's part of the standard usb 1.1 state machine, and + * doesn't affect OTG transitions. + */ + if (musb->may_wakeup && musb->is_suspended) + break; + goto done; + case OTG_STATE_B_IDLE: + /* Start SRP ... OTG not required. */ + devctl = os_readl(U3D_DEVICE_CONTROL); + dev_dbg(musb->controller, "Sending SRP: devctl: %02x\n", devctl); + devctl |= USB_DEVCTL_SESSION; + /* os_writel(U3D_DEVICE_CONTROL, devctl); + //We temoporarily disable DEV_CONTROL for writing SESSION. */ + devctl = os_readl(U3D_DEVICE_CONTROL); + retries = 100; + while (!(devctl & USB_DEVCTL_SESSION)) { + devctl = os_readl(U3D_DEVICE_CONTROL); + if (retries-- < 1) + break; + } + retries = 10000; + while (devctl & USB_DEVCTL_SESSION) { + devctl = os_readl(U3D_DEVICE_CONTROL); + if (retries-- < 1) + break; + } + + spin_unlock_irqrestore(&musb->lock, flags); + otg_start_srp(musb->xceiv->otg); + spin_lock_irqsave(&musb->lock, flags); + + /* Block idling for at least 1s */ + musb_platform_try_idle(musb, jiffies + msecs_to_jiffies(1 * HZ)); + + status = 0; + goto done; + default: + dev_dbg(musb->controller, "Unhandled wake: %s\n", + usb_otg_state_string(musb->xceiv->state)); + goto done; + } + + status = 0; + os_printk(K_DEBUG, "****************** musb_gadget_wakeup......\n"); +/* mu3d_hal_resume(); */ +done: + spin_unlock_irqrestore(&musb->lock, flags); + return status; +} + +static int musb_gadget_set_self_powered(struct usb_gadget *gadget, int is_selfpowered) +{ + struct musb *musb = gadget_to_musb(gadget); + + musb->is_self_powered = !!is_selfpowered; + return 0; +} + +static void musb_pullup(struct musb *musb, int is_on) +{ + if (musb->is_active == 0) { + os_printk(K_INFO, "power and clk is not ready!\n"); + return; + } + + if (is_on) { +#ifdef SUPPORT_U3 + mu3d_hal_u3dev_en(); +#else + mu3d_hal_u2dev_connect(); +#endif + } else { +#ifdef SUPPORT_U3 + mu3d_hal_u3dev_dis(); +#endif + mu3d_hal_u2dev_disconn(); + } + + dev_notice(musb->controller, "gadget D+ pullup %s\n", is_on ? "on" : "off"); +} + +#if 0 +static int musb_gadget_vbus_session(struct usb_gadget *gadget, int is_active) +{ + dev_dbg(musb->controller, "<= %s =>\n", __func__); + + /* + * FIXME iff driver's softconnect flag is set (as it is during probe, + * though that can clear it), just musb_pullup(). + */ + + return -EINVAL; +} +#endif + +static int musb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) +{ + struct musb *musb = gadget_to_musb(gadget); + + if (!musb->xceiv->set_power) + return -EOPNOTSUPP; + return usb_phy_set_power(musb->xceiv, mA); +} + +static int usb_rdy; /* default value 0 */ +static struct delayed_work mu3d_clk_off_work; +static struct musb *mu3d_clk_off_musb; +static void do_mu3d_clk_off_work(struct work_struct *work) +{ + os_printk(K_NOTICE, "do_mu3d_clk_off_work, issue connection work\n"); + schedule_delayed_work_on(0, &mu3d_clk_off_musb->connection_work, 0); +} + +void set_usb_rdy(void) +{ + os_printk(K_NOTICE, "set usb_rdy, wake up bat\n"); + usb_rdy = 1; +#if defined(CONFIG_MTK_SMART_BATTERY) + wake_up_bat(); +#endif +} + +bool is_usb_rdy(void) +{ + if (usb_rdy) + return true; + else + return false; +} + +static int musb_gadget_pullup(struct usb_gadget *gadget, int is_on) +{ + struct musb *musb = gadget_to_musb(gadget); + unsigned long flags; + + is_on = !!is_on; + + pm_runtime_get_sync(musb->controller); + + /* NOTE: this assumes we are sensing vbus; we'd rather + * not pullup unless the B-session is active. + */ + spin_lock_irqsave(&musb->lock, flags); + if (is_on != musb->softconnect) { + musb->softconnect = is_on; + musb_pullup(musb, is_on); + } + spin_unlock_irqrestore(&musb->lock, flags); + + pm_runtime_put(musb->controller); + if (is_usb_rdy() == false && is_on) { + set_usb_rdy(); + if (!is_otg_enabled(musb)) { +#define MY_DELAY 2000 + INIT_DELAYED_WORK(&mu3d_clk_off_work, do_mu3d_clk_off_work); + mu3d_clk_off_musb = musb; + os_printk(K_NOTICE, "queue mu3d_clk_off_work, %d ms delayed\n", MY_DELAY); + schedule_delayed_work(&mu3d_clk_off_work, msecs_to_jiffies(MY_DELAY)); + } + } + + return 0; +} + +static int musb_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver); +static int musb_gadget_stop(struct usb_gadget *g, struct usb_gadget_driver *driver); + +static const struct usb_gadget_ops musb_gadget_operations = { + .get_frame = musb_gadget_get_frame, + .wakeup = musb_gadget_wakeup, + .set_selfpowered = musb_gadget_set_self_powered, + /* .vbus_session = musb_gadget_vbus_session, */ + .vbus_draw = musb_gadget_vbus_draw, + .pullup = musb_gadget_pullup, + .udc_start = musb_gadget_start, + .udc_stop = musb_gadget_stop, + /*REVISIT-J: Do we need implement "get_config_params" to config U1/U2 */ +}; + +/* ----------------------------------------------------------------------- */ + +/* Registration */ + +/* Only this registration code "knows" the rule (from USB standards) + * about there being only one external upstream port. It assumes + * all peripheral ports are external... + */ + +#ifdef NEVER +static void musb_gadget_release(struct device *dev) +{ + /* kref_put(WHAT) */ + dev_dbg(dev, "%s\n", __func__); +} +#endif /* NEVER */ + + +static void init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) +{ + struct musb_hw_ep *hw_ep = musb->endpoints + epnum; + + memset(ep, 0, sizeof(*ep)); + + ep->current_epnum = epnum; + ep->musb = musb; + ep->hw_ep = hw_ep; + ep->is_in = is_in; + + INIT_LIST_HEAD(&ep->req_list); + + sprintf(ep->name, "ep%d%s", epnum, + (!epnum || hw_ep->is_shared_fifo) ? "" : (is_in ? "in" : "out")); + + os_printk(K_INFO, "%s, name=%s\n", __func__, ep->name); + + ep->end_point.name = ep->name; + INIT_LIST_HEAD(&ep->end_point.ep_list); + if (!epnum) { + ep->end_point.maxpacket = hw_ep->max_packet_sz_tx; + ep->end_point.ops = &musb_g_ep0_ops; + musb->g.ep0 = &ep->end_point; + } else { + if (is_in) + ep->end_point.maxpacket = hw_ep->max_packet_sz_tx; + else + ep->end_point.maxpacket = hw_ep->max_packet_sz_rx; + ep->end_point.ops = &musb_ep_ops; + list_add_tail(&ep->end_point.ep_list, &musb->g.ep_list); + } + + os_printk(K_INFO, "%s, name=%s, maxp=%d\n", __func__, ep->end_point.name, + ep->end_point.maxpacket); +} + +/* + * Initialize the endpoints exposed to peripheral drivers, with backlinks + * to the rest of the driver state. + */ +static inline void musb_g_init_endpoints(struct musb *musb) +{ + u8 epnum; + struct musb_hw_ep *hw_ep; + unsigned count = 0; + + /* initialize endpoint list just once */ + INIT_LIST_HEAD(&(musb->g.ep_list)); + + os_printk(K_INFO, "%s nr_endpoints=%d\n", __func__, musb->nr_endpoints); + + for (epnum = 0, hw_ep = musb->endpoints; epnum < musb->nr_endpoints; epnum++, hw_ep++) { + os_printk(K_INFO, "%s epnum=%d shared_fifo=%d rx_maxp=%d tx_maxp=%d\n", + __func__, epnum, hw_ep->is_shared_fifo, hw_ep->max_packet_sz_rx ? : 0, + hw_ep->max_packet_sz_tx ? : 0); + if (hw_ep->is_shared_fifo /* || !epnum */) { + init_peripheral_ep(musb, &hw_ep->ep_in, epnum, 0); + count++; + } else { + if (hw_ep->max_packet_sz_tx) { + init_peripheral_ep(musb, &hw_ep->ep_in, epnum, 1); + count++; + } + if (hw_ep->max_packet_sz_rx) { + init_peripheral_ep(musb, &hw_ep->ep_out, epnum, 0); + count++; + } + } + } +} + +/* called once during driver setup to initialize and link into + * the driver model; memory is zeroed. + */ +int musb_gadget_setup(struct musb *musb) +{ + int status; + + /* REVISIT minor race: if (erroneously) setting up two + * musb peripherals at the same time, only the bus lock + * is probably held. + */ + + musb->g.ops = &musb_gadget_operations; + musb->g.max_speed = USB_SPEED_SUPER; + musb->g.speed = USB_SPEED_UNKNOWN; + + /* this "gadget" abstracts/virtualizes the controller */ + /* dev_set_name(&musb->g.dev, "gadget"); */ + /* musb->g.dev.parent = musb->controller; */ + /* musb->g.dev.dma_mask = musb->controller->dma_mask; */ + /* musb->g.dev.release = musb_gadget_release; */ + musb->g.name = musb_driver_name; + + if (is_otg_enabled(musb)) + musb->g.is_otg = 1; + + musb_g_init_endpoints(musb); + + musb->is_active = 0; + musb_platform_try_idle(musb, 0); + + /* status = device_register(&musb->g.dev); */ + /* if (status != 0) { */ + /* put_device(&musb->g.dev); */ + /* return status; */ + /* } */ + + status = usb_add_gadget_udc(musb->controller, &musb->g); + if (status) + goto err; + + return 0; +err: + musb->g.dev.parent = NULL; + device_unregister(&musb->g.dev); + return status; +} + +void musb_gadget_cleanup(struct musb *musb) +{ + usb_del_gadget_udc(&musb->g); + /* if (musb->g.dev.parent) */ + /* device_unregister(&musb->g.dev); */ +} + +/* + * Register the gadget driver. Used by gadget drivers when + * registering themselves with the controller. + * + * -EINVAL something went wrong (not driver) + * -EBUSY another gadget is already using the controller + * -ENOMEM no memory to perform the operation + * + * @param driver the gadget driver + * @return <0 if error, 0 if everything is fine + */ +static int musb_gadget_start(struct usb_gadget *g, struct usb_gadget_driver *driver) +{ + struct musb *musb = gadget_to_musb(g); + struct usb_otg *otg = musb->xceiv->otg; + struct usb_hcd *hcd = musb_to_hcd(musb); + unsigned long flags; + int retval = 0; + + if (driver->max_speed < USB_SPEED_HIGH) { + retval = -EINVAL; + goto err; + } + + pm_runtime_get_sync(musb->controller); + + dev_dbg(musb->controller, "registering driver %s\n", driver->function); + + musb->softconnect = 0; + musb->gadget_driver = driver; + + spin_lock_irqsave(&musb->lock, flags); + if (is_usb_rdy() == true) + musb->is_active = 1; + else + os_printk(K_NOTICE, "skip set is_active to 1, leave it to connection_work\n"); + + + otg_set_peripheral(otg, &musb->g); + musb->xceiv->state = OTG_STATE_B_IDLE; + + /* + * FIXME this ignores the softconnect flag. Drivers are + * allowed hold the peripheral inactive until for example + * userspace hooks up printer hardware or DSP codecs, so + * hosts only see fully functional devices. + */ + + spin_unlock_irqrestore(&musb->lock, flags); + + if (is_otg_enabled(musb)) { + dev_dbg(musb->controller, "OTG startup...\n"); + + /* REVISIT: funcall to other code, which also + * handles power budgeting ... this way also + * ensures HdrcStart is indirectly called. + */ + retval = usb_add_hcd(hcd, 0, 0); + if (retval < 0) { + dev_dbg(musb->controller, "add_hcd failed, %d\n", retval); + goto err2; + } + + if (musb->xceiv->last_event == USB_EVENT_ID) + musb_platform_set_vbus(musb, 1); + + hcd->self.uses_pio_for_control = 1; + } + if (musb->xceiv->last_event == USB_EVENT_NONE) + pm_runtime_put(musb->controller); + + return 0; + +err2: + if (!is_otg_enabled(musb)) + musb_stop(musb); +err: + return retval; +} + +static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) +{ + int i; + struct musb_hw_ep *hw_ep; + + /* don't disconnect if it's not connected */ + if (musb->g.speed == USB_SPEED_UNKNOWN) + driver = NULL; + else + musb->g.speed = USB_SPEED_UNKNOWN; + + /* deactivate the hardware */ + if (musb->softconnect) { + musb->softconnect = 0; + musb_pullup(musb, 0); + } + musb_stop(musb); + + /* killing any outstanding requests will quiesce the driver; + * then report disconnect + */ + if (driver) { + for (i = 0, hw_ep = musb->endpoints; i < musb->nr_endpoints; i++, hw_ep++) { + if (hw_ep->is_shared_fifo /* || !epnum */) { + nuke(&hw_ep->ep_in, -ESHUTDOWN); + } else { + if (hw_ep->max_packet_sz_tx) + nuke(&hw_ep->ep_in, -ESHUTDOWN); + if (hw_ep->max_packet_sz_rx) + nuke(&hw_ep->ep_out, -ESHUTDOWN); + } + } + } +} + +/* + * Unregister the gadget driver. Used by gadget drivers when + * unregistering themselves from the controller. + * + * @param driver the gadget driver to unregister + */ +static int musb_gadget_stop(struct usb_gadget *g, struct usb_gadget_driver *driver) +{ + struct musb *musb = gadget_to_musb(g); + unsigned long flags; + + if (musb->xceiv->last_event == USB_EVENT_NONE) + pm_runtime_get_sync(musb->controller); + + /* + * REVISIT always use otg_set_peripheral() here too; + * this needs to shut down the OTG engine. + */ + + spin_lock_irqsave(&musb->lock, flags); + + musb_hnp_stop(musb); + + (void)musb_gadget_vbus_draw(&musb->g, 0); + + musb->xceiv->state = OTG_STATE_UNDEFINED; + stop_activity(musb, driver); + otg_set_peripheral(musb->xceiv->otg, NULL); + + dev_dbg(musb->controller, "unregistering driver %s\n", driver->function); + + musb->is_active = 0; + musb_platform_try_idle(musb, 0); + spin_unlock_irqrestore(&musb->lock, flags); + + if (is_otg_enabled(musb)) { + usb_remove_hcd(musb_to_hcd(musb)); + /* FIXME we need to be able to register another + * gadget driver here and have everything work; + * that currently misbehaves. + */ + } + + if (!is_otg_enabled(musb)) + musb_stop(musb); + + pm_runtime_put(musb->controller); + + return 0; +} + +/* ----------------------------------------------------------------------- */ + +/* lifecycle operations called through plat_uds.c */ + +void musb_g_resume(struct musb *musb) +{ + musb->is_suspended = 0; + switch (musb->xceiv->state) { + case OTG_STATE_B_IDLE: + break; + case OTG_STATE_B_WAIT_ACON: + case OTG_STATE_B_PERIPHERAL: + musb->is_active = 1; + if (musb->gadget_driver && musb->gadget_driver->resume) { + spin_unlock(&musb->lock); + musb->gadget_driver->resume(&musb->g); + spin_lock(&musb->lock); + } + break; + default: + WARNING("unhandled RESUME transition (%s)\n", + usb_otg_state_string(musb->xceiv->state)); + } +} + +/* called when SOF packets stop for 3+ msec */ +void musb_g_suspend(struct musb *musb) +{ + u32 devctl; + + devctl = os_readl(U3D_DEVICE_CONTROL); + dev_notice(musb->controller, "devctl %02x\n", devctl); + + switch (musb->xceiv->state) { + case OTG_STATE_B_IDLE: + if ((devctl & USB_DEVCTL_VBUSMASK) == USB_DEVCTL_VBUSVALID) + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + break; + case OTG_STATE_B_PERIPHERAL: + musb->is_suspended = 1; + if (musb->gadget_driver && musb->gadget_driver->suspend) { + spin_unlock(&musb->lock); + musb->gadget_driver->suspend(&musb->g); + spin_lock(&musb->lock); + } + musb_sync_with_bat(musb, USB_SUSPEND); /* announce to the battery */ + break; + default: + /* REVISIT if B_HOST, clear DEVCTL.HOSTREQ; + * A_PERIPHERAL may need care too + */ + WARNING("unhandled SUSPEND transition (%s)\n", + usb_otg_state_string(musb->xceiv->state)); + } +} + +/* Called during SRP */ +void musb_g_wakeup(struct musb *musb) +{ + musb_gadget_wakeup(&musb->g); +} + +/* called when VBUS drops below session threshold, and in other cases */ +void musb_g_disconnect(struct musb *musb) +{ + u32 devctl = os_readl(U3D_DEVICE_CONTROL); + + dev_notice(musb->controller, "devctl %02x\n", devctl); + + /* clear HR */ + /* marked off for 3.0 reset device test */ + /* os_writel(U3D_DEVICE_CONTROL, devctl & USB_DEVCTL_SESSION); */ + + /* don't draw vbus until new b-default session */ + (void)musb_gadget_vbus_draw(&musb->g, 0); + + musb->g.speed = USB_SPEED_UNKNOWN; + if (musb->gadget_driver && musb->gadget_driver->disconnect) { + spin_unlock(&musb->lock); + musb->gadget_driver->disconnect(&musb->g); + spin_lock(&musb->lock); + } + + switch (musb->xceiv->state) { + default: + dev_dbg(musb->controller, "Unhandled disconnect %s, setting a_idle\n", + usb_otg_state_string(musb->xceiv->state)); + musb->xceiv->state = OTG_STATE_A_IDLE; + MUSB_HST_MODE(musb); + break; + case OTG_STATE_A_PERIPHERAL: + musb->xceiv->state = OTG_STATE_A_WAIT_BCON; + MUSB_HST_MODE(musb); + break; + case OTG_STATE_B_WAIT_ACON: + case OTG_STATE_B_HOST: + case OTG_STATE_B_PERIPHERAL: + case OTG_STATE_B_IDLE: + musb->xceiv->state = OTG_STATE_B_IDLE; + break; + case OTG_STATE_B_SRP_INIT: + break; + } + + musb->is_active = 0; +} + + +void musb_conifg_ep0(struct musb *musb) +{ + os_printk(K_DEBUG, "U3D_DEVICE_CONF: %x\n", os_readl(U3D_DEVICE_CONF)); + + if (os_readl(U3D_DEVICE_CONF) & HW_USB2_3_SEL) { /* SS */ + musb->g.speed = USB_SPEED_SUPER; + musb->g.ep0->maxpacket = 512; + + os_printk(K_INFO, "musb_g_reset musb->g.speed: super\n"); + ep0_setup(musb, musb->endpoints, &ep0_cfg_u3); + } else { /* HS, FS */ + musb->g.speed = (u8) (os_readl(U3D_POWER_MANAGEMENT) & HS_MODE) + ? USB_SPEED_HIGH : USB_SPEED_FULL; + musb->g.ep0->maxpacket = 64; + + os_printk(K_INFO, "musb_g_reset musb->g.speed: %s\n", + (musb->g.speed == USB_SPEED_HIGH) ? "high" : "full"); + ep0_setup(musb, musb->endpoints, &ep0_cfg_u2); + } + + os_printk(K_DEBUG, "U3D_EP0CSR: %x\n", os_readl(U3D_EP0CSR)); + os_printk(K_DEBUG, "U3D_RXCOUNT0: %x\n", os_readl(U3D_RXCOUNT0)); +} + +void musb_g_reset(struct musb *musb) __releases(musb->lock) __acquires(musb->lock) +{ + u32 devctl = os_readl(U3D_DEVICE_CONTROL); + + /* it may greater than 2.5mA , but it should meet the spec's requirement !! */ + if (musb->test_mode == 0) + musb_sync_with_bat(musb, USB_UNCONFIGURED); + + mu3d_hal_unfigured_ep(); + + /* report disconnect, if we didn't already (flushing EP state) */ + if (musb->g.speed != USB_SPEED_UNKNOWN) + musb_g_disconnect(musb); + + /* clear HR */ + else if (devctl & USB_DEVCTL_HOSTREQUEST) { + /* marked off for 3.0 reset device test */ + /* os_writel(U3D_DEVICE_CONTROL, USB_DEVCTL_SESSION); */ + + } + + musb_conifg_ep0(musb); + /* start in USB_STATE_DEFAULT */ + musb->is_active = 1; + musb->is_suspended = 0; + MUSB_DEV_MODE(musb); + musb->address = 0; + musb->ep0_state = MUSB_EP0_STAGE_SETUP; + + musb->may_wakeup = 0; + musb->g.b_hnp_enable = 0; + musb->g.a_alt_hnp_support = 0; + musb->g.a_hnp_support = 0; + + /* Normal reset, as B-Device; + * or else after HNP, as A-Device + */ + if (devctl & USB_DEVCTL_BDEVICE) { + musb->xceiv->state = OTG_STATE_B_PERIPHERAL; + musb->g.is_a_peripheral = 0; + } else if (is_otg_enabled(musb)) { + musb->xceiv->state = OTG_STATE_A_PERIPHERAL; + musb->g.is_a_peripheral = 1; + } else + WARN_ON(1); + + /* start with default limits on VBUS power draw */ + (void)musb_gadget_vbus_draw(&musb->g, is_otg_enabled(musb) ? 8 : 100); +} diff --git a/drivers/misc/mediatek/mu3d/drv/musb_gadget.h b/drivers/misc/mediatek/mu3d/drv/musb_gadget.h new file mode 100644 index 000000000000..85790e9f8ffc --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_gadget.h @@ -0,0 +1,135 @@ +/* + * MUSB OTG driver peripheral defines + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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. + * + */ + +#ifndef __MUSB_GADGET_H +#define __MUSB_GADGET_H + +#include <linux/list.h> + +extern u32 is_prof; +extern unsigned int ep_prof[8][2]; + + +enum buffer_map_state { + UN_MAPPED = 0, + PRE_MAPPED, + MUSB_MAPPED +}; + +struct usb_dcd_config_params_ext { + __u8 bU1Enabled; /* added for U3 */ + __u8 bU2Enabled; /* added for U3 */ +}; +extern struct usb_dcd_config_params_ext pwr_params; + +struct musb_request { + struct usb_request request; + struct list_head list; + struct musb_ep *ep; + struct musb *musb; + u8 tx; /* endpoint direction */ + u8 epnum; + enum buffer_map_state map_state; +}; + +static inline struct musb_request *to_musb_request(struct usb_request *req) +{ + return req ? container_of(req, struct musb_request, request) : NULL; +} + +extern struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags); +extern void musb_free_request(struct usb_ep *ep, struct usb_request *req); + + +/* + * struct musb_ep - peripheral side view of endpoint rx or tx side + */ +struct musb_ep { + /* stuff towards the head is basically write-once. */ + struct usb_ep end_point; + char name[12]; + struct musb_hw_ep *hw_ep; + struct musb *musb; + u8 current_epnum; + + /* ... when enabled/disabled ... */ + u8 type; + u8 is_in; + u16 packet_sz; + const struct usb_endpoint_descriptor *desc; + struct dma_channel *dma; + + /* later things are modified based on usage */ + struct list_head req_list; + + u8 wedged; + + /* true if lock must be dropped but req_list may not be advanced */ + u8 busy; + + u8 hb_mult; +}; + +static inline struct musb_ep *to_musb_ep(struct usb_ep *ep) +{ + return ep ? container_of(ep, struct musb_ep, end_point) : NULL; +} + +static inline struct musb_request *next_request(struct musb_ep *ep) +{ + struct list_head *queue = &ep->req_list; + + if (list_empty(queue)) + return NULL; + return container_of(queue->next, struct musb_request, list); +} + +void musb_conifg_ep0(struct musb *musb); +extern void musb_g_tx(struct musb *musb, u8 epnum); +extern void musb_g_rx(struct musb *musb, u8 epnum); +extern const struct usb_ep_ops musb_g_ep0_ops; + +extern int musb_gadget_setup(struct musb *); +extern void musb_gadget_cleanup(struct musb *); + +extern void musb_g_giveback(struct musb_ep *, struct usb_request *, int); +extern void musb_ep_restart(struct musb *, struct musb_request *); + +extern struct musb_fifo_cfg ep0_cfg_u3; +extern struct musb_fifo_cfg ep0_cfg_u2; +extern void ep0_setup(struct musb *musb, struct musb_hw_ep *hw_ep0, + const struct musb_fifo_cfg *cfg); + + +#endif /* __MUSB_GADGET_H */ diff --git a/drivers/misc/mediatek/mu3d/drv/musb_gadget_ep0.c b/drivers/misc/mediatek/mu3d/drv/musb_gadget_ep0.c new file mode 100644 index 000000000000..3b74efaf7efb --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_gadget_ep0.c @@ -0,0 +1,1573 @@ +/* + * MUSB OTG peripheral driver ep0 handling + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * Copyright (C) 2008-2009 MontaVista Software, Inc. <source@mvista.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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 <linux/kernel.h> +#include <linux/list.h> +#include <linux/timer.h> +#include <linux/spinlock.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/interrupt.h> + +#include "musb_core.h" +#include "mu3d_hal_osal.h" +#include "mu3d_hal_usb_drv.h" +#include "mu3d_hal_hw.h" + +/* ep0 is always musb->endpoints[0].ep_in */ +#define next_ep0_request(musb) next_in_request(&(musb)->endpoints[0]) + +struct usb_dcd_config_params_ext pwr_params; + +/* + * locking note: we use only the controller lock, for simpler correctness. + * It's always held with IRQs blocked. + * + * It protects the ep0 request queue as well as ep0_state, not just the + * controller and indexed registers. And that lock stays held unless it + * needs to be dropped to allow reentering this driver ... like upcalls to + * the gadget driver, or adjusting endpoint halt status. + */ + +static char *decode_ep0stage(u8 stage) +{ + switch (stage) { + case MUSB_EP0_STAGE_IDLE: + return "idle"; + case MUSB_EP0_STAGE_SETUP: + return "setup"; + case MUSB_EP0_STAGE_TX: + return "in"; + case MUSB_EP0_STAGE_RX: + return "out"; + case MUSB_EP0_STAGE_ACKWAIT: + return "wait"; + case MUSB_EP0_STAGE_STATUSIN: + return "in/status"; + case MUSB_EP0_STAGE_STATUSOUT: + return "out/status"; + default: + return "?"; + } +} + + +static int +forward_to_driver(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest) +__releases(musb->lock) __acquires(musb->lock) +{ + int usb_state = 0; + int retval; + + os_printk(K_DEBUG, "%s\n", __func__); + if (!musb->gadget_driver) + return -EOPNOTSUPP; + spin_unlock(&musb->lock); + retval = musb->gadget_driver->setup(&musb->g, ctrlrequest); + os_printk(K_DEBUG, "%s retval=%d\n", __func__, retval); + + if (ctrlrequest->bRequest == USB_REQ_SET_CONFIGURATION) { + if (ctrlrequest->wValue & 0xff) + usb_state = USB_CONFIGURED; + else + usb_state = USB_UNCONFIGURED; + musb_sync_with_bat(musb, usb_state); /* annonce to the battery */ + } + spin_lock(&musb->lock); + return retval; +} + + +/* handle a standard GET_STATUS request + * Context: caller holds controller lock + */ +static int service_tx_status_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest) +{ + int handled = 1, maxp; + u8 result[2], epnum = 0; + const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK; + + os_printk(K_DEBUG, "%s\n", __func__); + + result[1] = 0; + + switch (recip) { + case USB_RECIP_DEVICE: + result[0] = musb->is_self_powered << USB_DEVICE_SELF_POWERED; + result[0] |= musb->may_wakeup << USB_DEVICE_REMOTE_WAKEUP; + /* superspeed only */ + if (musb->g.speed == USB_SPEED_SUPER) { + result[0] |= pwr_params.bU1Enabled << USB_DEV_STAT_U1_ENABLED; + result[0] |= pwr_params.bU2Enabled << USB_DEV_STAT_U2_ENABLED; + } + + if (musb->g.is_otg) { + result[0] |= musb->g.b_hnp_enable << USB_DEVICE_B_HNP_ENABLE; + result[0] |= musb->g.a_alt_hnp_support << USB_DEVICE_A_ALT_HNP_SUPPORT; + result[0] |= musb->g.a_hnp_support << USB_DEVICE_A_HNP_SUPPORT; + } + os_printk(K_DEBUG, "%s result=%x, U1=%x, U2=%x\n", __func__, result[0], + pwr_params.bU1Enabled, pwr_params.bU2Enabled); + break; + + case USB_RECIP_INTERFACE: + result[0] = 0; + break; + + case USB_RECIP_ENDPOINT:{ + int is_in; + struct musb_ep *ep; + u32 tmp; + + epnum = (u8) ctrlrequest->wIndex; + if (!epnum) { + result[0] = 0; + break; + } + + is_in = epnum & USB_DIR_IN; + if (is_in) { + epnum &= 0x0f; + ep = &musb->endpoints[epnum].ep_in; + } else { + ep = &musb->endpoints[epnum].ep_out; + } + + if (epnum >= MUSB_C_NUM_EPS || !ep->desc) { + handled = -EINVAL; + break; + } + + if (is_in) { + tmp = (USB_ReadCsr32(U3D_TX1CSR0, epnum) & TX_SENDSTALL) + || (USB_ReadCsr32(U3D_TX1CSR0, epnum) & TX_SENTSTALL); + /* tmp = USB_ReadCsr16(U3D_TX1CSR0, epnum) & TX_SENDSTALL; */ + } else { + tmp = (USB_ReadCsr32(U3D_RX1CSR0, epnum) & RX_SENDSTALL) + || (USB_ReadCsr32(U3D_RX1CSR0, epnum) & RX_SENTSTALL); + } + + result[0] = tmp ? 1 : 0; + } + break; + + default: + /* class, vendor, etc ... delegate */ + handled = 0; + break; + } + + /* fill up the fifo; caller updates csr0 */ + if (handled > 0) { + u16 len = le16_to_cpu(ctrlrequest->wLength); + + if (len > 2) + len = 2; + maxp = musb->endpoints->max_packet_sz_tx; + mu3d_hal_write_fifo(0, len, result, maxp); + } + + return handled; +} + +/* + * handle a control-IN request, the end0 buffer contains the current request + * that is supposed to be a standard control request. Assumes the fifo to + * be at least 2 bytes long. + * + * @return 0 if the request was NOT HANDLED, + * < 0 when error + * > 0 when the request is processed + * + * Context: caller holds controller lock + */ +static int service_in_request(struct musb *musb, const struct usb_ctrlrequest *ctrlrequest) +{ + int handled = 0; /* not handled */ + + os_printk(K_DEBUG, "%s\n", __func__); + + if ((ctrlrequest->bRequestType & USB_TYPE_MASK) + == USB_TYPE_STANDARD) { + switch (ctrlrequest->bRequest) { + case USB_REQ_GET_STATUS: + os_printk(K_DEBUG, "USB_REQ_GET_STATUS\n"); + handled = service_tx_status_request(musb, ctrlrequest); + break; + + /* case USB_REQ_SYNC_FRAME: */ + + default: + break; + } + } + return handled; +} + +/* + * Context: caller holds controller lock + */ +static void musb_g_ep0_giveback(struct musb *musb, struct usb_request *req) +{ + os_printk(K_DEBUG, "%s\n", __func__); + + musb_g_giveback(&musb->endpoints[0].ep_in, req, 0); +} + +/* + * Tries to start B-device HNP negotiation if enabled via sysfs + */ +static inline void musb_try_b_hnp_enable(struct musb *musb) +{ + u32 devctl; + + dev_dbg(musb->controller, "HNP: Setting HR\n"); + devctl = os_readl(U3D_DEVICE_CONTROL); + /* We temporarily disable this because the bitfile doesn't support yet.*/ + /* os_writeb(mbase + MAC_DEVICE_CONTROL, devctl | USB_DEVCTL_HOSTREQUEST); */ +} + +#ifdef CONFIG_USBIF_COMPLIANCE +static void update_U1_U2_pwr_params(__u8 bRequest, __le16 wValue) +{ + unsigned int tmp; + + tmp = (wValue == USB_DEVICE_U1_ENABLE) ? + SW_U1_ACCEPT_ENABLE : + SW_U2_ACCEPT_ENABLE; + + if (bRequest == USB_REQ_CLEAR_FEATURE) { + os_printk(K_INFO, "%s CLEAR_FEATURE reg=%x, tmp=%x\n", __func__, + os_readl(U3D_LINK_POWER_CONTROL), tmp); + + os_clrmsk(U3D_LINK_POWER_CONTROL, tmp); + + os_printk(K_INFO, "%s CLEAR_FEATURE reg=%x\n", __func__, + os_readl(U3D_LINK_POWER_CONTROL)); + + if (wValue == USB_DEVICE_U1_ENABLE) + pwr_params.bU1Enabled = 0; + else + pwr_params.bU2Enabled = 0; + } else if (bRequest == USB_REQ_SET_FEATURE) { + os_printk(K_INFO, "%s SET_FEATURE %s handled=%d val=%x\n", __func__, + (wValue == USB_DEVICE_U1_ENABLE) ? "U1" : + "U2", handled, tmp); + + os_setmsk(U3D_LINK_POWER_CONTROL, tmp); + + os_printk(K_INFO, "%s SET_FEATURE reg=%x\n", __func__, + os_readl(U3D_LINK_POWER_CONTROL)); + + if (wValue == USB_DEVICE_U1_ENABLE) + pwr_params.bU1Enabled = 1; + else + pwr_params.bU2Enabled = 1; + } else + pr_err("update_U1_U2_pwr_params error\n"); +} +#endif + +/* + * Handle all control requests with no DATA stage, including standard + * requests such as: + * USB_REQ_SET_CONFIGURATION, USB_REQ_SET_INTERFACE, unrecognized + * always delegated to the gadget driver + * USB_REQ_SET_ADDRESS, USB_REQ_CLEAR_FEATURE, USB_REQ_SET_FEATURE + * always handled here, except for class/vendor/... features + * + * Context: caller holds controller lock + */ +static int +service_zero_data_request(struct musb *musb, + struct usb_ctrlrequest *ctrlrequest) +__releases(musb->lock) __acquires(musb->lock) +{ + int handled = -EINVAL; + const u8 recip = ctrlrequest->bRequestType & USB_RECIP_MASK; +#ifdef CONFIG_USBIF_COMPLIANCE + unsigned int tmp; +#endif + + os_printk(K_DEBUG, "%s\n", __func__); + + /* the gadget driver handles everything except what we MUST handle */ + if ((ctrlrequest->bRequestType & USB_TYPE_MASK) + == USB_TYPE_STANDARD) { + switch (ctrlrequest->bRequest) { + case USB_REQ_SET_ISOCH_DELAY: + handled = 1; + break; + case USB_REQ_SET_ADDRESS: + /* change it after the status stage */ + musb->set_address = true; + musb->address = (u8) (ctrlrequest->wValue & 0x7f); + handled = 1; + break; + + case USB_REQ_CLEAR_FEATURE: + switch (recip) { + case USB_RECIP_DEVICE: + switch (ctrlrequest->wValue) { + case USB_DEVICE_REMOTE_WAKEUP: + musb->may_wakeup = 0; + handled = 1; + break; + case USB_DEVICE_U1_ENABLE: + case USB_DEVICE_U2_ENABLE: + /* superspeed only */ + if (musb->g.speed == USB_SPEED_SUPER) { + /* forward the request because of device state check */ + handled = forward_to_driver(musb, ctrlrequest); + +#ifdef CONFIG_USBIF_COMPLIANCE + if (handled >= 0) + update_U1_U2_pwr_params(ctrlrequest->bRequest, ctrlrequest->wValue); + else + os_printk(K_ERR, + "[COM] composite driver can not handle this control request!\n"); +#else + /* + * DO NOT SUPPORT U1/U2 for IOT. Return STALL. + * Under TUSB7340 + Lenovo MT-M5852-B88, IOT test failed. + */ + handled = -EINVAL; +#endif /* NEVER */ + } + break; + default: + handled = -EINVAL; + break; + } + break; + case USB_RECIP_INTERFACE: + /* superspeed only */ + if ((ctrlrequest->wValue == USB_INTRF_FUNC_SUSPEND) + && (musb->g.speed == USB_SPEED_SUPER)) + /* forward the request because of device state check */ + handled = forward_to_driver(musb, ctrlrequest); + break; + case USB_RECIP_ENDPOINT:{ + const u8 epnum = ctrlrequest->wIndex & 0x0f; + struct musb_ep *musb_ep; + struct musb_hw_ep *ep; + struct musb_request *request; + int is_in; + u32 csr; + + if (epnum == 0 || epnum >= MUSB_C_NUM_EPS || + ctrlrequest->wValue != USB_ENDPOINT_HALT) + break; + + ep = musb->endpoints + epnum; + is_in = ctrlrequest->wIndex & USB_DIR_IN; + if (is_in) + musb_ep = &ep->ep_in; + else + musb_ep = &ep->ep_out; + if (!musb_ep->desc) + break; + + handled = 1; + /* Ignore request if endpoint is wedged */ + if (musb_ep->wedged) + break; + + if (is_in) { /* TX */ + csr = + USB_ReadCsr32(U3D_TX1CSR0, epnum) & TX_W1C_BITS; + csr = (csr & (~TX_SENDSTALL)) | TX_SENTSTALL; + /* csr = csr & (~TX_SENDSTALL); */ + + USB_WriteCsr32(U3D_TX1CSR0, epnum, csr); + + os_printk(K_DEBUG, + " clear tx stall --> write csr[%d] 0x%04x. new CSR is: 0x%04x\n", + epnum, csr, USB_ReadCsr32(U3D_TX1CSR0, + epnum)); + /* reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) | (BIT16 << epnum)); + /* reset reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) & ~(BIT16 << epnum)); + os_printk(K_DEBUG, "RST TX%d\n", epnum); + + /* We cannot flush QMU now, because the MSC gadget + * will not re-submit the CBW request after clear halt. */ + + /* _ex_mu3d_hal_flush_qmu(epnum, USB_TX); */ + /* mu3d_hal_restart_qmu(epnum, USB_TX); */ + + } else { + csr = + USB_ReadCsr32(U3D_RX1CSR0, epnum) & RX_W1C_BITS; + csr = (csr & (~RX_SENDSTALL)) | RX_SENTSTALL; + + USB_WriteCsr32(U3D_RX1CSR0, epnum, csr); + + os_printk(K_DEBUG, + " clear rx stall --> write csr[%d] 0x%04x. new CSR is: 0x%04x\n", + epnum, csr, USB_ReadCsr32(U3D_RX1CSR0, epnum)); + /* reset RX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) | (1 << epnum)); + /* reset reset RX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) & (~(1 << epnum))); + os_printk(K_DEBUG, "RST RX%d\n", epnum); + /* We cannot flush QMU now, because the MSC gadget will not + * re-submit the CBW request after clear halt. */ + + /* _ex_mu3d_hal_flush_qmu(epnum, USB_RX); */ + /* mu3d_hal_restart_qmu(epnum, USB_RX); */ + } + + /* Maybe start the first request in the queue */ + request = next_request(musb_ep); + if (!musb_ep->busy && request) { + dev_dbg(musb->controller, + "restarting the request\n"); + musb_ep_restart(musb, request); + } + + /* select ep0 again */ + } + break; + default: + /* class, vendor, etc ... delegate */ + handled = 0; + break; + } + break; + + case USB_REQ_SET_FEATURE: + switch (recip) { + case USB_RECIP_DEVICE: + handled = 1; + switch (ctrlrequest->wValue) { + case USB_DEVICE_REMOTE_WAKEUP: + musb->may_wakeup = 1; + break; + case USB_DEVICE_TEST_MODE: + if (musb->g.speed != USB_SPEED_HIGH) + goto stall; + if (ctrlrequest->wIndex & 0xff) + goto stall; + + switch (ctrlrequest->wIndex >> 8) { + case 1: + pr_debug("TEST_J\n"); + /* TEST_J */ + musb->test_mode_nr = TEST_J_MODE; + break; + case 2: + /* TEST_K */ + pr_debug("TEST_K\n"); + musb->test_mode_nr = TEST_K_MODE; + break; + case 3: + /* TEST_SE0_NAK */ + pr_debug("TEST_SE0_NAK\n"); + musb->test_mode_nr = TEST_SE0_NAK_MODE; + break; + case 4: + /* TEST_PACKET */ + pr_debug("TEST_PACKET\n"); + musb->test_mode_nr = TEST_PACKET_MODE; + break; + + case 0xc0: + /* TEST_FORCE_HS */ + pr_debug("TEST_FORCE_HS\n"); + musb->test_mode_nr = FORCE_HS; + break; + case 0xc1: + /* TEST_FORCE_FS */ + pr_debug("TEST_FORCE_FS\n"); + musb->test_mode_nr = FORCE_FS; + break; + case 0xc2: + /* TEST_FIFO_ACCESS */ + pr_debug("TEST_FIFO_ACCESS\n"); + musb->test_mode_nr = FIFO_ACCESS; + break; + case 0xc3: + /* TEST_FORCE_HOST */ + pr_debug("TEST_FORCE_HOST\n"); + musb->test_mode_nr = FORCE_HOST; + break; + default: + goto stall; + } + + /* enter test mode after irq */ + if (handled > 0) + musb->test_mode = true; + break; + case USB_DEVICE_B_HNP_ENABLE: + if (!musb->g.is_otg) + goto stall; + musb->g.b_hnp_enable = 1; + musb_try_b_hnp_enable(musb); + break; + case USB_DEVICE_A_HNP_SUPPORT: + if (!musb->g.is_otg) + goto stall; + musb->g.a_hnp_support = 1; + break; + case USB_DEVICE_A_ALT_HNP_SUPPORT: + if (!musb->g.is_otg) + goto stall; + musb->g.a_alt_hnp_support = 1; + break; + case USB_DEVICE_U1_ENABLE: + case USB_DEVICE_U2_ENABLE: + /* superspeed only */ + if (musb->g.speed != USB_SPEED_SUPER) + break; + /* forward the request because of device state check */ + handled = forward_to_driver(musb, ctrlrequest); +#ifdef CONFIG_USBIF_COMPLIANCE + if (handled >= 0) + update_U1_U2_pwr_params(ctrlrequest->bRequest, ctrlrequest->wValue); + else + os_printk(K_ERR, + "[COM] composite driver can not handle this control request!\n"); +#else + /* + * DO NOT SUPPORT U1/U2 for IOT. Return STALL. + * Under TUSB7340 + Lenovo MT-M5852-B88, IOT test failed. + */ + handled = -EINVAL; +#endif /* NEVER */ + break; + case USB_DEVICE_DEBUG_MODE: + handled = 0; + break; +stall: + default: + handled = -EINVAL; + break; + } + break; + + case USB_RECIP_INTERFACE: + /* superspeed only */ + if ((ctrlrequest->wValue == USB_INTRF_FUNC_SUSPEND) + && (musb->g.speed == USB_SPEED_SUPER)) { + /* forward the request because of device state check */ + /* handled = forward_to_driver(musb, ctrlrequest); */ + + os_printk(K_DEBUG, "wIndex=%x\n", ctrlrequest->wIndex); + + if (ctrlrequest->wIndex & USB_INTRF_FUNC_SUSPEND_LP) + os_printk(K_DEBUG, "USB_INTRF_FUNC_SUSPEND_LP\n"); + else if (ctrlrequest->wIndex & USB_INTRF_FUNC_SUSPEND_RW) + os_printk(K_DEBUG, "USB_INTRF_FUNC_SUSPEND_RW\n"); + } + os_printk(K_DEBUG, "USB_RECIP_INTERFACE handled=%d\n", handled); + + /* Just pretend that the gadget driver can fully handle this control request */ + handled = 1; + + break; + + case USB_RECIP_ENDPOINT:{ + const u8 epnum = ctrlrequest->wIndex & 0x0f; + struct musb_ep *musb_ep; + struct musb_hw_ep *ep; + int is_in; + u32 csr; + + if (epnum == 0 || epnum >= MUSB_C_NUM_EPS || + ctrlrequest->wValue != USB_ENDPOINT_HALT) + break; + + ep = musb->endpoints + epnum; + is_in = ctrlrequest->wIndex & USB_DIR_IN; + if (is_in) + musb_ep = &ep->ep_in; + else + musb_ep = &ep->ep_out; + if (!musb_ep->desc) + break; + + if (is_in) { /* tx */ + csr = USB_ReadCsr32(U3D_TX1CSR0, epnum); + + if (!(csr & TX_FIFOEMPTY)) { + /* + csr &= TX_W1C_BITS; //don't clear W1C bits + csr |= USB_TXCSR_FLUSHFIFO; + //os_printk(K_DEBUG, "EP%d USB_TXCSR_FLUSHFIFO\n", epnum); + //flush fifo before sendstall. + SSUSB_WriteCsr16(U3D_TX1CSR0, epnum, csr ); + Follow ssusb programming guide. + while(USB_ReadCsr16(U3D_TX1CSR0, epnum) & USB_TXCSR_FLUSHFIFO) + { + cpu_relax(); + } + */ + /* reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) | (BIT16 << epnum)); + /* reset reset TX EP */ + os_writel(U3D_EP_RST, os_readl(U3D_EP_RST) & ~(BIT16 << epnum)); + + } + + + csr &= TX_W1C_BITS; + csr |= TX_SENDSTALL; + os_printk(K_DEBUG, + "@@@@@@@@@@@@@@@@@ EP%d(IN/TX) SEND_STALL\n", + epnum); + + /* ssusb: need further check. is WZC_BITS needed? */ + + USB_WriteCsr32(U3D_TX1CSR0, epnum, csr); + } else { + csr = USB_ReadCsr32(U3D_RX1CSR0, epnum); + csr &= RX_W1C_BITS; + csr |= RX_SENDSTALL; + + os_printk(K_DEBUG, + "@@@@@@@@@@@@@@@@@ EP%d(OUT/RX) SEND_STALL\n", + epnum); + /* musb_writew(regs, MUSB_RXCSR, csr); */ + USB_WriteCsr32(U3D_RX1CSR0, epnum, csr); + } + + /* select ep0 again */ + handled = 1; + } + break; + + default: + /* class, vendor, etc ... delegate */ + handled = 0; + break; + } + break; + default: + /* delegate SET_CONFIGURATION, etc */ + handled = 0; + } + } else + handled = 0; + return handled; +} + +/* we have an ep0out data packet + * Context: caller holds controller lock + */ +static void ep0_rxstate(struct musb *musb) +{ + struct musb_request *request; + struct usb_request *req; + u32 csr; + u16 count = 0; + + os_printk(K_DEBUG, "%s\n", __func__); + + /* Set the register which is W1C as 0. */ + csr = os_readl(U3D_EP0CSR) & EP0_W1C_BITS; + + request = next_ep0_request(musb); + req = &request->request; + + /* read packet and ack; or stall because of gadget driver bug: + * should have provided the rx buffer before setup() returned. + */ + if (req) { + void *buf = req->buf + req->actual; + unsigned len = req->length - req->actual; + +#ifdef AUTOCLEAR + if (!(os_readl(U3D_EP0CSR) & EP0_AUTOCLEAR)) + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_AUTOCLEAR); +#endif + /* read the buffer */ + count = os_readl(U3D_RXCOUNT0); + if (count > len) { + req->status = -EOVERFLOW; + count = len; + } + musb_read_fifo(&musb->endpoints[0], count, buf); + req->actual += count; + csr |= EP0_RXPKTRDY; + /*REVISIT-J: 64 is usb20 ep0 maxp, but usb30 ep0 maxp is 512. + *Do we need the modification? */ + if (count < 64 || req->actual == req->length) { + /* musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; */ + /* in ssusb, there is no interrupt to transit to idle phase. */ + musb->ep0_state = MUSB_EP0_IDLE; + os_printk(K_DEBUG, + "----- ep0 state: MUSB_EP0_STAGE_STATUSIN then MUSB_EP0_IDLE\n"); + + csr |= EP0_DATAEND; + } else + req = NULL; + } else { + csr |= EP0_RXPKTRDY | EP0_SENDSTALL; + os_printk(K_DEBUG, "@@@@@@@@@@@@@@@ SENDSTALL\n"); + } + + /* Completion handler may choose to stall, e.g. because the + * message just received holds invalid data. + */ + if (req) { + musb->ackpend = csr; + musb_g_ep0_giveback(musb, req); + if (!musb->ackpend) + return; + musb->ackpend = 0; + } + os_writel(U3D_EP0CSR, csr); +} + +/* + * transmitting to the host (IN), this code might be called from IRQ + * and from kernel thread. + * + * Context: caller holds controller lock + */ +static void ep0_txstate(struct musb *musb) +{ + struct musb_request *req = next_ep0_request(musb); + struct usb_request *request; + + u32 csr = EP0_TXPKTRDY; + u8 *fifo_src; + u16 fifo_count; + u32 maxp; + + os_printk(K_DEBUG, "%s\n", __func__); + + if (!req) { + /* WARN_ON(1); */ + /* dev_dbg(musb->controller, "odd; csr0 %04x\n", musb_readw(regs, MUSB_CSR0)); */ + return; + } + + maxp = musb->endpoints->max_packet_sz_tx; + + request = &req->request; + + /* load the data */ + fifo_src = (u8 *) request->buf + request->actual; + fifo_count = min((unsigned)maxp, request->length - request->actual); + musb_write_fifo(&musb->endpoints[0], fifo_count, fifo_src); + + os_printk(K_DEBUG, "%s act=%d, len=%d, cnt=%d, maxp=%d zero=%d\n", + __func__, request->actual, request->length, fifo_count, maxp, request->zero); + + /* + * The flow is difference between MTU3D and original musb. + * For example: + * Host <-- 12byte -- Device + * MUSB: + * Interrupt #1 : Write 12bytes in FIFO and set TXPKTRDY + DATAEND + * Interrupt #2 : Do nothing. + * MTU3D: + * Interrupt #1 : Write 12bytes in FIFO and set TXPKTRDY + * Interrupt #2 : set DATAEND + */ + /* update the flags */ + if (request->actual == request->length) { + if (request->zero && (request->length % maxp == 0) && (request->length / maxp > 0)) { + /* + * Send a ZLP without DATAEND. Because the length host requires + * is longer than the actual data device sends. So pad a ZLP to + * tell HOST the end of the data. If the transferred data length + * is exactly what host wants, just set DATAEND without ZLP. + */ + request->zero = 0; + os_printk(K_DEBUG, "%s Send a padding ZLP!!!!\n", __func__); + request = NULL; + } else { + musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT; + csr |= EP0_DATAEND; + } + } else { + /* Add the amount of the data written into fifo to "actual" first. */ + request->actual += fifo_count; + request = NULL; + } + + /* report completions as soon as the fifo's loaded; there's no + * win in waiting till this last packet gets acked. (other than + * very precise fault reporting, needed by USB TMC; possible with + * this hardware, but not usable from portable gadget drivers.) + */ + if (request) { + musb->ackpend = csr; + musb_g_ep0_giveback(musb, request); + if (!musb->ackpend) + return; + musb->ackpend = 0; + } + + os_printk(K_DEBUG, "%s csr=%x\n", __func__, csr); + + /* send it out, triggering a "txpktrdy cleared" irq */ + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | csr); +} + +/* + * Read a SETUP packet (struct usb_ctrlrequest) from the hardware. + * Fields are left in USB byte-order. + * + * Context: caller holds controller lock. + */ +static void musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req) +{ + struct musb_request *r; + u32 csr = 0; + + os_printk(K_DEBUG, "%s\n", __func__); + + csr = os_readl(U3D_EP0CSR) & EP0_W1C_BITS; /* Don't W1C */ + if (!(os_readl(U3D_EP0CSR) & EP0_AUTOCLEAR)) + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_AUTOCLEAR); + mu3d_hal_read_fifo(0, (u8 *) req); + + /* NOTE: earlier 2.6 versions changed setup packets to host + * order, but now USB packets always stay in USB byte order. + */ + /* dev_dbg(musb->controller, "SETUP req%02x.%02x v%04x i%04x l%d\n", */ + os_printk(K_DEBUG, "SETUP req%02x.%02x v%04x i%04x l%d\n", + req->bRequestType, + req->bRequest, + le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength)); + + /* clean up any leftover transfers */ + r = next_ep0_request(musb); + if (r) + musb_g_ep0_giveback(musb, &r->request); + + /* For zero-data requests we want to delay the STATUS stage to + * avoid SETUPEND errors. If we read data (OUT), delay accepting + * packets until there's a buffer to store them in. + * + * If we write data, the controller acts happier if we enable + * the TX FIFO right away, and give the controller a moment + * to switch modes... + */ + musb->set_address = false; + if (req->wLength == 0) { + musb->ep0_state = MUSB_EP0_STAGE_ACKWAIT; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_ACKWAIT\n"); + } else if (req->bRequestType & USB_DIR_IN) { + musb->ep0_state = MUSB_EP0_STAGE_TX; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_TX\n"); + os_writel(U3D_EP0CSR, csr | EP0_SETUPPKTRDY | EP0_DPHTX); + musb->ackpend = 0; + } else { + /* Set CSR0.SetupPktRdy(W1C) & CSR0.DPHTX=0 */ + os_writel(U3D_EP0CSR, (csr | EP0_SETUPPKTRDY) & (~EP0_DPHTX)); + musb->ackpend = 0; + musb->ep0_state = MUSB_EP0_STAGE_RX; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_RX\n"); + } +} + + +/* + * Handle peripheral ep0 interrupt + * + * Context: irq handler; we won't re-enter the driver that way. + */ +irqreturn_t musb_g_ep0_irq(struct musb *musb) +{ + u32 csr; + u16 len; + irqreturn_t retval = IRQ_NONE; + int i = 0; + + csr = os_readl(U3D_EP0CSR); + len = (u16) os_readl(U3D_RXCOUNT0); + + os_printk(K_DEBUG, "%s csr=0x%X\n", __func__, csr); + + /* dev_dbg(musb->controller, "csr %04x, count %d, myaddr %d, ep0stage %s\n", + csr, len, + musb_readb(mbase, MUSB_FADDR), + decode_ep0stage(musb->ep0_state)); + */ + + /* if (csr & MUSB_CSR0_P_DATAEND) { */ + /* + * If DATAEND is set we should not call the callback, + * hence the status stage is not complete. + */ + /* return IRQ_HANDLED; + } */ + + /* I sent a stall.. need to acknowledge it now.. */ + if (csr & EP0_SENTSTALL) { + os_writel(U3D_EP0CSR, (csr & EP0_W1C_BITS) | EP0_SENTSTALL); /* EP0_SENTSTALL is W1C */ + + if (os_readl(U3D_EP0CSR) & EP0_TXPKTRDY) { /* try to flushfifo after clear sentstall */ +#if 0 + u32 csr0 = 0; + + csr0 = os_readl(U3D_EP0CSR); + csr0 &= EP0_W1C_BITS; /* don't clear W1C bits */ + csr0 |= CSR0_FLUSHFIFO; + os_writel(U3D_EP0CSR, csr0); + + os_printk(K_DEBUG, "waiting for flushfifo....."); + while (os_readl(U3D_EP0CSR) & CSR0_FLUSHFIFO) { /* proceed before it clears */ + cpu_relax(); + } + os_printk(K_DEBUG, "done.\n"); +#else + /* toggle EP0_RST */ + os_setmsk(U3D_EP_RST, EP0_RST); + os_clrmsk(U3D_EP_RST, EP0_RST); +#endif + } + retval = IRQ_HANDLED; + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + csr = os_readl(U3D_EP0CSR); + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_IDLE. now csr is 0x%04x\n", + csr); + } + +/* SSUSB does not support this bit. So comment it.*/ +#ifdef NEVER + /* request ended "early" */ + if (csr & CSR0_SETUPEND) { + os_writel(U3D_EP0CSR, (os_readl(U3D_EP0CSR) & EP0_W1C_BITS) | CSR0_SERVICESETUPEND); + retval = IRQ_HANDLED; + /* Transition into the early status phase */ + switch (musb->ep0_state) { + case MUSB_EP0_STAGE_TX: + musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_STATUSOUT\n"); + break; + case MUSB_EP0_STAGE_RX: + musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_STATUSIN\n"); + break; + default: + ERR("SetupEnd came in a wrong ep0stage %s\n", + decode_ep0stage(musb->ep0_state)); + } + csr = os_readl(U3D_EP0CSR); + /* NOTE: request may need completion */ + } +#endif /* NEVER */ + + os_printk(K_DEBUG, "ep0_state=%d\n", musb->ep0_state); + + /* docs from Mentor only describe tx, rx, and idle/setup states. + * we need to handle nuances around status stages, and also the + * case where status and setup stages come back-to-back ... + */ + switch (musb->ep0_state) { + + case MUSB_EP0_STAGE_TX: + /* irq on clearing txpktrdy */ + if ((csr & EP0_FIFOFULL) == 0) { + os_printk(K_DEBUG, "csr & EP0_FIFOFULL\n"); + ep0_txstate(musb); + retval = IRQ_HANDLED; + } + break; + + case MUSB_EP0_STAGE_RX: + /* irq on set rxpktrdy */ + if (csr & EP0_RXPKTRDY) { + ep0_rxstate(musb); + retval = IRQ_HANDLED; + } + break; + + case MUSB_EP0_STAGE_STATUSIN: +/* Because ssusb doesn't have interrupt after In status, we actually don't have STATUSIN stage. + * It has been moved to MUSB_EP0_STAGE_SETUP. */ +#if 0 + /* end of sequence #2 (OUT/RX state) or #3 (no data) */ + + /* update address (if needed) only @ the end of the + * status phase per usb spec, which also guarantees + * we get 10 msec to receive this irq... until this + * is done we won't see the next packet. + */ + if (musb->set_address) { + musb->set_address = false; + os_writel(U3D_DEVICE_CONF, + os_readl(U3D_DEVICE_CONF) | (musb->address << DEV_ADDR_OFST)); + } + + /* enter test mode if needed (exit by reset) */ + else if (musb->test_mode) { + dev_dbg(musb->controller, "entering TESTMODE\n"); + + os_printk(K_DEBUG, "entering TESTMODE 1\n"); + + if (TEST_PACKET_MODE == musb->test_mode_nr) + musb_load_testpacket(musb); + + os_writel(U3D_USB2_TEST_MODE, musb->test_mode_nr); + } +#endif + /* FALLTHROUGH */ + + case MUSB_EP0_STAGE_STATUSOUT: + /* end of sequence #1: write to host (TX state) */ + { + struct musb_request *req; + + req = next_ep0_request(musb); + if (req) + musb_g_ep0_giveback(musb, &req->request); + } + + /* + * In case when several interrupts can get coalesced, + * check to see if we've already received a SETUP packet... + */ + if (csr & EP0_SETUPPKTRDY) /* in ssusb, we check SETUPPKTRDY for setup packet. */ + goto setup; + + retval = IRQ_HANDLED; + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_IDLE\n"); + break; + + case MUSB_EP0_STAGE_IDLE: + /* + * This state is typically (but not always) indiscernible + * from the status states since the corresponding interrupts + * tend to happen within too little period of time (with only + * a zero-length packet in between) and so get coalesced... + */ + retval = IRQ_HANDLED; + + /* REVISIT-J: No need, Cuz the following sequence does not effect. */ + /* added for ssusb: */ + if (!(csr & EP0_SETUPPKTRDY)) { + os_printk(K_DEBUG, "break from MUSB_EP0_STAGE_IDLE\n"); + break; /* Don't process, keep idle. a. */ + } + /* added for ssusb. */ + + musb->ep0_state = MUSB_EP0_STAGE_SETUP; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_SETUP\n"); + /* FALLTHROUGH */ + + case MUSB_EP0_STAGE_SETUP: +setup: + if (csr & EP0_SETUPPKTRDY) { + struct usb_ctrlrequest setup; + int handled = 0; + + if (len != 8) { + ERR("SETUP packet len %d != 8 ?\n", len); + break; + } + musb_read_setup(musb, &setup); + retval = IRQ_HANDLED; + + /* sometimes the RESET won't be reported */ + if (unlikely(musb->g.speed == USB_SPEED_UNKNOWN)) { + /*REVISIT-J: Shall we implement it? */ +/* mark temporarily for ssusb because PMU is not ready. + u8 power; + + printk(KERN_NOTICE "%s: peripheral reset " + "irq lost!\n", + musb_driver_name); + power = musb_readb(mbase, MUSB_POWER); + musb->g.speed = (power & HS_MODE) + ? USB_SPEED_HIGH : USB_SPEED_FULL; + +*/ + } + + switch (musb->ep0_state) { + + /* sequence #3 (no data stage), includes requests + * we can't forward (notably SET_ADDRESS and the + * device/endpoint feature set/clear operations) + * plus SET_CONFIGURATION and others we must + */ + case MUSB_EP0_STAGE_ACKWAIT: + os_printk(K_DEBUG, + "&&&&&&&&&&&&&&&&& process MUSB_EP0_STAGE_ACKWAIT\n"); + handled = service_zero_data_request(musb, &setup); + + /* + * We're expecting no data in any case, so + * always set the DATAEND bit -- doing this + * here helps avoid SetupEnd interrupt coming + * in the idle stage when we're stalling... + */ + + /*if (1)*/ /*marked for DEEP_INDENTATION*/ + { + /* Because status phase currently doesn't + * have interrupt, we process here. */ + /* Process here according to ssusb programming guide */ + if (musb->set_address) { + musb->set_address = false; + /* musb_writeb(mbase, MUSB_FADDR, musb->address); */ + os_printk(K_INFO, "Set address to 0x%08x...\n", + musb->address); + os_writel(U3D_DEVICE_CONF, + os_readl(U3D_DEVICE_CONF) | (musb->address + << + DEV_ADDR_OFST)); + } else if (musb->test_mode) { + os_printk(K_DEBUG, "entering TESTMODE 2\n"); + + if (TEST_PACKET_MODE == musb->test_mode_nr) + musb_load_testpacket(musb); + + /* musb_writeb(mbase, MUSB_TESTMODE, */ + /* musb->test_mode_nr); */ + + /* Need to send status before really entering test mode. */ + os_writel(U3D_EP0CSR, + (os_readl(U3D_EP0CSR) & EP0_W1C_BITS) | + musb->ackpend | EP0_DATAEND | + EP0_SETUPPKTRDY); + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + + while ((os_readl(U3D_EP0CSR) & EP0_DATAEND) != 0) { + /* Need to wait for status really loaded by host */ + mdelay(1);/* Without this delay, it will fail. */ + } + + os_writel(U3D_USB2_TEST_MODE, musb->test_mode_nr); + + return retval; + } + + /* end of sequence #1: write to host (TX state) */ + { + struct usb_request *request; + struct musb_request *req; + + req = next_ep0_request(musb); + if (req) { + request = &(req->request); + os_printk(K_DEBUG, + "&&&&&&&&&&&&&&&&& next_ep0_request\n"); + musb_g_ep0_giveback(musb, request); + } else { + /* os_printk(K_DEBUG, + "&&&&&&&&&&&&&&&&& next_ep0_request returns null\n"); */ + } + } + } + + /* Set CSR0.SetupPktRdy(W1C) & CSR0.DataEnd */ + musb->ackpend |= EP0_DATAEND | EP0_SETUPPKTRDY; + + /* status stage might be immediate */ + if (handled > 0) { + /* Change to idle because status in will be completed + * immediately after dataend is set */ + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + os_printk(K_DEBUG, + "----- ep0 state: MUSB_EP0_STAGE_IDLE\n"); + } + + break; + + /* sequence #1 (IN to host), includes GET_STATUS + * requests that we can't forward, GET_DESCRIPTOR + * and others that we must + */ + case MUSB_EP0_STAGE_TX: + handled = service_in_request(musb, &setup); + if (handled <= 0) { + /* os_printk(K_DEBUG, "Cannot service_in_request.\n"); */ + break; + } + os_printk(K_DEBUG, "handled MUSB_EP0_STAGE_TX.\n"); + /* Wait until FIFOFULL cleared by hrdc */ + while ((os_readl(U3D_EP0CSR) & EP0_FIFOFULL)) { + mdelay(5); + i++; + if (i > 5) { + os_printk(K_INFO, + "ep0 still full, something wrong!!!\n"); + break; + } + } + + musb->ackpend |= EP0_DATAEND; + musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT; + os_printk(K_DEBUG, + "----- ep0 state: MUSB_EP0_STAGE_STATUSOUT (%s:%d)\n", + __func__, __LINE__); + + /*if (1) */ /*DEEP_INDENTATION*/ + { + /* process MUSB_EP0_STAGE_STATUSOUT because currently + * we don't have interrupt after status out phase. */ + /* end of sequence #1: write to host (TX state) */ + { + struct usb_request *request; + struct musb_request *req; + + req = next_ep0_request(musb); + if (req) { + request = &(req->request); + musb_g_ep0_giveback(musb, request); + } + } + + /* + * In case when several interrupts can get coalesced, + * check to see if we've already received a SETUP packet... + */ + + retval = IRQ_HANDLED; + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + os_printk(K_DEBUG, + "----- ep0 state: MUSB_EP0_STAGE_IDLE (%s:%d)\n", + __func__, __LINE__); + } + /* process MUSB_EP0_STAGE_STATUSOUT because currently + * we don't have interrupt after status out phase. */ + + break; + + /* sequence #2 (OUT from host), always forward */ + default: /* MUSB_EP0_STAGE_RX */ + break; + } + + /* dev_dbg(musb->controller, "handled %d, csr %04x, ep0stage %s\n", */ + os_printk(K_DEBUG, "handled %d, csr %04x, ep0stage %s\n", + handled, csr, decode_ep0stage(musb->ep0_state)); + + /* unless we need to delegate this to the gadget + * driver, we know how to wrap this up: csr0 has + * not yet been written. + */ + if (handled < 0) + goto stall; + else if (handled > 0) + goto finish; + + handled = forward_to_driver(musb, &setup); + if (handled < 0) { +stall: + os_printk(K_INFO, "stall (%d)\n", handled); + /* flushfifo before send SENDSTALL */ + + if (os_readl(U3D_EP0CSR) & EP0_TXPKTRDY) { + /* try to flushfifo after clear sentstall */ +#if 0 + u32 csr0 = 0; + + csr0 = os_readl(U3D_EP0CSR); + csr0 &= EP0_W1C_BITS; /* don't clear W1C bits */ + csr0 |= CSR0_FLUSHFIFO; + os_writel(U3D_EP0CSR, csr0); + + os_printk(K_DEBUG, "waiting for flushfifo....."); + while (os_readl(U3D_EP0CSR) & CSR0_FLUSHFIFO) { + /* proceed before it clears */ + cpu_relax(); + } + os_printk(K_DEBUG, "done.\n"); +#else + /* toggle EP0_RST */ + os_setmsk(U3D_EP_RST, EP0_RST); + os_clrmsk(U3D_EP_RST, EP0_RST); +#endif + } + + + if (musb->ackpend & EP0_DATAEND) { + os_printk(K_DEBUG, "Do not send dataend due to stall.\n"); + musb->ackpend &= ~EP0_DATAEND; + } + + musb->ackpend |= EP0_SENDSTALL; + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + os_printk(K_INFO, "@@@@@@@@@@@@@@@ SENDSTALL\n"); + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_IDLE\n"); +finish: + os_writel(U3D_EP0CSR, + (os_readl(U3D_EP0CSR) & EP0_W1C_BITS) | musb->ackpend); + musb->ackpend = 0; + } + } + break; + + case MUSB_EP0_STAGE_ACKWAIT: + /* This should not happen. But happens with tusb6010 with + * g_file_storage and high speed. Do nothing. + */ + retval = IRQ_HANDLED; + break; + + default: + /* "can't happen" */ + WARN_ON(1); + os_printk(K_INFO, "@@@@@@@@@@@@@@@ SENDSTALL\n"); + + /* flushfifo before send SENDSTALL */ + + if (os_readl(U3D_EP0CSR) & EP0_TXPKTRDY) { /* try to flushfifo after clear sentstall */ +#if 0 + u32 csr0 = 0; + + csr0 = os_readl(U3D_EP0CSR); + csr0 &= EP0_W1C_BITS; /* don't clear W1C bits */ + csr0 |= CSR0_FLUSHFIFO; + os_writel(U3D_EP0CSR, csr0); + + os_printk(K_DEBUG, "waiting for flushfifo....."); + while (os_readl(U3D_EP0CSR) & CSR0_FLUSHFIFO) { /* proceed before it clears */ + cpu_relax(); + } + os_printk(K_DEBUG, "done.\n"); +#else + /* toggle EP0_RST */ + os_setmsk(U3D_EP_RST, EP0_RST); + os_clrmsk(U3D_EP_RST, EP0_RST); +#endif + } + + + os_writel(U3D_EP0CSR, (os_readl(U3D_EP0CSR) & EP0_W1C_BITS) | EP0_SENDSTALL); + + + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + break; + } + + return retval; +} + + +static int musb_g_ep0_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) +{ + /* always enabled */ + return -EINVAL; +} + +static int musb_g_ep0_disable(struct usb_ep *e) +{ + /* always enabled */ + return -EINVAL; +} + +static int musb_g_ep0_queue(struct usb_ep *e, struct usb_request *r, gfp_t gfp_flags) +{ + struct musb_ep *ep; + struct musb_request *req; + struct musb *musb; + int status; + unsigned long lockflags; + + if (!e || !r) + return -EINVAL; + + os_printk(K_DEBUG, "%s\n", __func__); + + ep = to_musb_ep(e); + musb = ep->musb; + + req = to_musb_request(r); + req->musb = musb; + req->request.actual = 0; + req->request.status = -EINPROGRESS; + req->tx = ep->is_in; + + spin_lock_irqsave(&musb->lock, lockflags); + + if (!list_empty(&ep->req_list)) { + status = -EBUSY; + goto cleanup; + } + + switch (musb->ep0_state) { + case MUSB_EP0_STAGE_RX: /* control-OUT data */ + case MUSB_EP0_STAGE_TX: /* control-IN data */ + case MUSB_EP0_STAGE_ACKWAIT: /* zero-length data */ + status = 0; + break; + default: + dev_dbg(musb->controller, "ep0 request queued in state %d\n", musb->ep0_state); + status = -EINVAL; + goto cleanup; + } + + /* add request to the list */ + list_add_tail(&req->list, &ep->req_list); + + /* dev_dbg(musb->controller, "queue to %s (%s), length=%d\n", */ + os_printk(K_DEBUG, "queue to %s (%s), length=%d\n", + ep->name, ep->is_in ? "IN/TX" : "OUT/RX", req->request.length); + + /* sequence #1, IN ... start writing the data */ + if (musb->ep0_state == MUSB_EP0_STAGE_TX) + ep0_txstate(musb); + + /* sequence #3, no-data ... issue IN status */ + else if (musb->ep0_state == MUSB_EP0_STAGE_ACKWAIT) { + if (req->request.length) + status = -EINVAL; + else { + musb->ep0_state = MUSB_EP0_STAGE_STATUSIN; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_STATUSIN\n"); + + os_writel(U3D_EP0CSR, + (os_readl(U3D_EP0CSR) & EP0_W1C_BITS) | musb->ackpend | + EP0_DATAEND); + + musb->ackpend = 0; + musb_g_ep0_giveback(ep->musb, r); + } + + /* else for sequence #2 (OUT), caller provides a buffer + * before the next packet arrives. deferred responses + * (after SETUP is acked) are racey. + */ + } else if (musb->ackpend) { + os_writel(U3D_EP0CSR, (os_readl(U3D_EP0CSR) & EP0_W1C_BITS) | musb->ackpend); + musb->ackpend = 0; + } + +cleanup: + spin_unlock_irqrestore(&musb->lock, lockflags); + return status; +} + +static int musb_g_ep0_dequeue(struct usb_ep *ep, struct usb_request *req) +{ + /* we just won't support this */ + return -EINVAL; +} + +static int musb_g_ep0_halt(struct usb_ep *e, int value) +{ + struct musb_ep *ep; + struct musb *musb; + void __iomem *base; + unsigned long flags; + int status; + u32 csr; + + os_printk(K_INFO, "%s\n", __func__); + + if (!e || !value) + return -EINVAL; + + ep = to_musb_ep(e); + musb = ep->musb; + base = musb->mregs; + status = 0; + + spin_lock_irqsave(&musb->lock, flags); + + if (!list_empty(&ep->req_list)) { + status = -EBUSY; + goto cleanup; + } + + csr = musb->ackpend; + + switch (musb->ep0_state) { + + /* Stalls are usually issued after parsing SETUP packet, either + * directly in irq context from setup() or else later. + */ + case MUSB_EP0_STAGE_TX: /* control-IN data */ + case MUSB_EP0_STAGE_ACKWAIT: /* STALL for zero-length data */ + case MUSB_EP0_STAGE_RX: /* control-OUT data */ + csr = os_readl(U3D_EP0CSR); + /* FALLTHROUGH */ + + /* It's also OK to issue stalls during callbacks when a non-empty + * DATA stage buffer has been read (or even written). + */ + case MUSB_EP0_STAGE_STATUSIN: /* control-OUT status */ + case MUSB_EP0_STAGE_STATUSOUT: /* control-IN status */ + + if (os_readl(U3D_EP0CSR) & EP0_TXPKTRDY) { /* try to flushfifo after clear sentstall */ +#if 0 + u32 csr0 = 0; + + csr0 = os_readl(U3D_EP0CSR); + csr0 &= EP0_W1C_BITS; /* don't clear W1C bits */ + csr0 |= CSR0_FLUSHFIFO; + os_writel(U3D_EP0CSR, csr0); + + os_printk(K_DEBUG, "waiting for flushfifo....."); + while (os_readl(U3D_EP0CSR) & CSR0_FLUSHFIFO) { /* proceed before it clears */ + cpu_relax(); + } + os_printk(K_DEBUG, "done.\n"); +#else + /* toggle EP0_RST */ + os_setmsk(U3D_EP_RST, EP0_RST); + os_clrmsk(U3D_EP_RST, EP0_RST); +#endif + } + + csr = (csr & EP0_W1C_BITS) | EP0_SENDSTALL; + os_printk(K_INFO, "@@@@@@@@@@@@@@@ SENDSTALL\n"); + os_writel(U3D_EP0CSR, csr); + musb->ep0_state = MUSB_EP0_STAGE_IDLE; + os_printk(K_DEBUG, "----- ep0 state: MUSB_EP0_STAGE_IDLE\n"); + musb->ackpend = 0; + break; + default: + dev_dbg(musb->controller, "ep0 can't halt in state %d\n", musb->ep0_state); + status = -EINVAL; + } + +cleanup: + spin_unlock_irqrestore(&musb->lock, flags); + return status; +} + +const struct usb_ep_ops musb_g_ep0_ops = { + .enable = musb_g_ep0_enable, + .disable = musb_g_ep0_disable, + .alloc_request = musb_alloc_request, + .free_request = musb_free_request, + .queue = musb_g_ep0_queue, + .dequeue = musb_g_ep0_dequeue, + .set_halt = musb_g_ep0_halt, +}; diff --git a/drivers/misc/mediatek/mu3d/drv/musb_init.c b/drivers/misc/mediatek/mu3d/drv/musb_init.c new file mode 100644 index 000000000000..b28de103d08b --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_init.c @@ -0,0 +1,860 @@ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/gpio.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/prefetch.h> +#include <linux/usb/nop-usb-xceiv.h> + +#include <asm/cacheflush.h> + +#include "musb_core.h" +#include "ssusb_qmu.h" +#include "mu3d_hal_osal.h" +#include "mu3d_hal_phy.h" +#include "mu3d_hal_usb_drv.h" +#include "musb_gadget.h" + +#ifdef CONFIG_PROJECT_PHY +#include "mtk-phy-asic.h" +#endif + +#ifdef CONFIG_OF +#include <linux/of_device.h> +#endif + +#ifdef CONFIG_USBIF_COMPLIANCE +static struct musb_fifo_cfg mtu3d_cfg[] = { +#else +static struct musb_fifo_cfg mtu3d_cfg[] __initdata = { +#endif + {.hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 1024,}, + {.hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 1024,}, + {.hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 1024,}, + {.hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 1024,}, + {.hw_ep_num = 5, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 5, .style = FIFO_RX, .maxpacket = 1024,}, + {.hw_ep_num = 6, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 6, .style = FIFO_RX, .maxpacket = 1024,}, + {.hw_ep_num = 7, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 7, .style = FIFO_RX, .maxpacket = 1024,}, + {.hw_ep_num = 8, .style = FIFO_TX, .maxpacket = 1024,}, + {.hw_ep_num = 8, .style = FIFO_RX, .maxpacket = 1024,}, +}; + +static struct musb_hdrc_config mtu3d_config = { + .multipoint = false, + /* FIXME:Seems no need */ + /* .soft_con = true, */ + .dma = true, + .num_eps = 9, /*EP0 ~ EP8 */ + .dma_channels = 8, + .ram_bits = 12, + .fifo_cfg = mtu3d_cfg, + .fifo_cfg_size = ARRAY_SIZE(mtu3d_cfg), +}; + +static int mtu3d_musb_init(struct musb *musb); +static int mtu3d_musb_exit(struct musb *musb); +static void mtu3d_musb_enable(struct musb *musb); +static void mtu3d_musb_disable(struct musb *musb); + +static const struct musb_platform_ops mtu3d_ops = { + .init = mtu3d_musb_init, + .exit = mtu3d_musb_exit, + + .enable = mtu3d_musb_enable, + .disable = mtu3d_musb_disable +}; + +static struct musb_hdrc_platform_data mtu3d_data = { + .mode = MUSB_PERIPHERAL, + .config = &mtu3d_config, + .platform_ops = &mtu3d_ops, +}; + +static const struct of_device_id mtu3d_of_match[] = { + { + .compatible = "mediatek,USB3", + .data = &mtu3d_data, + }, + {}, +}; + +struct mtu3d_glue { + struct device *dev; + struct platform_device *musb; +}; +#define glue_to_musb(g) platform_get_drvdata(g->musb) + +static void mtu3d_musb_reg_init(struct musb *musb); +static int mtu3d_set_power(struct usb_phy *x, unsigned mA); + +static u32 sts_ltssm; + +#ifdef CONFIG_USBIF_COMPLIANCE +void init_check_ltssm_work(void) +{ + sts_ltssm = 0; +} +#endif + +/* + * This work is to fix IOT problem. + * 1. PC(Lenovo MT-M5852-B88) + USB Host PCI-e TI(TUSB7340) or Fresco, + * --> PC enter SLERP/HIBERNATION --> USER wake up PC --> PC can not detect device. + * 2. PC(Lenovo MT-M5852-B88) + USB Host PCI-e Fresco, + * --> PC COLD reboot --> PC can not detect device. + * The root cause is that device try to link host too early. XHCI host does not ready to linkup. + * So create a delayed work to re-tran when device is stuck at RxDetect. + */ +void check_ltssm_work(struct work_struct *data) +{ + /* struct musb *musb = container_of(to_delayed_work(data), struct musb, check_ltssm_work); */ +#ifndef CONFIG_USBIF_COMPLIANCE + os_printk(K_INFO, "%s %x\n", __func__, sts_ltssm); + + if (sts_ltssm == RXDET_SUCCESS_INTR) { + sts_ltssm = 0; + mu3d_hal_u3dev_dis(); + mdelay(10); + mu3d_hal_u3dev_en(); + } +#endif +} + +#ifndef CONFIG_USBIF_COMPLIANCE +/* + * The workaround for IOT issue. + * Lenovo PC(MT-M 5852-B88) + Asmedia U3 Host controller + * The device stays at "SS" when connecting with PC. + * But after restarting PC, the device would stay at "HS". + */ +void reconnect_work(struct work_struct *data) +{ + os_printk(K_INFO, "%s\n", __func__); + + /* Disable U2 detect */ + mu3d_hal_u3dev_dis(); + mu3d_hal_u2dev_disconn(); + mdelay(1000); + mu3d_hal_u3dev_en(); +} +#endif + +static inline void mtu3d_u3_ltssm_intr_handler(struct musb *musb, u32 dwLtssmValue) +{ + static u32 soft_conn_num; + + if (dwLtssmValue & SS_DISABLE_INTR) { + os_printk(K_INFO, "LTSSM: SS_DISABLE_INTR [%d] & Set SOFT_CONN=1\n", + soft_conn_num++); + /* enable U2 link. after host reset, HS/FS EP0 configuration is applied in musb_g_reset */ + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, SSUSB_U2_PORT_PDN); + os_setmsk(U3D_POWER_MANAGEMENT, SOFT_CONN); + sts_ltssm = SS_DISABLE_INTR; + } + + if (dwLtssmValue & ENTER_U0_INTR) { + soft_conn_num = 0; + /* do not apply U3 EP0 setting again, if the speed is already U3 */ + /* LTSSM may go to recovery and back to U0 */ + if (musb->g.speed != USB_SPEED_SUPER) { + os_printk(K_INFO, "LTSSM: ENTER_U0_INTR %d\n", musb->g.speed); + musb_conifg_ep0(musb); + } + cancel_delayed_work(&musb->check_ltssm_work); + sts_ltssm = ENTER_U0_INTR; + } + + if (dwLtssmValue & VBUS_FALL_INTR) { + os_printk(K_INFO, "LTSSM: VBUS_FALL_INTR\n"); + mu3d_hal_pdn_ip_port(1, 1, 1, 1); + mu3d_hal_u3dev_dis(); + } + + if (dwLtssmValue & VBUS_RISE_INTR) { + os_printk(K_INFO, "LTSSM: VBUS_RISE_INTR\n"); + mu3d_hal_u3dev_en(); + } + + if (dwLtssmValue & ENTER_U3_INTR) { + os_printk(K_INFO, "LTSSM: ENTER_U3_INTR\n"); + mu3d_hal_pdn_ip_port(0, 0, 1, 0); + sts_ltssm = ENTER_U3_INTR; + } +#ifndef POWER_SAVING_MODE + if (dwLtssmValue & U3_RESUME_INTR) { + os_printk(K_INFO, "LTSSM: RESUME_INTR\n"); + mu3d_hal_pdn_ip_port(1, 0, 1, 0); + os_writel(U3D_LINK_POWER_CONTROL, os_readl(U3D_LINK_POWER_CONTROL) | UX_EXIT); + } +#endif + + if (dwLtssmValue & EXIT_U3_INTR) { + os_printk(K_INFO, "LTSSM: EXIT_U3_INTR\n"); + mu3d_hal_pdn_ip_port(1, 0, 1, 0); + sts_ltssm = EXIT_U3_INTR; + } + + /*7.5.12.2 Hot Reset Requirements + * 1. A downstream port shall reset its Link Error Count as defined in Section 7.4.2. + * 2. A downstream port shall reset its PM timers and the associated U1 and U2 timeout values to zero. + * 3. The port Configuration information shall remain unchanged (refer to Section 8.4.6 for details). + * 4. The port shall maintain its transmitter specifications defined in Table 6-10. + * 5. The port shall maintain its low-impedance receiver termination (RRX-DC) defined in Table 6-13. + */ + if (dwLtssmValue & HOT_RST_INTR) { + DEV_INT32 link_err_cnt; + DEV_INT32 timeout_val; + + os_printk(K_INFO, "LTSSM: HOT_RST_INTR\n"); + /* Clear link error count */ + link_err_cnt = os_readl(U3D_LINK_ERR_COUNT); + os_printk(K_INFO, "LTSSM: link_err_cnt=%x\n", link_err_cnt); + os_writel(U3D_LINK_ERR_COUNT, CLR_LINK_ERR_CNT); + + /* Clear U1 & U2 Enable */ + os_clrmsk(U3D_LINK_POWER_CONTROL, (SW_U1_ACCEPT_ENABLE | SW_U2_ACCEPT_ENABLE)); + + pwr_params.bU1Enabled = 0; + pwr_params.bU2Enabled = 0; + + /* Reset U1 & U2 timeout value */ + timeout_val = os_readl(U3D_LINK_UX_INACT_TIMER); + os_printk(K_INFO, "LTSSM: timer_val =%x\n", timeout_val); + timeout_val &= ~(U1_INACT_TIMEOUT_VALUE | DEV_U2_INACT_TIMEOUT_VALUE); + os_writel(U3D_LINK_UX_INACT_TIMER, timeout_val); + } + + if (dwLtssmValue & SS_INACTIVE_INTR) { + os_printk(K_INFO, "LTSSM: SS_INACTIVE_INTR\n"); + sts_ltssm = SS_INACTIVE_INTR; + } + + if (dwLtssmValue & RECOVERY_INTR) { + os_printk(K_DEBUG, "LTSSM: RECOVERY_INTR\n"); + sts_ltssm = RECOVERY_INTR; + } + + /* A completion of a Warm Reset shall result in the following. + * 1. A downstream port shall reset its Link Error Count. + * 2. Port configuration information of an upstream port shall be reset to default values. Refer to + * Sections 8.4.5 and 8.4.6 for details. + * 3. The PHY level variables (such as Rx equalization settings) shall be reinitialized or retrained. + * 4. The LTSSM of a port shall transition to U0 through RxDetect and Polling. + */ + if (dwLtssmValue & WARM_RST_INTR) { + DEV_INT32 link_err_cnt; + + os_printk(K_INFO, "LTSSM: WARM_RST_INTR\n"); + /* Clear link error count */ + link_err_cnt = os_readl(U3D_LINK_ERR_COUNT); + os_printk(K_INFO, "LTSSM: link_err_cnt=%x\n", link_err_cnt); + os_writel(U3D_LINK_ERR_COUNT, CLR_LINK_ERR_CNT); + + cancel_delayed_work(&musb->check_ltssm_work); + sts_ltssm = WARM_RST_INTR; + } + + if (dwLtssmValue & ENTER_U2_INTR) + os_printk(K_DEBUG, "LTSSM: ENTER_U2_INTR\n"); + if (dwLtssmValue & ENTER_U1_INTR) + os_printk(K_DEBUG, "LTSSM: ENTER_U1_INTR\n"); + if (dwLtssmValue & RXDET_SUCCESS_INTR) { + /*create a delay work. This work will work after 0.5sec. + If LTSSM state is still at RxDet. Clear USB3_EN and set again. */ + os_printk(K_INFO, "LTSSM: RXDET_SUCCESS_INTR\n"); + sts_ltssm = RXDET_SUCCESS_INTR; + schedule_delayed_work_on(0, &musb->check_ltssm_work, msecs_to_jiffies(1000)); + } +} + +static inline void mtu3d_u2_common_intr_handler(u32 dwIntrUsbValue) +{ + if (dwIntrUsbValue & DISCONN_INTR) { + mu3d_hal_pdn_ip_port(1, 0, 1, 1); + + os_printk(K_NOTICE, "[U2 DISCONN_INTR] Set SOFT_CONN=0\n"); + os_clrmsk(U3D_POWER_MANAGEMENT, SOFT_CONN); + + /*TODO-J: ADD musb_g_disconnect(musb);?? */ + } + + if (dwIntrUsbValue & LPM_INTR) { + u32 rmwake; + + rmwake = os_readl(U3D_POWER_MANAGEMENT); + + os_printk(K_NOTICE, "[U2 LPM interrupt] last rmwake is 0x%x\n", rmwake & LPM_RWP); + + if (!((os_readl(U3D_POWER_MANAGEMENT) & LPM_HRWE))) + mu3d_hal_pdn_ip_port(0, 0, 0, 1); + +#ifdef CONFIG_USBIF_COMPLIANCE + /* SW word around for USBIF test with Fresco FL1100 with LPM L1C enabling */ +#if 0 + if (rmwake & LPM_RWP) { + os_writel(U3D_USB20_MISC_CONTROL, + os_readl(U3D_USB20_MISC_CONTROL) | LPM_U3_ACK_EN); + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) | RESUME); + } +#endif +#endif + } + + if (dwIntrUsbValue & LPM_RESUME_INTR) { + if (!(os_readl(U3D_POWER_MANAGEMENT) & LPM_HRWE)) { + mu3d_hal_pdn_ip_port(1, 0, 0, 1); + + os_writel(U3D_USB20_MISC_CONTROL, + os_readl(U3D_USB20_MISC_CONTROL) | LPM_U3_ACK_EN); + } + } + + if (dwIntrUsbValue & SUSPEND_INTR) { + os_printk(K_NOTICE, "[U2 SUSPEND_INTR]\n"); + mu3d_hal_pdn_ip_port(0, 0, 0, 1); + } + + if (dwIntrUsbValue & RESUME_INTR) { + os_printk(K_NOTICE, "[U2 RESUME_INTR]\n"); + mu3d_hal_pdn_ip_port(1, 0, 0, 1); + } + + if (dwIntrUsbValue & RESET_INTR) + os_printk(K_NOTICE, "[U2 RESET_INTR]\n"); + +} + +static inline void mtu3d_link_intr_handler(struct musb *musb, u32 dwLinkIntValue) +{ + u32 dwTemp; +#ifndef CONFIG_USBIF_COMPLIANCE + static u32 speed_last = SSUSB_SPEED_INACTIVE; + static u32 speed = SSUSB_SPEED_INACTIVE; + static struct timespec ss_timestamp = { 0, 0 }; +#endif + + dwTemp = os_readl(U3D_DEVICE_CONF) & SSUSB_DEV_SPEED; + mu3d_hal_pdn_cg_en(); + + switch (dwTemp) { + case SSUSB_SPEED_FULL: + os_printk(K_ALET, "USB Speed = Full Speed\n"); +#ifndef CONFIG_USBIF_COMPLIANCE + speed_last = speed; + speed = SSUSB_SPEED_FULL; +#endif + +#ifdef CONFIG_PROJECT_PHY + /* Comment from CC Chou. + * When detecting HS or FS and setting RG_USB20_SW_PLLMODE=1, It is OK to enter LPM L1 with BESL=0. + * When disconnecting, set RG_USB20_SW_PLLMODE=0 back. + */ + os_setmsk(U3D_U2PHYDCR1, (0x1 << E60802_RG_USB20_SW_PLLMODE_OFST)); + + /*BESLCK = 0 < BESLCK_U3 = 1 < BESLDCK = 15 */ + os_writel(U3D_USB20_LPM_PARAMETER, 0x10f0); + + /* + * The default value of LPM_BESL_STALL and LPM_BESLD_STALL are 1. + * So Does _NOT_ need to set. + */ + /*os_setmsk(U3D_POWER_MANAGEMENT, (LPM_BESL_STALL|LPM_BESLD_STALL)); */ +#else + /*BESLCK = 4 < BESLCK_U3 = 10 < BESLDCK = 15 */ + os_writel(U3D_USB20_LPM_PARAMETER, 0xa4f0); + os_setmsk(U3D_POWER_MANAGEMENT, (LPM_BESL_STALL | LPM_BESLD_STALL)); +#endif + break; + + case SSUSB_SPEED_HIGH: + os_printk(K_ALET, "USB Speed = High Speed\n"); +#ifndef CONFIG_USBIF_COMPLIANCE + if ((speed == SSUSB_SPEED_INACTIVE) && (speed_last == SSUSB_SPEED_SUPER)) { + struct timespec tmp = get_connect_timestamp(); + + if (timespec_compare(&ss_timestamp, &tmp) > 0) { + os_printk(K_INFO, "queue reconnect work\n"); + + schedule_delayed_work_on(0, &musb->reconnect_work, 0); + } + } + speed_last = speed; + speed = SSUSB_SPEED_HIGH; +#endif + +#ifdef CONFIG_PROJECT_PHY + /* Comment from CC Chou. + * When detecting HS or FS and setting RG_USB20_SW_PLLMODE=1, It is OK to enter LPM L1 with BESL=0. + * When disconnecting, set RG_USB20_SW_PLLMODE=0 back. + */ + os_setmsk(U3D_U2PHYDCR1, (0x1 << E60802_RG_USB20_SW_PLLMODE_OFST)); + + /*BESLCK = 0 < BESLCK_U3 = 1 < BESLDCK = 15 */ + os_writel(U3D_USB20_LPM_PARAMETER, 0x10f0); + /* + * The default value of LPM_BESL_STALL and LPM_BESLD_STALL are 1. + * So Does _NOT_ need to set. + */ + /*os_setmsk(U3D_POWER_MANAGEMENT, (LPM_BESL_STALL|LPM_BESLD_STALL)); */ +#else + /*BESLCK = 4 < BESLCK_U3 = 10 < BESLDCK = 15 */ + os_writel(U3D_USB20_LPM_PARAMETER, 0xa4f0); + os_setmsk(U3D_POWER_MANAGEMENT, (LPM_BESL_STALL | LPM_BESLD_STALL)); +#endif + break; + + case SSUSB_SPEED_SUPER: + os_printk(K_ALET, "USB Speed = Super Speed\n"); +#ifndef CONFIG_USBIF_COMPLIANCE + speed_last = speed; + speed = SSUSB_SPEED_SUPER; + ss_timestamp = CURRENT_TIME; +#endif + break; + + default: + os_printk(K_ALET, "USB Speed = Invalid (%x)\n", dwTemp); +#ifndef CONFIG_USBIF_COMPLIANCE + speed_last = speed; + speed = SSUSB_SPEED_INACTIVE; +#endif + break; + } +} + +#ifdef SUPPORT_OTG +static inline void mtu3d_otg_intr_handler(u32 dwOtgIntValue) +{ + if (dwOtgIntValue & VBUS_CHG_INTR) { + os_printk(K_NOTICE, "OTG: VBUS_CHG_INTR\n"); + os_setmsk(U3D_SSUSB_OTG_STS_CLR, SSUSB_VBUS_INTR_CLR); + } + /* this interrupt is issued when B device becomes device */ + if (dwOtgIntValue & SSUSB_CHG_B_ROLE_B) { + os_printk(K_NOTICE, "OTG: CHG_B_ROLE_B\n"); + os_setmsk(U3D_SSUSB_OTG_STS_CLR, SSUSB_CHG_B_ROLE_B_CLR); + + /* switch DMA module to device */ + os_printk(K_NOTICE, "Switch DMA to device\n"); + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, SSUSB_U2_PORT_HOST_SEL); + } + /* this interrupt is issued when B device becomes host */ + if (dwOtgIntValue & SSUSB_CHG_A_ROLE_B) { + os_printk(K_NOTICE, "OTG: CHG_A_ROLE_B\n"); + os_setmsk(U3D_SSUSB_OTG_STS_CLR, SSUSB_CHG_A_ROLE_B_CLR); + } + /* this interrupt is issued when IDDIG reads B */ + if (dwOtgIntValue & SSUSB_ATTACH_B_ROLE) { + os_printk(K_NOTICE, "OTG: CHG_ATTACH_B_ROLE\n"); + os_setmsk(U3D_SSUSB_OTG_STS_CLR, SSUSB_ATTACH_B_ROLE_CLR); + + /* switch DMA module to device */ + os_printk(K_NOTICE, "Switch DMA to device\n"); + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, SSUSB_U2_PORT_HOST_SEL); + } + +} +#endif + +static irqreturn_t generic_interrupt(int irq, void *__hci) +{ + unsigned long flags; + irqreturn_t retval = IRQ_HANDLED; + struct musb *musb = __hci; + + u32 dwL1Value = 0; + u32 dwIntrUsbValue = 0; + u32 dwDmaIntrValue = 0; + u32 dwIntrEPValue = 0; + u16 wIntrTxValue = 0; + u16 wIntrRxValue = 0; +#ifdef USE_SSUSB_QMU + u32 wIntrQMUValue = 0; + u32 wIntrQMUDoneValue = 0; +#endif + u32 dwLtssmValue = 0; + u32 dwLinkIntValue = 0; + +#ifdef SUPPORT_OTG + u32 dwOtgIntValue = 0; +#endif + + spin_lock_irqsave(&musb->lock, flags); + + dwL1Value = os_readl(U3D_LV1ISR) & os_readl(U3D_LV1IER); + + if (dwL1Value & EP_CTRL_INTR) { + u32 dwRxEpDataerrVal = os_readl(U3D_USB2_RX_EP_DATAERR_INTR); + + if (dwRxEpDataerrVal != 0) { + /* Write 1 clear */ + os_writel(U3D_USB2_RX_EP_DATAERR_INTR, dwRxEpDataerrVal); + os_printk(K_INFO, "===L1[%x] RxDataErr[%x]\n", dwL1Value, + (dwRxEpDataerrVal >> USB2_RX_EP_DATAERR_INTR_EN_OFST + && dwRxEpDataerrVal)); + } + dwLinkIntValue = os_readl(U3D_DEV_LINK_INTR) & os_readl(U3D_DEV_LINK_INTR_ENABLE); + if (dwLinkIntValue != 0) { + /* Write 1 clear */ + os_writel(U3D_DEV_LINK_INTR, dwLinkIntValue); + os_printk(K_INFO, "===L1[%x] LinkInt[%x]\n", dwL1Value, dwLinkIntValue); + } + } + + if (dwL1Value & MAC2_INTR) { + dwIntrUsbValue = + os_readl(U3D_COMMON_USB_INTR) & os_readl(U3D_COMMON_USB_INTR_ENABLE); + /* Write 1 clear */ + os_writel(U3D_COMMON_USB_INTR, dwIntrUsbValue); + os_printk(K_INFO, "===L1[%x] U2[%x]\n", dwL1Value, dwIntrUsbValue); + } + + if (dwL1Value & DMA_INTR) { + dwDmaIntrValue = os_readl(U3D_DMAISR) & os_readl(U3D_DMAIER); + /* Write 1 clear */ + os_writel(U3D_DMAISR, dwDmaIntrValue); + os_printk(K_INFO, "===L1[%x] DMA[%x]\n", dwL1Value, dwDmaIntrValue); + } + + if (dwL1Value & MAC3_INTR) { + dwLtssmValue = os_readl(U3D_LTSSM_INTR) & os_readl(U3D_LTSSM_INTR_ENABLE); + /* Write 1 clear */ + os_writel(U3D_LTSSM_INTR, dwLtssmValue); + os_printk(K_DEBUG, "===L1[%x] LTSSM[%x]\n", dwL1Value, dwLtssmValue); + } +#ifdef USE_SSUSB_QMU + if (dwL1Value & QMU_INTR) { + wIntrQMUValue = os_readl(U3D_QISAR1) & os_readl(U3D_QIER1); + wIntrQMUDoneValue = os_readl(U3D_QISAR0) & os_readl(U3D_QIER0); + /* Write 1 clear */ + os_writel(U3D_QISAR0, wIntrQMUDoneValue); + qmu_printk(K_DEBUG, "===L1[%x] QMUDone[Tx=%x,Rx=%x] QMU[%x]===\n", + dwL1Value, ((wIntrQMUDoneValue & 0xFFFF) >> 1), wIntrQMUDoneValue >> 17, + wIntrQMUValue); + } +#endif + + if (dwL1Value & BMU_INTR) { + dwIntrEPValue = os_readl(U3D_EPISR) & os_readl(U3D_EPIER); + wIntrTxValue = dwIntrEPValue & 0xFFFF; + wIntrRxValue = (dwIntrEPValue >> 16); + os_writel(U3D_EPISR, dwIntrEPValue); + os_printk(K_DEBUG, "===L1[%x] Tx[%x] Rx[%x]===\n", + dwL1Value, wIntrTxValue, wIntrRxValue); + + } + + /*TODO: need to handle SetupEnd Interrupt!!! */ + + /*--Handle each interrupt--*/ + if ((dwL1Value & (BMU_INTR | MAC2_INTR)) || dwIntrUsbValue) { + musb->int_usb = dwIntrUsbValue; + musb->int_tx = wIntrTxValue; + musb->int_rx = wIntrRxValue; + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval = musb_interrupt(musb); + else + os_printk(K_INFO, "===L1[%x] Nothing can do?? Tx[%x] Rx[%x] U2[%x]===\n", + dwL1Value, wIntrTxValue, wIntrRxValue, dwIntrUsbValue); + } +#ifdef SUPPORT_OTG + dwOtgIntValue = os_readl(U3D_SSUSB_OTG_STS) & os_readl(U3D_SSUSB_OTG_INT_EN); +#endif + +#if defined(USE_SSUSB_QMU) + if (wIntrQMUDoneValue) { + if (musb->qmu_done_intr != 0) { + musb->qmu_done_intr = wIntrQMUDoneValue | musb->qmu_done_intr; + qmu_printk(K_DEBUG, "Has not handle yet %x\n", musb->qmu_done_intr); + } else { + musb->qmu_done_intr = wIntrQMUDoneValue; + } + tasklet_schedule(&musb->qmu_done); + } + + if (wIntrQMUValue) + qmu_exception_interrupt(musb, wIntrQMUValue); +#endif + + if (dwLtssmValue) + mtu3d_u3_ltssm_intr_handler(musb, dwLtssmValue); + + if (dwIntrUsbValue) + mtu3d_u2_common_intr_handler(dwIntrUsbValue); + + if (dwLinkIntValue & SSUSB_DEV_SPEED_CHG_INTR) + mtu3d_link_intr_handler(musb, dwLinkIntValue); + +#ifdef SUPPORT_OTG + if (dwOtgIntValue) + mtu3d_otg_intr_handler(dwOtgIntValue); +#endif + + spin_unlock_irqrestore(&musb->lock, flags); + + return retval; +} + + +static void mtu3d_musb_enable(struct musb *musb) +{ + os_printk(K_INFO, "%s\n", __func__); +} + +static void mtu3d_musb_disable(struct musb *musb) +{ + os_printk(K_INFO, "%s\n", __func__); + +#ifdef CONFIG_PROJECT_PHY + /* Comment from CC Chou. + * When detecting HS or FS and setting RG_USB20_SW_PLLMODE=1, It is OK to enter LPM L1 with BESL=0. + * When disconnecting, set RG_USB20_SW_PLLMODE=0 back. + */ + os_clrmsk(U3D_U2PHYDCR1, E60802_RG_USB20_SW_PLLMODE); +#endif +} + +static int mtu3d_musb_init(struct musb *musb) +{ + os_printk(K_DEBUG, "%s\n", __func__); + + musb->xceiv = usb_get_phy(USB_PHY_TYPE_USB2); + if (IS_ERR_OR_NULL(musb->xceiv)) + goto unregister; + + mtu3d_musb_reg_init(musb); + + if (is_peripheral_enabled(musb)) + musb->xceiv->set_power = mtu3d_set_power; + + musb->isr = generic_interrupt; + return 0; + +unregister: + return -ENODEV; + +} + +static int mtu3d_set_power(struct usb_phy *x, unsigned mA) +{ + os_printk(K_DEBUG, "%s\n", __func__); + return 0; +} + +static int mtu3d_musb_exit(struct musb *musb) +{ +#ifdef NEVER + struct device *dev = musb->controller; + struct musb_hdrc_platform_data *plat = dev->platform_data; +#endif /* NEVER */ + + usb_put_phy(musb->xceiv); + + return 0; +} + +static void mtu3d_musb_reg_init(struct musb *musb) +{ + int ret = 1; + + os_printk(K_DEBUG, "%s\n", __func__); + + /* initialize PHY related data structure */ + if (!u3phy_ops) + ret = u3phy_init(); + + if (ret || u3phy_ops) { + +#ifdef CONFIG_MTK_UART_USB_SWITCH + if (usb_phy_check_in_uart_mode()) { + os_printk(K_INFO, "%s+ UART_MODE\n", __func__); + in_uart_mode = true; + } else { + os_printk(K_INFO, "%s+ USB_MODE\n", __func__); + } +#endif + + u3phy_ops->init(u3phy); + + musb->is_clk_on = 1; + +#ifndef CONFIG_MTK_FPGA + usb_phy_recover(musb->is_clk_on); +#endif + /* USB 2.0 slew rate calibration */ + u3phy_ops->u2_slew_rate_calibration(u3phy); + + /* disable ip power down, disable U2/U3 ip power down */ + _ex_mu3d_hal_ssusb_en(); + + /* USB PLL Force settings */ +#ifdef CONFIG_PROJECT_PHY + usb20_pll_settings(false, false); +#endif + + /* reset U3D all dev module. */ + mu3d_hal_rst_dev(); + + } else { + os_printk(K_ERR, "%s: PHY initialization fail!\n", __func__); + BUG_ON(1); + } +} + +static u64 usb_dmamask = DMA_BIT_MASK(32); + +static int mtu3d_probe(struct platform_device *pdev) +{ + const struct musb_hdrc_platform_data *pdata = dev_get_platdata(&pdev->dev); + const struct of_device_id *match; + struct platform_device *musb; + struct mtu3d_glue *glue; + + int ret = -ENOMEM; + + os_printk(K_DEBUG, "%s\n", __func__); + + glue = kzalloc(sizeof(*glue), GFP_KERNEL); + if (!glue) { + /*WARNING:OOM_MESSAGE: Possible unnecessary 'out of memory' message*/ + /*dev_err(&pdev->dev, "failed to allocate glue context\n");*/ + goto err0; + } + + musb = platform_device_alloc(MUSB_DRIVER_NAME, PLATFORM_DEVID_NONE); + if (!musb) { + dev_err(&pdev->dev, "failed to allocate musb device\n"); + goto err1; + } + + musb->dev.parent = &pdev->dev; + musb->dev.dma_mask = &usb_dmamask; + musb->dev.coherent_dma_mask = usb_dmamask; + + glue->dev = &pdev->dev; + glue->musb = musb; + + match = of_match_device(of_match_ptr(mtu3d_of_match), &pdev->dev); + if (match) + pdata = match->data; + + platform_set_drvdata(pdev, glue); + + ret = platform_device_add_resources(musb, pdev->resource, pdev->num_resources); + if (ret) { + dev_err(&pdev->dev, "failed to add resources\n"); + goto err2; + } + + ret = platform_device_add_data(musb, pdata, sizeof(*pdata)); + if (ret) { + dev_err(&pdev->dev, "failed to add platform_data\n"); + goto err2; + } + + ret = platform_device_add(musb); + if (ret) { + dev_err(&pdev->dev, "failed to register musb device\n"); + goto err2; + } + + return 0; + +err2: + platform_device_put(musb); + +err1: + kfree(glue); + +err0: + return ret; +} + +static int mtu3d_remove(struct platform_device *pdev) +{ + struct mtu3d_glue *glue = platform_get_drvdata(pdev); + + platform_device_del(glue->musb); + platform_device_put(glue->musb); + kfree(glue); + + return 0; +} + +#ifdef CONFIG_PM +static int mtu3d_suspend_noirq(struct device *dev) +{ + os_printk(K_INFO, "%s\n", __func__); + + /*J:I think it does _NOT_ have to do PHY savecurrent. Because when the phone with USB cable, + * the system does _NOT_ enter suspend mode. At the normal case, the USB driver calls PHY savecurrent, + * when USB cable is plugged out. + */ + /*usb_phy_savecurrent(); */ + + /* + * SSUSB IP Software Reset - When this bit is set, whole SSUSB IP is reset. + * All MAC regs(DEV, EPCTL CSR, USB3 MAC/SYS CSR, USB2 CSR can _NOT_ be read/written when this bit is set.) + * Setting this bit when suspend is to improve USB current leakage problem of AVDD18_USB_P0. + * After clearing this bit, the whole MAC registers would reset to the default value. + */ + /* os_setmsk(U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); */ + + return 0; +} + +static int mtu3d_resume_noirq(struct device *dev) +{ + os_printk(K_INFO, "%s\n", __func__); + + /* disable ip power down, disable U2/U3 ip power down */ + /* _ex_mu3d_hal_ssusb_en(); */ + + /* reset U3D all dev module. */ + /* mu3d_hal_rst_dev(); */ + + /*J:I think it does _NOT_ have to do PHY savecurrent. Because after USB cable is plugged in, + * the USB driver calls PHY recovery. So does _NOT_ have to do PHY recovery at this moment.*/ + /* usb_phy_recover(); */ + + return 0; +} + +static const struct dev_pm_ops mtu3d_pm_ops = { + .suspend_noirq = mtu3d_suspend_noirq, + .resume_noirq = mtu3d_resume_noirq, +}; + +#define DEV_PM_OPS (&mtu3d_pm_ops) +#else +#define DEV_PM_OPS NULL +#endif + +static struct platform_driver mtu3d_driver = { + .probe = mtu3d_probe, + .remove = mtu3d_remove, + .driver = { + .name = "musb-mtu3d", + .owner = THIS_MODULE, + .pm = DEV_PM_OPS, + .of_match_table = of_match_ptr(mtu3d_of_match), + }, +}; + +MODULE_DESCRIPTION("mtu3d MUSB Glue Layer"); +MODULE_AUTHOR("MediaTek"); +MODULE_LICENSE("GPL v2"); +module_platform_driver(mtu3d_driver); diff --git a/drivers/misc/mediatek/mu3d/drv/musb_io.h b/drivers/misc/mediatek/mu3d/drv/musb_io.h new file mode 100644 index 000000000000..4fb47b1e4c9d --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_io.h @@ -0,0 +1,183 @@ +/* + * MUSB OTG driver register I/O + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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. + * + */ + +#ifndef __MUSB_LINUX_PLATFORM_ARCH_H__ +#define __MUSB_LINUX_PLATFORM_ARCH_H__ + +#include <linux/io.h> + +#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ + && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \ + && !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) +static inline void readsl(const void __iomem *addr, void *buf, int len) +{ + insl((unsigned long)addr, buf, len); +} + +static inline void readsw(const void __iomem *addr, void *buf, int len) +{ + insw((unsigned long)addr, buf, len); +} + +static inline void readsb(const void __iomem *addr, void *buf, int len) +{ + insb((unsigned long)addr, buf, len); +} + +static inline void writesl(const void __iomem *addr, const void *buf, int len) +{ + outsl((unsigned long)addr, buf, len); +} + +static inline void writesw(const void __iomem *addr, const void *buf, int len) +{ + outsw((unsigned long)addr, buf, len); +} + +static inline void writesb(const void __iomem *addr, const void *buf, int len) +{ + outsb((unsigned long)addr, buf, len); +} + +#endif + +#ifndef CONFIG_BLACKFIN + +/* NOTE: these offsets are all in bytes */ + +static inline u16 musb_readw(const void __iomem *addr, unsigned offset) +{ + return __raw_readw(addr + offset); +} + +static inline u32 musb_readl(const void __iomem *addr, unsigned offset) +{ + return __raw_readl(addr + offset); +} + + +static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data) +{ + __raw_writew(data, addr + offset); +} + +static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) +{ + __raw_writel(data, addr + offset); +} + + +#ifdef CONFIG_USB_MUSB_TUSB6010 + +/* + * TUSB6010 doesn't allow 8-bit access; 16-bit access is the minimum. + */ +static inline u8 musb_readb(const void __iomem *addr, unsigned offset) +{ + u16 tmp; + u8 val; + + tmp = __raw_readw(addr + (offset & ~1)); + if (offset & 1) + val = (tmp >> 8); + else + val = tmp & 0xff; + + return val; +} + +static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) +{ + u16 tmp; + + tmp = __raw_readw(addr + (offset & ~1)); + if (offset & 1) + tmp = (data << 8) | (tmp & 0xff); + else + tmp = (tmp & 0xff00) | data; + + __raw_writew(tmp, addr + (offset & ~1)); +} + +#else + +static inline u8 musb_readb(const void __iomem *addr, unsigned offset) +{ + return __raw_readb(addr + offset); +} + +static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) +{ + __raw_writeb(data, addr + offset); +} + +#endif /* CONFIG_USB_MUSB_TUSB6010 */ + +#else + +static inline u8 musb_readb(const void __iomem *addr, unsigned offset) +{ + return (u8) (bfin_read16(addr + offset)); +} + +static inline u16 musb_readw(const void __iomem *addr, unsigned offset) +{ + return bfin_read16(addr + offset); +} + +static inline u32 musb_readl(const void __iomem *addr, unsigned offset) +{ + return (u32) (bfin_read16(addr + offset)); +} + +static inline void musb_writeb(void __iomem *addr, unsigned offset, u8 data) +{ + bfin_write16(addr + offset, (u16) data); +} + +static inline void musb_writew(void __iomem *addr, unsigned offset, u16 data) +{ + bfin_write16(addr + offset, data); +} + +static inline void musb_writel(void __iomem *addr, unsigned offset, u32 data) +{ + bfin_write16(addr + offset, (u16) data); +} + +#endif /* CONFIG_BLACKFIN */ + + + +#endif diff --git a/drivers/misc/mediatek/mu3d/drv/musb_regs.h b/drivers/misc/mediatek/mu3d/drv/musb_regs.h new file mode 100644 index 000000000000..ae9300df4f16 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/musb_regs.h @@ -0,0 +1,503 @@ +/* + * MUSB OTG driver register defines + * + * Copyright 2005 Mentor Graphics Corporation + * Copyright (C) 2005-2006 by Texas Instruments + * Copyright (C) 2006-2007 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + * THIS SOFTWARE IS PROVIDED "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 AUTHORS 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. + * + */ + +#ifndef __MUSB_REGS_H__ +#define __MUSB_REGS_H__ + +#define MUSB_EP0_FIFOSIZE 64 /* This is non-configurable */ + +/* + * MUSB Register bits + */ + +/* CODA PORTING */ + +/* DEVCTL */ +#define MUSB_DEVCTL_BDEVICE 0x80 +#define MUSB_DEVCTL_FSDEV 0x40 +#define MUSB_DEVCTL_LSDEV 0x20 +#define MUSB_DEVCTL_VBUS 0x18 +#define MUSB_DEVCTL_VBUS_SHIFT 3 +#define MUSB_DEVCTL_HM 0x04 +#define MUSB_DEVCTL_HR 0x02 +#define MUSB_DEVCTL_SESSION 0x01 + +/* MUSB ULPI VBUSCONTROL */ +#define MUSB_ULPI_USE_EXTVBUS 0x01 +#define MUSB_ULPI_USE_EXTVBUSIND 0x02 +/* ULPI_REG_CONTROL */ +#define MUSB_ULPI_REG_REQ (1 << 0) +#define MUSB_ULPI_REG_CMPLT (1 << 1) +#define MUSB_ULPI_RDN_WR (1 << 2) + +/* Allocate for double-packet buffering (effectively doubles assigned _SIZE) */ +#define MUSB_FIFOSZ_DPB 0x10 +/* Allocation size (8, 16, 32, ... 4096) */ +#define MUSB_FIFOSZ_SIZE 0x0f + +/* CSR0 in Peripheral mode */ +#define MUSB_CSR0_P_DATAEND 0x0008 + +/* TxType/RxType */ +#define MUSB_TYPE_SPEED 0xc0 +#define MUSB_TYPE_SPEED_SHIFT 6 +#define MUSB_TYPE_PROTO 0x30 /* Implicitly zero for ep0 */ +#define MUSB_TYPE_PROTO_SHIFT 4 +#define MUSB_TYPE_REMOTE_END 0xf /* Implicitly zero for ep0 */ + +/* CONFIGDATA */ +#define MUSB_CONFIGDATA_MPRXE 0x80 /* Auto bulk pkt combining */ +#define MUSB_CONFIGDATA_MPTXE 0x40 /* Auto bulk pkt splitting */ +#define MUSB_CONFIGDATA_BIGENDIAN 0x20 +#define MUSB_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */ +#define MUSB_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */ +#define MUSB_CONFIGDATA_DYNFIFO 0x04 /* Dynamic FIFO sizing */ +#define MUSB_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */ +#define MUSB_CONFIGDATA_UTMIDW 0x01 /* Data width 0/1 => 8/16bits */ + + +#ifndef CONFIG_BLACKFIN + +/* + * Common USB registers + */ + +#define MUSB_FADDR 0x00 /* 8-bit */ +#define MUSB_POWER 0x01 /* 8-bit */ + +#define MUSB_INTRTX 0x02 /* 16-bit */ +#define MUSB_INTRRX 0x04 +#define MUSB_INTRTXE 0x06 +#define MUSB_INTRRXE 0x08 +#define MUSB_INTRUSB 0x0A /* 8 bit */ +#define MUSB_INTRUSBE 0x0B /* 8 bit */ +#define MUSB_FRAME 0x0C +#define MUSB_INDEX 0x0E /* 8 bit */ +#define MUSB_TESTMODE 0x0F /* 8 bit */ + +/* Get offset for a given FIFO from musb->mregs */ +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) +#define MUSB_FIFO_OFFSET(epnum) (0x200 + ((epnum) * 0x20)) +#else +#define MUSB_FIFO_OFFSET(epnum) (U3D_FIFO0 + ((epnum) * 0x10)) +#endif + +/* + * Additional Control Registers + */ + +#define MUSB_DEVCTL 0x60 /* 8 bit */ + +/* These are always controlled through the INDEX register */ +#define MUSB_TXFIFOSZ 0x62 /* 8-bit (see masks) */ +#define MUSB_RXFIFOSZ 0x63 /* 8-bit (see masks) */ +#define MUSB_TXFIFOADD 0x64 /* 16-bit offset shifted right 3 */ +#define MUSB_RXFIFOADD 0x66 /* 16-bit offset shifted right 3 */ + +/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */ +#define MUSB_HWVERS 0x6C /* 8 bit */ +#define MUSB_ULPI_BUSCONTROL 0x70 /* 8 bit */ +#define MUSB_ULPI_INT_MASK 0x72 /* 8 bit */ +#define MUSB_ULPI_INT_SRC 0x73 /* 8 bit */ +#define MUSB_ULPI_REG_DATA 0x74 /* 8 bit */ +#define MUSB_ULPI_REG_ADDR 0x75 /* 8 bit */ +#define MUSB_ULPI_REG_CONTROL 0x76 /* 8 bit */ +#define MUSB_ULPI_RAW_DATA 0x77 /* 8 bit */ + +#define MUSB_EPINFO 0x78 /* 8 bit */ +#define MUSB_RAMINFO 0x79 /* 8 bit */ +#define MUSB_LINKINFO 0x7a /* 8 bit */ +#define MUSB_VPLEN 0x7b /* 8 bit */ +#define MUSB_HS_EOF1 0x7c /* 8 bit */ +#define MUSB_FS_EOF1 0x7d /* 8 bit */ +#define MUSB_LS_EOF1 0x7e /* 8 bit */ + +/* Offsets to endpoint registers */ +#define MUSB_TXMAXP 0x00 +#define MUSB_TXCSR 0x02 +#define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ +#define MUSB_RXMAXP 0x04 +#define MUSB_RXCSR 0x06 +#define MUSB_RXCOUNT 0x08 +#define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ +#define MUSB_TXTYPE 0x0A +#define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ +#define MUSB_TXINTERVAL 0x0B +#define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ +#define MUSB_RXTYPE 0x0C +#define MUSB_RXINTERVAL 0x0D +#define MUSB_FIFOSIZE 0x0F +#define MUSB_CONFIGDATA MUSB_FIFOSIZE /* Re-used for EP0 */ + +/* Offsets to endpoint registers in indexed model (using INDEX register) */ +#define MUSB_INDEXED_OFFSET(_epnum, _offset) \ + (0x10 + (_offset)) + +/* Offsets to endpoint registers in flat models */ +#define MUSB_FLAT_OFFSET(_epnum, _offset) \ + (0x100 + (0x10*(_epnum)) + (_offset)) + +#if defined(CONFIG_USB_MUSB_TUSB6010) || \ + defined(CONFIG_USB_MUSB_TUSB6010_MODULE) +/* TUSB6010 EP0 configuration register is special */ +#define MUSB_TUSB_OFFSET(_epnum, _offset) \ + (0x10 + _offset) +#include "tusb6010.h" /* Needed "only" for TUSB_EP0_CONF */ +#endif + +#define MUSB_TXCSR_MODE 0x2000 + +/* "bus control"/target registers, for host side multipoint (external hubs) */ +#define MUSB_TXFUNCADDR 0x00 +#define MUSB_TXHUBADDR 0x02 +#define MUSB_TXHUBPORT 0x03 + +#define MUSB_RXFUNCADDR 0x04 +#define MUSB_RXHUBADDR 0x06 +#define MUSB_RXHUBPORT 0x07 + +#define MUSB_BUSCTL_OFFSET(_epnum, _offset) \ + (0x80 + (8*(_epnum)) + (_offset)) + +static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) +{ + musb_writeb(mbase, MUSB_TXFIFOSZ, c_size); +} + +static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off) +{ + musb_writew(mbase, MUSB_TXFIFOADD, c_off); +} + +static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size) +{ + musb_writeb(mbase, MUSB_RXFIFOSZ, c_size); +} + +static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) +{ + musb_writew(mbase, MUSB_RXFIFOADD, c_off); +} + +static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) +{ + musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val); +} + +static inline u8 musb_read_txfifosz(void __iomem *mbase) +{ + return musb_readb(mbase, MUSB_TXFIFOSZ); +} + +static inline u16 musb_read_txfifoadd(void __iomem *mbase) +{ + return musb_readw(mbase, MUSB_TXFIFOADD); +} + +static inline u8 musb_read_rxfifosz(void __iomem *mbase) +{ + return musb_readb(mbase, MUSB_RXFIFOSZ); +} + +static inline u16 musb_read_rxfifoadd(void __iomem *mbase) +{ + return musb_readw(mbase, MUSB_RXFIFOADD); +} + +static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) +{ + return musb_readb(mbase, MUSB_ULPI_BUSCONTROL); +} + +static inline u8 musb_read_configdata(void __iomem *mbase) +{ + musb_writeb(mbase, MUSB_INDEX, 0); + return musb_readb(mbase, 0x10 + MUSB_CONFIGDATA); +} + +static inline u16 musb_read_hwvers(void __iomem *mbase) +{ + return musb_readw(mbase, MUSB_HWVERS); +} + +static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) +{ + return MUSB_BUSCTL_OFFSET(i, 0) + mbase; +} + +static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, u8 qh_addr_reg) +{ + musb_writeb(ep_target_regs, MUSB_RXFUNCADDR, qh_addr_reg); +} + +static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, u8 qh_h_addr_reg) +{ + musb_writeb(ep_target_regs, MUSB_RXHUBADDR, qh_h_addr_reg); +} + +static inline void musb_write_rxhubport(void __iomem *ep_target_regs, u8 qh_h_port_reg) +{ + musb_writeb(ep_target_regs, MUSB_RXHUBPORT, qh_h_port_reg); +} + +static inline void musb_write_txfunaddr(void __iomem *mbase, u8 epnum, u8 qh_addr_reg) +{ + musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR), qh_addr_reg); +} + +static inline void musb_write_txhubaddr(void __iomem *mbase, u8 epnum, u8 qh_addr_reg) +{ + musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR), qh_addr_reg); +} + +static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, u8 qh_h_port_reg) +{ + musb_writeb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT), qh_h_port_reg); +} + +static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) +{ + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXFUNCADDR)); +} + +static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) +{ + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBADDR)); +} + +static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) +{ + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_RXHUBPORT)); +} + +static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) +{ + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXFUNCADDR)); +} + +static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) +{ + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBADDR)); +} + +static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) +{ + return musb_readb(mbase, MUSB_BUSCTL_OFFSET(epnum, MUSB_TXHUBPORT)); +} + +#else /* CONFIG_BLACKFIN */ + +#define USB_BASE USB_FADDR +#define USB_OFFSET(reg) (reg - USB_BASE) + +/* + * Common USB registers + */ +#define MUSB_FADDR USB_OFFSET(USB_FADDR) /* 8-bit */ +#define MUSB_POWER USB_OFFSET(USB_POWER) /* 8-bit */ +#define MUSB_INTRTX USB_OFFSET(USB_INTRTX) /* 16-bit */ +#define MUSB_INTRRX USB_OFFSET(USB_INTRRX) +#define MUSB_INTRTXE USB_OFFSET(USB_INTRTXE) +#define MUSB_INTRRXE USB_OFFSET(USB_INTRRXE) +#define MUSB_INTRUSB USB_OFFSET(USB_INTRUSB) /* 8 bit */ +#define MUSB_INTRUSBE USB_OFFSET(USB_INTRUSBE) /* 8 bit */ +#define MUSB_FRAME USB_OFFSET(USB_FRAME) +#define MUSB_INDEX USB_OFFSET(USB_INDEX) /* 8 bit */ +#define MUSB_TESTMODE USB_OFFSET(USB_TESTMODE) /* 8 bit */ + +/* Get offset for a given FIFO from musb->mregs */ +#define MUSB_FIFO_OFFSET(epnum) \ + (USB_OFFSET(USB_EP0_FIFO) + ((epnum) * 8)) + +/* + * Additional Control Registers + */ + +#define MUSB_DEVCTL USB_OFFSET(USB_OTG_DEV_CTL) /* 8 bit */ + +#define MUSB_LINKINFO USB_OFFSET(USB_LINKINFO) /* 8 bit */ +#define MUSB_VPLEN USB_OFFSET(USB_VPLEN) /* 8 bit */ +#define MUSB_HS_EOF1 USB_OFFSET(USB_HS_EOF1) /* 8 bit */ +#define MUSB_FS_EOF1 USB_OFFSET(USB_FS_EOF1) /* 8 bit */ +#define MUSB_LS_EOF1 USB_OFFSET(USB_LS_EOF1) /* 8 bit */ + +/* Offsets to endpoint registers */ +#define MUSB_TXMAXP 0x00 +#define MUSB_TXCSR 0x04 +#define MUSB_CSR0 MUSB_TXCSR /* Re-used for EP0 */ +#define MUSB_RXMAXP 0x08 +#define MUSB_RXCSR 0x0C +#define MUSB_RXCOUNT 0x10 +#define MUSB_COUNT0 MUSB_RXCOUNT /* Re-used for EP0 */ +#define MUSB_TXTYPE 0x14 +#define MUSB_TYPE0 MUSB_TXTYPE /* Re-used for EP0 */ +#define MUSB_TXINTERVAL 0x18 +#define MUSB_NAKLIMIT0 MUSB_TXINTERVAL /* Re-used for EP0 */ +#define MUSB_RXTYPE 0x1C +#define MUSB_RXINTERVAL 0x20 +#define MUSB_TXCOUNT 0x28 + +/* Offsets to endpoint registers in indexed model (using INDEX register) */ +#define MUSB_INDEXED_OFFSET(_epnum, _offset) \ + (0x40 + (_offset)) + +/* Offsets to endpoint registers in flat models */ +#define MUSB_FLAT_OFFSET(_epnum, _offset) \ + (USB_OFFSET(USB_EP_NI0_TXMAXP) + (0x40 * (_epnum)) + (_offset)) + +/* Not implemented - HW has separate Tx/Rx FIFO */ +#define MUSB_TXCSR_MODE 0x0000 + +static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) +{ +} + +static inline void musb_write_txfifoadd(void __iomem *mbase, u16 c_off) +{ +} + +static inline void musb_write_rxfifosz(void __iomem *mbase, u8 c_size) +{ +} + +static inline void musb_write_rxfifoadd(void __iomem *mbase, u16 c_off) +{ +} + +static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val) +{ +} + +static inline u8 musb_read_txfifosz(void __iomem *mbase) +{ + return 0; +} + +static inline u16 musb_read_txfifoadd(void __iomem *mbase) +{ + return 0; +} + +static inline u8 musb_read_rxfifosz(void __iomem *mbase) +{ + return 0; +} + +static inline u16 musb_read_rxfifoadd(void __iomem *mbase) +{ + return 0; +} + +static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) +{ + return 0; +} + +static inline u8 musb_read_configdata(void __iomem *mbase) +{ + return 0; +} + +static inline u16 musb_read_hwvers(void __iomem *mbase) +{ + /* + * This register is invisible on Blackfin, actually the MUSB + * RTL version of Blackfin is 1.9, so just harcode its value. + */ + return MUSB_HWVERS_1900; +} + +static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase) +{ + return NULL; +} + +static inline void musb_write_rxfunaddr(void __iomem *ep_target_regs, u8 qh_addr_req) +{ +} + +static inline void musb_write_rxhubaddr(void __iomem *ep_target_regs, u8 qh_h_addr_reg) +{ +} + +static inline void musb_write_rxhubport(void __iomem *ep_target_regs, u8 qh_h_port_reg) +{ +} + +static inline void musb_write_txfunaddr(void __iomem *mbase, u8 epnum, u8 qh_addr_reg) +{ +} + +static inline void musb_write_txhubaddr(void __iomem *mbase, u8 epnum, u8 qh_addr_reg) +{ +} + +static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum, u8 qh_h_port_reg) +{ +} + +static inline u8 musb_read_rxfunaddr(void __iomem *mbase, u8 epnum) +{ + return 0; +} + +static inline u8 musb_read_rxhubaddr(void __iomem *mbase, u8 epnum) +{ + return 0; +} + +static inline u8 musb_read_rxhubport(void __iomem *mbase, u8 epnum) +{ + return 0; +} + +static inline u8 musb_read_txfunaddr(void __iomem *mbase, u8 epnum) +{ + return 0; +} + +static inline u8 musb_read_txhubaddr(void __iomem *mbase, u8 epnum) +{ + return 0; +} + +static inline u8 musb_read_txhubport(void __iomem *mbase, u8 epnum) +{ + return 0; +} + +#endif /* CONFIG_BLACKFIN */ + +#endif /* __MUSB_REGS_H__ */ diff --git a/drivers/misc/mediatek/mu3d/drv/ssusb_qmu.c b/drivers/misc/mediatek/mu3d/drv/ssusb_qmu.c new file mode 100644 index 000000000000..714fe2811929 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/ssusb_qmu.c @@ -0,0 +1,526 @@ +#ifdef USE_SSUSB_QMU +#include <linux/spinlock.h> +#include <linux/dma-mapping.h> + +#include "musb_core.h" +#include "mu3d_hal_osal.h" +#include "mu3d_hal_qmu_drv.h" +#include "mu3d_hal_hw.h" +#include "ssusb_qmu.h" + +/* Sanity CR check in */ +/* + 1. Find the last gpd HW has executed and update Tx_gpd_last[] + 2. Set the flag for txstate to know that TX has been completed + + ported from proc_qmu_tx() from test driver. + + caller:qmu_interrupt after getting QMU done interrupt and TX is raised + +*/ +void qmu_done_tx(struct musb *musb, u8 ep_num, unsigned long flags) +{ + TGPD *gpd = Tx_gpd_last[ep_num]; + /* QMU GPD address --> CPU DMA address */ + TGPD *gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_TQCPR(ep_num))); + struct musb_ep *musb_ep = &musb->endpoints[ep_num].ep_in; + struct usb_request *request = NULL; + struct musb_request *req = NULL; + + /*Transfer PHY addr got from QMU register to VIR addr */ + gpd_current = gpd_phys_to_virt((void *)gpd_current, USB_TX, ep_num); + + /* + gpd or Last gdp_current + | | + |-> GPD1 --> GPD2 --> GPD3 --> GPD4 --> GPD5 -| + |----------------------------------------------| + */ + + qmu_printk(K_DEBUG, "[TXD]" "%s EP%d, Last=%p, Current=%p, End=%p\n", + __func__, ep_num, gpd, gpd_current, Tx_gpd_end[ep_num]); + + /*gpd_current should at least point to the next GPD to the previous last one. */ + if (gpd == gpd_current) { + qmu_printk(K_ERR, "[TXD]" "%s gpd(%p) == gpd_current(%p)\n", __func__, gpd, + gpd_current); + return; + } + + if (TGPD_IS_FLAGS_HWO(gpd)) { + qmu_printk(K_DEBUG, "[TXD]" "%s HWO=1, CPR=%x\n", __func__, + os_readl(USB_QMU_TQCPR(ep_num))); + BUG_ON(1); + } + + while (gpd != gpd_current && !TGPD_IS_FLAGS_HWO(gpd)) { + + qmu_printk(K_DEBUG, + "[TXD]" "gpd=%p ->HWO=%d, BPD=%d, Next_GPD=%lx, DataBuffer=%lx,BufferLen=%d request=%p\n", + gpd, (u32) TGPD_GET_FLAG(gpd), + (u32) TGPD_GET_FORMAT(gpd), (uintptr_t) TGPD_GET_NEXT(gpd), + (uintptr_t) TGPD_GET_DATA(gpd), (u32) TGPD_GET_BUF_LEN(gpd), req); + + if (!TGPD_GET_NEXT(gpd)) { + qmu_printk(K_ERR, "[TXD][ERROR]" "Next GPD is null!!\n"); + /* BUG_ON(1); */ + break; + } + + gpd = TGPD_GET_NEXT(gpd); + + gpd = gpd_phys_to_virt(gpd, USB_TX, ep_num); + + /* trying to give_back the request to gadget driver. */ + req = next_request(musb_ep); + if (!req) { + qmu_printk(K_INFO, "[TXD]" "%s Cannot get next request of %d, but QMU has done.\n", + __func__, ep_num); + return; + } + + request = &req->request; + + Tx_gpd_last[ep_num] = gpd; + musb_g_giveback(musb_ep, request, 0); + req = next_request(musb_ep); + if (req != NULL) + request = &req->request; + } + + if (gpd != gpd_current && TGPD_IS_FLAGS_HWO(gpd)) { + qmu_printk(K_ERR, "[TXD][ERROR]" "EP%d TQCSR=%x, TQSAR=%x, TQCPR=%x\n", + ep_num, os_readl(USB_QMU_TQCSR(ep_num)), os_readl(USB_QMU_TQSAR(ep_num)), + os_readl(USB_QMU_TQCPR(ep_num))); + + qmu_printk(K_ERR, "[TXD][ERROR]" "QCR0=%x, QCR1=%x, QCR2=%x, QCR3=%x, QGCSR=%x\n", + os_readl(U3D_QCR0), os_readl(U3D_QCR1), os_readl(U3D_QCR2), + os_readl(U3D_QCR3), os_readl(U3D_QGCSR)); + + qmu_printk(K_ERR, "[TXD][ERROR]" "HWO=%d, BPD=%d, Next_GPD=%lx\n", + (u32) TGPD_GET_FLAG(gpd), + (u32) TGPD_GET_FORMAT(gpd), (uintptr_t) TGPD_GET_NEXT(gpd)); + + qmu_printk(K_ERR, "[TXD][ERROR]" "DataBuffer=%lx, BufferLen=%d, Endpoint=%d\n", + (uintptr_t) TGPD_GET_DATA(gpd), (u32) TGPD_GET_BUF_LEN(gpd), + (u32) TGPD_GET_EPaddr(gpd)); + } + + qmu_printk(K_DEBUG, "[TXD]" "%s EP%d, Last=%p, End=%p, complete\n", __func__, + ep_num, Tx_gpd_last[ep_num], Tx_gpd_end[ep_num]); + + if (req != NULL) { + if (request->length == 0) { + u32 val = 0; + + qmu_printk(K_DEBUG, "[TXD]" "==Send ZLP== %p\n", req); + + if (wait_for_value_us + (USB_END_OFFSET(req->epnum, U3D_TX1CSR0), TX_FIFOEMPTY, TX_FIFOEMPTY, 1, + 10) == RET_SUCCESS) + qmu_printk(K_DEBUG, "Tx[%d] 0x%x\n", req->epnum, + USB_ReadCsr32(U3D_TX1CSR0, req->epnum)); + else { + qmu_printk(K_CRIT, "Tx[%d] NOT FIFOEMPTY 0x%x\n", req->epnum, + USB_ReadCsr32(U3D_TX1CSR0, req->epnum)); + return; + } + + /*Disable Tx_DMAREQEN */ + val = USB_ReadCsr32(U3D_TX1CSR0, req->epnum) & ~TX_DMAREQEN; + + mb(); + + USB_WriteCsr32(U3D_TX1CSR0, req->epnum, val); + + val = USB_ReadCsr32(U3D_TX1CSR0, req->epnum) | TX_TXPKTRDY; + + mb(); + + USB_WriteCsr32(U3D_TX1CSR0, req->epnum, val); + + qmu_printk(K_DEBUG, + "[TXD]" "Giveback ZLP of EP%d, actual:%d, length:%d %p\n", + req->epnum, request->actual, request->length, request); + + musb_g_giveback(musb_ep, request, 0); + } + } +} + +/* + When receiving RXQ done interrupt, qmu_interrupt calls this function. + + 1. Traverse GPD/BD data structures to count actual transferred length. + 2. Set the done flag to notify rxstate_qmu() to report status to upper gadget driver. + + ported from proc_qmu_rx() from test driver. + + caller:qmu_interrupt after getting QMU done interrupt and TX is raised + +*/ +void qmu_done_rx(struct musb *musb, u8 ep_num, unsigned long flags) +{ + TGPD *gpd = Rx_gpd_last[ep_num]; + /* QMU GPD address --> CPU DMA address */ + TGPD *gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_RQCPR(ep_num))); + struct musb_ep *musb_ep = &musb->endpoints[ep_num].ep_out; + struct usb_request *request = NULL; + struct musb_request *req; + + /* trying to give_back the request to gadget driver. */ + req = next_request(musb_ep); + if (!req) { + qmu_printk(K_ERR, "[RXD]" "%s Cannot get next request of %d, but QMU has done.\n", + __func__, ep_num); + return; + } + + request = &req->request; + + /*Transfer PHY addr got from QMU register to VIR addr */ + gpd_current = gpd_phys_to_virt(gpd_current, USB_RX, ep_num); + + qmu_printk(K_DEBUG, "[RXD]" "%s EP%d, Last=%p, Current=%p, End=%p\n", + __func__, ep_num, gpd, gpd_current, Rx_gpd_end[ep_num]); + + /*gpd_current should at least point to the next GPD to the previous last one. */ + if (gpd == gpd_current) { + qmu_printk(K_ERR, "[RXD][ERROR]" "%s gpd(%p) == gpd_current(%p)\n", __func__, gpd, + gpd_current); + + qmu_printk(K_ERR, "[RXD][ERROR] EP%d RQCSR=%x, RQSAR=%x, RQCPR=%x, RQLDPR=%x\n", + ep_num, os_readl(USB_QMU_RQCSR(ep_num)), os_readl(USB_QMU_RQSAR(ep_num)), + os_readl(USB_QMU_RQCPR(ep_num)), os_readl(USB_QMU_RQLDPR(ep_num))); + + qmu_printk(K_ERR, "[RXD][ERROR] QCR0=%x, QCR1=%x, QCR2=%x, QCR3=%x, QGCSR=%x\n", + os_readl(U3D_QCR0), os_readl(U3D_QCR1), os_readl(U3D_QCR2), + os_readl(U3D_QCR3), os_readl(U3D_QGCSR)); + + qmu_printk(K_INFO, "[RXD][ERROR] HWO=%d, Next_GPD=%lx ,DataBufLen=%d, DataBuf=%lx\n", + (u32) TGPD_GET_FLAG(gpd), (uintptr_t) TGPD_GET_NEXT(gpd), + (u32) TGPD_GET_DataBUF_LEN(gpd), (uintptr_t) TGPD_GET_DATA(gpd)); + + qmu_printk(K_INFO, "[RXD][ERROR] RecvLen=%d, Endpoint=%d\n", + (u32) TGPD_GET_BUF_LEN(gpd), (u32) TGPD_GET_EPaddr(gpd)); + + return; + } + + if (!gpd || !gpd_current) { + qmu_printk(K_ERR, + "[RXD][ERROR]" "%s EP%d, gpd=%p, gpd_current=%p, ishwo=%d, rx_gpd_last=%p, RQCPR=0x%x\n", + __func__, ep_num, gpd, gpd_current, + ((gpd == NULL) ? 999 : TGPD_IS_FLAGS_HWO(gpd)), + Rx_gpd_last[ep_num], + os_readl(USB_QMU_RQCPR(ep_num))); + return; + } + + if (TGPD_IS_FLAGS_HWO(gpd)) { + qmu_printk(K_ERR, "[RXD][ERROR]" "HWO=1!!\n"); + BUG_ON(1); + } + + while (gpd != gpd_current && !TGPD_IS_FLAGS_HWO(gpd)) { + DEV_UINT32 rcv_len = (DEV_UINT32) TGPD_GET_BUF_LEN(gpd); + DEV_UINT32 buf_len = (DEV_UINT32) TGPD_GET_DataBUF_LEN(gpd); + + if (rcv_len > buf_len) + qmu_printk(K_ERR, "[RXD][ERROR]" "%s rcv(%d) > buf(%d) AUK!?\n", __func__, + rcv_len, buf_len); + + qmu_printk(K_DEBUG, + "[RXD]" "gpd=%p ->HWO=%d, Next_GPD=%p, RcvLen=%d, BufLen=%d, pBuf=%p\n", + gpd, TGPD_GET_FLAG(gpd), TGPD_GET_NEXT(gpd), rcv_len, buf_len, + TGPD_GET_DATA(gpd)); + + request->actual += rcv_len; + + if (!TGPD_GET_NEXT(gpd) || !TGPD_GET_DATA(gpd)) { + qmu_printk(K_ERR, "[RXD][ERROR]" "%s EP%d ,gpd=%p\n", __func__, ep_num, + gpd); + BUG_ON(1); + } + + gpd = TGPD_GET_NEXT(gpd); + + gpd = gpd_phys_to_virt(gpd, USB_RX, ep_num); + + if (!gpd) { + qmu_printk(K_ERR, "[RXD][ERROR]" "%s EP%d ,gpd=%p\n", __func__, ep_num, + gpd); + BUG_ON(1); + } + + Rx_gpd_last[ep_num] = gpd; + musb_g_giveback(musb_ep, request, 0); + req = next_request(musb_ep); + request = &req->request; + } + + if (gpd != gpd_current && TGPD_IS_FLAGS_HWO(gpd)) { + qmu_printk(K_ERR, "[RXD][ERROR]" "gpd=%p\n", gpd); + + qmu_printk(K_ERR, "[RXD][ERROR]" "EP%d RQCSR=%x, RQSAR=%x, RQCPR=%x, RQLDPR=%x\n", + ep_num, os_readl(USB_QMU_RQCSR(ep_num)), os_readl(USB_QMU_RQSAR(ep_num)), + os_readl(USB_QMU_RQCPR(ep_num)), os_readl(USB_QMU_RQLDPR(ep_num))); + + qmu_printk(K_ERR, "[RXD][ERROR]" "QCR0=%x, QCR1=%x, QCR2=%x, QCR3=%x, QGCSR=%x\n", + os_readl(U3D_QCR0), os_readl(U3D_QCR1), os_readl(U3D_QCR2), + os_readl(U3D_QCR3), os_readl(U3D_QGCSR)); + + qmu_printk(K_INFO, "[RXD][ERROR] HWO=%d, Next_GPD=%lx ,DataBufLen=%d, DataBuf=%lx\n", + (u32) TGPD_GET_FLAG(gpd), (uintptr_t) TGPD_GET_NEXT(gpd), + (u32) TGPD_GET_DataBUF_LEN(gpd), (uintptr_t) TGPD_GET_DATA(gpd)); + + qmu_printk(K_INFO, "[RXD][ERROR] RecvLen=%d, Endpoint=%d\n", + (u32) TGPD_GET_BUF_LEN(gpd), (u32) TGPD_GET_EPaddr(gpd)); + } + + qmu_printk(K_DEBUG, "[RXD]" "%s EP%d, Last=%p, End=%p, complete\n", __func__, + ep_num, Rx_gpd_last[ep_num], Rx_gpd_end[ep_num]); +} + +void qmu_done_tasklet(unsigned long data) +{ + unsigned int qmu_val; + unsigned int i; + unsigned long flags; + struct musb *musb = (struct musb *)data; + + spin_lock_irqsave(&musb->lock, flags); + + qmu_val = musb->qmu_done_intr; + + musb->qmu_done_intr = 0; + + for (i = 1; i <= MAX_QMU_EP; i++) { + if (qmu_val & QMU_RX_DONE(i)) + qmu_done_rx(musb, i, flags); + if (qmu_val & QMU_TX_DONE(i)) + qmu_done_tx(musb, i, flags); + } + spin_unlock_irqrestore(&musb->lock, flags); +} + +void qmu_error_recovery(unsigned long data) +{ +#ifdef USE_SSUSB_QMU + u8 ep_num; + USB_DIR dir; + unsigned long flags; + struct musb *musb = (struct musb *)data; + struct musb_ep *musb_ep; + struct musb_request *request; + bool is_len_err = false; + int i = 0; + + spin_lock_irqsave(&musb->lock, flags); + ep_num = 0; + if ((musb->error_wQmuVal & RXQ_CSERR_INT) || (musb->error_wQmuVal & RXQ_LENERR_INT)) { + dir = USB_RX; + for (i = 1; i <= MAX_QMU_EP; i++) { + if (musb->error_wErrVal & QMU_RX_CS_ERR(i)) { + qmu_printk(K_ERR, "mu3d_hal_resume_qmu Rx %d checksum error!\r\n", + i); + ep_num = i; + break; + } + + if (musb->error_wErrVal & QMU_RX_LEN_ERR(i)) { + qmu_printk(K_ERR, "mu3d_hal_resume_qmu RX EP%d Recv Length error\n", + i); + ep_num = i; + is_len_err = true; + break; + } + } + } else if ((musb->error_wQmuVal & TXQ_CSERR_INT) || (musb->error_wQmuVal & TXQ_LENERR_INT)) { + dir = USB_TX; + for (i = 1; i <= MAX_QMU_EP; i++) { + if (musb->error_wErrVal & QMU_TX_CS_ERR(i)) { + qmu_printk(K_ERR, "mu3d_hal_resume_qmu Tx %d checksum error!\r\n", + i); + ep_num = i; + break; + } + + if (musb->error_wErrVal & QMU_TX_LEN_ERR(i)) { + qmu_printk(K_ERR, "mu3d_hal_resume_qmu TX EP%d Recv Length error\n", + i); + ep_num = i; + is_len_err = true; + break; + } + } + } + + if (ep_num == 0) { + qmu_printk(K_ERR, "Error but ep_num == 0!\r\n"); + goto done; + } + + _ex_mu3d_hal_flush_qmu(ep_num, dir); + /* mu3d_hal_restart_qmu(ep_num, dir); */ + + if (dir == USB_TX) + musb_ep = &musb->endpoints[ep_num].ep_in; + else + musb_ep = &musb->endpoints[ep_num].ep_out; + + list_for_each_entry(request, &musb_ep->req_list, list) { + qmu_printk(K_ERR, "%s : request 0x%p length(0x%d)\n", __func__, request, + request->request.length); + + if (request->request.dma != DMA_ADDR_INVALID) { + if (request->tx) { + qmu_printk(K_ERR, "[TX]" "%s gpd=%p, epnum=%d, len=%d\n", __func__, + Tx_gpd_end[ep_num], ep_num, request->request.length); + request->request.actual = request->request.length; + if (request->request.length > 0) { + u32 txcsr; + + if (is_len_err == true) { + _ex_mu3d_hal_insert_transfer_gpd(request->epnum, + USB_TX, + request-> + request.dma, 4096, + true, true, false, + ((musb_ep->type == + USB_ENDPOINT_XFER_ISOC) + ? 0 : 1), + musb_ep-> + end_point.maxpacket); + } else { + _ex_mu3d_hal_insert_transfer_gpd(request->epnum, + USB_TX, + request-> + request.dma, + request-> + request.length, + true, true, false, + ((musb_ep->type == + USB_ENDPOINT_XFER_ISOC) + ? 0 : 1), + musb_ep-> + end_point.maxpacket); + } + + /*Enable Tx_DMAREQEN */ + txcsr = + USB_ReadCsr32(U3D_TX1CSR0, + request->epnum) | TX_DMAREQEN; + + mb(); + + USB_WriteCsr32(U3D_TX1CSR0, request->epnum, txcsr); + + } else if (request->request.length == 0) { + qmu_printk(K_DEBUG, "[TX]" "Send ZLP\n"); + } + } else { + qmu_printk(K_ERR, "[RX]" "%s, gpd=%p, epnum=%d, len=%d\n", + __func__, Rx_gpd_end[ep_num], ep_num, + request->request.length); + if (is_len_err == true) { + _ex_mu3d_hal_insert_transfer_gpd(request->epnum, USB_RX, + request->request.dma, 4096, + true, true, false, + (musb_ep->type == + USB_ENDPOINT_XFER_ISOC ? 0 + : 1), + musb_ep-> + end_point.maxpacket); + } else { + _ex_mu3d_hal_insert_transfer_gpd(request->epnum, USB_RX, + request->request.dma, + request->request.length, + true, true, false, + (musb_ep->type == + USB_ENDPOINT_XFER_ISOC ? 0 + : 1), + musb_ep-> + end_point.maxpacket); + } + } + } + } + + mu3d_hal_resume_qmu(ep_num, dir); +done: + spin_unlock_irqrestore(&musb->lock, flags); +#endif +} + +void qmu_exception_interrupt(struct musb *musb, DEV_UINT32 wQmuVal) +{ + u32 wErrVal; + int i = (int)wQmuVal; + + if (wQmuVal & RXQ_CSERR_INT) + qmu_printk(K_ERR, "==Rx %d checksum error==\n", i); + + if (wQmuVal & RXQ_LENERR_INT) + qmu_printk(K_ERR, "==Rx %d length error==\n", i); + + if (wQmuVal & TXQ_CSERR_INT) + qmu_printk(K_ERR, "==Tx %d checksum error==\n", i); + + if (wQmuVal & TXQ_LENERR_INT) + qmu_printk(K_ERR, "==Tx %d length error==\n", i); + + if ((wQmuVal & RXQ_CSERR_INT) || (wQmuVal & RXQ_LENERR_INT)) { + wErrVal = os_readl(U3D_RQERRIR0); + qmu_printk(K_DEBUG, "Rx Queue error in QMU mode![0x%x]\r\n", (unsigned int)wErrVal); + for (i = 1; i <= MAX_QMU_EP; i++) { + if (wErrVal & QMU_RX_CS_ERR(i)) + qmu_printk(K_ERR, "Rx %d checksum error!\r\n", i); + + if (wErrVal & QMU_RX_LEN_ERR(i)) + qmu_printk(K_ERR, "RX EP%d Recv Length error\n", i); + } + os_writel(U3D_RQERRIR0, wErrVal); + musb->error_wQmuVal = wQmuVal; + musb->error_wErrVal = wErrVal; + tasklet_schedule(&musb->error_recovery); + } + + if (wQmuVal & RXQ_ZLPERR_INT) { + wErrVal = os_readl(U3D_RQERRIR1); + qmu_printk(K_DEBUG, "Rx Queue error in QMU mode![0x%x]\r\n", (unsigned int)wErrVal); + for (i = 1; i <= MAX_QMU_EP; i++) { + if (wErrVal & QMU_RX_ZLP_ERR(i)) { + /*FIXME: should _NOT_ got this error. But now just accept. */ + qmu_printk(K_DEBUG, "RX EP%d Recv ZLP\n", i); + } + } + os_writel(U3D_RQERRIR1, wErrVal); + } + + if ((wQmuVal & TXQ_CSERR_INT) || (wQmuVal & TXQ_LENERR_INT)) { + wErrVal = os_readl(U3D_TQERRIR0); + qmu_printk(K_DEBUG, "Tx Queue error in QMU mode![0x%x]\r\n", (unsigned int)wErrVal); + for (i = 1; i <= MAX_QMU_EP; i++) { + if (wErrVal & QMU_TX_CS_ERR(i)) + qmu_printk(K_ERR, "Tx %d checksum error!\r\n", i); + + if (wErrVal & QMU_TX_LEN_ERR(i)) + qmu_printk(K_ERR, "Tx %d buffer length error!\r\n", i); + } + os_writel(U3D_TQERRIR0, wErrVal); + musb->error_wQmuVal = wQmuVal; + musb->error_wErrVal = wErrVal; + tasklet_schedule(&musb->error_recovery); + } + + if ((wQmuVal & RXQ_EMPTY_INT) || (wQmuVal & TXQ_EMPTY_INT)) { + DEV_UINT32 wEmptyVal = os_readl(U3D_QEMIR); + + qmu_printk(K_DEBUG, "%s Empty in QMU mode![0x%x]\r\n", + (wQmuVal & TXQ_EMPTY_INT) ? "TX" : "RX", wEmptyVal); + os_writel(U3D_QEMIR, wEmptyVal); + } +} + +#endif diff --git a/drivers/misc/mediatek/mu3d/drv/ssusb_qmu.h b/drivers/misc/mediatek/mu3d/drv/ssusb_qmu.h new file mode 100644 index 000000000000..063b1e047385 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/drv/ssusb_qmu.h @@ -0,0 +1,17 @@ +#ifndef __SSUSB_QMU_H__ +#define __SSUSB_QMU_H__ + +#include "mu3d_hal_qmu_drv.h" + +#ifdef USE_SSUSB_QMU + +#undef EXTERN +#define EXTERN + +/* Sanity CR check in */ +void qmu_done_tasklet(unsigned long data); +void qmu_error_recovery(unsigned long data); +void qmu_exception_interrupt(struct musb *musb, DEV_UINT32 wQmuVal); + +#endif +#endif diff --git a/drivers/misc/mediatek/mu3d/hal/Makefile b/drivers/misc/mediatek/mu3d/hal/Makefile new file mode 100644 index 000000000000..3b1450721bc3 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/Makefile @@ -0,0 +1,12 @@ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/mu3d/drv \ + -I$(srctree)/drivers/misc/mediatek/mu3d/hal \ + -I$(srctree)/drivers/misc/mediatek/mu3phy + +ccflags-y += -DUSE_SSUSB_QMU + +obj-y := mu3d_hal.o + +mu3d_hal-y := mu3d_hal_osal.o \ + mu3d_hal_qmu_drv.o \ + mu3d_hal_usb_drv.o \ + mu3d_hal_phy.o diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_comm.h b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_comm.h new file mode 100644 index 000000000000..fbc832f9b3bf --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_comm.h @@ -0,0 +1,189 @@ +#ifndef _DRV_COMM_H +#define _DRV_COMM_H +#include "mu3d_hal_hw.h" +#include <linux/io.h> + +#undef EXTERN + +#ifdef _DRV_COMM_H +#define EXTERN +#else +#define EXTERN \ +extern +#endif + + +/* CONSTANTS */ + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +/* TYPES */ + +typedef unsigned int DEV_UINT32; +typedef int DEV_INT32; +typedef unsigned short DEV_UINT16; +typedef short DEV_INT16; +typedef unsigned char DEV_UINT8; +typedef char DEV_INT8; + +typedef enum { + RET_SUCCESS = 0, + RET_FAIL, +} USB_RESULT; + +#ifdef NEVER +#define os_writeb(addr, data) {\ + (*((volatile DEV_UINT8*)(addr)) = (DEV_UINT8)data);\ + if (0) \ + pr_debug("****** os_writeb [0x%08x] = 0x%08x (%s#%d)\n", (unsigned int)addr, data, __func__, __LINE__);\ + } + +#define os_writew(addr, data) {\ + (*((volatile DEV_UINT16*)(addr)) = (DEV_UINT16)data);\ + if (0) \ + pr_debug("****** os_writew [0x%08x] = 0x%08x (%s#%d)\n", (unsigned int)addr, data, __func__, __LINE__);\ + } + +#define os_writel(addr, data) {\ + (*((volatile DEV_UINT32*)(addr)) = (DEV_UINT32)data);\ + if (0) \ + pr_debug("****** os_writel [0x%08x] = 0x%08x (%s#%d)\n", (unsigned int)addr, data, __func__, __LINE__);\ + } + +#define os_readl(addr) (*((volatile DEV_UINT32 *)(addr))) +#define os_writelmsk(addr, data, msk) \ + { os_writel(addr, ((os_readl(addr) & ~(msk)) | ((data) & (msk)))); \ + } +#define os_setmsk(addr, msk) \ + { os_writel(addr, os_readl(addr) | msk); \ + } +#define os_clrmsk(addr, msk) \ + { os_writel(addr, os_readl(addr) & ~msk); \ + } +/*msk the data first, then umsk with the umsk.*/ +#define os_writelmskumsk(addr, data, msk, umsk) \ +{\ + os_writel(addr, ((os_readl(addr) & ~(msk)) | ((data) & (msk))) & (umsk));\ +} + +#define USB_END_OFFSET(_bEnd, _bOffset) ((0x10*(_bEnd-1)) + _bOffset) +#define USB_ReadCsr32(_bOffset, _bEnd) os_readl(USB_END_OFFSET(_bEnd, _bOffset)) +#define USB_WriteCsr32(_bOffset, _bEnd, _bData) os_writel(USB_END_OFFSET(_bEnd, _bOffset), _bData) +#else +static inline void os_writeb(void __iomem *addr, unsigned char data) +{ + writeb(data, (void __iomem *)addr); + if (0) + pr_debug("%s writeb [%p] = 0x%08x\n", __func__, (void *)addr, data); +} + +static inline void os_writew(void __iomem *addr, unsigned short data) +{ + writew(data, (void __iomem *)addr); + if (0) + pr_debug("%s writew [%p] = 0x%08x\n", __func__, (void *)addr, data); +} + +static inline void os_writel(void __iomem *addr, unsigned int data) +{ + writel(data, (void __iomem *)addr); + if (0) + pr_debug("%s writel [%p] = 0x%08x\n", __func__, (void *)addr, data); +} + +#define os_readl(addr) readl((void __iomem *)((unsigned long)addr)) + +static inline void os_writelmsk(void __iomem *addr, unsigned int data, unsigned int msk) +{ + unsigned int tmp = readl((void __iomem *)addr); + + mb(); + writel(((tmp & ~(msk)) | ((data) & (msk))), (void __iomem *)addr); +} + +static inline void os_setmsk(void __iomem *addr, unsigned int msk) +{ + unsigned int tmp = readl((void __iomem *)addr); + + if (0) + pr_debug("%s setmsk [%p] = 0x%08x\n", __func__, (void *)addr, tmp); + mb(); + writel((tmp | msk), (void __iomem *)addr); + if (0) + pr_debug("%s setmsk [%p] = 0x%08x\n", __func__, (void *)addr, + readl((void __iomem *)addr)); +} + +static inline void os_clrmsk(void __iomem *addr, unsigned int msk) +{ + unsigned int tmp = readl((void __iomem *)addr); + + if (0) + pr_debug("%s clrmsk [%p] = 0x%08x\n", __func__, (void *)addr, tmp); + mb(); + writel((tmp & ~(msk)), (void __iomem *)addr); + if (0) + pr_debug("%s clrmsk [%p] = 0x%08x\n", __func__, (void *)addr, + readl((void __iomem *)addr)); +} + +/*msk the data first, then umsk with the umsk.*/ +static inline void os_writelmskumsk(void __iomem *addr, unsigned int data, + unsigned int msk, unsigned int umsk) +{ + unsigned int tmp = readl((void __iomem *)addr); + + mb(); + writel(((tmp & ~(msk)) | ((data) & (msk))) & (umsk), (void __iomem *)addr); +} + +static inline int wait_for_value(void __iomem *addr, unsigned int msk, + unsigned int value, unsigned int ms_intvl, unsigned int count) +{ + u32 i; + + for (i = 0; i < count; i++) { + if ((os_readl(addr) & msk) == value) + return RET_SUCCESS; + mb(); + mdelay(ms_intvl); + } + return RET_FAIL; +} + +static inline int wait_for_value_us(void __iomem *addr, unsigned int msk, + unsigned int value, unsigned int us_intvl, unsigned int count) +{ + u32 i; + + for (i = 0; i < count; i++) { + if ((os_readl(addr) & msk) == value) + return RET_SUCCESS; + mb(); + udelay(us_intvl); + } + return RET_FAIL; +} + +#define USB_END_OFFSET(_bEnd, _bOffset) ((0x10*(_bEnd-1)) + _bOffset) + +#define USB_ReadCsr32(_bOffset, _bEnd) \ + readl((void __iomem *)(uintptr_t)(USB_END_OFFSET(_bEnd, _bOffset))) + +#define USB_WriteCsr32(_bOffset, _bEnd, _bData) \ + do {\ + writel(_bData, (void __iomem *)(uintptr_t)(USB_END_OFFSET(_bEnd, _bOffset)));\ + mb();\ + } while (0) + +#endif + +#define div_and_rnd_up(x, y) (((x) + (y) - 1) / (y)) + +#endif /*_DRV_COMM_H*/ diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_hw.h b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_hw.h new file mode 100644 index 000000000000..9fa9dbeea414 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_hw.h @@ -0,0 +1,285 @@ +#ifndef USB_HW_H +#define USB_HW_H + +#include <linux/types.h> + +#define SW_VERSION "20130627" + +/* U3D configuration */ + +/*This define for DVT OTG testing*/ +#ifdef CONFIG_USBIF_COMPLIANCE +#define SUPPORT_OTG +#endif +/* This should be defined if superspeed is supported */ +#define SUPPORT_U3 +#ifdef SUPPORT_U3 + +#define U3D_DFT_SPEED SSUSB_SPEED_SUPER +#define U2_U3_SWITCH +/* #define U2_U3_SWITCH_AUTO */ +#else +#define U3D_DFT_SPEED SSUSB_SPEED_HIGH +#endif + +#ifndef CONFIG_USB_MU3D_DRV +#define POWER_SAVING_MODE +#endif + +/* clock setting + this setting is applied ONLY for DR FPGA + please check integrator for your platform setting + */ +/* OSC 125MHz/2 = 62.5MHz, ceil(62.5) = 63 */ +#define U3D_MAC_SYS_CK 63 +/* OSC 20Mhz/2 = 10MHz */ +/* #define U3D_MAC_REF_CK 10 */ +#define U3D_MAC_REF_CK 26 +/* U3D_PHY_REF_CK = U3D_MAC_REF_CK on ASIC */ +/* On FPGA, these two clocks are separated */ +#define U3D_PHY_REF_CK 26 + + +#define PIO_MODE 1 +#define DMA_MODE 2 +#define QMU_MODE 3 +#define BUS_MODE PIO_MODE + +#ifdef CONFIG_USBIF_COMPLIANCE +#define EP0_BUS_MODE DMA_MODE +#else +#define EP0_BUS_MODE PIO_MODE +#endif + + +#define AUTOSET +#define AUTOCLEAR +#define BOUNDARY_4K +#define DIS_ZLP_CHECK_CRC32 /* disable check crc32 in zlp */ + +#define CS_12B 1 +#define CS_16B 2 +#define CHECKSUM_TYPE CS_16B +#define U3D_COMMAND_TIMER 10 + +#if (CHECKSUM_TYPE == CS_16B) +#define CHECKSUM_LENGTH 16 +#else +#define CHECKSUM_LENGTH 12 +#endif + +#define NO_ZLP 0 +#define HW_MODE 1 +#define GPD_MODE 2 + +#ifdef _USB_NORMAL_ +#define TXZLP NO_ZLP +#else +#define TXZLP GPD_MODE +#endif + +#define ISO_UPDATE_TEST 0 +#define ISO_UPDATE_MODE 1 + +#define LPM_STRESS 0 + +/* USBIF , uevent */ +/* #define USBIF_OTG_EVENT_DEV_CONN_TMOUT "DEV_CONN_TMOUT" */ +/* #define USBIF_OTG_EVENT_NO_RESP_FOR_HNP_ENABLE "NO_RESP_FOR_HNP_ENABLE" */ +/* #define USBIF_OTG_EVENT_HUB_NOT_SUPPORTED "HUB_NOT_SUPPORTED" */ +/* #define USBIF_OTG_EVENT_DEV_NOT_SUPPORTED "DEV_NOT_SUPPORTED" */ +#define USBIF_OTG_EVENT_HNP_FAILED "HNP_FAILED" +#define USBIF_OTG_EVENT_NO_RESP_FOR_SRP "NO_RESP_FOR_SRP" + +/*EP number is hard code, not read from U3D_CAP_EPINFO*/ +#define HARDCODE_EP + +extern void __iomem *u3_base; +extern void __iomem *u3_sif_base; +extern void __iomem *u3_sif2_base; + +#ifdef CONFIG_MTK_FPGA +extern void __iomem *i2c1_base; +#endif + +/** + * @U3D register map + */ + +/* + * 0x1127_0000 for MAC register + */ +/* 4K for each, offset may differ from project to project. Please check integrator */ +#define SSUSB_DEV_BASE (u3_base+0x1000) +#define SSUSB_EPCTL_CSR_BASE (u3_base+0x1800) +#define SSUSB_USB3_MAC_CSR_BASE (u3_base+0x2400) +#define SSUSB_USB3_SYS_CSR_BASE (u3_base+0x2400) +#define SSUSB_USB2_CSR_BASE (u3_base+0x3400) + +/* + * 0x1128_0000 for sifslv register in Infra + */ +#define SSUSB_SIFSLV_SPLLC_BASE (u3_sif_base+0x000) +#define SSUSB_SIFSLV_IPPC_BASE (u3_sif_base+0x700) +#define SSUSB_SIFSLV_U2PHY_COM_BASE (u3_sif_base+0x800) +#define SSUSB_SIFSLV_U3PHYD_BASE (u3_sif_base+0x900) + +#ifdef CONFIG_PROJECT_PHY +/* + * 0x1129_0000 for sifslv register in top_ao + */ +#define SSUSB_SIFSLV_U2PHY_COM_SIV_B_BASE (u3_sif2_base+0x800) +#define SSUSB_USB30_PHYA_SIV_B_BASE (u3_sif2_base+0xB00) +#define SSUSB_SIFSLV_U3PHYA_DA_BASE (u3_sif2_base+0xC00) +#endif + +#include "ssusb_dev_c_header.h" +#include "ssusb_epctl_csr_c_header.h" +/* usb3_mac / usb3_sys do not exist in U2 ONLY IP */ +#include "ssusb_usb3_mac_csr_c_header.h" +#include "ssusb_usb3_sys_csr_c_header.h" +#include "ssusb_usb2_csr_c_header.h" +#include "ssusb_sifslv_ippc_c_header.h" +#include "mtk-phy.h" + +#ifdef EXT_VBUS_DET +#define FPGA_REG 0xf0008098 +#define VBUS_RISE_BIT (1<<11) /* W1C */ +#define VBUS_FALL_BIT (1<<12) /* W1C */ +#define VBUS_MSK (VBUS_RISE_BIT | VBUS_FALL_BIT) +#define VBUS_RISE_IRQ 13 +#define VBUS_FALL_IRQ 14 +#endif +#define USB_IRQ 146 + + +#define RISC_SIZE_1B 0x0 +#define RISC_SIZE_2B 0x1 +#define RISC_SIZE_4B 0x2 + + +#define USB_FIFO(ep_num) (U3D_FIFO0+ep_num*0x10) + +#define USB_FIFOSZ_SIZE_8 (0x03) +#define USB_FIFOSZ_SIZE_16 (0x04) +#define USB_FIFOSZ_SIZE_32 (0x05) +#define USB_FIFOSZ_SIZE_64 (0x06) +#define USB_FIFOSZ_SIZE_128 (0x07) +#define USB_FIFOSZ_SIZE_256 (0x08) +#define USB_FIFOSZ_SIZE_512 (0x09) +#define USB_FIFOSZ_SIZE_1024 (0x0A) +#define USB_FIFOSZ_SIZE_2048 (0x0B) +#define USB_FIFOSZ_SIZE_4096 (0x0C) +#define USB_FIFOSZ_SIZE_8192 (0x0D) +#define USB_FIFOSZ_SIZE_16384 (0x0E) +#define USB_FIFOSZ_SIZE_32768 (0x0F) + + +/* U3D_EP0CSR */ +#define CSR0_SETUPEND (0x00200000) /* /removed, use SETUPENDISR */ +#define CSR0_FLUSHFIFO (0x01000000) /* /removed */ +#define CSR0_SERVICESETUPEND (0x08000000) /* /removed, W1C SETUPENDISR */ +#define EP0_W1C_BITS (~(EP0_RXPKTRDY | EP0_SETUPPKTRDY | EP0_SENTSTALL)) +/* U3D_TX1CSR0 */ +#define USB_TXCSR_FLUSHFIFO (0x00100000) /* removed */ +#define TX_W1C_BITS (~(TX_SENTSTALL)) +/* USB_RXCSR */ +#define USB_RXCSR_FLUSHFIFO (0x00100000) /* removed */ +#define RX_W1C_BITS (~(RX_SENTSTALL|RX_RXPKTRDY)) + + +#define BIT0 (1<<0) +#define BIT16 (1<<16) + +#define TYPE_BULK (0x00) +#define TYPE_INT (0x10) +#define TYPE_ISO (0x20) +#define TYPE_MASK (0x30) + + +/* QMU macros */ +#define USB_QMU_RQCSR(n) (U3D_RXQCSR1+0x0010*((n)-1)) +#define USB_QMU_RQSAR(n) (U3D_RXQSAR1+0x0010*((n)-1)) +#define USB_QMU_RQCPR(n) (U3D_RXQCPR1+0x0010*((n)-1)) +#define USB_QMU_RQLDPR(n) (U3D_RXQLDPR1+0x0010*((n)-1)) +#define USB_QMU_TQCSR(n) (U3D_TXQCSR1+0x0010*((n)-1)) +#define USB_QMU_TQSAR(n) (U3D_TXQSAR1+0x0010*((n)-1)) +#define USB_QMU_TQCPR(n) (U3D_TXQCPR1+0x0010*((n)-1)) + +#define QMU_Q_START (0x00000001) +#define QMU_Q_RESUME (0x00000002) +#define QMU_Q_STOP (0x00000004) +#define QMU_Q_ACTIVE (0x00008000) + +#define QMU_TX_EN(n) (BIT0<<(n)) +#define QMU_RX_EN(n) (BIT16<<(n)) +#define QMU_TX_CS_EN(n) (BIT0<<(n)) +#define QMU_RX_CS_EN(n) (BIT16<<(n)) +#define QMU_TX_ZLP(n) (BIT0<<(n)) +#define QMU_RX_MULTIPLE(n) (BIT16<<((n)-1)) +#define QMU_RX_ZLP(n) (BIT0<<(n)) +#define QMU_RX_COZ(n) (BIT16<<(n)) + +#define QMU_RX_EMPTY(n) (BIT16<<(n)) +#define QMU_TX_EMPTY(n) (BIT0<<(n)) +#define QMU_RX_DONE(n) (BIT16<<(n)) +#define QMU_TX_DONE(n) (BIT0<<(n)) + +#define QMU_RX_ZLP_ERR(n) (BIT16<<(n)) +#define QMU_RX_EP_ERR(n) (BIT0<<(n)) +#define QMU_RX_LEN_ERR(n) (BIT16<<(n)) +#define QMU_RX_CS_ERR(n) (BIT0<<(n)) + +#define QMU_TX_LEN_ERR(n) (BIT16<<(n)) +#define QMU_TX_CS_ERR(n) (BIT0<<(n)) + +/** + * @MAC value Definition + */ + +/* U3D_LINK_STATE_MACHINE */ +#define STATE_RESET (0) +#define STATE_DISABLE (1) +#define STATE_DISABLE_EXIT (2) +#define STATE_SS_INACTIVE_QUITE (3) +#define STATE_SS_INACTIVE_DISC_DETECT (4) +#define STATE_RX_DETECT_RESET (5) +#define STATE_RX_DETECT_ACTIVE (6) +#define STATE_RX_DETECT_QUITE (7) +#define STATE_POLLING_LFPS (8) +#define STATE_POLLING_RXEQ (9) +#define STATE_POLLING_ACTIVE (10) +#define STATE_POLLING_CONFIGURATION (11) +#define STATE_POLLING_IDLE (12) +#define STATE_U0_STATE (13) +#define STATE_U1_STATE (14) +#define STATE_U1_TX_PING (15) +#define STATE_U1_EXIT (16) +#define STATE_U2_STATE (17) +#define STATE_U2_DETECT (18) +#define STATE_U2_EXIT (19) +#define STATE_U3_STATE (20) +#define STATE_U3_DETECT (21) +#define STATE_U3_EXIT (22) +#define STATE_COMPLIANCE (23) +#define STATE_RECOVERY_ACTIVE (24) +#define STATE_RECOVERY_CONFIGURATION (25) +#define STATE_RECOVERY_IDLE (26) +#define STATE_LOOPBACK_ACTIVE_MASTER (27) +#define STATE_LOOPBACK_ACTIVE_SLAVE (28) + +/* TODO: remove these definitions */ +#if 1 +/* DEVICE_CONTROL */ +#define USB_DEVCTL_SESSION (0x1) +#define USB_DEVCTL_HOSTREQUEST (0x2) +#define USB_DEVCTL_HOSTMODE (0x4) +#define USB_DEVCTL_LS_DEV (0x5) +#define USB_DEVCTL_FS_DEV (0x6) +#define USB_DEVCTL_BDEVICE (0x80) +#define USB_DEVCTL_VBUSMASK (0x18) +#define USB_DEVCTL_VBUSVALID (0x18) +#define USB_DEVCTL_VBUS_OFFSET (0x3) +#endif + +#endif /* USB_HW_H */ diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.c b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.c new file mode 100644 index 000000000000..8e67f0c38e61 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.c @@ -0,0 +1,176 @@ +#define _USB_OSAI_EXT_ +#include "mu3d_hal_osal.h" +#undef _USB_OSAI_EXT_ + +void os_ms_delay(unsigned int ui4_delay) +{ + mdelay(ui4_delay); +} + +void os_us_delay(unsigned int ui4_delay) +{ + udelay(ui4_delay); +} + +void os_ms_sleep(unsigned int ui4_sleep) +{ + msleep(ui4_sleep); +} + + +#ifdef NEVER +void os_spin_lock(spinlock_t *lock) +{ + /* spin_lock(lock); */ +} + +void os_spin_unlock(spinlock_t *lock) +{ + /* spin_unlock(lock); */ +} +#endif /* NEVER */ + +void os_memcpy(DEV_INT8 *pv_to, DEV_INT8 *pv_from, size_t z_l) +{ + /*FIXME: just use memcpy(), why use this???? */ + DEV_INT32 i; + + if ((pv_to != NULL) || (z_l == 0)) { + for (i = 0; i < z_l; i++) + *(pv_to + i) = *(pv_from + i); + } else { + BUG_ON(1); + } +} + +#ifdef NEVER +void *os_virt_to_phys(void *vaddr) +{ + + return virt_to_phys(vaddr); +} +#endif /* NEVER */ + +void *os_phys_to_virt(void *paddr) +{ + + /* return phys_to_virt((phys_addr_t)paddr); */ + return phys_to_virt((phys_addr_t) (long)paddr); +} + +#ifdef NEVER +void *os_ioremap(void *paddr, DEV_UINT32 t_size) +{ + + /* return ioremap(paddr,t_size); */ + return ioremap_nocache(paddr, t_size); +} + +void os_iounmap(void *vaddr) +{ + iounmap(vaddr); + vaddr = NULL; +} +#endif /* NEVER */ + + +void *os_memset(void *pv_to, DEV_UINT8 ui1_c, size_t z_l) +{ + + if ((pv_to != NULL) || (z_l == 0)) + return memset(pv_to, ui1_c, z_l); + /* else */ + BUG_ON(1); + + return pv_to; +} + +void *os_mem_alloc(size_t z_size) +{ + void *pv_mem = NULL; + + pv_mem = kmalloc(z_size, GFP_NOIO); + + if (pv_mem == NULL) { + /*WARNING:OOM_MESSAGE: Possible unnecessary 'out of memory' message*/ + /*pr_err("kmalloc fail!!\n");*/ + BUG_ON(1); + } + + return pv_mem; +} + +void os_mem_free(void *pv_mem) +{ + + kfree(pv_mem); + pv_mem = NULL; +} + +void os_disableIrq(DEV_UINT32 irq) +{ + disable_irq(irq); + os_ms_delay(20); +} + +void os_enableIrq(DEV_UINT32 irq) +{ + enable_irq(irq); +} + +void os_clearIrq(DEV_UINT32 irq) +{ + os_writel(U3D_LV1IECR, os_readl(U3D_LV1ISR)); +} + + +void os_get_random_bytes(void *buf, DEV_INT32 nbytes) +{ + get_random_bytes(buf, nbytes); +} + +void os_disableDcache(void) +{ + /* HalDisableDCache(); */ +} + +void os_flushinvalidateDcache(void) +{ + /* HalFlushInvalidateDCache(); */ +} + +/*---------------------------------------------------------------------------- + * Function: os_reg_isr() + * + * Description: + * this API registers an ISR with its vector id. it performs + * 1. parse argument. + * 2. guard isr. + * 3. call OS driver reg isr API. + * + * Inputs: + * ui2_vec_id: an vector id to register an ISR. + * pf_isr: pointer to a ISR to set. + * ppf_old_isr: pointer to hold the current ISR setting. + * + * Outputs: + * None + *---------------------------------------------------------------------------*/ + +int os_reg_isr(DEV_UINT32 irq, irq_handler_t handler, void *isrbuffer) +{ + DEV_INT32 i4_ret; + + i4_ret = request_irq(irq, handler, /* our handler */ + IRQF_TRIGGER_LOW, "usb device handler", isrbuffer); + + return i4_ret; +} + + + +void os_free_isr(DEV_UINT32 irq, void *isrbuffer) +{ + + free_irq(irq, isrbuffer); +} diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.h b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.h new file mode 100644 index 000000000000..fe23687cc87b --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.h @@ -0,0 +1,80 @@ +#ifndef _USB_OSAI_H_ +#define _USB_OSAI_H_ +#include <linux/delay.h> +#include <linux/spinlock_types.h> +#include <linux/spinlock.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/dma-mapping.h> +#include <linux/random.h> +#include <linux/slab.h> +#include "mu3d_hal_comm.h" +#include "mu3d_hal_hw.h" + +#undef EXTERN + +#ifdef _USB_OSAI_EXT_ +#define EXTERN +#else +#define EXTERN \ +extern +#endif + +#define K_EMERG (1<<7) +#define K_QMU (1<<7) +#define K_ALET (1<<6) +#define K_CRIT (1<<5) +#define K_ERR (1<<4) +#define K_WARNIN (1<<3) +#define K_NOTICE (1<<2) +#define K_INFO (1<<1) +#define K_DEBUG (1<<0) + +/*Set the debug level at musb_core.c*/ +extern u32 debug_level; + +#ifdef USE_SSUSB_QMU +#define qmu_printk(level, fmt, args...) do { \ + if (debug_level & (level|K_QMU)) { \ + pr_debug("[U3D][Q]" fmt, ## args); \ + } \ + } while (0) +#endif + +#define os_printk(level, fmt, args...) do { \ + if (debug_level & level) { \ + pr_debug("[U3D]" fmt, ## args); \ + } \ + } while (0) + +#define OS_R_OK ((DEV_INT32) 0) + +EXTERN spinlock_t _lock; +EXTERN DEV_INT32 os_reg_isr(DEV_UINT32 irq, irq_handler_t handler, void *isrbuffer); +/* USBIF */ +EXTERN void os_free_isr(DEV_UINT32 irq, void *isrbuffer); +EXTERN void os_ms_delay(DEV_UINT32 ui4_delay); +EXTERN void os_us_delay(DEV_UINT32 ui4_delay); +EXTERN void os_ms_sleep(DEV_UINT32 ui4_sleep); + +void os_memcpy(DEV_INT8 *pv_to, DEV_INT8 *pv_from, size_t z_l); +EXTERN void *os_memset(void *pv_to, DEV_UINT8 ui1_c, size_t z_l); +EXTERN void *os_mem_alloc(size_t z_size); + +EXTERN void *os_phys_to_virt(void *paddr); + +EXTERN void os_mem_free(void *pv_mem); +EXTERN void os_disableIrq(DEV_UINT32 irq); +EXTERN void os_disableIrq(DEV_UINT32 irq); +EXTERN void os_enableIrq(DEV_UINT32 irq); +EXTERN void os_clearIrq(DEV_UINT32 irq); +EXTERN void os_get_random_bytes(void *buf, DEV_INT32 nbytes); +EXTERN void os_disableDcache(void); +EXTERN void os_flushinvalidateDcache(void); +extern DEV_INT32 rand(void); +extern void HalFlushInvalidateDCache(void); + + +#undef EXTERN + +#endif diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.c b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.c new file mode 100644 index 000000000000..6e38eac5c961 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.c @@ -0,0 +1,92 @@ +#include "mu3d_hal_osal.h" +#include "mu3d_hal_phy.h" +#include "mu3d_hal_usb_drv.h" +#include "mtk-phy.h" + +/** + * mu3d_hal_phy_scan - u3 phy clock phase scan + * + */ +DEV_INT32 mu3d_hal_phy_scan(DEV_INT32 latch_val, DEV_UINT8 driving) +{ +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + DEV_INT32 count, fset_phase_val, recov_cnt, link_error_count, U0_count; + DEV_UINT8 phase_val; + /* DEV_UINT8 driving; */ + + /* disable ip power down,disable U2/U3 ip power down. */ + mu3d_hal_ssusb_en(); + /* mu3d_hal_pdn_dis(); */ + u3phy_ops->change_pipe_phase(u3phy, 0, 0); + os_writel(U3D_PIPE_LATCH_SELECT, latch_val); /* set tx/rx latch sel */ + + /* driving = 2; */ + u3phy_ops->change_pipe_phase(u3phy, driving, 0); + phase_val = 0; + count = 0; + fset_phase_val = TRUE; + + while (TRUE) { + + if (fset_phase_val) { + u3phy_ops->change_pipe_phase(u3phy, driving, phase_val); + mu3d_hal_rst_dev(); + os_ms_delay(50); + os_writel(U3D_USB3_CONFIG, USB3_EN); + os_writel(U3D_PIPE_LATCH_SELECT, latch_val); /* set tx/rx latch sel */ + fset_phase_val = FALSE; + U0_count = 0; + link_error_count = 0; + recov_cnt = 0; + count = 0; + } + os_ms_delay(50); + count++; + recov_cnt = os_readl(U3D_RECOVERY_COUNT); /* read U0 recovery count */ + link_error_count = os_readl(U3D_LINK_ERR_COUNT); /* read link error count */ + if ((os_readl(U3D_LINK_STATE_MACHINE) & LTSSM) == STATE_U0_STATE) { /* enter U0 state */ + U0_count++; + } + if (U0_count > ENTER_U0_TH) { /* link up */ + os_ms_delay(1000); /* 1s */ + recov_cnt = os_readl(U3D_RECOVERY_COUNT); + link_error_count = os_readl(U3D_LINK_ERR_COUNT); + os_writel(U3D_RECOVERY_COUNT, CLR_RECOV_CNT); /* clear recovery count */ + os_writel(U3D_LINK_ERR_COUNT, CLR_LINK_ERR_CNT); /* clear link error count */ + pr_debug("[PASS] Link Error Count=%d, Recovery Count=%d\n", + link_error_count, recov_cnt); + pr_debug("I2C(0x%02x) : [0x%02x], I2C(0x%02x) : [0x%02x]\n", + U3_PHY_I2C_PCLK_DRV_REG, + _U3Read_Reg(U3_PHY_I2C_PCLK_DRV_REG), + U3_PHY_I2C_PCLK_PHASE_REG, + _U3Read_Reg(U3_PHY_I2C_PCLK_PHASE_REG)); + pr_debug("Reg(0x130) : [0x%02x], PhaseDelay[0x%02x], Driving[0x%02x], Latch[0x%02x]\n", + os_readl(U3D_PIPE_LATCH_SELECT), phase_val, driving, latch_val); + + phase_val++; + fset_phase_val = TRUE; + } else if ((os_readl(U3D_LINK_STATE_MACHINE) & LTSSM) == STATE_DISABLE) { /* link fail */ + pr_debug("[FAIL] STATE_DISABLE, PhaseDelay[0x%02x]\n", phase_val); + phase_val++; + fset_phase_val = TRUE; + } else if (count > MAX_TIMEOUT_COUNT) { /* link timeout */ + pr_debug("[FAIL] TIMEOUT, PhaseDelay[0x%02x]\n", phase_val); + phase_val++; + fset_phase_val = TRUE; + } + if (phase_val > MAX_PHASE_RANGE) { + /* reset device */ + mu3d_hal_rst_dev(); + os_ms_delay(50); + /* disable ip power down,disable U2/U3 ip power down. */ + mu3d_hal_ssusb_en(); + /* mu3d_hal_pdn_dis(); */ + os_ms_delay(10); + + break; + } + } +#endif + + return 0; +} diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.h b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.h new file mode 100644 index 000000000000..0f1d1632cc9a --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.h @@ -0,0 +1,29 @@ +#ifndef MTK_PHY_H +#define MTK_PHY_H + +#include "mu3d_hal_comm.h" +#include "mtk-phy.h" + +#undef EXTERN + +#define ENTER_U0_TH 10 +#define MAX_PHASE_RANGE 31 +#define MAX_TIMEOUT_COUNT 100 + +#ifdef _MTK_PHY_EXT_ +#define EXTERN +#else +#define EXTERN \ +extern +#endif + +#define U3_PHY_I2C_PCLK_DRV_REG 0x0A +#define U3_PHY_I2C_PCLK_PHASE_REG 0x0B + +EXTERN DEV_INT32 mu3d_hal_phy_scan(DEV_INT32 latch_val, DEV_UINT8 driving); +EXTERN PHY_INT32 _U3Read_Reg(PHY_INT32 address); +EXTERN PHY_INT32 _U3Write_Reg(PHY_INT32 address, PHY_INT32 value); + +#undef EXTERN + +#endif diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.c b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.c new file mode 100644 index 000000000000..e123596c1b7d --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.c @@ -0,0 +1,1441 @@ + +#ifdef USE_SSUSB_QMU + +#include "mu3d_hal_osal.h" +#define _MTK_QMU_DRV_EXT_ +#include "mu3d_hal_qmu_drv.h" +#undef _MTK_QMU_DRV_EXT_ +#include "mu3d_hal_usb_drv.h" +#include "mu3d_hal_hw.h" + +/** + * get_bd - get a null bd + * @args - arg1: dir, arg2: ep number + */ +PBD get_bd(USB_DIR dir, DEV_UINT32 num) +{ + PBD ptr; + + if (dir == USB_RX) { + ptr = (PBD) Rx_bd_List[num].pNext; + + os_printk(K_DEBUG, "%s Rx_bd_List[%d].pNext=%p\n", __func__, num, + (Rx_bd_List[num].pNext)); + + if ((Rx_bd_List[num].pNext + 1) < Rx_bd_List[num].pEnd) + Rx_bd_List[num].pNext++; + else + Rx_bd_List[num].pNext = Rx_bd_List[num].pStart; + + } else { + ptr = (PBD) Tx_bd_List[num].pNext; + + os_printk(K_DEBUG, "%s Tx_gpd_List[%d].pNext=%p\n", __func__, num, + (Tx_bd_List[num].pNext)); + + Tx_bd_List[num].pNext++; + Tx_bd_List[num].pNext = Tx_bd_List[num].pNext + AT_BD_EXT_LEN; + + if (Tx_bd_List[num].pNext >= Tx_bd_List[num].pEnd) + Tx_bd_List[num].pNext = Tx_bd_List[num].pStart; + } + return ptr; +} + +/** + * get_bd - get a null gpd + * @args - arg1: dir, arg2: ep number + */ +PGPD get_gpd(USB_DIR dir, DEV_UINT32 num) +{ + PGPD ptr; + + if (dir == USB_RX) { + ptr = Rx_gpd_List[num].pNext; + + /* qmu_printk(K_DEBUG, "[RX]""GPD List[%d]->Next=%p\n", num, Rx_gpd_List[num].pNext); */ + + Rx_gpd_List[num].pNext = + Rx_gpd_List[num].pNext + (AT_GPD_EXT_LEN / sizeof(TGPD) + 1); + + /* qmu_printk(K_DEBUG, "[Rx]""GPD List[%d]->Start=%p, Next=%p, End=%p\n", */ + /* num, Rx_gpd_List[num].pStart, Rx_gpd_List[num].pNext, Rx_gpd_List[num].pEnd); */ + + if (Rx_gpd_List[num].pNext >= Rx_gpd_List[num].pEnd) + Rx_gpd_List[num].pNext = Rx_gpd_List[num].pStart; + + } else { + ptr = Tx_gpd_List[num].pNext; + + /* qmu_printk(K_DEBUG, "[TX]""GPD List[%d]->Next=%p\n", num, Tx_gpd_List[num].pNext); */ + + /* + * Here is really tricky. + * The size of a GPD is 16 bytes. But the cache line size is 64B. + * If all GPDs are allocated continiously. + * When doing invalidating the cache. The size of 64B from the specified address would flush to + * the physical memory. This action may cause that other GPDs corrupted, like HWO=1 when receiving + * QMU Done interrupt. Current workaround is that let a GPD as 64 bytes. So the next + * GPD is behind 64bytes. + */ + Tx_gpd_List[num].pNext = + Tx_gpd_List[num].pNext + (AT_GPD_EXT_LEN / sizeof(TGPD) + 1); + + /* qmu_printk(K_DEBUG, "[TX]""GPD List[%d]->Start=%p, pNext=%p, pEnd=%p\n", */ + /* num, Tx_gpd_List[num].pStart, Tx_gpd_List[num].pNext, Tx_gpd_List[num].pEnd); */ + + if (Tx_gpd_List[num].pNext >= Tx_gpd_List[num].pEnd) + Tx_gpd_List[num].pNext = Tx_gpd_List[num].pStart; + } + return ptr; +} + +/** + * get_bd - align gpd ptr to target ptr + * @args - arg1: dir, arg2: ep number, arg3: target ptr + */ +void gpd_ptr_align(USB_DIR dir, DEV_UINT32 num, PGPD ptr) +{ + DEV_UINT32 run_next; + + run_next = true; + + /* qmu_printk(K_DEBUG,"%s %d, EP%d, ptr=%p\n", __func__, dir, num, ptr); */ + + while (run_next) { + if (ptr == get_gpd(dir, num)) + run_next = false; + } +} + +/** + * bd_virt_to_phys - map bd virtual address to physical address + * @args - arg1: virtual address, arg2: dir, arg3: ep number + * @return - physical address + */ +dma_addr_t bd_virt_to_phys(void *vaddr, USB_DIR dir, DEV_UINT32 num) +{ + uintptr_t ptr; + + if (dir == USB_RX) + ptr = rx_bd_map[num].p_desc_dma; + else + ptr = tx_bd_map[num].p_desc_dma; + + os_printk(K_DEBUG, "%s %s[%d]phys=%lx<->virt=%p\n", __func__, + ((dir == USB_RX) ? "RX" : "TX"), num, ptr, vaddr); + + return (dma_addr_t) ptr; +} + +/** + * bd_phys_to_virt - map bd physical address to virtual address + * @args - arg1: physical address, arg2: dir, arg3: ep number + * @return - virtual address + */ +void *bd_phys_to_virt(void *paddr, USB_DIR dir, DEV_UINT32 num) +{ + void *ptr; + + os_printk(K_DEBUG, "bd_phys_to_virt paddr=%p, num=%d\n", paddr, num); + + if (dir == USB_RX) + ptr = rx_bd_map[num].p_desc; + else + ptr = tx_bd_map[num].p_desc; + + /*os_printk(K_DEBUG,"%s %s[%d]phys=%p<->virt=%p\n", __func__, \ + ((dir==USB_RX)?"RX":"TX"), num , paddr, ptr); */ + + return ptr; +} + +/** + * mu3d_hal_gpd_virt_to_phys - map gpd virtual address to physical address + * @args - arg1: virtual address, arg2: dir, arg3: ep number + * @return - physical address + */ +dma_addr_t mu3d_hal_gpd_virt_to_phys(void *vaddr, USB_DIR dir, DEV_UINT32 num) +{ + uintptr_t ptr; + + if (dir == USB_RX) + ptr = rx_gpd_map[num].p_desc_dma + (dma_addr_t) (vaddr - rx_gpd_map[num].p_desc); + else + ptr = tx_gpd_map[num].p_desc_dma + (dma_addr_t) (vaddr - tx_gpd_map[num].p_desc); + + os_printk(K_DEBUG, "%s %s[%d]phys=%lx<->virt=%p\n", __func__, + ((dir == USB_RX) ? "RX" : "TX"), num, ptr, vaddr); + + return (dma_addr_t) ptr; +} + +/** + * gpd_phys_to_virt - map gpd physical address to virtual address + * @args - arg1: physical address, arg2: dir, arg3: ep number + * @return - virtual address + */ +void *gpd_phys_to_virt(void *paddr, USB_DIR dir, DEV_UINT32 num) +{ + void *ptr; + + /* os_printk(K_DEBUG,"%s paddr=%p, num=%d\n", __func__, paddr, num); */ + + if (dir == USB_RX) { + /*os_printk(K_DEBUG, "%s Rx_gpd_Offset[%d]=0x%08X\n", __func__, num, \ + Rx_gpd_Offset[num]); */ + ptr = + (void *)((uintptr_t) rx_gpd_map[num].p_desc + + (uintptr_t) (paddr - rx_gpd_map[num].p_desc_dma)); + } else { + /*os_printk(K_DEBUG,"%s Tx_gpd_Offset[%d]=0x%08X\n", __func__, num, \ + Tx_gpd_Offset[num]); */ + ptr = + (void *)((uintptr_t) tx_gpd_map[num].p_desc + + (uintptr_t) (paddr - tx_gpd_map[num].p_desc_dma)); + } + /*os_printk(K_DEBUG,"%s %s[%d]phys=%p<->virt=%p\n", __func__, \ + ((dir==USB_RX)?"RX":"TX"), num , paddr, ptr); */ + + return ptr; +} + +/** + * init_bd_list - initialize bd management list + * @args - arg1: dir, arg2: ep number, arg3: bd virtual addr, arg4: bd ioremap addr, arg5: bd number + */ +void init_bd_list(USB_DIR dir, int num, PBD ptr, dma_addr_t io_ptr, DEV_UINT32 size) +{ + if (dir == USB_RX) { + Rx_bd_List[num].pStart = ptr; + Rx_bd_List[num].pEnd = (PBD) (ptr + size); + rx_bd_map[num].p_desc = (void *)ptr; + rx_bd_map[num].p_desc_dma = io_ptr; + ptr++; + Rx_bd_List[num].pNext = ptr; + + os_printk(K_DEBUG, "Rx_bd_List[%d].pStart=%p, pNext=%p, pEnd=%p\n", + num, Rx_bd_List[num].pStart, Rx_bd_List[num].pNext, Rx_bd_List[num].pEnd); + + os_printk(K_DEBUG, "rx_bd_map[%d] vir=%p dma=%08llx\n", num, + rx_bd_map[num].p_desc, (unsigned long long)rx_bd_map[num].p_desc_dma); + + os_printk(K_DEBUG, "vir=%p dma=%08llx\n", ptr, (unsigned long long)io_ptr); + } else { + Tx_bd_List[num].pStart = ptr; + Tx_bd_List[num].pEnd = (PBD) ((DEV_UINT8 *) (ptr + size) + AT_BD_EXT_LEN * size); + tx_bd_map[num].p_desc = (void *)ptr; + tx_bd_map[num].p_desc_dma = io_ptr; + ptr++; + Tx_bd_List[num].pNext = (PBD) ((DEV_UINT8 *) ptr + AT_BD_EXT_LEN); + + os_printk(K_DEBUG, "Tx_bd_List[%d].pStart=%p, pNext=%p, pEnd=%p\n", + num, Tx_bd_List[num].pStart, Tx_bd_List[num].pNext, Tx_bd_List[num].pEnd); + + os_printk(K_DEBUG, "tx_bd_map[%d] vir=%p dma=%08llx\n", num, + tx_bd_map[num].p_desc, (unsigned long long)tx_bd_map[num].p_desc_dma); + + os_printk(K_DEBUG, "vir=%p, dma=%08llx\n", ptr, (unsigned long long)io_ptr); + } +} + + +/** + * init_gpd_list - initialize gpd management list + * @args - arg1: dir, arg2: ep number, arg3: gpd virtual addr, arg4: gpd ioremap addr, arg5: gpd number + */ +void init_gpd_list(USB_DIR dir, int num, PGPD ptr, dma_addr_t io_ptr, DEV_UINT32 size) +{ + if (dir == USB_RX) { + Rx_gpd_List[num].pStart = ptr; + Rx_gpd_List[num].pEnd = (PGPD) ((DEV_UINT8 *) (ptr + size) + AT_GPD_EXT_LEN * size); + rx_gpd_map[num].p_desc = (void *)ptr; + rx_gpd_map[num].p_desc_dma = io_ptr; + ptr++; + Rx_gpd_List[num].pNext = (PGPD) ((DEV_UINT8 *) ptr + AT_GPD_EXT_LEN); + + qmu_printk(K_INFO, "Rx_gpd_List[%d].pStart=%p, pNext=%p, pEnd=%p\n", + num, Rx_gpd_List[num].pStart, Rx_gpd_List[num].pNext, + Rx_gpd_List[num].pEnd); + + qmu_printk(K_INFO, "rx_gpd_map[%d] vir=%p dma=%08llx\n", num, + rx_gpd_map[num].p_desc, (unsigned long long)rx_gpd_map[num].p_desc_dma); + + qmu_printk(K_INFO, "vir=%p, dma=%08llx\n", ptr, (unsigned long long)io_ptr); + } else { + Tx_gpd_List[num].pStart = ptr; + Tx_gpd_List[num].pEnd = (PGPD) ((DEV_UINT8 *) (ptr + size) + AT_GPD_EXT_LEN * size); + tx_gpd_map[num].p_desc = (void *)ptr; + tx_gpd_map[num].p_desc_dma = io_ptr; + ptr++; + Tx_gpd_List[num].pNext = (PGPD) ((DEV_UINT8 *) ptr + AT_GPD_EXT_LEN); + + qmu_printk(K_INFO, "Tx_gpd_List[%d].pStart=%p, pNext=%p, pEnd=%p\n", + num, Tx_gpd_List[num].pStart, Tx_gpd_List[num].pNext, + Tx_gpd_List[num].pEnd); + + qmu_printk(K_INFO, "tx_gpd_map[%d] vir=%p dma=%08llx\n", num, + tx_gpd_map[num].p_desc, (unsigned long long)tx_gpd_map[num].p_desc_dma); + + qmu_printk(K_INFO, "vir=%p, dma=%08llx\n", ptr, (unsigned long long)io_ptr); + } +} + +/** + * free_gpd - free gpd management list + * @args - arg1: dir, arg2: ep number + */ +void free_gpd(USB_DIR dir, int num) +{ + if (dir == USB_RX) { + os_memset(Rx_gpd_List[num].pStart, 0, + MAX_GPD_NUM * (sizeof(TGPD) + AT_GPD_EXT_LEN)); + } else { + os_memset(Tx_gpd_List[num].pStart, 0, + MAX_GPD_NUM * (sizeof(TGPD) + AT_GPD_EXT_LEN)); + } +} + +/** + * mu3d_hal_alloc_qmu_mem - allocate gpd and bd memory for all ep + * + */ +/* USBIF */ + +static dma_addr_t Tx_gpd_ioptr[15]; +static dma_addr_t Rx_gpd_ioptr[15]; + +void _ex_mu3d_hal_free_qmu_mem(struct device *dev) +{ + DEV_UINT32 i; + DEV_UINT32 size = (sizeof(TGPD) + AT_GPD_EXT_LEN) * MAX_GPD_NUM; + + qmu_printk(K_INFO, "_ex_mu3d_hal_free_qmu_mem +\n"); + /*TODO:dma_free_coherent() is needed + if _ex_mu3d_hal_alloc_qmu_mem() would be called more than once + */ + for (i = 1; i <= MAX_QMU_EP; i++) { +#if 0 + kfree(Rx_gpd_head[i]); + kfree(Tx_gpd_head[i]); +#else + dma_free_coherent(dev, size, Rx_gpd_head[i], Rx_gpd_ioptr[i]); + dma_free_coherent(dev, size, Tx_gpd_head[i], Tx_gpd_ioptr[i]); +#endif + } + qmu_printk(K_INFO, "_ex_mu3d_hal_free_qmu_mem -\n"); +} + +void _ex_mu3d_hal_alloc_qmu_mem(struct device *dev) +{ + DEV_UINT32 i, size; + TGPD *ptr; + dma_addr_t io_ptr; + dma_addr_t dma_handle; + + /*TODO: dma_pool_alloc() is an alternative choice + once the memory size is a concern + */ + for (i = 1; i <= MAX_QMU_EP; i++) { + /* Allocate Rx GPD */ + size = (sizeof(TGPD) + AT_GPD_EXT_LEN) * MAX_GPD_NUM; + ptr = (TGPD *) dma_alloc_coherent(dev, size, &dma_handle, GFP_KERNEL); + memset(ptr, 0, size); + Rx_gpd_ioptr[i] = io_ptr = dma_handle; + + init_gpd_list(USB_RX, i, ptr, io_ptr, MAX_GPD_NUM); + Rx_gpd_end[i] = ptr; + + qmu_printk(K_INFO, "ALLOC RX GPD End [%d] Virtual Mem=%p, DMA addr=%08llx\n", + i, Rx_gpd_end[i], (unsigned long long)io_ptr); + + TGPD_CLR_FLAGS_HWO(Rx_gpd_end[i]); + Rx_gpd_head[i] = Rx_gpd_last[i] = Rx_gpd_end[i]; + + qmu_printk(K_INFO, "RQSAR[%d]=%08llx\n", i, + (unsigned long long)mu3d_hal_gpd_virt_to_phys(Rx_gpd_end[i], USB_RX, i)); + + /* Allocate Tx GPD */ + size = (sizeof(TGPD) + AT_GPD_EXT_LEN) * MAX_GPD_NUM; + ptr = (TGPD *) dma_alloc_coherent(dev, size, &dma_handle, GFP_KERNEL); + memset(ptr, 0, size); + Tx_gpd_ioptr[i] = io_ptr = dma_handle; + + init_gpd_list(USB_TX, i, ptr, io_ptr, MAX_GPD_NUM); + Tx_gpd_end[i] = ptr; + + qmu_printk(K_INFO, "ALLOC TX GPD End [%d] Virtual Mem=%p, DMA addr=%08llx\n", + i, Tx_gpd_end[i], (unsigned long long)io_ptr); + + TGPD_CLR_FLAGS_HWO(Tx_gpd_end[i]); + Tx_gpd_head[i] = Tx_gpd_last[i] = Tx_gpd_end[i]; + + qmu_printk(K_INFO, "TQSAR[%d]=%08llx\n", i, + (unsigned long long)mu3d_hal_gpd_virt_to_phys(Tx_gpd_end[i], USB_TX, i)); + } +} + +void mu3d_hal_free_qmu_mem(void) +{ + DEV_UINT32 i; + + for (i = 1; i <= MAX_QMU_EP; i++) { + kfree(Rx_gpd_head[i]); + kfree(Tx_gpd_head[i]); + kfree(Rx_bd_List[i].pStart); + kfree(Tx_bd_List[i].pStart); + } +} + +void mu3d_hal_alloc_qmu_mem(void) +{ + DEV_UINT32 i, size; + TGPD *ptr; + dma_addr_t io_ptr; + TBD *bptr; + dma_addr_t io_bptr; + + for (i = 1; i <= MAX_QMU_EP; i++) { + /* Allocate Tx GPD */ + size = sizeof(TGPD); + size *= MAX_GPD_NUM; + ptr = (TGPD *) os_mem_alloc(size); + os_memset(ptr, 0, size); + + io_ptr = dma_map_single(NULL, ptr, size, DMA_TO_DEVICE); + init_gpd_list(USB_RX, i, ptr, io_ptr, MAX_GPD_NUM); + Rx_gpd_end[i] = ptr; + + os_printk(K_DEBUG, "ALLOC RX GPD End [%d] Virtual Mem=%p, DMA addr=%08llx\n", + i, Rx_gpd_end[i], (unsigned long long)io_ptr); + + /* os_memset(Rx_gpd_end[i], 0 , sizeof(TGPD)); */ + TGPD_CLR_FLAGS_HWO(Rx_gpd_end[i]); + Rx_gpd_head[i] = Rx_gpd_last[i] = Rx_gpd_end[i]; + + os_printk(K_DEBUG, "RQSAR[%d]=%08llx\n", i, + (unsigned long long)mu3d_hal_gpd_virt_to_phys(Rx_gpd_end[i], USB_RX, i)); + + /* Allocate Rx GPD */ + size = sizeof(TGPD); + size += AT_GPD_EXT_LEN; + size *= MAX_GPD_NUM; + ptr = (TGPD *) os_mem_alloc(size); + os_memset(ptr, 0, size); + + io_ptr = dma_map_single(NULL, ptr, size, DMA_TO_DEVICE); + init_gpd_list(USB_TX, i, ptr, io_ptr, MAX_GPD_NUM); + Tx_gpd_end[i] = ptr; + + os_printk(K_DEBUG, "ALLOC TX GPD End [%d] Virtual Mem=%p, DMA addr=%08llx\n", + i, Tx_gpd_end[i], (unsigned long long)io_ptr); + + TGPD_CLR_FLAGS_HWO(Tx_gpd_end[i]); + Tx_gpd_head[i] = Tx_gpd_last[i] = Tx_gpd_end[i]; + + os_printk(K_DEBUG, "TQSAR[%d]=%08llx\n", i, + (unsigned long long)mu3d_hal_gpd_virt_to_phys(Tx_gpd_end[i], USB_TX, i)); + + /* Allocate Tx BD */ + size = (sizeof(TBD)); + size *= MAX_BD_NUM; + bptr = (TBD *) os_mem_alloc(size); + os_memset(bptr, 0, size); + io_bptr = dma_map_single(NULL, bptr, size, DMA_TO_DEVICE); + init_bd_list(USB_RX, i, bptr, io_bptr, MAX_BD_NUM); + + /* Allocate Rx BD */ + size = (sizeof(TBD)); + size += AT_BD_EXT_LEN; + size *= MAX_BD_NUM; + bptr = (TBD *) os_mem_alloc(size); + os_memset(bptr, 0, size); + io_bptr = dma_map_single(NULL, bptr, size, DMA_TO_DEVICE); + init_bd_list(USB_TX, i, bptr, io_bptr, MAX_BD_NUM); + } +} + +/** + * mu3d_hal_init_qmu - initialize qmu + * + */ +void _ex_mu3d_hal_init_qmu(void) +{ + DEV_UINT32 i; + DEV_UINT32 QCR = 0; + + /* Initialize QMU Tx/Rx start address. */ + for (i = 1; i <= MAX_QMU_EP; i++) { + qmu_printk(K_INFO, "==EP[%d]==Start addr RXQ=0x%08lx, TXQ=0x%08lx\n", i, + (uintptr_t) mu3d_hal_gpd_virt_to_phys(Rx_gpd_head[i], USB_RX, i), + (uintptr_t) mu3d_hal_gpd_virt_to_phys(Tx_gpd_head[i], USB_TX, i)); + QCR |= QMU_RX_EN(i); + QCR |= QMU_TX_EN(i); + os_writel(USB_QMU_RQSAR(i), mu3d_hal_gpd_virt_to_phys(Rx_gpd_head[i], USB_RX, i)); + os_writel(USB_QMU_TQSAR(i), mu3d_hal_gpd_virt_to_phys(Tx_gpd_head[i], USB_TX, i)); + Tx_gpd_end[i] = Tx_gpd_last[i] = Tx_gpd_head[i]; + Rx_gpd_end[i] = Rx_gpd_last[i] = Rx_gpd_head[i]; + gpd_ptr_align(USB_TX, i, Tx_gpd_end[i]); + gpd_ptr_align(USB_RX, i, Rx_gpd_end[i]); + } + + /* Enable QMU interrupt. */ + os_writel(U3D_QIESR1, TXQ_EMPTY_IESR | TXQ_CSERR_IESR | TXQ_LENERR_IESR | + RXQ_EMPTY_IESR | RXQ_CSERR_IESR | RXQ_LENERR_IESR | RXQ_ZLPERR_IESR); + os_writel(U3D_EPIESR, EP0ISR); +} + + +void mu3d_hal_init_qmu(void) +{ + DEV_UINT32 i; + DEV_UINT32 QCR = 0; + + /* Initialize QMU Tx/Rx start address. */ + for (i = 1; i <= MAX_QMU_EP; i++) { + os_printk(K_DEBUG, "==EP[%d]==Start addr RXQ=0x%08lx, TXQ=0x%08lx\n", i, + (uintptr_t) mu3d_hal_gpd_virt_to_phys(Rx_gpd_head[i], USB_RX, i), + (uintptr_t) mu3d_hal_gpd_virt_to_phys(Tx_gpd_head[i], USB_TX, i)); + QCR |= QMU_RX_EN(i); + QCR |= QMU_TX_EN(i); + os_writel(USB_QMU_RQSAR(i), mu3d_hal_gpd_virt_to_phys(Rx_gpd_head[i], USB_RX, i)); + os_writel(USB_QMU_TQSAR(i), mu3d_hal_gpd_virt_to_phys(Tx_gpd_head[i], USB_TX, i)); + Tx_gpd_end[i] = Tx_gpd_last[i] = Tx_gpd_head[i]; + Rx_gpd_end[i] = Rx_gpd_last[i] = Rx_gpd_head[i]; + gpd_ptr_align(USB_TX, i, Tx_gpd_end[i]); + gpd_ptr_align(USB_RX, i, Rx_gpd_end[i]); + } + /* Enable QMU Tx/Rx. */ + os_writel(U3D_QGCSR, QCR); + os_writel(U3D_QIESR0, QCR); + /* Enable QMU interrupt. */ + os_writel(U3D_QIESR1, + TXQ_EMPTY_IESR | TXQ_CSERR_IESR | TXQ_LENERR_IESR | RXQ_EMPTY_IESR | + RXQ_CSERR_IESR | RXQ_LENERR_IESR | RXQ_ZLPERR_IESR); + os_writel(U3D_EPIESR, EP0ISR); +} + +/** + * mu3d_hal_cal_checksum - calculate check sum + * @args - arg1: data buffer, arg2: data length + */ +noinline DEV_UINT8 mu3d_hal_cal_checksum(DEV_UINT8 *data, DEV_INT32 len) +{ + DEV_UINT8 *uDataPtr, ckSum; + DEV_INT32 i; + + *(data + 1) = 0x0; + uDataPtr = data; + ckSum = 0; + /* For ALPS01572117, we found calculated QMU check sum is wrong. (Dump memory value directly.) */ + /* After check this function, we did not find any flaw. Still cannot find how to get this wrong value. */ + /* Maybe it is a memory corruption or complier problem. Add "noinline" and "mb();" to prevent this problem. */ + mb(); + for (i = 0; i < len; i++) + ckSum += *(uDataPtr + i); + + return 0xFF - ckSum; +} + +/** + * mu3d_hal_resume_qmu - resume qmu function + * @args - arg1: ep number, arg2: dir + */ +void mu3d_hal_resume_qmu(DEV_INT32 q_num, USB_DIR dir) +{ + if (dir == USB_TX) { + /* qmu_printk(K_DEBUG, "%s EP%d CSR=%x, CPR=%x\n", __func__, q_num, + os_readl(USB_QMU_TQCSR(q_num)), os_readl(USB_QMU_TQCPR(q_num))); */ + os_writel(USB_QMU_TQCSR(q_num), QMU_Q_RESUME); + if (!os_readl(USB_QMU_TQCSR(q_num))) { + qmu_printk(K_WARNIN, "[ERROR]" "%s TQCSR[%d]=%x\n", __func__, q_num, + os_readl(USB_QMU_TQCSR(q_num))); + os_writel(USB_QMU_TQCSR(q_num), QMU_Q_RESUME); + qmu_printk(K_WARNIN, "[ERROR]" "%s TQCSR[%d]=%x\n", __func__, q_num, + os_readl(USB_QMU_TQCSR(q_num))); + } + } else if (dir == USB_RX) { + os_writel(USB_QMU_RQCSR(q_num), QMU_Q_RESUME); + if (!os_readl(USB_QMU_RQCSR(q_num))) { + qmu_printk(K_WARNIN, "[ERROR]" "%s RQCSR[%d]=%x\n", __func__, q_num, + os_readl(USB_QMU_RQCSR(q_num))); + os_writel(USB_QMU_RQCSR(q_num), QMU_Q_RESUME); + qmu_printk(K_WARNIN, "[ERROR]" "%s RQCSR[%d]=%x\n", __func__, q_num, + os_readl(USB_QMU_RQCSR(q_num))); + } + } else { + qmu_printk(K_ERR, "%s wrong direction!!!\n", __func__); + BUG_ON(1); + } +} + +/** + * mu3d_hal_prepare_tx_gpd - prepare tx gpd/bd + * @args - arg1: gpd address, arg2: data buffer address, arg3: data length, arg4: ep number, + * arg5: with bd or not, arg6: write hwo bit or not, arg7: write ioc bit or not + */ +TGPD *_ex_mu3d_hal_prepare_tx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_len, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT8 zlp) +{ + qmu_printk(K_DEBUG, + "[TX]" "%s gpd=%p, epnum=%d, len=%d, zlp=%d, size(TGPD)=%lld, pBuf=%08lx\n", + __func__, gpd, ep_num, data_len, zlp, (u64) sizeof(TGPD), (unsigned long)pBuf); + + /*Set actual data point to "DATA Buffer" */ + TGPD_SET_DATA(gpd, (unsigned long)pBuf); + /*Clear "BDP(Buffer Descriptor Present)" flag */ + TGPD_CLR_FORMAT_BDP(gpd); + /* + * "Data Buffer Length" = + * 0 (If data length > GPD buffer length, use BDs), + * data_len (If data length < GPD buffer length, only use GPD) + */ + TGPD_SET_BUF_LEN(gpd, data_len); + + /*"GPD extension length" = 0. Does not use GPD EXT!! */ + TGPD_SET_EXT_LEN(gpd, 0); + + if (zlp) + TGPD_SET_FORMAT_ZLP(gpd); + else + TGPD_CLR_FORMAT_ZLP(gpd); + + /*Default: bps=false */ + TGPD_CLR_FORMAT_BPS(gpd); + + /*Default: ioc=true */ + TGPD_SET_FORMAT_IOC(gpd); + + /*Get the next GPD */ + Tx_gpd_end[ep_num] = get_gpd(USB_TX, ep_num); + qmu_printk(K_DEBUG, "[TX]" "Tx_gpd_end[%d]=%p\n", ep_num, Tx_gpd_end[ep_num]); + + /*Initialize the new GPD */ + memset(Tx_gpd_end[ep_num], 0, sizeof(TGPD) + AT_GPD_EXT_LEN); + + /*Clear "HWO(Hardware Own)" flag */ + TGPD_CLR_FLAGS_HWO(Tx_gpd_end[ep_num]); + + /*Set "Next GDP pointer" as the next GPD */ + TGPD_SET_NEXT(gpd, + (unsigned long)mu3d_hal_gpd_virt_to_phys(Tx_gpd_end[ep_num], USB_TX, ep_num)); + + /*Default: isHWO=true */ + TGPD_SET_CHKSUM(gpd, CHECKSUM_LENGTH); /*Set GPD Checksum */ + TGPD_SET_FLAGS_HWO(gpd); /*Set HWO flag */ + + return gpd; +} + +TGPD *mu3d_hal_prepare_tx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_len, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT8 zlp) +{ + DEV_UINT32 offset; + DEV_INT32 i; + DEV_INT32 bd_num; + DEV_UINT32 length; + + TBD *bd_next; + TBD *bd_head; + TBD *bd; + DEV_UINT8 *pBuffer; + + /*If data length is less than the GPD buffer size, just use GPD */ + /* if (data_len <= GPD_BUF_SIZE) { */ + /* _is_bdp = 0; */ + /* } */ + + os_printk(K_INFO, "%s gpd=%p, epnum=%d, len=%d, _is_bdp=%d\n", __func__, + gpd, ep_num, data_len, _is_bdp); + + if (!_is_bdp) { + /*Set actual data point to "DATA Buffer" */ + TGPD_SET_DATA(gpd, (unsigned long)pBuf); + /*Clear "BDP(Buffer Descriptor Present)" flag */ + TGPD_CLR_FORMAT_BDP(gpd); + } else { + /*Get the first BD */ + bd_head = (TBD *) get_bd(USB_TX, ep_num); + os_printk(K_INFO, "bd_head=x%p\n", bd_head); + + bd = bd_head; + os_memset(bd, 0, sizeof(TBD)); + + /*Date length for transfer */ + length = data_len; + + /*Point of data buffer */ + pBuffer = (DEV_UINT8 *) (uintptr_t) (pBuf); + + /*The size of BD buffer */ + offset = BD_BUF_SIZE; + + /*Count how many BD this transfer need. */ + bd_num = (!(length % offset)) ? (length / offset) : ((length / offset) + 1); + + os_printk(K_INFO, "bd_num=%d\n", bd_num); + + /*If the size of BD buffer is bigger than the length of actual transfer, use the actual length */ + if (offset > length) + offset = length; + + /*Insert data into each BD */ + for (i = 0; i < bd_num; i++) { + os_printk(K_INFO, "bd[%d]=%p\n", i, bd); + if (i == (bd_num - 1)) { /*The last BD */ + TBD_SET_EXT_LEN(bd, 0); /*"BD Extension Length" = 0. Does not use BD EXT!! */ + TBD_SET_BUF_LEN(bd, length); /*"Data Buffer Length" = the rest of data length */ + /*Store the data pointer to "Data Buffer" */ + TBD_SET_DATA(bd, (unsigned long)pBuffer); + + TBD_SET_FLAGS_EOL(bd); /*Set "EOL" */ + TBD_SET_NEXT(bd, 0); /*Set "Next BD pointer" = 0 */ + TBD_SET_CHKSUM(bd, CHECKSUM_LENGTH); /*Set "BD Checksum" */ + + /*Flush the data of BD struct to device */ + dma_sync_single_for_device(NULL, + bd_virt_to_phys(bd, USB_RX, ep_num), + sizeof(TBD), DMA_BIDIRECTIONAL); + + /*There is no data left to be transferred by GPD */ + /* data_len=length; */ + data_len = 0; + + /*There is no data left to insert BD */ + length = 0; + } else { + TBD_SET_EXT_LEN(bd, 0); /*"BD Extension length" = 0. Does not use BD EXT!! */ + TBD_SET_BUF_LEN(bd, offset); /*"Data Buffer Length" = the MAX BD transfer size */ + /*Store the data pointer to "Data Buffer" */ + TBD_SET_DATA(bd, (unsigned long)pBuffer); + + TBD_CLR_FLAGS_EOL(bd); /*Clear "EOL" */ + /*Get the next BD */ + bd_next = (TBD *) get_bd(USB_TX, ep_num); + os_memset(bd_next, 0, sizeof(TBD)); + + /*Set "Next BD pointer" as the next BD */ + TBD_SET_NEXT(bd, + (unsigned long)bd_virt_to_phys(bd_next, USB_TX, + ep_num)); + TBD_SET_CHKSUM(bd, CHECKSUM_LENGTH); /*Set BD Checksum */ + + /*Flush the data of BD struct to device */ + dma_sync_single_for_device(NULL, + bd_virt_to_phys(bd, USB_RX, ep_num), + sizeof(TBD), DMA_BIDIRECTIONAL); + + /*Calculate the left data length */ + length -= offset; + + /*Move to pointer of buffer */ + pBuffer += offset; + + /*Move to next BD */ + bd = bd_next; + } + } + + /*Set the BD pointer into "BD Pointer" at GPD */ + TGPD_SET_DATA(gpd, (unsigned long)bd_virt_to_phys(bd_head, USB_TX, ep_num)); + + /*Set "BDP(Buffer Descriptor Present)" flag */ + TGPD_SET_FORMAT_BDP(gpd); + } + + os_printk(K_INFO, "%s GPD data_length=%d\n", __func__, data_len); + + /* + * "Data Buffer Length" = + * 0 (If data length > GPD buffer length, use BDs), + * data_len (If data length < GPD buffer length, only use GPD) + */ + TGPD_SET_BUF_LEN(gpd, data_len); + + /*"GPD extension length" = 0. Does not use GPD EXT!! */ + TGPD_SET_EXT_LEN(gpd, 0); + + /*Default: zlp=false, except type=ISOC */ + if (zlp) + TGPD_SET_FORMAT_ZLP(gpd); + else + TGPD_CLR_FORMAT_ZLP(gpd); + + /*Default: bps=false */ + if (bps) + TGPD_SET_FORMAT_BPS(gpd); + else + TGPD_CLR_FORMAT_BPS(gpd); + + /*Default: ioc=true */ + if (ioc) + TGPD_SET_FORMAT_IOC(gpd); + else + TGPD_CLR_FORMAT_IOC(gpd); + + /*Get the next GPD */ + Tx_gpd_end[ep_num] = get_gpd(USB_TX, ep_num); + os_printk(K_INFO, "Tx_gpd_end[%d]=%p\n", ep_num, Tx_gpd_end[ep_num]); + + /*Initialize the new GPD */ + os_memset(Tx_gpd_end[ep_num], 0, sizeof(TGPD)); + + /*Clear "HWO(Hardware Own)" flag */ + TGPD_CLR_FLAGS_HWO(Tx_gpd_end[ep_num]); + + /*Set "Next GDP pointer" as the next GPD */ + TGPD_SET_NEXT(gpd, + (unsigned long)mu3d_hal_gpd_virt_to_phys(Tx_gpd_end[ep_num], USB_TX, ep_num)); + + /*Default: isHWO=true */ + if (isHWO) { + TGPD_SET_CHKSUM(gpd, CHECKSUM_LENGTH); /*Set GPD Checksum */ + TGPD_SET_FLAGS_HWO(gpd); /*Set HWO flag */ + } else { + TGPD_CLR_FLAGS_HWO(gpd); + TGPD_SET_CHKSUM_HWO(gpd, CHECKSUM_LENGTH); + } + + /*Flush the data of GPD struct to device */ + dma_sync_single_for_device(NULL, mu3d_hal_gpd_virt_to_phys(gpd, USB_TX, ep_num), + sizeof(TGPD), DMA_BIDIRECTIONAL); + +#if defined(USB_RISC_CACHE_ENABLED) + os_flushinvalidateDcache(); +#endif + + return gpd; +} + +static inline int check_next_gpd(TGPD *gpd, TGPD *next_gpd) +{ + if (((uintptr_t) next_gpd - (uintptr_t) gpd) == 0x40) + return 1; + else if (((uintptr_t) gpd - (uintptr_t) next_gpd) == 0x7c0) + return 1; + + /*UNNECESSARY_ELSE*/ + qmu_printk(K_ERR, "[RX]" "%p <-> %p\n", gpd, next_gpd); + return 0; +} + +/** + * mu3d_hal_prepare_rx_gpd - prepare rx gpd/bd + * @args - arg1: gpd address, arg2: data buffer address, arg3: data length, + * arg4: ep number, arg5: with bd or not, arg6: write hwo bit or not, arg7: write ioc bit or not + */ +TGPD *_ex_mu3d_hal_prepare_rx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_len, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT32 cMaxPacketSize) +{ + qmu_printk(K_DEBUG, "[RX]" "%s gpd=%p, epnum=%d, len=%d, pBuf=%08lx\n", __func__, + gpd, ep_num, data_len, (unsigned long)pBuf); + + /*Set actual data point to "DATA Buffer" */ + TGPD_SET_DATA(gpd, (unsigned long)pBuf); + /*Clear "BDP(Buffer Descriptor Present)" flag */ + TGPD_CLR_FORMAT_BDP(gpd); + /* + * Set "Allow Data Buffer Length" = + * 0 (If data length > GPD buffer length, use BDs), + * data_len (If data length < GPD buffer length, only use GPD) + */ + TGPD_SET_DataBUF_LEN(gpd, data_len); + + /*Set "Transferred Data Length" = 0 */ + TGPD_SET_BUF_LEN(gpd, 0); + + /*Default: bps=false */ + TGPD_CLR_FORMAT_BPS(gpd); + + /*Default: ioc=true */ + TGPD_SET_FORMAT_IOC(gpd); + + /*Get the next GPD */ + Rx_gpd_end[ep_num] = get_gpd(USB_RX, ep_num); + qmu_printk(K_DEBUG, "[RX]" "Rx_gpd_end[%d]=%p gpd=%p\n", ep_num, Rx_gpd_end[ep_num], gpd); + + /* BUG_ON(!check_next_gpd(gpd, Rx_gpd_end[ep_num])); */ + + /*Initialize the new GPD */ + memset(Rx_gpd_end[ep_num], 0, sizeof(TGPD) + AT_GPD_EXT_LEN); + + /*Clear "HWO(Hardware Own)" flag */ + TGPD_CLR_FLAGS_HWO(Rx_gpd_end[ep_num]); + + /*Set Next GDP pointer to the next GPD */ + TGPD_SET_NEXT(gpd, + (unsigned long)mu3d_hal_gpd_virt_to_phys(Rx_gpd_end[ep_num], USB_RX, ep_num)); + + /*Default: isHWO=true */ + TGPD_SET_CHKSUM(gpd, CHECKSUM_LENGTH); /*Set GPD Checksum */ + TGPD_SET_FLAGS_HWO(gpd); /*Set HWO flag */ + + /* os_printk(K_DEBUG,"Rx gpd info { HWO %d, Next_GPD %x ,DataBufferLength %d, */ + /* DataBuffer %x, Recived Len %d, Endpoint %d, TGL %d, ZLP %d}\n", */ + /* (DEV_UINT32)TGPD_GET_FLAG(gpd), (DEV_UINT32)TGPD_GET_NEXT(gpd), */ + /* (DEV_UINT32)TGPD_GET_DataBUF_LEN(gpd), (DEV_UINT32)TGPD_GET_DATA(gpd), */ + /* (DEV_UINT32)TGPD_GET_BUF_LEN(gpd), (DEV_UINT32)TGPD_GET_EPaddr(gpd), */ + /* (DEV_UINT32)TGPD_GET_TGL(gpd), (DEV_UINT32)TGPD_GET_ZLP(gpd)); */ + + return gpd; +} + +TGPD *mu3d_hal_prepare_rx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_len, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT32 cMaxPacketSize) +{ + DEV_UINT32 offset; + DEV_INT32 i; + DEV_INT32 bd_num; + DEV_UINT32 length; + + TBD *bd_next; + TBD *bd_head; + TBD *bd; + DEV_UINT8 *pBuffer; + + /*If data length is less than the GPD buffer size, just use GPD */ + if (data_len < GPD_BUF_SIZE) + _is_bdp = 0; + + os_printk(K_INFO, "%s gpd=%p, epnum=%d, len=%d, _is_bdp=%d, maxp=%d\n", __func__, + gpd, ep_num, data_len, _is_bdp, cMaxPacketSize); + + if (!_is_bdp) { + /*Set actual data point to "DATA Buffer" */ + TGPD_SET_DATA(gpd, (unsigned long)pBuf); + /*Clear "BDP(Buffer Descriptor Present)" flag */ + TGPD_CLR_FORMAT_BDP(gpd); + } else { + /*Get the first BD */ + bd_head = (TBD *) get_bd(USB_RX, ep_num); + os_printk(K_INFO, "bd_head=x%p\n", bd_head); + + bd = bd_head; + os_memset(bd, 0, sizeof(TBD)); + + /*Date length for transfer */ + length = data_len; + + /*Point of data buffer */ + pBuffer = (DEV_UINT8 *) (uintptr_t) (pBuf); + + /*The size of BD buffer */ + offset = BD_BUF_SIZE; + + /*Count how many BD this transfer need. */ + bd_num = (!(length % offset)) ? (length / offset) : ((length / offset) + 1); + + os_printk(K_INFO, "%s bd_num=%d\n", __func__, bd_num); + + /*Insert data into each BD */ + for (i = 0; i < bd_num; i++) { + os_printk(K_INFO, "%s bd[%d]=%p\n", __func__, i, bd); + if (i == (bd_num - 1)) { + TBD_SET_BUF_LEN(bd, 0); /*Set "Transferred Data Length" = 0 */ + + /*The last one's data buffer lengnth must be precise, or the GPD will never + * done unless ZLP or short packet. */ + /*"Allow Data Buffer Length" = the rest of data length* */ + length = + (!(length % cMaxPacketSize)) ? (length) : ((length / + cMaxPacketSize) + + 1) * cMaxPacketSize; + TBD_SET_DataBUF_LEN(bd, length); + /*Store the data pointer to "Data Buffer" */ + TBD_SET_DATA(bd, (unsigned long)pBuffer); + + TBD_SET_FLAGS_EOL(bd); /*Set "EOL" */ + TBD_SET_NEXT(bd, 0); /*Set "Next BD pointer" = 0 */ + TBD_SET_CHKSUM(bd, CHECKSUM_LENGTH); /*Set "BD Checksum" */ + + /*Flush the data of BD struct to device */ + dma_sync_single_for_device(NULL, + bd_virt_to_phys(bd, USB_RX, ep_num), + sizeof(TBD), DMA_BIDIRECTIONAL); + + break; + } + /*WARNING:UNNECESSARY_ELSE: else is not generally useful after a break or return*/ + /*else*/ + { + TBD_SET_BUF_LEN(bd, 0); /*Set "Transferred Data Length" = 0 */ + + /*"Allow Data Buffer Length" = the MAX BD transfer size */ + TBD_SET_DataBUF_LEN(bd, offset); + /*Store the data pointer to "Data Buffer" */ + TBD_SET_DATA(bd, (unsigned long)pBuffer); + + TBD_CLR_FLAGS_EOL(bd); /*Clear "EOL" */ + /*Get the next BD */ + bd_next = (TBD *) get_bd(USB_RX, ep_num); + os_memset(bd_next, 0, sizeof(TBD)); + + /*Set "Next BD pointer" as the next BD */ + TBD_SET_NEXT(bd, + (unsigned long)bd_virt_to_phys(bd_next, USB_RX, + ep_num)); + TBD_SET_CHKSUM(bd, CHECKSUM_LENGTH); /*Set BD Checksum */ + + /*Flush the data of BD struct to device */ + dma_sync_single_for_device(NULL, + bd_virt_to_phys(bd, USB_RX, ep_num), + sizeof(TBD), DMA_BIDIRECTIONAL); + + /*Calculate the left data length */ + length -= offset; + + /*Move to pointer of buffer */ + pBuffer += offset; + + /*Move to next BD */ + bd = bd_next; + } + } + + /*Set the BD pointer into "BD Pointer" at GPD */ + TGPD_SET_DATA(gpd, (unsigned long)bd_virt_to_phys(bd_head, USB_RX, ep_num)); + + /*Set "BDP(Buffer Descriptor Present)" flag */ + TGPD_SET_FORMAT_BDP(gpd); + } + + os_printk(K_INFO, "%s GPD data_length=%d\n", __func__, data_len); + + /* + * Set "Allow Data Buffer Length" = + * 0 (If data length > GPD buffer length, use BDs), + * data_len (If data length < GPD buffer length, only use GPD) + */ + TGPD_SET_DataBUF_LEN(gpd, data_len); + /* TGPD_SET_DataBUF_LEN(gpd, gpd_buf_size); */ + + /*Set "Transferred Data Length" = 0 */ + TGPD_SET_BUF_LEN(gpd, 0); + + /*Default: bps=false */ + if (bps) + TGPD_SET_FORMAT_BPS(gpd); + else + TGPD_CLR_FORMAT_BPS(gpd); + + /*Default: ioc=true */ + if (ioc) + TGPD_SET_FORMAT_IOC(gpd); + else + TGPD_CLR_FORMAT_IOC(gpd); + + /*Get the next GPD */ + Rx_gpd_end[ep_num] = get_gpd(USB_RX, ep_num); + os_printk(K_INFO, "%s Rx_gpd_end[%d]=%p\n", __func__, ep_num, Tx_gpd_end[ep_num]); + + /*Initialize the new GPD */ + os_memset(Rx_gpd_end[ep_num], 0, sizeof(TGPD)); + + /*Clear "HWO(Hardware Own)" flag */ + TGPD_CLR_FLAGS_HWO(Rx_gpd_end[ep_num]); + + /*Set Next GDP pointer to the next GPD */ + TGPD_SET_NEXT(gpd, + (unsigned long)mu3d_hal_gpd_virt_to_phys(Rx_gpd_end[ep_num], USB_RX, ep_num)); + + /*Default: isHWO=true */ + if (isHWO) { + TGPD_SET_CHKSUM(gpd, CHECKSUM_LENGTH); /*Set GPD Checksum */ + TGPD_SET_FLAGS_HWO(gpd); /*Set HWO flag */ + } else { + TGPD_CLR_FLAGS_HWO(gpd); + TGPD_SET_CHKSUM_HWO(gpd, CHECKSUM_LENGTH); + } + + /* os_printk(K_DEBUG,"Rx gpd info { HWO %d, Next_GPD %x ,DataBufferLength %d, + * DataBuffer %x, Recived Len %d, Endpoint %d, TGL %d, ZLP %d}\n", */ + /* (DEV_UINT32)TGPD_GET_FLAG(gpd), (DEV_UINT32)TGPD_GET_NEXT(gpd), */ + /* (DEV_UINT32)TGPD_GET_DataBUF_LEN(gpd), (DEV_UINT32)TGPD_GET_DATA(gpd), */ + /* (DEV_UINT32)TGPD_GET_BUF_LEN(gpd), (DEV_UINT32)TGPD_GET_EPaddr(gpd), */ + /* (DEV_UINT32)TGPD_GET_TGL(gpd), (DEV_UINT32)TGPD_GET_ZLP(gpd)); */ + + /*Flush the data of GPD struct to device */ + dma_sync_single_for_device(NULL, mu3d_hal_gpd_virt_to_phys(gpd, USB_RX, ep_num), + sizeof(TGPD), DMA_BIDIRECTIONAL); + + return gpd; +} + +/* + * mu3d_hal_insert_transfer_gpd - insert new gpd/bd + * @args - arg1: ep number, arg2: dir, arg3: data buffer, arg4: data length, + * arg5: write hwo bit or not, arg6: write ioc bit or not + */ +void _ex_mu3d_hal_insert_transfer_gpd(DEV_INT32 ep_num, USB_DIR dir, dma_addr_t buf, + DEV_UINT32 count, DEV_UINT8 isHWO, DEV_UINT8 ioc, + DEV_UINT8 bps, DEV_UINT8 zlp, DEV_UINT32 maxp) +{ + TGPD *gpd; + + if (dir == USB_TX) { + gpd = Tx_gpd_end[ep_num]; + _ex_mu3d_hal_prepare_tx_gpd(gpd, buf, count, ep_num, IS_BDP, isHWO, ioc, bps, zlp); + } else if (dir == USB_RX) { + gpd = Rx_gpd_end[ep_num]; + _ex_mu3d_hal_prepare_rx_gpd(gpd, buf, count, ep_num, IS_BDP, isHWO, ioc, bps, maxp); + } +} + +void mu3d_hal_insert_transfer_gpd(DEV_INT32 ep_num, USB_DIR dir, dma_addr_t buf, + DEV_UINT32 count, DEV_UINT8 isHWO, DEV_UINT8 ioc, + DEV_UINT8 bps, DEV_UINT8 zlp, DEV_UINT32 maxp) +{ + TGPD *gpd; + + if (dir == USB_TX) { + gpd = Tx_gpd_end[ep_num]; + /* os_printk(K_INFO,"TX gpd :%x\n", (unsigned int)gpd); */ + mu3d_hal_prepare_tx_gpd(gpd, buf, count, ep_num, IS_BDP, isHWO, ioc, bps, zlp); + } else if (dir == USB_RX) { + gpd = Rx_gpd_end[ep_num]; + /* os_printk(K_INFO,"RX gpd :%x\n",(unsigned int)gpd); */ + mu3d_hal_prepare_rx_gpd(gpd, buf, count, ep_num, IS_BDP, isHWO, ioc, bps, maxp); + } +} + +/** + * mu3d_hal_start_qmu - start qmu function (QMU flow : + * mu3d_hal_init_qmu ->mu3d_hal_start_qmu -> mu3d_hal_insert_transfer_gpd -> mu3d_hal_resume_qmu) + * @args - arg1: ep number, arg2: dir + */ +void mu3d_hal_start_qmu(DEV_INT32 Q_num, USB_DIR dir) +{ + DEV_UINT32 QCR; + DEV_UINT32 txcsr; + + if (dir == USB_TX) { + txcsr = USB_ReadCsr32(U3D_TX1CSR0, Q_num) & 0xFFFEFFFF; + USB_WriteCsr32(U3D_TX1CSR0, Q_num, txcsr | TX_DMAREQEN); + QCR = os_readl(U3D_QCR0); + os_writel(U3D_QCR0, QCR | QMU_TX_CS_EN(Q_num)); +#if (TXZLP == HW_MODE) + QCR = os_readl(U3D_QCR1); + os_writel(U3D_QCR1, QCR & ~QMU_TX_ZLP(Q_num)); + QCR = os_readl(U3D_QCR2); + os_writel(U3D_QCR2, QCR | QMU_TX_ZLP(Q_num)); +#elif (TXZLP == GPD_MODE) + QCR = os_readl(U3D_QCR1); + os_writel(U3D_QCR1, QCR | QMU_TX_ZLP(Q_num)); +#endif + os_writel(U3D_QEMIESR, os_readl(U3D_QEMIESR) | QMU_TX_EMPTY(Q_num)); + os_writel(U3D_TQERRIESR0, QMU_TX_LEN_ERR(Q_num) | QMU_TX_CS_ERR(Q_num)); + + qmu_printk(K_INFO, "USB_QMU_TQCSR:0x%08X\n", os_readl(USB_QMU_TQCSR(Q_num))); + + if (os_readl(USB_QMU_TQCSR(Q_num)) & QMU_Q_ACTIVE) { + qmu_printk(K_INFO, "Tx %d Active Now!\n", Q_num); + return; + } + + os_writel(USB_QMU_TQCSR(Q_num), QMU_Q_START); + + qmu_printk(K_INFO, "USB_QMU_TQCSR:0x%08X\n", os_readl(USB_QMU_TQCSR(Q_num))); + } else if (dir == USB_RX) { + USB_WriteCsr32(U3D_RX1CSR0, Q_num, + USB_ReadCsr32(U3D_RX1CSR0, Q_num) | (RX_DMAREQEN)); + QCR = os_readl(U3D_QCR0); + os_writel(U3D_QCR0, QCR | QMU_RX_CS_EN(Q_num)); + +#ifdef CFG_RX_ZLP_EN + QCR = os_readl(U3D_QCR3); + os_writel(U3D_QCR3, QCR | QMU_RX_ZLP(Q_num)); +#else + QCR = os_readl(U3D_QCR3); + os_writel(U3D_QCR3, QCR & ~(QMU_RX_ZLP(Q_num))); +#endif + +#ifdef CFG_RX_COZ_EN + QCR = os_readl(U3D_QCR3); + os_writel(U3D_QCR3, QCR | QMU_RX_COZ(Q_num)); +#else + QCR = os_readl(U3D_QCR3); + os_writel(U3D_QCR3, QCR & ~(QMU_RX_COZ(Q_num))); +#endif + + os_writel(U3D_QEMIESR, os_readl(U3D_QEMIESR) | QMU_RX_EMPTY(Q_num)); + os_writel(U3D_RQERRIESR0, QMU_RX_LEN_ERR(Q_num) | QMU_RX_CS_ERR(Q_num)); + os_writel(U3D_RQERRIESR1, QMU_RX_EP_ERR(Q_num) | QMU_RX_ZLP_ERR(Q_num)); + + qmu_printk(K_INFO, "USB_QMU_RQCSR:0x%08X\n", os_readl(USB_QMU_RQCSR(Q_num))); + + if (os_readl(USB_QMU_RQCSR(Q_num)) & QMU_Q_ACTIVE) { + qmu_printk(K_INFO, "Rx %d Active Now!\n", Q_num); + return; + } + + os_writel(USB_QMU_RQCSR(Q_num), QMU_Q_START); + + qmu_printk(K_INFO, "USB_QMU_RQCSR:0x%08X\n", os_readl(USB_QMU_RQCSR(Q_num))); + } +#if (CHECKSUM_TYPE == CS_16B) + os_writel(U3D_QCR0, os_readl(U3D_QCR0) | CS16B_EN); +#else + os_writel(U3D_QCR0, os_readl(U3D_QCR0) & ~CS16B_EN); +#endif +} + +/** + * mu3d_hal_stop_qmu - stop qmu function (after qmu stop, fifo should be flushed) + * @args - arg1: ep number, arg2: dir + */ +void mu3d_hal_stop_qmu(DEV_INT32 q_num, USB_DIR dir) +{ + if (dir == USB_TX) { + if (!(os_readl(USB_QMU_TQCSR(q_num)) & (QMU_Q_ACTIVE))) { + qmu_printk(K_CRIT, "Tx%d inActive Now!\n", q_num); + return; + } + os_writel(USB_QMU_TQCSR(q_num), QMU_Q_STOP); + mb(); + if (wait_for_value(USB_QMU_TQCSR(q_num), QMU_Q_ACTIVE, 0, 10, 100) == RET_SUCCESS) + qmu_printk(K_CRIT, "Tx%d stop Now! CSR=0x%x\n", q_num, + os_readl(USB_QMU_TQCSR(q_num))); + else { + qmu_printk(K_CRIT, "Tx%d UNSTOPABLE!! CSR=0x%x\n", q_num, + os_readl(USB_QMU_TQCSR(q_num))); + WARN_ON(1); + } + } else if (dir == USB_RX) { + if (!(os_readl(USB_QMU_RQCSR(q_num)) & QMU_Q_ACTIVE)) { + qmu_printk(K_CRIT, "Rx%d inActive Now!\n", q_num); + return; + } + os_writel(USB_QMU_RQCSR(q_num), QMU_Q_STOP); + mb(); + if (wait_for_value(USB_QMU_RQCSR(q_num), QMU_Q_ACTIVE, 0, 10, 100) == RET_SUCCESS) + qmu_printk(K_CRIT, "Rx%d stop Now! CSR=0x%x\n", q_num, + os_readl(USB_QMU_RQCSR(q_num))); + else { + qmu_printk(K_CRIT, "Rx%d UNSTOPABLE!! CSR=0x%x\n", q_num, + os_readl(USB_QMU_RQCSR(q_num))); + WARN_ON(1); + } + } +} + +/** + * mu3d_hal_send_stall - send stall + * @args - arg1: ep number, arg2: dir + */ +void mu3d_hal_send_stall(DEV_INT32 q_num, USB_DIR dir) +{ + if (dir == USB_TX) { + USB_WriteCsr32(U3D_TX1CSR0, q_num, + USB_ReadCsr32(U3D_TX1CSR0, q_num) | TX_SENDSTALL); + while (!(USB_ReadCsr32(U3D_TX1CSR0, q_num) & TX_SENTSTALL)) + ; + USB_WriteCsr32(U3D_TX1CSR0, q_num, + USB_ReadCsr32(U3D_TX1CSR0, q_num) | TX_SENTSTALL); + USB_WriteCsr32(U3D_TX1CSR0, q_num, + USB_ReadCsr32(U3D_TX1CSR0, q_num) & ~TX_SENDSTALL); + } else if (dir == USB_RX) { + USB_WriteCsr32(U3D_RX1CSR0, q_num, + USB_ReadCsr32(U3D_RX1CSR0, q_num) | RX_SENDSTALL); + while (!(USB_ReadCsr32(U3D_RX1CSR0, q_num) & RX_SENTSTALL)) + ; + USB_WriteCsr32(U3D_RX1CSR0, q_num, + USB_ReadCsr32(U3D_RX1CSR0, q_num) | RX_SENTSTALL); + USB_WriteCsr32(U3D_RX1CSR0, q_num, + USB_ReadCsr32(U3D_RX1CSR0, q_num) & ~RX_SENDSTALL); + } + + os_printk(K_CRIT, "%s %s-EP[%d] sent stall\n", __func__, ((dir == USB_TX) ? "TX" : "RX"), + q_num); +} + +/** + * mu3d_hal_restart_qmu - clear toggle(or sequence) number and start qmu + * @args - arg1: ep number, arg2: dir + */ +void mu3d_hal_restart_qmu(DEV_INT32 q_num, USB_DIR dir) +{ + DEV_UINT32 ep_rst; + + qmu_printk(K_CRIT, "%s : Reset %s-EP[%d]\n", __func__, ((dir == USB_TX) ? "TX" : "RX"), + q_num); + + if (dir == USB_TX) { + ep_rst = BIT16 << q_num; + os_writel(U3D_EP_RST, ep_rst); + os_ms_delay(1); + os_writel(U3D_EP_RST, 0); + } else { + ep_rst = 1 << q_num; + os_writel(U3D_EP_RST, ep_rst); + os_ms_delay(1); + os_writel(U3D_EP_RST, 0); + } + mu3d_hal_start_qmu(q_num, dir); +} + +/** + * flush_qmu - stop qmu and align qmu start ptr t0 current ptr + * @args - arg1: ep number, arg2: dir + */ +void _ex_mu3d_hal_flush_qmu(DEV_INT32 Q_num, USB_DIR dir) +{ + TGPD *gpd_current; + + qmu_printk(K_CRIT, "%s flush QMU %s-EP[%d]\n", __func__, ((dir == USB_TX) ? "TX" : "RX"), + Q_num); + + if (dir == USB_TX) { + /*Stop QMU */ + mu3d_hal_stop_qmu(Q_num, USB_TX); + + /*Get TX Queue Current Pointer Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_TQCPR(Q_num))); + + /*If gpd_current = 0, it means QMU has not yet to execute GPD in QMU. */ + if (!gpd_current) { + /*Get TX Queue Starting Address Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_TQSAR(Q_num))); + } + + /* + * Even if the GPD pointer got from SAR is corrupted. We should use the head of GPD list. + * We know that Tx_gpd_head[Q_num] is always correct. + */ + if (!gpd_current) { + gpd_current = Tx_gpd_head[Q_num]; + qmu_printk(K_CRIT, "gpd is null, so use the head of GPD list %p\n", + gpd_current); + } else { + /*Switch physical to virtual address */ + qmu_printk(K_CRIT, "gpd_current(P) %p\n", gpd_current); + gpd_current = gpd_phys_to_virt((void *)gpd_current, USB_TX, Q_num); + qmu_printk(K_CRIT, "gpd_current(V) %p\n", (void *)gpd_current); + } + + /*Reset the TX GPD list state */ + Tx_gpd_end[Q_num] = Tx_gpd_last[Q_num] = gpd_current; + gpd_ptr_align(dir, Q_num, Tx_gpd_end[Q_num]); + free_gpd(dir, Q_num); + + /*FIXME: Do not know why... */ + os_writel(USB_QMU_TQSAR(Q_num), + mu3d_hal_gpd_virt_to_phys(Tx_gpd_last[Q_num], USB_TX, Q_num)); + qmu_printk(K_ERR, "USB_QMU_TQSAR %x\n", os_readl(USB_QMU_TQSAR(Q_num))); + } else if (dir == USB_RX) { + /*Stop QMU */ + mu3d_hal_stop_qmu(Q_num, USB_RX); + + /*Get RX Queue Current Pointer Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_RQCPR(Q_num))); + if (!gpd_current) { + /*Get RX Queue Starting Address Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_RQSAR(Q_num))); + } + + /* + * Even if the GPD pointer got from SAR is corrupted. We should use the head of GPD list. + * We know that Rx_gpd_head[Q_num] is always correct. + */ + if (!gpd_current) { + gpd_current = Rx_gpd_head[Q_num]; + qmu_printk(K_CRIT, "gpd is null, so use the head of GPD list %p\n", + gpd_current); + } else { + /*Switch physical to virtual address */ + qmu_printk(K_CRIT, "gpd_current(P) %p\n", gpd_current); + gpd_current = gpd_phys_to_virt((void *)gpd_current, USB_RX, Q_num); + qmu_printk(K_CRIT, "gpd_current(V) %p\n", (void *)gpd_current); + } + + /*Reset the RX GPD list state */ + Rx_gpd_end[Q_num] = Rx_gpd_last[Q_num] = gpd_current; + gpd_ptr_align(dir, Q_num, Rx_gpd_end[Q_num]); + free_gpd(dir, Q_num); + + /*FIXME: Do not know why... */ + os_writel(USB_QMU_RQSAR(Q_num), + mu3d_hal_gpd_virt_to_phys(Rx_gpd_end[Q_num], USB_RX, Q_num)); + qmu_printk(K_ERR, "USB_QMU_RQSAR %x\n", os_readl(USB_QMU_RQSAR(Q_num))); + } +} + +void mu3d_hal_flush_qmu(DEV_INT32 Q_num, USB_DIR dir) +{ + TGPD *gpd_current; + + struct USB_REQ *req = mu3d_hal_get_req(Q_num, dir); + + os_printk(K_CRIT, "%s flush QMU %s\n", __func__, ((dir == USB_TX) ? "TX" : "RX")); + + if (dir == USB_TX) { + /*Stop QMU */ + mu3d_hal_stop_qmu(Q_num, USB_TX); + + /*Get TX Queue Current Pointer Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_TQCPR(Q_num))); + + /*If gpd_current = 0, it means QMU has not yet to execute GPD in QMU. */ + if (!gpd_current) { + /*Get TX Queue Starting Address Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_TQSAR(Q_num))); + } + + /*Switch physical to virtual address */ + os_printk(K_CRIT, "gpd_current(P) %p\n", gpd_current); + gpd_current = gpd_phys_to_virt(gpd_current, USB_TX, Q_num); + os_printk(K_CRIT, "gpd_current(V) %p\n", gpd_current); + + /*Reset the TX GPD list state */ + Tx_gpd_end[Q_num] = Tx_gpd_last[Q_num] = gpd_current; + gpd_ptr_align(dir, Q_num, Tx_gpd_end[Q_num]); + free_gpd(dir, Q_num); + + /*FIXME: Do not know why... */ + os_writel(USB_QMU_TQSAR(Q_num), + mu3d_hal_gpd_virt_to_phys(Tx_gpd_last[Q_num], USB_TX, Q_num)); + os_printk(K_ERR, "USB_QMU_TQSAR %x\n", os_readl(USB_QMU_TQSAR(Q_num))); + req->complete = true; + /* os_printk(K_ERR,"TxQ %d Flush Now!\n", Q_num); */ + } else if (dir == USB_RX) { + /*Stop QMU */ + mu3d_hal_stop_qmu(Q_num, USB_RX); + + /*Get RX Queue Current Pointer Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_RQCPR(Q_num))); + if (!gpd_current) { + /*Get RX Queue Starting Address Register */ + /* QMU GPD address --> CPU DMA address */ + gpd_current = (TGPD *) (uintptr_t) (os_readl(USB_QMU_RQSAR(Q_num))); + } + + /*Switch physical to virtual address */ + os_printk(K_CRIT, "gpd_current(P) %p\n", gpd_current); + gpd_current = gpd_phys_to_virt(gpd_current, USB_RX, Q_num); + os_printk(K_CRIT, "gpd_current(V) %p\n", gpd_current); + + /*Reset the RX GPD list state */ + Rx_gpd_end[Q_num] = Rx_gpd_last[Q_num] = gpd_current; + gpd_ptr_align(dir, Q_num, Rx_gpd_end[Q_num]); + free_gpd(dir, Q_num); + + /*FIXME: Do not know why... */ + os_writel(USB_QMU_RQSAR(Q_num), + mu3d_hal_gpd_virt_to_phys(Rx_gpd_end[Q_num], USB_RX, Q_num)); + os_printk(K_ERR, "USB_QMU_RQSAR %x\n", os_readl(USB_QMU_RQSAR(Q_num))); + req->complete = true; + /* os_printk(K_ERR,"RxQ %d Flush Now!\n", Q_num); */ + } +} + +#endif diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.h b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.h new file mode 100644 index 000000000000..f873f879b086 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.h @@ -0,0 +1,293 @@ +#ifndef MTK_QMU_H +#define MTK_QMU_H + +#include "mu3d_hal_osal.h" +#include "mu3d_hal_hw.h" +#include "mu3d_hal_comm.h" +#include "mu3d_hal_usb_drv.h" +#include <linux/platform_device.h> + +typedef struct _TGPD { + DEV_UINT8 flag; + DEV_UINT8 chksum; + DEV_UINT16 DataBufferLen; /*Rx Allow Length */ +#ifdef CONFIG_ARM64 + DEV_UINT32 pNext; + DEV_UINT32 pBuf; +#else + struct _TGPD *pNext; + DEV_UINT8 *pBuf; +#endif + DEV_UINT16 bufLen; + DEV_UINT8 ExtLength; + DEV_UINT8 ZTepFlag; +/*} __attribute__ ((packed, aligned(4))) TGPD, *PGPD;*/ +} __packed __aligned(4)TGPD, *PGPD; + + + +typedef struct _TBD { + DEV_UINT8 flag; + DEV_UINT8 chksum; + DEV_UINT16 DataBufferLen; /*Rx Allow Length */ +#ifdef CONFIG_ARM64 + DEV_UINT32 pNext; + DEV_UINT32 pBuf; +#else + struct _TBD *pNext; + DEV_UINT8 *pBuf; +#endif + DEV_UINT16 bufLen; + DEV_UINT8 extLen; + DEV_UINT8 reserved; +/*} __attribute__ ((packed, aligned(4))) TBD, *PBD;*/ +} __packed __aligned(4) TBD, *PBD; + +typedef struct _GPD_RANGE { + PGPD pNext; + PGPD pStart; + PGPD pEnd; +} GPD_R, *RGPD; + +typedef struct _BD_RANGE { + PBD pNext; + PBD pStart; + PBD pEnd; +} BD_R, *RBD; + +struct qmu_desc_map { + void *p_desc; + dma_addr_t p_desc_dma; +}; + +/* + * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0464d/BABCFDAH.html + * CA7 , CA15 + * The L1 data memory system has the following features: + * data side cache line length of 64-bytes + */ +#define CACHE_LINE_SIZE 64 +#ifdef CACHE_LINE_SIZE +/* + * The min size of GPD must align cache line size. + * So using GPD_EXT_LEN as the dummy space. +*/ +#define AT_GPD_EXT_LEN (CACHE_LINE_SIZE-16) +#else +#define AT_GPD_EXT_LEN 0 +#endif +#define AT_BD_EXT_LEN 0 +#define MAX_GPD_NUM 32 +#define MAX_BD_NUM 0 +/* DVT+ */ +#define STRESS_IOC_TH 8 +#define STRESS_GPD_TH 24 +#define RANDOM_STOP_DELAY 80 +#ifdef CONFIG_USBIF_COMPLIANCE +#define STRESS_DATA_LENGTH 1024 +#else +#define STRESS_DATA_LENGTH (1024*64) /* 1024*16 */ +#endif +/* DVT- */ +#define GPD_BUF_SIZE 65532 +#define BD_BUF_SIZE 32768 /* set to half of 64K of max size */ + +#define IS_BDP 1 + +#define MAX_QMU_EP MAX_EP_NUM /*The better way is to read U3D_CAP_EPINFO */ + +#define TGPD_FLAGS_HWO 0x01 +#define TGPD_IS_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag & TGPD_FLAGS_HWO) +#define TGPD_SET_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag |= TGPD_FLAGS_HWO) +#define TGPD_CLR_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FLAGS_HWO)) +#define TGPD_FORMAT_BDP 0x02 +#define TGPD_IS_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag & TGPD_FORMAT_BDP) +#define TGPD_SET_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag |= TGPD_FORMAT_BDP) +#define TGPD_CLR_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FORMAT_BDP)) +#define TGPD_FORMAT_BPS 0x04 +#define TGPD_IS_FORMAT_BPS(_pd) (((TGPD *)_pd)->flag & TGPD_FORMAT_BPS) +#define TGPD_SET_FORMAT_BPS(_pd) (((TGPD *)_pd)->flag |= TGPD_FORMAT_BPS) +#define TGPD_CLR_FORMAT_BPS(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FORMAT_BPS)) +#define TGPD_SET_FLAG(_pd, _flag) (((TGPD *)_pd)->flag = (((TGPD *)_pd)->flag&(~TGPD_FLAGS_HWO))|(_flag)) +#define TGPD_GET_FLAG(_pd) ((((TGPD *)_pd)->flag & TGPD_FLAGS_HWO)) +#define TGPD_SET_CHKSUM(_pd, _n) (((TGPD *)_pd)->chksum = mu3d_hal_cal_checksum((DEV_UINT8 *)_pd, _n)-1) +#define TGPD_SET_CHKSUM_HWO(_pd, _n) (((TGPD *)_pd)->chksum = mu3d_hal_cal_checksum((DEV_UINT8 *)_pd, _n)-1) +#define TGPD_GET_CHKSUM(_pd) (((TGPD *)_pd)->chksum) +#define TGPD_SET_FORMAT(_pd, _fmt) (((TGPD *)_pd)->flag = (((TGPD *)_pd)->flag&(~TGPD_FORMAT_BDP))|(_fmt)) +#define TGPD_GET_FORMAT(_pd) ((((TGPD *)_pd)->flag & TGPD_FORMAT_BDP)>>1) +#define TGPD_SET_DataBUF_LEN(_pd, _len) (((TGPD *)_pd)->DataBufferLen = _len) +#define TGPD_ADD_DataBUF_LEN(_pd, _len) (((TGPD *)_pd)->DataBufferLen += _len) +#define TGPD_GET_DataBUF_LEN(_pd) (((TGPD *)_pd)->DataBufferLen) + +#ifdef CONFIG_ARM64 + +#define TGPD_SET_NEXT(_pd, _next) (((TGPD *)_pd)->pNext = (u32)_next) +#define TGPD_GET_NEXT(_pd) ((TGPD *)(uintptr_t)((TGPD *)_pd)->pNext) + +#define TGPD_SET_TBD(_pd, _tbd) (((TGPD *)_pd)->pBuf = (u32)_tbd; TGPD_SET_FORMAT_BDP(_pd)) +#define TGPD_GET_TBD(_pd) ((TBD *)(uintptr_t)((TGPD *)_pd)->pBuf) + +#define TGPD_SET_DATA(_pd, _data) (((TGPD *)_pd)->pBuf = (u32)_data) +#define TGPD_GET_DATA(_pd) ((DEV_UINT8 *)(uintptr_t)((TGPD *)_pd)->pBuf) + +#else + +#define TGPD_SET_NEXT(_pd, _next) (((TGPD *)_pd)->pNext = (TGPD *)_next) +#define TGPD_GET_NEXT(_pd) ((TGPD *)((TGPD *)_pd)->pNext) + +#define TGPD_SET_TBD(_pd, _tbd) (((TGPD *)_pd)->pBuf = (DEV_UINT8 *)_tbd; TGPD_SET_FORMAT_BDP(_pd)) +#define TGPD_GET_TBD(_pd) ((TBD *)((TGPD *)_pd)->pBuf) + +#define TGPD_SET_DATA(_pd, _data) (((TGPD *)_pd)->pBuf = (DEV_UINT8 *)_data) +#define TGPD_GET_DATA(_pd) ((DEV_UINT8 *)((TGPD *)_pd)->pBuf) + +#endif + +#define TGPD_SET_BUF_LEN(_pd, _len) (((TGPD *)_pd)->bufLen = _len) +#define TGPD_ADD_BUF_LEN(_pd, _len) (((TGPD *)_pd)->bufLen += _len) +#define TGPD_GET_BUF_LEN(_pd) (((TGPD *)_pd)->bufLen) +#define TGPD_SET_EXT_LEN(_pd, _len) (((TGPD *)_pd)->ExtLength = _len) +#define TGPD_GET_EXT_LEN(_pd) (((TGPD *)_pd)->ExtLength) +#define TGPD_SET_EPaddr(_pd, _EP) (((TGPD *)_pd)->ZTepFlag = (((TGPD *)_pd)->ZTepFlag&0xF0)|(_EP)) +#define TGPD_GET_EPaddr(_pd) (((TGPD *)_pd)->ZTepFlag & 0x0F) +#define TGPD_FORMAT_TGL 0x10 +#define TGPD_IS_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag & TGPD_FORMAT_TGL) +#define TGPD_SET_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag |= TGPD_FORMAT_TGL) +#define TGPD_CLR_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag &= (~TGPD_FORMAT_TGL)) +#define TGPD_FORMAT_ZLP 0x20 +#define TGPD_IS_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag & TGPD_FORMAT_ZLP) +#define TGPD_SET_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag |= TGPD_FORMAT_ZLP) +#define TGPD_CLR_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag &= (~TGPD_FORMAT_ZLP)) +#define TGPD_FORMAT_IOC 0x80 +#define TGPD_IS_FORMAT_IOC(_pd) (((TGPD *)_pd)->flag & TGPD_FORMAT_IOC) +#define TGPD_SET_FORMAT_IOC(_pd) (((TGPD *)_pd)->flag |= TGPD_FORMAT_IOC) +#define TGPD_CLR_FORMAT_IOC(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FORMAT_IOC)) +#define TGPD_SET_TGL(_pd, _TGL) (((TGPD *)_pd)->ZTepFlag |= ((_TGL) ? 0x10 : 0x00)) +#define TGPD_GET_TGL(_pd) (((TGPD *)_pd)->ZTepFlag & 0x10 ? 1:0) +#define TGPD_SET_ZLP(_pd, _ZLP) (((TGPD *)_pd)->ZTepFlag |= ((_ZLP) ? 0x20 : 0x00)) +#define TGPD_GET_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag & 0x20 ? 1:0) +#define TGPD_GET_EXT(_pd) ((DEV_UINT8 *)_pd + sizeof(TGPD)) + + +#define TBD_FLAGS_EOL 0x01 +#define TBD_IS_FLAGS_EOL(_bd) (((TBD *)_bd)->flag & TBD_FLAGS_EOL) +#define TBD_SET_FLAGS_EOL(_bd) (((TBD *)_bd)->flag |= TBD_FLAGS_EOL) +#define TBD_CLR_FLAGS_EOL(_bd) (((TBD *)_bd)->flag &= (~TBD_FLAGS_EOL)) +#define TBD_SET_FLAG(_bd, _flag) (((TBD *)_bd)->flag = (DEV_UINT8)_flag) +#define TBD_GET_FLAG(_bd) (((TBD *)_bd)->flag) +#define TBD_SET_CHKSUM(_pd, _n) (((TBD *)_pd)->chksum = mu3d_hal_cal_checksum((DEV_UINT8 *)_pd, _n)) +#define TBD_GET_CHKSUM(_pd) (((TBD *)_pd)->chksum) +#define TBD_SET_DataBUF_LEN(_pd, _len) (((TBD *)_pd)->DataBufferLen = _len) +#define TBD_GET_DataBUF_LEN(_pd) (((TBD *)_pd)->DataBufferLen) + +#ifdef CONFIG_ARM64 + +#define TBD_SET_NEXT(_bd, _next) (((TBD *)_bd)->pNext = (u32)_next) +#define TBD_GET_NEXT(_bd) ((TBD *)(uintptr_t)((TBD *)_bd)->pNext) +#define TBD_SET_DATA(_bd, _data) (((TBD *)_bd)->pBuf = (u32)_data) +#define TBD_GET_DATA(_bd) ((DEV_UINT8 *)(uintptr_t)((TBD *)_bd)->pBuf) + +#else + +#define TBD_SET_NEXT(_bd, _next) (((TBD *)_bd)->pNext = (TBD *)_next) +#define TBD_GET_NEXT(_bd) ((TBD *)((TBD *)_bd)->pNext) +#define TBD_SET_DATA(_bd, _data) (((TBD *)_bd)->pBuf = (DEV_UINT8 *)_data) +#define TBD_GET_DATA(_bd) ((DEV_UINT8 *)((TBD *)_bd)->pBuf) + +#endif + +#define TBD_SET_BUF_LEN(_bd, _len) (((TBD *)_bd)->bufLen = _len) +#define TBD_ADD_BUF_LEN(_bd, _len) (((TBD *)_bd)->bufLen += _len) +#define TBD_GET_BUF_LEN(_bd) (((TBD *)_bd)->bufLen) +#define TBD_SET_EXT_LEN(_bd, _len) (((TBD *)_bd)->extLen = _len) +#define TBD_ADD_EXT_LEN(_bd, _len) (((TBD *)_bd)->extLen += _len) +#define TBD_GET_EXT_LEN(_bd) (((TBD *)_bd)->extLen) +#define TBD_GET_EXT(_bd) (((DEV_UINT8 *)_bd + sizeof(TBD))) + + + +#undef EXTERN + +#ifdef _MTK_QMU_DRV_EXT_ +#define EXTERN +#else +#define EXTERN \ +extern +#endif + + +EXTERN DEV_UINT8 is_bdp; +/* DVT+ */ +EXTERN DEV_UINT32 gpd_buf_size; +EXTERN DEV_UINT16 bd_buf_size; +EXTERN DEV_UINT8 bBD_Extension; +EXTERN DEV_UINT8 bGPD_Extension; +EXTERN DEV_UINT32 g_dma_buffer_size; +/* DVT+ */ +EXTERN PGPD Rx_gpd_head[15]; +EXTERN PGPD Tx_gpd_head[15]; +EXTERN PGPD Rx_gpd_end[15]; +EXTERN PGPD Tx_gpd_end[15]; +EXTERN PGPD Rx_gpd_last[15]; +EXTERN PGPD Tx_gpd_last[15]; +EXTERN GPD_R Rx_gpd_List[15]; +EXTERN GPD_R Tx_gpd_List[15]; +EXTERN BD_R Rx_bd_List[15]; +EXTERN BD_R Tx_bd_List[15]; +EXTERN struct qmu_desc_map rx_gpd_map[15]; +EXTERN struct qmu_desc_map tx_gpd_map[15]; +EXTERN struct qmu_desc_map rx_bd_map[15]; +EXTERN struct qmu_desc_map tx_bd_map[15]; + + +EXTERN void mu3d_hal_resume_qmu(DEV_INT32 Q_num, USB_DIR dir); +EXTERN void mu3d_hal_stop_qmu(DEV_INT32 Q_num, USB_DIR dir); +EXTERN TGPD *_ex_mu3d_hal_prepare_tx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_length, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT8 zlp); +EXTERN TGPD *mu3d_hal_prepare_tx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_length, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT8 zlp); +EXTERN TGPD *_ex_mu3d_hal_prepare_rx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_len, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT32 cMaxPacketSize); +EXTERN TGPD *mu3d_hal_prepare_rx_gpd(TGPD *gpd, dma_addr_t pBuf, DEV_UINT32 data_len, + DEV_UINT8 ep_num, DEV_UINT8 _is_bdp, DEV_UINT8 isHWO, + DEV_UINT8 ioc, DEV_UINT8 bps, DEV_UINT32 cMaxPacketSize); +EXTERN void _ex_mu3d_hal_insert_transfer_gpd(DEV_INT32 ep_num, USB_DIR dir, dma_addr_t buf, + DEV_UINT32 count, DEV_UINT8 isHWO, DEV_UINT8 ioc, + DEV_UINT8 bps, DEV_UINT8 zlp, + DEV_UINT32 cMaxPacketSize); +EXTERN void mu3d_hal_insert_transfer_gpd(DEV_INT32 ep_num, USB_DIR dir, dma_addr_t buf, + DEV_UINT32 count, DEV_UINT8 isHWO, DEV_UINT8 ioc, + DEV_UINT8 bps, DEV_UINT8 zlp, DEV_UINT32 cMaxPacketSize); +EXTERN void _ex_mu3d_hal_alloc_qmu_mem(struct device *dev); +EXTERN void _ex_mu3d_hal_free_qmu_mem(struct device *dev); +EXTERN void mu3d_hal_alloc_qmu_mem(void); +EXTERN void mu3d_hal_free_qmu_mem(void); +EXTERN void _ex_mu3d_hal_init_qmu(void); +EXTERN void mu3d_hal_init_qmu(void); +EXTERN void mu3d_hal_start_qmu(DEV_INT32 Q_num, USB_DIR dir); +EXTERN void _ex_mu3d_hal_flush_qmu(DEV_INT32 Q_num, USB_DIR dir); +EXTERN void mu3d_hal_flush_qmu(DEV_INT32 Q_num, USB_DIR dir); +EXTERN void mu3d_hal_restart_qmu(DEV_INT32 Q_num, USB_DIR dir); +EXTERN void mu3d_hal_send_stall(DEV_INT32 Q_num, USB_DIR dir); +EXTERN DEV_UINT8 mu3d_hal_cal_checksum(DEV_UINT8 *data, DEV_INT32 len); + +EXTERN dma_addr_t _ex_mu3d_hal_gpd_virt_to_phys(void *vaddr, USB_DIR dir, DEV_UINT32 num); +EXTERN dma_addr_t mu3d_hal_gpd_virt_to_phys(void *vaddr, USB_DIR dir, DEV_UINT32 num); + +EXTERN PBD _ex_get_bd(USB_DIR dir, DEV_UINT32 num); +EXTERN PBD get_bd(USB_DIR dir, DEV_UINT32 num); + +EXTERN dma_addr_t bd_virt_to_phys(void *vaddr, USB_DIR dir, DEV_UINT32 num); +EXTERN void *bd_phys_to_virt(void *paddr, USB_DIR dir, DEV_UINT32 num); + +EXTERN PGPD get_gpd(USB_DIR dir, DEV_UINT32 num); + +EXTERN void *gpd_phys_to_virt(void *paddr, USB_DIR dir, DEV_UINT32 num); +EXTERN void gpd_ptr_align(USB_DIR dir, DEV_UINT32 num, PGPD ptr); + +#undef EXTERN + +#endif diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.c b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.c new file mode 100644 index 000000000000..ff7e0f74ddd7 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.c @@ -0,0 +1,1751 @@ +#include "mu3d_hal_osal.h" +#define _MTK_USB_DRV_EXT_ +#include "mu3d_hal_usb_drv.h" +#undef _MTK_USB_DRV_EXT_ +#include "mu3d_hal_hw.h" +#include "mu3d_hal_qmu_drv.h" +#include "mu3d_hal_comm.h" +#include "mtk-phy.h" + +struct USB_REQ *mu3d_hal_get_req(DEV_INT32 ep_num, USB_DIR dir) +{ + DEV_INT32 ep_index = 0; + + if (dir == USB_TX) + ep_index = ep_num; + else if (dir == USB_RX) + ep_index = ep_num + MAX_EP_NUM; + else + BUG_ON(1); + + return &g_u3d_req[ep_index]; +} + +/** + * mu3d_hal_pdn_dis - disable ssusb power down & clock gated + * + */ +void mu3d_hal_pdn_dis(void) +{ + os_clrmsk(U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); +#ifdef SUPPORT_U3 + os_clrmsk(U3D_SSUSB_U3_CTRL_0P, + (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_U2_CG_EN)); +#endif + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, + (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_U2_CG_EN)); +} + +/** + * mu3d_hal_ssusb_en - disable ssusb power down & enable u2/u3 ports + * + */ +void mu3d_hal_ssusb_en(void) +{ + os_printk(K_INFO, "%s\n", __func__); + + os_clrmsk(U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); + os_clrmsk(U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); + +#ifdef SUPPORT_U3 + os_clrmsk(U3D_SSUSB_U3_CTRL_0P, + (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_HOST_SEL)); +#endif + +#ifdef SUPPORT_OTG + os_setmsk(U3D_SSUSB_U2_CTRL_0P, (SSUSB_U2_PORT_OTG_MAC_AUTO_SEL | SSUSB_U2_PORT_OTG_SEL)); + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN)); +#else + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, + (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_HOST_SEL)); +#endif + + os_setmsk(U3D_SSUSB_REF_CK_CTRL, + (SSUSB_REF_MAC_CK_GATE_EN | SSUSB_REF_PHY_CK_GATE_EN | SSUSB_REF_CK_GATE_EN | + SSUSB_REF_MAC3_CK_GATE_EN)); + + /* check U3D sys125,u3 mac,u2 mac clock status. */ + mu3d_hal_check_clk_sts(); +} + +void _ex_mu3d_hal_ssusb_en(void) +{ + os_printk(K_INFO, "%s\n", __func__); + + os_clrmsk(U3D_SSUSB_IP_PW_CTRL0, SSUSB_IP_SW_RST); + os_clrmsk(U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); +#ifdef SUPPORT_U3 + os_clrmsk(U3D_SSUSB_U3_CTRL_0P, + (SSUSB_U3_PORT_DIS | SSUSB_U3_PORT_PDN | SSUSB_U3_PORT_HOST_SEL)); +#endif + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, + (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN | SSUSB_U2_PORT_HOST_SEL)); + + os_setmsk(U3D_SSUSB_REF_CK_CTRL, + (SSUSB_REF_MAC_CK_GATE_EN | SSUSB_REF_PHY_CK_GATE_EN | SSUSB_REF_CK_GATE_EN | + SSUSB_REF_MAC3_CK_GATE_EN)); + + /* check U3D sys125,u3 mac,u2 mac clock status. */ + mu3d_hal_check_clk_sts(); +} + + +/** + * mu3d_hal_dft_reg - apply default register settings + */ +void mu3d_hal_dft_reg(void) +{ + DEV_UINT32 tmp; + + /* set sys_ck related registers */ +#ifdef NEVER + /* sys_ck = OSC 125MHz/2 = 62.5MHz */ + os_setmsk(U3D_SSUSB_SYS_CK_CTRL, SSUSB_SYS_CK_DIV2_EN); + /* U2 MAC sys_ck = ceil(62.5) = 63 */ + os_writelmsk(U3D_USB20_TIMING_PARAMETER, 63, TIME_VALUE_1US); +#ifdef SUPPORT_U3 + /* U3 MAC sys_ck = ceil(62.5) = 63 */ + os_writelmsk(U3D_TIMING_PULSE_CTRL, 63, CNT_1US_VALUE); +#endif +#endif + + /* USB 2.0 related */ + /* sys_ck */ + os_writelmsk(U3D_USB20_TIMING_PARAMETER, U3D_MAC_SYS_CK, TIME_VALUE_1US); + /* ref_ck */ + os_writelmsk(U3D_SSUSB_U2_PHY_PLL, U3D_MAC_REF_CK, SSUSB_U2_PORT_1US_TIMER); + /* spec: >600ns */ + tmp = div_and_rnd_up(600, (1000 / U3D_MAC_REF_CK)) + 1; + os_writelmsk(U3D_SSUSB_IP_PW_CTRL0, + (tmp << SSUSB_IP_U2_ENTER_SLEEP_CNT_OFST), SSUSB_IP_U2_ENTER_SLEEP_CNT); + + /* USB 3.0 related */ +#ifdef SUPPORT_U3 + /* sys_ck */ + os_writelmsk(U3D_TIMING_PULSE_CTRL, U3D_MAC_SYS_CK, CNT_1US_VALUE); + /* ref_ck */ + os_writelmsk(U3D_REF_CK_PARAMETER, U3D_MAC_REF_CK, REF_1000NS); + /* spec: >=300ns */ + tmp = div_and_rnd_up(300, (1000 / U3D_MAC_REF_CK)); + os_writelmsk(U3D_UX_EXIT_LFPS_TIMING_PARAMETER, + (tmp << RX_UX_EXIT_LFPS_REF_OFST), RX_UX_EXIT_LFPS_REF); +#endif + +#ifdef NEVER + /* set ref_ck related registers */ + /* U2 ref_ck = OSC 20MHz/2 = 10MHz */ + os_writelmsk(U3D_SSUSB_U2_PHY_PLL, 10, SSUSB_U2_PORT_1US_TIMER); + /* >600ns */ + os_writelmsk(U3D_SSUSB_IP_PW_CTRL0, + (7 << SSUSB_IP_U2_ENTER_SLEEP_CNT_OFST), SSUSB_IP_U2_ENTER_SLEEP_CNT); +#ifdef SUPPORT_U3 + /* U3 ref_ck = 20MHz/2 = 10MHz */ + os_writelmsk(U3D_REF_CK_PARAMETER, 10, REF_1000NS); + /* >=300ns */ + os_writelmsk(U3D_UX_EXIT_LFPS_TIMING_PARAMETER, + (3 << RX_UX_EXIT_LFPS_REF_OFST), RX_UX_EXIT_LFPS_REF); +#endif +#endif /* NEVER */ + + /* code to override HW default values, FPGA ONLY */ +#ifndef CONFIG_MTK_FPGA + /* enable debug probe */ + os_writel(U3D_SSUSB_PRB_CTRL0, 0xffff); +#endif + + /* USB 2.0 related */ + /* response STALL to host if LPM BESL value is not in supporting range */ + os_setmsk(U3D_POWER_MANAGEMENT, (LPM_BESL_STALL | LPM_BESLD_STALL)); + + + /* USB 3.0 related */ +#ifdef SUPPORT_U3 +#ifdef U2_U3_SWITCH_AUTO + os_setmsk(U3D_USB2_TEST_MODE, U2U3_AUTO_SWITCH); +#endif + + /* device responses to u3_exit from host automatically */ + os_writel(U3D_LTSSM_CTRL, os_readl(U3D_LTSSM_CTRL) & ~SOFT_U3_EXIT_EN); + +#ifndef CONFIG_MTK_FPGA + os_writel(U3D_PIPE_LATCH_SELECT, 0); +#endif + +#endif + +#if ISO_UPDATE_TEST & ISO_UPDATE_MODE + os_setmsk(U3D_POWER_MANAGEMENT, ISO_UPDATE); +#else + os_clrmsk(U3D_POWER_MANAGEMENT, ISO_UPDATE); +#endif + +#ifdef DIS_ZLP_CHECK_CRC32 + /* disable CRC check of ZLP, for compatibility concern */ + os_writel(U3D_LINK_CAPABILITY_CTRL, ZLP_CRC32_CHK_DIS); +#endif +} + +/** + * mu3d_hal_rst_dev - reset all device modules + * + */ +void mu3d_hal_rst_dev(void) +{ + DEV_INT32 ret; + + os_printk(K_ERR, "%s\n", __func__); + +#if 0 + os_writel(U3D_SSUSB_DEV_RST_CTRL, + SSUSB_DEV_SW_RST | SSUSB_DEV_SW_BMU_RST | SSUSB_DEV_SW_QMU_RST | + SSUSB_DEV_SW_DRAM_RST); + os_writel(U3D_SSUSB_DEV_RST_CTRL, 0); +#else + os_writel(U3D_SSUSB_DEV_RST_CTRL, SSUSB_DEV_SW_RST); + os_writel(U3D_SSUSB_DEV_RST_CTRL, 0); +#endif + + mu3d_hal_check_clk_sts(); + + ret = + wait_for_value(U3D_SSUSB_IP_PW_STS1, SSUSB_DEV_QMU_RST_B_STS, SSUSB_DEV_QMU_RST_B_STS, + 1, 10); + if (ret == RET_FAIL) + os_printk(K_ERR, "SSUSB_DEV_QMU_RST_B_STS NG\n"); + + ret = + wait_for_value(U3D_SSUSB_IP_PW_STS1, SSUSB_DEV_BMU_RST_B_STS, SSUSB_DEV_BMU_RST_B_STS, + 1, 10); + if (ret == RET_FAIL) + os_printk(K_ERR, "SSUSB_DEV_BMU_RST_B_STS NG\n"); + + ret = wait_for_value(U3D_SSUSB_IP_PW_STS1, SSUSB_DEV_RST_B_STS, SSUSB_DEV_RST_B_STS, 1, 10); + if (ret == RET_FAIL) + os_printk(K_ERR, "SSUSB_DEV_RST_B_STS NG\n"); +} + +/** + * mu3d_hal_check_clk_sts - check sys125,u3 mac,u2 mac clock status + * + */ +DEV_INT32 mu3d_hal_check_clk_sts(void) +{ + DEV_INT32 ret; + + os_printk(K_ERR, "%s\n", __func__); + + ret = + wait_for_value(U3D_SSUSB_IP_PW_STS1, SSUSB_SYS125_RST_B_STS, SSUSB_SYS125_RST_B_STS, 1, + 10); + if (ret == RET_FAIL) + os_printk(K_ERR, "SSUSB_SYS125_RST_B_STS NG\n"); + + /* do not check when SSUSB_U2_PORT_PDN = 1, because U2 port stays in reset state */ + if (!(os_readl(U3D_SSUSB_U2_CTRL_0P) & SSUSB_U2_PORT_PDN)) { + ret = + wait_for_value(U3D_SSUSB_IP_PW_STS2, SSUSB_U2_MAC_SYS_RST_B_STS, + SSUSB_U2_MAC_SYS_RST_B_STS, 1, 10); + if (ret == RET_FAIL) + os_printk(K_ERR, "SSUSB_U2_MAC_SYS_RST_B_STS NG\n"); + } +#ifdef SUPPORT_U3 + /* do not check when SSUSB_U3_PORT_PDN = 1, because U3 port stays in reset state */ + if (!(os_readl(U3D_SSUSB_U3_CTRL_0P) & SSUSB_U3_PORT_PDN)) { + ret = + wait_for_value(U3D_SSUSB_IP_PW_STS1, SSUSB_U3_MAC_RST_B_STS, + SSUSB_U3_MAC_RST_B_STS, 1, 100); + if (ret == RET_FAIL) + os_printk(K_ERR, + "SSUSB_U3_MAC_RST_B_STS NG, U3D_SSUSB_IP_PW_STS1 is 0x%x\n", + os_readl(U3D_SSUSB_IP_PW_STS1)); + } +#endif + + os_printk(K_CRIT, "check clk pass!!\n"); + return RET_SUCCESS; +} + +/** + * mu3d_hal_link_up - u3d link up + * + */ +DEV_INT32 mu3d_hal_link_up(DEV_INT32 latch_val) +{ + mu3d_hal_ssusb_en(); + mu3d_hal_rst_dev(); + os_ms_delay(50); + os_writel(U3D_USB3_CONFIG, USB3_EN); + os_writel(U3D_PIPE_LATCH_SELECT, latch_val); /* set tx/rx latch sel */ + + return 0; +} + +/** + * mu3d_hal_initr_dis - disable all interrupts + * + */ +void mu3d_hal_initr_dis(void) +{ + /* Disable Level 1 interrupts */ + os_writel(U3D_LV1IECR, 0xFFFFFFFF); + + /* Disable Endpoint interrupts */ + os_writel(U3D_EPIECR, 0xFFFFFFFF); + + /* Disable DMA interrupts */ + os_writel(U3D_DMAIECR, 0xFFFFFFFF); + +#ifdef SUPPORT_OTG + /* Disable TxQ/RxQ Done interrupts */ + os_writel(U3D_QIECR0, 0xFFFFFFFF); + + /* Disable TxQ/RxQ Empty/Checksum/Length/ZLP Error indication */ + os_writel(U3D_QIECR1, 0xFFFFFFFF); + + /* Disable TxQ/RxQ Empty Indication */ + os_writel(U3D_QEMIECR, 0xFFFFFFFF); + + /* Disable Interrupt of TxQ GPD Checksum/Data Buffer Length Error */ + os_writel(U3D_TQERRIECR0, 0xFFFFFFFF); + + /* Disable Interrupt of RxQ GPD Checksum/Data Buffer Length Error */ + os_writel(U3D_RQERRIECR0, 0xFFFFFFFF); + + /* Disable RxQ ZLP Error indication */ + os_writel(U3D_RQERRIECR1, 0xFFFFFFFF); +#endif +} + +void mu3d_hal_clear_intr(void) +{ + os_printk(K_ERR, "%s\n", __func__); + + /* Clear EP0 and Tx/Rx EPn interrupts status */ + os_writel(U3D_EPISR, 0xFFFFFFFF); + + /* Clear EP0 and Tx/Rx EPn DMA interrupts status */ + os_writel(U3D_DMAISR, 0xFFFFFFFF); + +#ifdef SUPPORT_OTG + /* Clear TxQ/RxQ Done interrupts status */ + os_writel(U3D_QISAR0, 0xFFFFFFFF); + + /* Clear TxQ/RxQ Empty/Checksum/Length/ZLP Error indication status */ + os_writel(U3D_QISAR1, 0xFFFFFFFF); + + /* Clear TxQ/RxQ Empty indication */ + os_writel(U3D_QEMIR, 0xFFFFFFFF); + + /* Clear Interrupt of RxQ GPD Checksum/Data Buffer Length Error */ + os_writel(U3D_TQERRIR0, 0xFFFFFFFF); + + /* Clear Interrupt of RxQ GPD Checksum/Data Buffer Length Error */ + os_writel(U3D_RQERRIR0, 0xFFFFFFFF); + + /* Clear RxQ ZLP Error indication */ + os_writel(U3D_RQERRIR1, 0xFFFFFFFF); +#endif + + /* Clear speed change event */ + os_writel(U3D_DEV_LINK_INTR, 0xFFFFFFFF); + + /* Clear U2 USB common interrupt status */ + os_writel(U3D_COMMON_USB_INTR, 0xFFFFFFFF); + + /* Clear U3 LTSSM interrupt status */ + os_writel(U3D_LTSSM_INTR, 0xFFFFFFFF); +} + +/** + * mu3d_hal_system_intr_en - enable system global interrupt + * + */ +void mu3d_hal_system_intr_en(void) +{ + DEV_UINT16 int_en; + DEV_UINT32 ltssm_int_en; + + os_printk(K_ERR, "%s\n", __func__); + + /* Disable All endpoint interrupt */ + os_writel(U3D_EPIECR, os_readl(U3D_EPIER)); + + /* Disable All DMA interrput */ + os_writel(U3D_DMAIECR, os_readl(U3D_DMAIER)); + + /* Disable U2 common USB interrupts */ + os_writel(U3D_COMMON_USB_INTR_ENABLE, 0x00); + + /* Clear U2 common USB interrupts status */ + os_writel(U3D_COMMON_USB_INTR, os_readl(U3D_COMMON_USB_INTR)); + + /* Enable U2 common USB interrupt */ + int_en = SUSPEND_INTR_EN | RESUME_INTR_EN | RESET_INTR_EN | CONN_INTR_EN | DISCONN_INTR_EN + | VBUSERR_INTR_EN | LPM_INTR_EN | LPM_RESUME_INTR_EN; + os_writel(U3D_COMMON_USB_INTR_ENABLE, int_en); + +#ifdef SUPPORT_U3 + /* Disable U3 LTSSM interrupts */ + os_writel(U3D_LTSSM_INTR_ENABLE, 0x00); + os_printk(K_ERR, "U3D_LTSSM_INTR: %x\n", os_readl(U3D_LTSSM_INTR)); + + /* Clear U3 LTSSM interrupts */ + os_writel(U3D_LTSSM_INTR, os_readl(U3D_LTSSM_INTR)); + + /* Enable U3 LTSSM interrupts */ + ltssm_int_en = + SS_INACTIVE_INTR_EN | SS_DISABLE_INTR_EN | COMPLIANCE_INTR_EN | LOOPBACK_INTR_EN | + HOT_RST_INTR_EN | WARM_RST_INTR_EN | RECOVERY_INTR_EN | ENTER_U0_INTR_EN | + ENTER_U1_INTR_EN | ENTER_U2_INTR_EN | ENTER_U3_INTR_EN | EXIT_U1_INTR_EN | + EXIT_U2_INTR_EN | EXIT_U3_INTR_EN | RXDET_SUCCESS_INTR_EN | VBUS_RISE_INTR_EN | + VBUS_FALL_INTR_EN | U3_LFPS_TMOUT_INTR_EN | U3_RESUME_INTR_EN; + os_writel(U3D_LTSSM_INTR_ENABLE, ltssm_int_en); +#endif + +#ifdef SUPPORT_OTG + /* os_writel(U3D_SSUSB_OTG_INT_EN, 0x0); */ + os_printk(K_ERR, "U3D_SSUSB_OTG_STS: %x\n", os_readl(U3D_SSUSB_OTG_STS)); + os_writel(U3D_SSUSB_OTG_STS_CLR, os_readl(U3D_SSUSB_OTG_STS)); + os_writel(U3D_SSUSB_OTG_INT_EN, + os_readl(U3D_SSUSB_OTG_INT_EN) | SSUSB_VBUS_CHG_INT_B_EN | + SSUSB_CHG_B_ROLE_B_INT_EN | SSUSB_CHG_A_ROLE_B_INT_EN | + SSUSB_ATTACH_B_ROLE_INT_EN); +#endif + +#ifdef USE_SSUSB_QMU + /* Enable QMU interrupt. */ + os_writel(U3D_QIESR1, TXQ_EMPTY_IESR | TXQ_CSERR_IESR | TXQ_LENERR_IESR | + RXQ_EMPTY_IESR | RXQ_CSERR_IESR | RXQ_LENERR_IESR | RXQ_ZLPERR_IESR); +#endif + + /* Enable EP0 DMA interrupt */ + os_writel(U3D_DMAIESR, EP0DMAIESR); + + /* Enable speed change interrupt */ + os_writel(U3D_DEV_LINK_INTR_ENABLE, SSUSB_DEV_SPEED_CHG_INTR_EN); +} + +void _ex_mu3d_hal_system_intr_en(void) +{ + DEV_UINT16 int_en; + DEV_UINT32 ltssm_int_en; + + os_printk(K_ERR, "%s\n", __func__); + + /* Disable All endpoint interrupt */ + os_writel(U3D_EPIECR, os_readl(U3D_EPIER)); + + /* Disable All DMA interrput */ + os_writel(U3D_DMAIECR, os_readl(U3D_DMAIER)); + + /* Disable U2 common USB interrupts */ + os_writel(U3D_COMMON_USB_INTR_ENABLE, 0x00); + + /* Clear U2 common USB interrupts status */ + os_writel(U3D_COMMON_USB_INTR, os_readl(U3D_COMMON_USB_INTR)); + + /* Enable U2 common USB interrupt */ + int_en = SUSPEND_INTR_EN | RESUME_INTR_EN | RESET_INTR_EN | CONN_INTR_EN | DISCONN_INTR_EN + | VBUSERR_INTR_EN | LPM_INTR_EN | LPM_RESUME_INTR_EN; + os_writel(U3D_COMMON_USB_INTR_ENABLE, int_en); + +#ifdef SUPPORT_U3 + /* Disable U3 LTSSM interrupts */ + os_writel(U3D_LTSSM_INTR_ENABLE, 0x00); + os_printk(K_ERR, "U3D_LTSSM_INTR: %x\n", os_readl(U3D_LTSSM_INTR)); + + /* Clear U3 LTSSM interrupts */ + os_writel(U3D_LTSSM_INTR, os_readl(U3D_LTSSM_INTR)); + + /* Enable U3 LTSSM interrupts */ + ltssm_int_en = + SS_INACTIVE_INTR_EN | SS_DISABLE_INTR_EN | COMPLIANCE_INTR_EN | LOOPBACK_INTR_EN | + HOT_RST_INTR_EN | WARM_RST_INTR_EN | RECOVERY_INTR_EN | ENTER_U0_INTR_EN | + ENTER_U1_INTR_EN | ENTER_U2_INTR_EN | ENTER_U3_INTR_EN | EXIT_U1_INTR_EN | + EXIT_U2_INTR_EN | EXIT_U3_INTR_EN | RXDET_SUCCESS_INTR_EN | VBUS_RISE_INTR_EN | + VBUS_FALL_INTR_EN | U3_LFPS_TMOUT_INTR_EN | U3_RESUME_INTR_EN; + os_writel(U3D_LTSSM_INTR_ENABLE, ltssm_int_en); +#endif + +#ifdef SUPPORT_OTG + /* os_writel(U3D_SSUSB_OTG_INT_EN, 0x0); */ + os_printk(K_ERR, "U3D_SSUSB_OTG_STS: %x\n", os_readl(U3D_SSUSB_OTG_STS)); + os_writel(U3D_SSUSB_OTG_STS_CLR, os_readl(U3D_SSUSB_OTG_STS)); + os_writel(U3D_SSUSB_OTG_INT_EN, + os_readl(U3D_SSUSB_OTG_INT_EN) | SSUSB_VBUS_CHG_INT_B_EN | + SSUSB_CHG_B_ROLE_B_INT_EN | SSUSB_CHG_A_ROLE_B_INT_EN | + SSUSB_ATTACH_B_ROLE_INT_EN); +#endif + +#ifdef USE_SSUSB_QMU + /* Enable QMU interrupt. */ + os_writel(U3D_QIESR1, TXQ_EMPTY_IESR | TXQ_CSERR_IESR | TXQ_LENERR_IESR | + RXQ_EMPTY_IESR | RXQ_CSERR_IESR | RXQ_LENERR_IESR | RXQ_ZLPERR_IESR); +#endif + + /* Enable EP0 DMA interrupt */ + os_writel(U3D_DMAIESR, EP0DMAIESR); + + /* Enable speed change interrupt */ + os_writel(U3D_DEV_LINK_INTR_ENABLE, SSUSB_DEV_SPEED_CHG_INTR_EN); +} + +/** + * mu3d_hal_resume - power mode resume + * + */ +void mu3d_hal_resume(void) +{ +#ifdef SUPPORT_U3 + if (os_readl(U3D_DEVICE_CONF) & HW_USB2_3_SEL) { /* SS */ + mu3d_hal_pdn_ip_port(1, 0, 1, 0); + + os_setmsk(U3D_LINK_POWER_CONTROL, UX_EXIT); + } else +#endif + { /* hs fs */ + mu3d_hal_pdn_ip_port(1, 0, 0, 1); + + os_setmsk(U3D_POWER_MANAGEMENT, RESUME); + os_ms_delay(10); + os_clrmsk(U3D_POWER_MANAGEMENT, RESUME); + } +} + +/** + * mu3d_hal_u2dev_connect - u2 device softconnect + * + */ +void mu3d_hal_u2dev_connect(void) +{ + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) | SOFT_CONN); + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) | SUSPENDM_ENABLE); + os_printk(K_INFO, "SOFTCONN = 1\n"); +} + +void mu3d_hal_u2dev_disconn(void) +{ + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) & ~SOFT_CONN); + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) & ~SUSPENDM_ENABLE); + os_printk(K_INFO, "SOFTCONN = 0\n"); +} + +/** + * mu3d_hal_u3dev_en - enable U3D SS dev + * + */ +void mu3d_hal_dump_register(void) +{ + void __iomem *i; + + pr_debug("\n\n[mu3d_hal_dump_register]\n"); + pr_debug("SSUSB_DEV_BASE ==================>\n"); + + for (i = SSUSB_DEV_BASE; i <= SSUSB_DEV_BASE + 0xC; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x20; i <= SSUSB_DEV_BASE + 0x24; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x30; i <= SSUSB_DEV_BASE + 0x34; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x40; i <= SSUSB_DEV_BASE + 0x44; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x50; i <= SSUSB_DEV_BASE + 0x50; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x70; i <= SSUSB_DEV_BASE + 0x74; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x80; i <= SSUSB_DEV_BASE + 0x9C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0xC0; i <= SSUSB_DEV_BASE + 0xEC; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x100; i <= SSUSB_DEV_BASE + 0x10C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x400; i <= SSUSB_DEV_BASE + 0x410; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0x700; i <= SSUSB_DEV_BASE + 0x71C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0xC04; i <= SSUSB_DEV_BASE + 0xC10; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0xC20; i <= SSUSB_DEV_BASE + 0xC3C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_DEV_BASE + 0xC84; i <= SSUSB_DEV_BASE + 0xC84; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + pr_debug("SSUSB_DEV_BASE <==================\n"); + + + pr_debug("SSUSB_USB2_CSR ==================>\n"); + for (i = SSUSB_USB2_CSR_BASE + 0x0000; i <= SSUSB_USB2_CSR_BASE + 0x0060; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + pr_debug("SSUSB_USB2_CSR <==================\n"); + + + pr_debug("SSUSB_SIFSLV_IPPC_BASE ==================>\n"); + for (i = SSUSB_SIFSLV_IPPC_BASE + 0x0000; i <= SSUSB_SIFSLV_IPPC_BASE + 0x002C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_SIFSLV_IPPC_BASE + 0x0030; i <= SSUSB_SIFSLV_IPPC_BASE + 0x0038; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_SIFSLV_IPPC_BASE + 0x0050; i <= SSUSB_SIFSLV_IPPC_BASE + 0x0050; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_SIFSLV_IPPC_BASE + 0x007C; i <= SSUSB_SIFSLV_IPPC_BASE + 0x00A4; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + pr_debug("SSUSB_SIFSLV_IPPC_BASE <==================\n"); + + pr_debug("SSUSB_EPCTL_CSR_BASE ==================>\n"); + for (i = SSUSB_EPCTL_CSR_BASE + 0x0000; i <= SSUSB_EPCTL_CSR_BASE + 0x0028; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_EPCTL_CSR_BASE + 0x0030; i <= SSUSB_EPCTL_CSR_BASE + 0x0030; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_EPCTL_CSR_BASE + 0x0040; i <= SSUSB_EPCTL_CSR_BASE + 0x0048; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_EPCTL_CSR_BASE + 0x0050; i <= SSUSB_EPCTL_CSR_BASE + 0x0054; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_EPCTL_CSR_BASE + 0x0060; i <= SSUSB_EPCTL_CSR_BASE + 0x0064; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + pr_debug("SSUSB_EPCTL_CSR_BASE <==================\n"); + + pr_debug("SSUSB_USB3_SYS_CSR_BASE ==================>\n"); + for (i = SSUSB_USB3_SYS_CSR_BASE + 0x0200; i <= SSUSB_USB3_SYS_CSR_BASE + 0x022C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_SYS_CSR_BASE + 0x0240; i <= SSUSB_USB3_SYS_CSR_BASE + 0x0244; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_SYS_CSR_BASE + 0x0290; i <= SSUSB_USB3_SYS_CSR_BASE + 0x029C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_SYS_CSR_BASE + 0x02A0; i <= SSUSB_USB3_SYS_CSR_BASE + 0x02AC; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_SYS_CSR_BASE + 0x02B0; i <= SSUSB_USB3_SYS_CSR_BASE + 0x02B8; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_SYS_CSR_BASE + 0x02C0; i <= SSUSB_USB3_SYS_CSR_BASE + 0x02DC; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + pr_debug("SSUSB_USB3_SYS_CSR_BASE <==================\n"); + + pr_debug("SSUSB_USB3_MAC_CSR ==================>\n"); + for (i = SSUSB_USB3_MAC_CSR_BASE + 0x0000; i <= SSUSB_USB3_MAC_CSR_BASE + 0x001C; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_MAC_CSR_BASE + 0x0050; i <= SSUSB_USB3_MAC_CSR_BASE + 0x0054; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_MAC_CSR_BASE + 0x007C; i <= SSUSB_USB3_MAC_CSR_BASE + 0x00B0; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + for (i = SSUSB_USB3_MAC_CSR_BASE + 0x0010C; i <= SSUSB_USB3_MAC_CSR_BASE + 0x0148; i += 0x4) + pr_debug("[0x%lx] 0x%x\n", (unsigned long)i, os_readl(i)); + + pr_debug("SSUSB_USB3_MAC_CSR <==================\n"); + + pr_debug("\n[mu3d_hal_dump_register]\n\n\n"); +} + +void mu3d_hal_u3dev_en(void) +{ + /* + * Enable super speed function. + */ + os_writel(U3D_USB3_CONFIG, USB3_EN); + os_printk(K_INFO, "USB3_EN = 1\n"); +} + +/** + * mu3d_hal_u3dev_dis - disable U3D SS dev + * + */ +void mu3d_hal_u3dev_dis(void) +{ + /* + * If usb3_en =0 => LTSSM will go to SS.Disable state. + */ + os_writel(U3D_USB3_CONFIG, 0); + os_printk(K_INFO, "USB3_EN = 0\n"); +} + +/** + * mu3d_hal_set_speed - enable ss or connect to hs/fs + *@args - arg1: speed + */ +void mu3d_hal_set_speed(USB_SPEED speed) +{ +#ifndef EXT_VBUS_DET + os_writel(U3D_MISC_CTRL, 0); +#else + os_writel(U3D_MISC_CTRL, 0x3); +#endif + + pr_debug("mu3d_hal_set_speed speed=%d\n", speed); + + /* clear ltssm state */ + if (speed == SSUSB_SPEED_FULL) { + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) & ~HS_ENABLE); + mu3d_hal_u2dev_connect(); + g_u3d_setting.speed = SSUSB_SPEED_FULL; + } else if (speed == SSUSB_SPEED_HIGH) { + os_writel(U3D_POWER_MANAGEMENT, os_readl(U3D_POWER_MANAGEMENT) | HS_ENABLE); + mu3d_hal_u2dev_connect(); + g_u3d_setting.speed = SSUSB_SPEED_HIGH; + } +#ifdef SUPPORT_U3 + else if (speed == SSUSB_SPEED_SUPER) { + g_u3d_setting.speed = SSUSB_SPEED_SUPER; + mu3d_hal_u2dev_disconn(); + mu3d_hal_u3dev_en(); + } +#endif + else { + os_printk(K_ALET, "Unsupported speed!!\n"); + BUG_ON(1); + } +} + +/** + * mu3d_hal_pdn_cg_en - enable U2/U3 pdn & cg + *@args - + */ +void mu3d_hal_pdn_cg_en(void) +{ +#ifdef POWER_SAVING_MODE + DEV_UINT8 speed = (os_readl(U3D_DEVICE_CONF) & SSUSB_DEV_SPEED); + + os_printk(K_INFO, "%s\n", __func__); + + switch (speed) { + case SSUSB_SPEED_SUPER: + os_printk(K_NOTICE, "Device: SUPER SPEED LOW POWER\n"); + os_setmsk(U3D_SSUSB_U2_CTRL_0P, SSUSB_U2_PORT_PDN); + break; + case SSUSB_SPEED_HIGH: + os_printk(K_NOTICE, "Device: HIGH SPEED LOW POWER\n"); +#ifdef SUPPORT_U3 + os_setmsk(U3D_SSUSB_U3_CTRL_0P, SSUSB_U3_PORT_PDN); +#endif + break; + case SSUSB_SPEED_FULL: + os_printk(K_NOTICE, "Device: FULL SPEED LOW POWER\n"); +#ifdef SUPPORT_U3 + os_setmsk(U3D_SSUSB_U3_CTRL_0P, SSUSB_U3_PORT_PDN); +#endif + break; + default: + os_printk(K_NOTICE, "[ERROR] Are you kidding!?!?\n"); + break; + } +#endif +} + +void mu3d_hal_pdn_ip_port(DEV_UINT8 on, DEV_UINT8 touch_dis, DEV_UINT8 u3, DEV_UINT8 u2) +{ +#ifdef POWER_SAVING_MODE + os_printk(K_INFO, "%s on=%d, touch_dis=%d, u3=%d, u2=%d\n", __func__, on, touch_dis, u3, + u2); + if (on) { + os_clrmsk(U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); + +#ifdef SUPPORT_U3 + if (u3) + os_clrmsk(U3D_SSUSB_U3_CTRL_0P, SSUSB_U3_PORT_PDN + | ((touch_dis) ? SSUSB_U3_PORT_DIS : 0)); +#endif + if (u2) + os_clrmsk(U3D_SSUSB_U2_CTRL_0P, SSUSB_U2_PORT_PDN + | ((touch_dis) ? SSUSB_U2_PORT_DIS : 0)); + + while (!(os_readl(U3D_SSUSB_IP_PW_STS1) & SSUSB_SYSPLL_STABLE)) + ; + } else { +#ifdef SUPPORT_U3 + if (u3) + os_setmsk(U3D_SSUSB_U3_CTRL_0P, SSUSB_U3_PORT_PDN + | ((touch_dis) ? SSUSB_U3_PORT_DIS : 0)); +#endif + if (u2) + os_setmsk(U3D_SSUSB_U2_CTRL_0P, SSUSB_U2_PORT_PDN + | ((touch_dis) ? SSUSB_U2_PORT_DIS : 0)); + + os_setmsk(U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); + } +#else + os_printk(K_INFO, "%s Does NOT support IP power down\n", __func__); +#endif +} + +/** + * mu3d_hal_det_speed - detect device speed + *@args - arg1: speed + */ +void mu3d_hal_det_speed(USB_SPEED speed, DEV_UINT8 det_speed) +{ + DEV_UINT8 temp; + DEV_UINT16 cnt_down = 10000; + + pr_debug("===Start polling===\n"); + + /* #ifdef EXT_VBUS_DET */ + if (!det_speed) { + while (!(os_readl(U3D_DEV_LINK_INTR) & SSUSB_DEV_SPEED_CHG_INTR)) { + os_ms_delay(1); + cnt_down--; + + if (cnt_down == 0) { + pr_debug("===Polling FAIL===\n"); + return; + } + } + } else { + while (!(os_readl(U3D_DEV_LINK_INTR) & SSUSB_DEV_SPEED_CHG_INTR)) + ; + } + /* #else */ + /* while(!(os_readl(U3D_DEV_LINK_INTR) & SSUSB_DEV_SPEED_CHG_INTR)); */ + /* #endif */ + + pr_debug("===Polling End===\n"); + + os_writel(U3D_DEV_LINK_INTR, SSUSB_DEV_SPEED_CHG_INTR); + + temp = (os_readl(U3D_DEVICE_CONF) & SSUSB_DEV_SPEED); + switch (temp) { + case SSUSB_SPEED_SUPER: + os_printk(K_EMERG, "Device: SUPER SPEED\n"); + break; + case SSUSB_SPEED_HIGH: + os_printk(K_EMERG, "Device: HIGH SPEED\n"); + break; + case SSUSB_SPEED_FULL: + os_printk(K_EMERG, "Device: FULL SPEED\n"); + break; + case SSUSB_SPEED_INACTIVE: + os_printk(K_EMERG, "Device: INACTIVE\n"); + break; + } + + if (temp != speed) { + os_printk(K_EMERG, "desired speed: %d, detected speed: %d\n", speed, temp); + os_ms_delay(5000); + /* while(1); */ + } +} + +/** + * mu3d_hal_write_fifo - pio write one packet + *@args - arg1: ep number, arg2: data length, arg3: data buffer, arg4: max packet size + */ +DEV_INT32 mu3d_hal_write_fifo(DEV_INT32 ep_num, DEV_INT32 length, DEV_UINT8 *buf, DEV_INT32 maxp) +{ + DEV_UINT32 residue; + DEV_UINT32 count; + DEV_UINT32 temp; + + os_printk(K_DEBUG, "%s epnum=%d, len=%d, buf=%p, maxp=%d\n", __func__, ep_num, length, buf, + maxp); + + count = residue = length; + + while (residue > 0) { + if (residue == 1) { + temp = ((*buf) & 0xFF); + os_writeb(USB_FIFO(ep_num), temp); + buf += 1; + residue -= 1; + } else if (residue == 2) { + temp = ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00); + os_writew(USB_FIFO(ep_num), temp); + buf += 2; + residue -= 2; + } else if (residue == 3) { + temp = ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00); + os_writew(USB_FIFO(ep_num), temp); + buf += 2; + + temp = ((*buf) & 0xFF); + os_writeb(USB_FIFO(ep_num), temp); + buf += 1; + residue -= 3; + } else { + temp = + ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00) + + (((*(buf + 2)) << 16) & 0xFF0000) + (((*(buf + 3)) << 24) & 0xFF000000); + os_writel(USB_FIFO(ep_num), temp); + buf += 4; + residue -= 4; + } + } + + if (ep_num == 0) { + if (count == 0) { + os_printk(K_DEBUG, "USB_EP0_DATAEND %8X+\n", os_readl(U3D_EP0CSR)); + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_DATAEND | EP0_TXPKTRDY); + os_printk(K_DEBUG, "USB_EP0_DATAEND %8X-\n", os_readl(U3D_EP0CSR)); + } else { +#ifdef AUTOSET + if (count < maxp) { + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_TXPKTRDY); + os_printk(K_DEBUG, "EP0_TXPKTRDY\n"); + } +#else + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_TXPKTRDY); +#endif + } + } else { + if (count == 0) { + USB_WriteCsr32(U3D_TX1CSR0, ep_num, + USB_ReadCsr32(U3D_TX1CSR0, ep_num) | TX_TXPKTRDY); + } else { +#ifdef AUTOSET + if (count < maxp) { + USB_WriteCsr32(U3D_TX1CSR0, ep_num, + USB_ReadCsr32(U3D_TX1CSR0, ep_num) | TX_TXPKTRDY); + os_printk(K_DEBUG, "short packet\n"); + } +#else + USB_WriteCsr32(U3D_TX1CSR0, ep_num, + USB_ReadCsr32(U3D_TX1CSR0, ep_num) | TX_TXPKTRDY); +#endif + } + } + return count; +} + +/** + * mu3d_hal_read_fifo - pio read one packet + *@args - arg1: ep number, arg2: data buffer + */ +DEV_INT32 mu3d_hal_read_fifo(DEV_INT32 ep_num, DEV_UINT8 *buf) +{ + DEV_UINT16 count, residue; + DEV_UINT32 temp; + DEV_UINT8 *bp = buf; + + if (ep_num == 0) + residue = count = os_readl(U3D_RXCOUNT0); + else + residue = count = (USB_ReadCsr32(U3D_RX1CSR3, ep_num) >> EP_RX_COUNT_OFST); + + os_printk(K_DEBUG, "%s, req->buf=%p, cnt=%d\n", __func__, buf, count); + + while (residue > 0) { + temp = os_readl(USB_FIFO(ep_num)); + + /*Store the first byte */ + *bp = temp & 0xFF; + + /*Store the 2nd byte, If have */ + if (residue > 1) + *(bp + 1) = (temp >> 8) & 0xFF; + + /*Store the 3rd byte, If have */ + if (residue > 2) + *(bp + 2) = (temp >> 16) & 0xFF; + + /*Store the 4th byte, If have */ + if (residue > 3) + *(bp + 3) = (temp >> 24) & 0xFF; + + if (residue > 4) { + bp = bp + 4; + residue = residue - 4; + } else { + residue = 0; + } + } + +#ifdef AUTOCLEAR + if (ep_num == 0) { + if (!count) { + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_RXPKTRDY); + os_printk(K_DEBUG, "EP0_RXPKTRDY\n"); + } + } else { + if (!count) { + USB_WriteCsr32(U3D_RX1CSR0, ep_num, + USB_ReadCsr32(U3D_RX1CSR0, ep_num) | RX_RXPKTRDY); + os_printk(K_ALET, "ZLP\n"); + } + } +#else + if (ep_num == 0) { + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_RXPKTRDY); + os_printk(K_DEBUG, "EP0_RXPKTRDY\n"); + } else { + USB_WriteCsr32(U3D_RX1CSR0, ep_num, + USB_ReadCsr32(U3D_RX1CSR0, ep_num) | RX_RXPKTRDY); + os_printk(K_DEBUG, "RX_RXPKTRDY\n"); + } +#endif + return count; +} + +/** + * mu3d_hal_write_fifo_burst - pio write n packets with polling buffer full (epn only) + *@args - arg1: ep number, arg2: u3d req + */ +DEV_INT32 mu3d_hal_write_fifo_burst(DEV_INT32 ep_num, DEV_INT32 length, DEV_UINT8 *buf, + DEV_INT32 maxp) +{ + DEV_UINT32 residue, count, actual; + DEV_UINT32 temp; + DEV_UINT8 *bp; + + os_printk(K_DEBUG, "%s ep_num=%d, length=%d, buf=%p, maxp=%d\n", __func__, ep_num, length, + buf, maxp); + +#if (BUS_MODE == PIO_MODE) + /* Here is really tricky, need to print this log to pass EPn PIO loopback + * No time to figure out why. Sorry~ + */ + pr_debug("write_fifo_burst=ep_num=%d, length=%d, buf=%p, maxp=%d\n", ep_num, length, buf, + maxp); +#endif + + actual = 0; + +#ifdef AUTOSET + while (!(USB_ReadCsr32(U3D_TX1CSR0, ep_num) & TX_FIFOFULL)) { +#endif + + if (length - actual > maxp) + count = residue = maxp; + else + count = residue = length - actual; + + bp = buf + actual; + + while (residue > 0) { + + if (residue == 1) { + temp = ((*buf) & 0xFF); + os_writeb(USB_FIFO(ep_num), temp); + buf += 1; + residue -= 1; + } else if (residue == 2) { + temp = ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00); + os_writew(USB_FIFO(ep_num), temp); + buf += 2; + residue -= 2; + } else if (residue == 3) { + temp = ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00); + os_writew(USB_FIFO(ep_num), temp); + buf += 2; + + temp = ((*buf) & 0xFF); + os_writeb(USB_FIFO(ep_num), temp); + buf += 1; + residue -= 3; + } else { + temp = + ((*buf) & 0xFF) + (((*(buf + 1)) << 8) & 0xFF00) + + (((*(buf + 2)) << 16) & 0xFF0000) + + (((*(buf + 3)) << 24) & 0xFF000000); + os_writel(USB_FIFO(ep_num), temp); + buf += 4; + residue -= 4; + } + } +#ifdef NEVER + while (residue > 0) { + + if (residue == 1) { + temp = ((*bp) & 0xFF); + os_writel(U3D_RISC_SIZE, RISC_SIZE_1B); + unit = 1; + } else if (residue == 2) { + temp = ((*bp) & 0xFF) + (((*(bp + 1)) << 8) & 0xFF00); + os_writel(U3D_RISC_SIZE, RISC_SIZE_2B); + unit = 2; + } else if (residue == 3) { + temp = ((*bp) & 0xFF) + (((*(bp + 1)) << 8) & 0xFF00); + os_writel(U3D_RISC_SIZE, RISC_SIZE_2B); + unit = 2; + } else { + temp = + ((*bp) & 0xFF) + (((*(bp + 1)) << 8) & 0xFF00) + + (((*(bp + 2)) << 16) & 0xFF0000) + + (((*(bp + 3)) << 24) & 0xFF000000); + unit = 4; + } + os_writel(USB_FIFO(ep_num), temp); + bp = bp + unit; + residue -= unit; + } + if (os_readl(U3D_RISC_SIZE) != RISC_SIZE_4B) + os_writel(U3D_RISC_SIZE, RISC_SIZE_4B); +#endif /* NEVER */ + actual += count; + + if (length == 0) { + USB_WriteCsr32(U3D_TX1CSR0, ep_num, + USB_ReadCsr32(U3D_TX1CSR0, ep_num) | TX_TXPKTRDY); + return actual; + } + /*WARNING:UNNECESSARY_ELSE: else is not generally useful after a break or return*/ + /*else*/ + { +#ifdef AUTOSET + if ((count < maxp) && (count > 0)) { + USB_WriteCsr32(U3D_TX1CSR0, ep_num, + USB_ReadCsr32(U3D_TX1CSR0, ep_num) | TX_TXPKTRDY); + os_printk(K_DEBUG, "short packet\n"); + return actual; + } + if (count == 0) + return actual; +#else + USB_WriteCsr32(U3D_TX1CSR0, ep_num, + USB_ReadCsr32(U3D_TX1CSR0, ep_num) | TX_TXPKTRDY); +#endif + } +#ifdef AUTOSET + } +#endif + return actual; +} + +/** + * mu3d_hal_read_fifo_burst - pio read n packets with polling buffer empty (epn only) + *@args - arg1: ep number, arg2: data buffer + */ +DEV_INT32 mu3d_hal_read_fifo_burst(DEV_INT32 ep_num, DEV_UINT8 *buf) +{ + DEV_UINT16 count, residue; + DEV_UINT32 temp, actual; + DEV_UINT8 *bp; + + os_printk(K_INFO, "mu3d_hal_read_fifo_burst\n"); + os_printk(K_ALET, "req->buf=%p\n", buf); + actual = 0; +#ifdef AUTOCLEAR + while (!(USB_ReadCsr32(U3D_RX1CSR0, ep_num) & RX_FIFOEMPTY)) { +#endif + residue = count = (USB_ReadCsr32(U3D_RX1CSR3, ep_num) >> EP_RX_COUNT_OFST); + os_printk(K_INFO, "count :%d ; req->actual :%d\n", count, actual); + bp = buf + actual; + + while (residue > 0) { + temp = os_readl(USB_FIFO(ep_num)); + *bp = temp & 0xFF; + *(bp + 1) = (temp >> 8) & 0xFF; + *(bp + 2) = (temp >> 16) & 0xFF; + *(bp + 3) = (temp >> 24) & 0xFF; + bp = bp + 4; + if (residue > 4) + residue = residue - 4; + else + residue = 0; + } + actual += count; + +#ifdef AUTOCLEAR + if (!count) { + USB_WriteCsr32(U3D_RX1CSR0, ep_num, + USB_ReadCsr32(U3D_RX1CSR0, ep_num) | RX_RXPKTRDY); + os_printk(K_ALET, "zlp\n"); + os_printk(K_ALET, "actual :%d\n", actual); + return actual; + } +#else + if (ep_num == 0) { + os_writel(U3D_EP0CSR, os_readl(U3D_EP0CSR) | EP0_RXPKTRDY); + } else { + USB_WriteCsr32(U3D_RX1CSR0, ep_num, + USB_ReadCsr32(U3D_RX1CSR0, ep_num) | RX_RXPKTRDY); + } +#endif +#ifdef AUTOCLEAR + } +#endif + + return actual; +} + + +/** +* mu3d_hal_unfigured_ep - + *@args - + */ +void mu3d_hal_unfigured_ep(void) +{ + DEV_UINT32 i, tx_ep_num, rx_ep_num; + struct USB_EP_SETTING *ep_setting; + + os_printk(K_INFO, "%s\n", __func__); + + g_TxFIFOadd = USB_TX_FIFO_START_ADDRESS; + g_RxFIFOadd = USB_RX_FIFO_START_ADDRESS; + +#ifdef HARDCODE_EP + tx_ep_num = MAX_QMU_EP; /* os_readl(U3D_CAP_EPINFO) & CAP_TX_EP_NUM; */ + rx_ep_num = MAX_QMU_EP; /* (os_readl(U3D_CAP_EPINFO) & CAP_RX_EP_NUM) >> 8; */ +#else + tx_ep_num = os_readl(U3D_CAP_EPINFO) & CAP_TX_EP_NUM; + rx_ep_num = (os_readl(U3D_CAP_EPINFO) & CAP_RX_EP_NUM) >> 8; +#endif + + for (i = 1; i <= tx_ep_num; i++) { + USB_WriteCsr32(U3D_TX1CSR0, i, USB_ReadCsr32(U3D_TX1CSR0, i) & (~0x7FF)); + USB_WriteCsr32(U3D_TX1CSR1, i, 0); + USB_WriteCsr32(U3D_TX1CSR2, i, 0); + ep_setting = &g_u3d_setting.ep_setting[i]; + ep_setting->fifoaddr = 0; + ep_setting->enabled = 0; + } + + for (i = 1; i <= rx_ep_num; i++) { + USB_WriteCsr32(U3D_RX1CSR0, i, USB_ReadCsr32(U3D_RX1CSR0, i) & (~0x7FF)); + USB_WriteCsr32(U3D_RX1CSR1, i, 0); + USB_WriteCsr32(U3D_RX1CSR2, i, 0); + ep_setting = &g_u3d_setting.ep_setting[i + MAX_EP_NUM]; + ep_setting->fifoaddr = 0; + ep_setting->enabled = 0; + } +} + +/** +* mu3d_hal_unfigured_ep_num - + *@args - + */ +void mu3d_hal_unfigured_ep_num(DEV_UINT8 ep_num, USB_DIR dir) +{ + struct USB_EP_SETTING *ep_setting; + + os_printk(K_INFO, "%s %d\n", __func__, ep_num); + + if (dir == USB_TX) { + USB_WriteCsr32(U3D_TX1CSR0, ep_num, USB_ReadCsr32(U3D_TX1CSR0, ep_num) & (~0x7FF)); + USB_WriteCsr32(U3D_TX1CSR1, ep_num, 0); + USB_WriteCsr32(U3D_TX1CSR2, ep_num, 0); + ep_setting = &g_u3d_setting.ep_setting[ep_num]; + ep_setting->enabled = 0; + } else { + USB_WriteCsr32(U3D_RX1CSR0, ep_num, USB_ReadCsr32(U3D_RX1CSR0, ep_num) & (~0x7FF)); + USB_WriteCsr32(U3D_RX1CSR1, ep_num, 0); + USB_WriteCsr32(U3D_RX1CSR2, ep_num, 0); + ep_setting = &g_u3d_setting.ep_setting[ep_num + MAX_EP_NUM]; + ep_setting->enabled = 0; + } +} + +/** +* mu3d_hal_ep_enable - configure ep +*@args - arg1: ep number, arg2: dir, arg3: transfer type, arg4: max packet size, arg5: interval, arg6: slot, arg7: burst, arg8: mult +*/ +void _ex_mu3d_hal_ep_enable(DEV_UINT8 ep_num, USB_DIR dir, TRANSFER_TYPE type, DEV_INT32 maxp, + DEV_INT8 interval, DEV_INT8 slot, DEV_INT8 burst, DEV_INT8 mult) +{ + DEV_INT32 ep_index = 0; + DEV_INT32 used_before; + DEV_UINT8 fifosz = 0, max_pkt, binterval; + DEV_INT32 csr0, csr1, csr2; + struct USB_EP_SETTING *ep_setting; + DEV_UINT8 update_FIFOadd = 0; + + os_printk(K_INFO, "%s\n", __func__); + + /*TODO: Enable in future. */ + /*Enable Burst, NumP=0, EoB */ + /* os_writel( U3D_USB3_EPCTRL_CAP, os_readl(U3D_USB3_EPCTRL_CAP) | TX_NUMP_0_EN | SET_EOB_EN | TX_BURST_EN); */ + + /* + * Default value of U3D_USB3_EPCTRL_CAP + * 1. tx_burst_en 1'b1 + * 2. set_eob_en 1'b0 + * 3. usb3_iso_crc_chk_dis 1'b1 + * 4. send_stall_clr_pp_en 1'b1 + * 5. tx_nump_0_en 1'b0 + */ + + if (slot > MAX_SLOT) { + os_printk(K_ALET, "[ERROR]Configure wrong slot number(MAX=%d, Not=%d)\n", MAX_SLOT, + slot); + slot = MAX_SLOT; + } + + if (type == USB_CTRL) { + ep_setting = &g_u3d_setting.ep_setting[0]; + ep_setting->fifosz = maxp; + ep_setting->maxp = maxp; + csr0 = os_readl(U3D_EP0CSR) & EP0_W1C_BITS; + csr0 |= maxp; + os_writel(U3D_EP0CSR, csr0); + + os_setmsk(U3D_USB2_RX_EP_DATAERR_INTR, BIT16); /* EP0 data error interrupt */ + return; + } + + if (dir == USB_TX) + ep_index = ep_num; + else if (dir == USB_RX) + ep_index = ep_num + MAX_EP_NUM; + else + BUG_ON(1); + + ep_setting = &g_u3d_setting.ep_setting[ep_index]; + used_before = ep_setting->fifoaddr; + + if (ep_setting->enabled) + return; + + binterval = interval; + if (dir == USB_TX) { + if ((g_TxFIFOadd + maxp * (slot + 1) > os_readl(U3D_CAP_EPNTXFFSZ)) + && (!used_before)) { + os_printk(K_ALET, "mu3d_hal_ep_enable, FAILED: sram exhausted\n"); + os_printk(K_ALET, "g_FIFOadd :%x\n", g_TxFIFOadd); + os_printk(K_ALET, "maxp :%d\n", maxp); + os_printk(K_ALET, "mult :%d\n", slot); + WARN_ON(1); + } + } else { + if ((g_RxFIFOadd + maxp * (slot + 1) > os_readl(U3D_CAP_EPNRXFFSZ)) + && (!used_before)) { + os_printk(K_ALET, "mu3d_hal_ep_enable, FAILED: sram exhausted\n"); + os_printk(K_ALET, "g_FIFOadd :%x\n", g_RxFIFOadd); + os_printk(K_ALET, "maxp :%d\n", maxp); + os_printk(K_ALET, "mult :%d\n", slot); + WARN_ON(1); + } + } + + ep_setting->transfer_type = type; + + if (dir == USB_TX) { + if (!ep_setting->fifoaddr) { + ep_setting->fifoaddr = g_TxFIFOadd; + update_FIFOadd = 1; + } + } else { + if (!ep_setting->fifoaddr) { + ep_setting->fifoaddr = g_RxFIFOadd; + update_FIFOadd = 1; + } + } + + ep_setting->fifosz = maxp; + ep_setting->maxp = maxp; + ep_setting->dir = dir; + ep_setting->enabled = 1; + + /* + * Indicate the Tx/Rx FIFO size of 2^n bytes, (ex: value 10 means 2^10 = 1024 bytes.) + * It means the value of Tx/RxFIFOSz _MUST_ be a power of 2 (2^n). + * It can _NOT_ be 5,48,180 the kind of values. + * TX/RXFIFOSEGSIZE should be equal or bigger than 4. The Tx/RxFIFO + * size of 2^n bytes also should be equal + * or bigger than TX/RXMAXPKTSZ. This EndPoint occupy total memory size + * (TX/RX_SLOT + 1 )*2^TX/RXFIFOSEGSIZE bytes. + */ + if (maxp <= 16) + fifosz = USB_FIFOSZ_SIZE_16; + else if (maxp <= 32) + fifosz = USB_FIFOSZ_SIZE_32; + else if (maxp <= 64) + fifosz = USB_FIFOSZ_SIZE_64; + else if (maxp <= 128) + fifosz = USB_FIFOSZ_SIZE_128; + else if (maxp <= 256) + fifosz = USB_FIFOSZ_SIZE_256; + else if (maxp <= 512) + fifosz = USB_FIFOSZ_SIZE_512; + else if (maxp <= 32768) + fifosz = USB_FIFOSZ_SIZE_1024; + else { + os_printk(K_ERR, "%s Wrong MAXP\n", __func__); + fifosz = USB_FIFOSZ_SIZE_1024; + } + + if (dir == USB_TX) { + /* CSR0 */ + csr0 = USB_ReadCsr32(U3D_TX1CSR0, ep_num) & ~TX_TXMAXPKTSZ; + csr0 |= (maxp & TX_TXMAXPKTSZ); + +#ifdef USE_SSUSB_QMU + /* from SSUSB Device Programming Guide(Revision 0.1) page26 + * TX EP Setting of QMU + * TXnCSR0.TxMaxPktSz + * TXnCSR1.SS_BURST/TxType/TxSlot + * TXnCSR1.Tx_Max_Pkt/Tx_Mult (ISO Only) + * TXnCSR2.TxFIFOAddr/TxFIFOSegSize + * TXnCSR2.TxBInterval (SS ISO/INT Only) + * TxnCSR0.AutoSet = 0 + * TxnCSR0.DMARegEn = 1 + */ + csr0 &= ~TX_AUTOSET; + csr0 |= TX_DMAREQEN; +#else +#ifdef AUTOSET + csr0 |= TX_AUTOSET; +#endif + /*Disable DMA, Use PIO mode */ + csr0 &= ~TX_DMAREQEN; +#endif + + /* CSR1 */ + max_pkt = (burst + 1) * (mult + 1) - 1; + csr1 = (burst & SS_TX_BURST); + csr1 |= (slot << TX_SLOT_OFST) & TX_SLOT; + csr1 |= (max_pkt << TX_MAX_PKT_OFST) & TX_MAX_PKT; + csr1 |= (mult << TX_MULT_OFST) & TX_MULT; + + /* CSR2 */ + csr2 = (ep_setting->fifoaddr >> 4) & TXFIFOADDR; + csr2 |= (fifosz << TXFIFOSEGSIZE_OFST) & TXFIFOSEGSIZE; + + if (type == USB_BULK) { + csr1 |= TYPE_BULK; + } else if (type == USB_INTR) { + csr1 |= TYPE_INT; + csr2 |= (binterval << TXBINTERVAL_OFST) & TXBINTERVAL; + } else if (type == USB_ISO) { + csr1 |= TYPE_ISO; + csr2 |= (binterval << TXBINTERVAL_OFST) & TXBINTERVAL; + } +#ifdef USE_SSUSB_QMU + /*Disable Endpoint interrupt */ + os_setmsk(U3D_EPIECR, (BIT0 << ep_num)); + /* Enable QMU */ + os_setmsk(U3D_QGCSR, QMU_TX_EN(ep_num)); + /* Enable QMU Done interrupt */ + os_setmsk(U3D_QIESR0, QMU_TX_EN(ep_num)); +#endif + USB_WriteCsr32(U3D_TX1CSR0, ep_num, csr0); + USB_WriteCsr32(U3D_TX1CSR1, ep_num, csr1); + USB_WriteCsr32(U3D_TX1CSR2, ep_num, csr2); + + os_printk(K_INFO, "[CSR]U3D_TX%dCSR0 :%x\n", ep_num, + USB_ReadCsr32(U3D_TX1CSR0, ep_num)); + os_printk(K_INFO, "[CSR]U3D_TX%dCSR1 :%x\n", ep_num, + USB_ReadCsr32(U3D_TX1CSR1, ep_num)); + os_printk(K_INFO, "[CSR]U3D_TX%dCSR2 :%x\n", ep_num, + USB_ReadCsr32(U3D_TX1CSR2, ep_num)); + + } else if (dir == USB_RX) { + /* CSR0 */ + csr0 = USB_ReadCsr32(U3D_RX1CSR0, ep_num) & ~RX_RXMAXPKTSZ; + csr0 |= (maxp & RX_RXMAXPKTSZ); + +#ifdef USE_SSUSB_QMU + /* from SSUSB Device Programming Guide(Revision 0.1) page32 + * RX EP Setting of QMU + * RXnCSR0.RxMaxPktSz + * RXnCSR1.SS_BURST/RxType/RxSlot + * RXnCSR1.Rx_Max_Pkt/Rx_Mult (ISO Only) + * RXnCSR2.RxFIFOAddr/RxFIFOSegSize + * RXnCSR2.RxBInterval (SS ISO/INT Only) + * RxnCSR0.AutoClear = 0 + * RxnCSR0.DMARegEn = 1 + */ + csr0 &= ~RX_AUTOCLEAR; + csr0 |= RX_DMAREQEN; +#else +#ifdef AUTOCLEAR + csr0 |= RX_AUTOCLEAR; +#endif + /*Disable DMA, Use PIO mode */ + csr0 &= ~RX_DMAREQEN; +#endif + + /* CSR1 */ + max_pkt = (burst + 1) * (mult + 1) - 1; + csr1 = (burst & SS_RX_BURST); + csr1 |= (slot << RX_SLOT_OFST) & RX_SLOT; + csr1 |= (max_pkt << RX_MAX_PKT_OFST) & RX_MAX_PKT; + csr1 |= (mult << RX_MULT_OFST) & RX_MULT; + + /* CSR2 */ + csr2 = (ep_setting->fifoaddr >> 4) & RXFIFOADDR; + csr2 |= (fifosz << RXFIFOSEGSIZE_OFST) & RXFIFOSEGSIZE; + + if (type == USB_BULK) { + csr1 |= TYPE_BULK; + } else if (type == USB_INTR) { + csr1 |= TYPE_INT; + csr2 |= (binterval << RXBINTERVAL_OFST) & RXBINTERVAL; + } else if (type == USB_ISO) { + csr1 |= TYPE_ISO; + csr2 |= (binterval << RXBINTERVAL_OFST) & RXBINTERVAL; + } +#ifdef USE_SSUSB_QMU + /*Disable Endpoint interrupt */ + os_setmsk(U3D_EPIECR, (BIT16 << ep_num)); + /* Enable QMU */ + os_setmsk(U3D_QGCSR, QMU_TX_EN(ep_num)); + /*Enable QMU Done interrupt */ + os_setmsk(U3D_QIESR0, QMU_RX_EN(ep_num)); +#endif + USB_WriteCsr32(U3D_RX1CSR0, ep_num, csr0); + USB_WriteCsr32(U3D_RX1CSR1, ep_num, csr1); + USB_WriteCsr32(U3D_RX1CSR2, ep_num, csr2); + + os_printk(K_INFO, "[CSR]U3D_RX%dCSR0 :%x\n", ep_num, + USB_ReadCsr32(U3D_RX1CSR0, ep_num)); + os_printk(K_INFO, "[CSR]U3D_RX%dCSR1 :%x\n", ep_num, + USB_ReadCsr32(U3D_RX1CSR1, ep_num)); + os_printk(K_INFO, "[CSR]U3D_RX%dCSR2 :%x\n", ep_num, + USB_ReadCsr32(U3D_RX1CSR2, ep_num)); + + os_setmsk(U3D_USB2_RX_EP_DATAERR_INTR, BIT16 << ep_num); /* EPn data error interrupt */ + } else { + os_printk(K_ERR, "WHAT THE DIRECTION IS?!?!\n"); + BUG_ON(1); + } + + if (update_FIFOadd == 1) { + if (dir == USB_TX) { + /* The minimum unit of FIFO address is _16_ bytes. + * So let the offset of each EP fifo address aligns _16_ bytes.*/ + int fifo_offset = 0; + + if ((maxp & 0xF)) + fifo_offset = ((maxp + 16) >> 4) << 4; + else + fifo_offset = maxp; + + g_TxFIFOadd += (fifo_offset * (slot + 1)); + } else { + int fifo_offset = 0; + + if ((maxp & 0xF)) + fifo_offset = ((maxp + 16) >> 4) << 4; + else + fifo_offset = maxp; + + g_RxFIFOadd += (fifo_offset * (slot + 1)); + } + } +} + +void mu3d_hal_ep_enable(DEV_UINT8 ep_num, USB_DIR dir, TRANSFER_TYPE type, DEV_INT32 maxp, + DEV_INT8 interval, DEV_INT8 slot, DEV_INT8 burst, DEV_INT8 mult) +{ + DEV_INT32 ep_index = 0; + DEV_INT32 used_before; + DEV_UINT8 fifosz = 0, max_pkt, binterval; + DEV_INT32 csr0, csr1, csr2; + struct USB_EP_SETTING *ep_setting; + DEV_UINT8 update_FIFOadd = 0; + + /*Enable Burst, NumP=0, EoB */ + os_writel(U3D_USB3_EPCTRL_CAP, + os_readl(U3D_USB3_EPCTRL_CAP) | TX_NUMP_0_EN | SET_EOB_EN | TX_BURST_EN); + + if (slot > MAX_SLOT) { + os_printk(K_ALET, + "!!!!!!!!!!!!!!Configure wrong slot number!!!!!!!!!(MAX=%d, Not=%d)\n", + MAX_SLOT, slot); + slot = MAX_SLOT; + } + + if (type == USB_CTRL) { + + ep_setting = &g_u3d_setting.ep_setting[0]; + ep_setting->fifosz = maxp; + ep_setting->maxp = maxp; + csr0 = os_readl(U3D_EP0CSR) & EP0_W1C_BITS; + csr0 |= maxp; + os_writel(U3D_EP0CSR, csr0); + + os_setmsk(U3D_USB2_RX_EP_DATAERR_INTR, BIT16); /* EP0 data error interrupt */ + return; + } + + if (dir == USB_TX) + ep_index = ep_num; + else if (dir == USB_RX) + ep_index = ep_num + MAX_EP_NUM; + else + BUG_ON(1); + + ep_setting = &g_u3d_setting.ep_setting[ep_index]; + used_before = ep_setting->fifoaddr; + + if (ep_setting->enabled) + return; + + binterval = interval; + if (dir == USB_TX) { + if ((g_TxFIFOadd + maxp * (slot + 1) > os_readl(U3D_CAP_EPNTXFFSZ)) + && (!used_before)) { + os_printk(K_ALET, "mu3d_hal_ep_enable, FAILED: sram exhausted\n"); + os_printk(K_ALET, "g_FIFOadd :%x\n", g_TxFIFOadd); + os_printk(K_ALET, "maxp :%d\n", maxp); + os_printk(K_ALET, "mult :%d\n", slot); + WARN_ON(1); + } + } else { + if ((g_RxFIFOadd + maxp * (slot + 1) > os_readl(U3D_CAP_EPNRXFFSZ)) + && (!used_before)) { + os_printk(K_ALET, "mu3d_hal_ep_enable, FAILED: sram exhausted\n"); + os_printk(K_ALET, "g_FIFOadd :%x\n", g_RxFIFOadd); + os_printk(K_ALET, "maxp :%d\n", maxp); + os_printk(K_ALET, "mult :%d\n", slot); + WARN_ON(1); + } + } + + ep_setting->transfer_type = type; + + if (dir == USB_TX) { + if (!ep_setting->fifoaddr) { + ep_setting->fifoaddr = g_TxFIFOadd; + update_FIFOadd = 1; + } + } else { + if (!ep_setting->fifoaddr) { + ep_setting->fifoaddr = g_RxFIFOadd; + update_FIFOadd = 1; + } + } + + ep_setting->fifosz = maxp; + ep_setting->maxp = maxp; + ep_setting->dir = dir; + ep_setting->enabled = 1; + + if (maxp <= 16) + fifosz = USB_FIFOSZ_SIZE_16; + else if (maxp <= 32) + fifosz = USB_FIFOSZ_SIZE_32; + else if (maxp <= 64) + fifosz = USB_FIFOSZ_SIZE_64; + else if (maxp <= 128) + fifosz = USB_FIFOSZ_SIZE_128; + else if (maxp <= 256) + fifosz = USB_FIFOSZ_SIZE_256; + else if (maxp <= 512) + fifosz = USB_FIFOSZ_SIZE_512; + else if (maxp <= 32768) + fifosz = USB_FIFOSZ_SIZE_1024; + else { + os_printk(K_ERR, "%s Wrong MAXP\n", __func__); + fifosz = USB_FIFOSZ_SIZE_1024; + } + + if (dir == USB_TX) { + /* CSR0 */ + csr0 = USB_ReadCsr32(U3D_TX1CSR0, ep_num) & ~TX_TXMAXPKTSZ; + csr0 |= (maxp & TX_TXMAXPKTSZ); +#if (BUS_MODE == PIO_MODE) +#ifdef AUTOSET + csr0 |= TX_AUTOSET; +#endif + csr0 &= ~TX_DMAREQEN; +#endif + + /* CSR1 */ + max_pkt = (burst + 1) * (mult + 1) - 1; + csr1 = (burst & SS_TX_BURST); + csr1 |= (slot << TX_SLOT_OFST) & TX_SLOT; + csr1 |= (max_pkt << TX_MAX_PKT_OFST) & TX_MAX_PKT; + csr1 |= (mult << TX_MULT_OFST) & TX_MULT; + + /* CSR2 */ + csr2 = (ep_setting->fifoaddr >> 4) & TXFIFOADDR; + csr2 |= (fifosz << TXFIFOSEGSIZE_OFST) & TXFIFOSEGSIZE; + + if (type == USB_BULK) { + csr1 |= TYPE_BULK; + } else if (type == USB_INTR) { + csr1 |= TYPE_INT; + csr2 |= (binterval << TXBINTERVAL_OFST) & TXBINTERVAL; + } else if (type == USB_ISO) { + csr1 |= TYPE_ISO; + csr2 |= (binterval << TXBINTERVAL_OFST) & TXBINTERVAL; + } +#ifdef USE_SSUSB_QMU + os_writel(U3D_EPIECR, os_readl(U3D_EPIECR) | (BIT0 << ep_num)); +#endif + USB_WriteCsr32(U3D_TX1CSR0, ep_num, csr0); + USB_WriteCsr32(U3D_TX1CSR1, ep_num, csr1); + USB_WriteCsr32(U3D_TX1CSR2, ep_num, csr2); + + os_printk(K_INFO, "[CSR]U3D_TX1CSR0 :%x\n", USB_ReadCsr32(U3D_TX1CSR0, ep_num)); + os_printk(K_INFO, "[CSR]U3D_TX1CSR1 :%x\n", USB_ReadCsr32(U3D_TX1CSR1, ep_num)); + os_printk(K_INFO, "[CSR]U3D_TX1CSR2 :%x\n", USB_ReadCsr32(U3D_TX1CSR2, ep_num)); + + } else if (dir == USB_RX) { + /* CSR0 */ + csr0 = USB_ReadCsr32(U3D_RX1CSR0, ep_num) & ~RX_RXMAXPKTSZ; + csr0 |= (maxp & RX_RXMAXPKTSZ); +#if (BUS_MODE == PIO_MODE) +#ifdef AUTOCLEAR + csr0 |= RX_AUTOCLEAR; +#endif + csr0 &= ~RX_DMAREQEN; +#endif + + /* CSR1 */ + max_pkt = (burst + 1) * (mult + 1) - 1; + csr1 = (burst & SS_RX_BURST); + csr1 |= (slot << RX_SLOT_OFST) & RX_SLOT; + csr1 |= (max_pkt << RX_MAX_PKT_OFST) & RX_MAX_PKT; + csr1 |= (mult << RX_MULT_OFST) & RX_MULT; + + /* CSR2 */ + csr2 = (ep_setting->fifoaddr >> 4) & RXFIFOADDR; + csr2 |= (fifosz << RXFIFOSEGSIZE_OFST) & RXFIFOSEGSIZE; + + if (type == USB_BULK) { + csr1 |= TYPE_BULK; + } else if (type == USB_INTR) { + csr1 |= TYPE_INT; + csr2 |= (binterval << RXBINTERVAL_OFST) & RXBINTERVAL; + } else if (type == USB_ISO) { + csr1 |= TYPE_ISO; + csr2 |= (binterval << RXBINTERVAL_OFST) & RXBINTERVAL; + } +#ifdef USE_SSUSB_QMU + os_writel(U3D_EPIECR, os_readl(U3D_EPIECR) | (BIT16 << ep_num)); +#endif + USB_WriteCsr32(U3D_RX1CSR0, ep_num, csr0); + USB_WriteCsr32(U3D_RX1CSR1, ep_num, csr1); + USB_WriteCsr32(U3D_RX1CSR2, ep_num, csr2); + + os_printk(K_INFO, "[CSR]U3D_RX1CSR0 :%x\n", USB_ReadCsr32(U3D_RX1CSR0, ep_num)); + os_printk(K_INFO, "[CSR]U3D_RX1CSR1 :%x\n", USB_ReadCsr32(U3D_RX1CSR1, ep_num)); + os_printk(K_INFO, "[CSR]U3D_RX1CSR2 :%x\n", USB_ReadCsr32(U3D_RX1CSR2, ep_num)); + + os_setmsk(U3D_USB2_RX_EP_DATAERR_INTR, BIT16 << ep_num); /* EPn data error interrupt */ + } else { + os_printk(K_ERR, "WHAT THE DIRECTION IS?!?!\n"); + BUG_ON(1); + } + + if (update_FIFOadd == 1) { + if (dir == USB_TX) { + if (maxp == 1023) + g_TxFIFOadd += (1024 * (slot + 1)); + else + g_TxFIFOadd += (maxp * (slot + 1)); + } else { + if (maxp == 1023) + g_RxFIFOadd += (1024 * (slot + 1)); + else + g_RxFIFOadd += (maxp * (slot + 1)); + } + } +} diff --git a/drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.h b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.h new file mode 100644 index 000000000000..bcae9e407ef3 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.h @@ -0,0 +1,193 @@ + +#ifndef MTK_USB_DRV_H +#define MTK_USB_DRV_H + +#include "mu3d_hal_hw.h" +#undef EXTERN + +#ifdef _MTK_USB_DRV_EXT_ +#define EXTERN +#else +#define EXTERN \ +extern +#endif + + + +#define MAX_EP_NUM 8 /* 4 Tx and 4 Rx */ +#define USB_BUF_SIZE 65536 +#define MAX_SLOT (2-1) + +/*EP0, TX, RX has separate SRAMs*/ +#define USB_TX_FIFO_START_ADDRESS 0 +#define USB_RX_FIFO_START_ADDRESS 0 + +#ifndef IRQ_USB_MC_NINT_CODE +#define IRQ_USB_MC_NINT_CODE 8 +#endif +#ifndef IRQ_USB_DMA_NINT_CODE +#define IRQ_USB_DMA_NINT_CODE 9 +#endif + +/* IN, OUT pipe index for ep_number */ +typedef enum { + USB_TX = 0, + USB_RX +} USB_DIR; + +/* CTRL, BULK, INTR, ISO endpoint */ +typedef enum { + USB_CTRL = 0, + USB_BULK = 2, + USB_INTR = 3, + USB_ISO = 1 +} TRANSFER_TYPE; + +typedef enum { + SSUSB_SPEED_INACTIVE = 0, + SSUSB_SPEED_FULL = 1, + SSUSB_SPEED_HIGH = 3, + SSUSB_SPEED_SUPER = 4, +} USB_SPEED; + +typedef enum { + EP0_IDLE = 0, + EP0_TX, + EP0_RX, +} EP0_STATE; + +struct USB_EP_SETTING { + TRANSFER_TYPE transfer_type; + DEV_UINT32 fifoaddr; + DEV_UINT32 fifosz; + DEV_UINT32 maxp; + USB_DIR dir; + DEV_UINT8 enabled; +}; + +struct USB_REQ { + DEV_UINT8 *buf; + /* DEV_UINT8* dma_adr; */ + dma_addr_t dma_adr; + DEV_UINT32 actual; + DEV_UINT32 count; + DEV_UINT32 currentCount; + DEV_UINT32 complete; + DEV_UINT32 needZLP; + DEV_UINT32 transferCount; +}; + +struct USB_TEST_SETTING { + USB_SPEED speed; + struct USB_EP_SETTING ep_setting[2 * MAX_EP_NUM + 1]; +}; + +/*============================================= +* +* USB 3 test +* +*=============================================*/ + +/* #define NUM_TXENDPS 4 */ +/* #define NUM_RXENDPS 4 */ +/* #define NUM_EPS (NUM_TXENDPS + NUM_RXENDPS + 1) */ + +/* #define MGC_END0_FIFOSIZE 64 */ +/* #define MGC_RX_DMA_ENABLE_LEVEL 32 */ + +/* #define IsDbf 0x00000001 */ +/* #define IsTx 0x00000002 */ +/* #define IsHalt 0x00000004 */ +/* #define IsEnabled 0x80000000 */ + +/* #define REQUEST_START_TX 0x1 */ +/* #define REQUEST_START_RX 0x2 */ + + + /* + * USB directions + * + * This bit flag is used in endpoint descriptors' bEndpointAddress field. + * It's also one of three fields in control requests bRequestType. + */ +#define USB_DIR_OUT 0 /* to device */ +#define USB_DIR_IN 0x80 /* to host */ +#define USB_DIR_MASK 0x80 /* to host */ + + /* + * USB request types + */ + +#define USB_TYPE_MASK (0x03 << 5) +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + + + /* + * Standard requests + */ +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C +#define USB_REQ_EP0_IN_STALL 0xFD +#define USB_REQ_EP0_OUT_STALL 0xFE +#define USB_REQ_EP0_STALL 0xFF + + + + +EXTERN struct USB_REQ g_u3d_req[2 * MAX_EP_NUM + 1]; +EXTERN struct USB_TEST_SETTING g_u3d_setting; +EXTERN DEV_UINT32 g_TxFIFOadd; +EXTERN DEV_UINT32 g_RxFIFOadd; + + +EXTERN struct USB_REQ *mu3d_hal_get_req(DEV_INT32 ep_num, USB_DIR dir); +EXTERN void mu3d_hal_pdn_dis(void); +EXTERN void mu3d_hal_ssusb_en(void); +EXTERN void _ex_mu3d_hal_ssusb_en(void); +EXTERN void mu3d_hal_rst_dev(void); +EXTERN DEV_INT32 mu3d_hal_check_clk_sts(void); +EXTERN DEV_INT32 mu3d_hal_link_up(DEV_INT32 latch_val); +EXTERN void mu3d_hal_initr_dis(void); +EXTERN void mu3d_hal_clear_intr(void); +EXTERN void mu3d_hal_system_intr_en(void); +EXTERN void _ex_mu3d_hal_system_intr_en(void); +EXTERN DEV_INT32 mu3d_hal_read_fifo_burst(DEV_INT32 ep_num, DEV_UINT8 *buf); +EXTERN DEV_INT32 mu3d_hal_read_fifo(DEV_INT32 ep_num, DEV_UINT8 *buf); +EXTERN DEV_INT32 mu3d_hal_write_fifo_burst(DEV_INT32 ep_num, DEV_INT32 length, DEV_UINT8 *buf, + DEV_INT32 maxp); +EXTERN DEV_INT32 mu3d_hal_write_fifo(DEV_INT32 ep_num, DEV_INT32 length, DEV_UINT8 *buf, + DEV_INT32 maxp); +EXTERN void _ex_mu3d_hal_ep_enable(DEV_UINT8 ep_num, USB_DIR dir, TRANSFER_TYPE type, + DEV_INT32 maxp, DEV_INT8 interval, DEV_INT8 slot, DEV_INT8 burst, + DEV_INT8 mult); +EXTERN void mu3d_hal_ep_enable(DEV_UINT8 ep_num, USB_DIR dir, TRANSFER_TYPE type, DEV_INT32 maxp, + DEV_INT8 interval, DEV_INT8 slot, DEV_INT8 burst, DEV_INT8 mult); +EXTERN void mu3d_hal_resume(void); +EXTERN void mu3d_hal_u2dev_connect(void); +EXTERN void mu3d_hal_u2dev_disconn(void); +EXTERN void mu3d_hal_u3dev_en(void); +EXTERN void mu3d_hal_u3dev_dis(void); +EXTERN void mu3d_hal_unfigured_ep(void); +EXTERN void mu3d_hal_unfigured_ep_num(DEV_UINT8 ep_num, USB_DIR dir); +EXTERN void mu3d_hal_set_speed(USB_SPEED usb_speed); +EXTERN void mu3d_hal_det_speed(USB_SPEED speed, DEV_UINT8 det_speed); +EXTERN void mu3d_hal_pdn_cg_en(void); +EXTERN void mu3d_hal_pdn_ip_port(DEV_UINT8 on, DEV_UINT8 touch_dis, DEV_UINT8 u3, DEV_UINT8 u2); +EXTERN void mu3d_hal_dft_reg(void); + +#undef EXTERN + + +#endif /* USB_DRV_H */ diff --git a/drivers/misc/mediatek/mu3d/hal/ssusb_dev_c_header.h b/drivers/misc/mediatek/mu3d/hal/ssusb_dev_c_header.h new file mode 100644 index 000000000000..2a4e27bbeae2 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/ssusb_dev_c_header.h @@ -0,0 +1,3727 @@ +/* SSUSB_DEV REGISTER DEFINITION */ + +#define U3D_LV1ISR (SSUSB_DEV_BASE+0x0000) +#define U3D_LV1IER (SSUSB_DEV_BASE+0x0004) +#define U3D_LV1IESR (SSUSB_DEV_BASE+0x0008) +#define U3D_LV1IECR (SSUSB_DEV_BASE+0x000C) +#define U3D_AXI_WR_DMA_CFG (SSUSB_DEV_BASE+0x0020) +#define U3D_AXI_RD_DMA_CFG (SSUSB_DEV_BASE+0x0024) +#define U3D_MAC_U1_EN_CTRL (SSUSB_DEV_BASE+0x0030) +#define U3D_MAC_U2_EN_CTRL (SSUSB_DEV_BASE+0x0034) +#define U3D_SRAM_DBG_CTRL (SSUSB_DEV_BASE+0x0040) +#define U3D_SRAM_DBG_CTRL_1 (SSUSB_DEV_BASE+0x0044) +#define U3D_RISC_SIZE (SSUSB_DEV_BASE+0x0050) +#define U3D_WRBUF_ERR_STS (SSUSB_DEV_BASE+0x0070) +#define U3D_BUF_ERR_EN (SSUSB_DEV_BASE+0x0074) +#define U3D_EPISR (SSUSB_DEV_BASE+0x0080) +#define U3D_EPIER (SSUSB_DEV_BASE+0x0084) +#define U3D_EPIESR (SSUSB_DEV_BASE+0x0088) +#define U3D_EPIECR (SSUSB_DEV_BASE+0x008C) +#define U3D_DMAISR (SSUSB_DEV_BASE+0x0090) +#define U3D_DMAIER (SSUSB_DEV_BASE+0x0094) +#define U3D_DMAIESR (SSUSB_DEV_BASE+0x0098) +#define U3D_DMAIECR (SSUSB_DEV_BASE+0x009C) +#define U3D_EP0DMACTRL (SSUSB_DEV_BASE+0x00C0) +#define U3D_EP0DMASTRADDR (SSUSB_DEV_BASE+0x00C4) +#define U3D_EP0DMATFRCOUNT (SSUSB_DEV_BASE+0x00C8) +#define U3D_EP0DMARLCOUNT (SSUSB_DEV_BASE+0x00CC) +#define U3D_TXDMACTRL (SSUSB_DEV_BASE+0x00D0) +#define U3D_TXDMASTRADDR (SSUSB_DEV_BASE+0x00D4) +#define U3D_TXDMATRDCNT (SSUSB_DEV_BASE+0x00D8) +#define U3D_TXDMARLCOUNT (SSUSB_DEV_BASE+0x00DC) +#define U3D_RXDMACTRL (SSUSB_DEV_BASE+0x00E0) +#define U3D_RXDMASTRADDR (SSUSB_DEV_BASE+0x00E4) +#define U3D_RXDMATRDCNT (SSUSB_DEV_BASE+0x00E8) +#define U3D_RXDMARLCOUNT (SSUSB_DEV_BASE+0x00EC) +#define U3D_EP0CSR (SSUSB_DEV_BASE+0x0100) +#define U3D_RXCOUNT0 (SSUSB_DEV_BASE+0x0108) +#define U3D_RESERVED (SSUSB_DEV_BASE+0x010C) +#define U3D_TX1CSR0 (SSUSB_DEV_BASE+0x0110) +#define U3D_TX1CSR1 (SSUSB_DEV_BASE+0x0114) +#define U3D_TX1CSR2 (SSUSB_DEV_BASE+0x0118) +#define U3D_TX2CSR0 (SSUSB_DEV_BASE+0x0120) +#define U3D_TX2CSR1 (SSUSB_DEV_BASE+0x0124) +#define U3D_TX2CSR2 (SSUSB_DEV_BASE+0x0128) +#define U3D_TX3CSR0 (SSUSB_DEV_BASE+0x0130) +#define U3D_TX3CSR1 (SSUSB_DEV_BASE+0x0134) +#define U3D_TX3CSR2 (SSUSB_DEV_BASE+0x0138) +#define U3D_TX4CSR0 (SSUSB_DEV_BASE+0x0140) +#define U3D_TX4CSR1 (SSUSB_DEV_BASE+0x0144) +#define U3D_TX4CSR2 (SSUSB_DEV_BASE+0x0148) +#define U3D_TX5CSR0 (SSUSB_DEV_BASE+0x0150) +#define U3D_TX5CSR1 (SSUSB_DEV_BASE+0x0154) +#define U3D_TX5CSR2 (SSUSB_DEV_BASE+0x0158) +#define U3D_TX6CSR0 (SSUSB_DEV_BASE+0x0160) +#define U3D_TX6CSR1 (SSUSB_DEV_BASE+0x0164) +#define U3D_TX6CSR2 (SSUSB_DEV_BASE+0x0168) +#define U3D_TX7CSR0 (SSUSB_DEV_BASE+0x0170) +#define U3D_TX7CSR1 (SSUSB_DEV_BASE+0x0174) +#define U3D_TX7CSR2 (SSUSB_DEV_BASE+0x0178) +#define U3D_TX8CSR0 (SSUSB_DEV_BASE+0x0180) +#define U3D_TX8CSR1 (SSUSB_DEV_BASE+0x0184) +#define U3D_TX8CSR2 (SSUSB_DEV_BASE+0x0188) +#define U3D_TX9CSR0 (SSUSB_DEV_BASE+0x0190) +#define U3D_TX9CSR1 (SSUSB_DEV_BASE+0x0194) +#define U3D_TX9CSR2 (SSUSB_DEV_BASE+0x0198) +#define U3D_TX10CSR0 (SSUSB_DEV_BASE+0x01A0) +#define U3D_TX10CSR1 (SSUSB_DEV_BASE+0x01A4) +#define U3D_TX10CSR2 (SSUSB_DEV_BASE+0x01A8) +#define U3D_TX11CSR0 (SSUSB_DEV_BASE+0x01B0) +#define U3D_TX11CSR1 (SSUSB_DEV_BASE+0x01B4) +#define U3D_TX11CSR2 (SSUSB_DEV_BASE+0x01B8) +#define U3D_TX12CSR0 (SSUSB_DEV_BASE+0x01C0) +#define U3D_TX12CSR1 (SSUSB_DEV_BASE+0x01C4) +#define U3D_TX12CSR2 (SSUSB_DEV_BASE+0x01C8) +#define U3D_TX13CSR0 (SSUSB_DEV_BASE+0x01D0) +#define U3D_TX13CSR1 (SSUSB_DEV_BASE+0x01D4) +#define U3D_TX13CSR2 (SSUSB_DEV_BASE+0x01D8) +#define U3D_TX14CSR0 (SSUSB_DEV_BASE+0x01E0) +#define U3D_TX14CSR1 (SSUSB_DEV_BASE+0x01E4) +#define U3D_TX14CSR2 (SSUSB_DEV_BASE+0x01E8) +#define U3D_TX15CSR0 (SSUSB_DEV_BASE+0x01F0) +#define U3D_TX15CSR1 (SSUSB_DEV_BASE+0x01F4) +#define U3D_TX15CSR2 (SSUSB_DEV_BASE+0x01F8) +#define U3D_RX1CSR0 (SSUSB_DEV_BASE+0x0210) +#define U3D_RX1CSR1 (SSUSB_DEV_BASE+0x0214) +#define U3D_RX1CSR2 (SSUSB_DEV_BASE+0x0218) +#define U3D_RX1CSR3 (SSUSB_DEV_BASE+0x021C) +#define U3D_RX2CSR0 (SSUSB_DEV_BASE+0x0220) +#define U3D_RX2CSR1 (SSUSB_DEV_BASE+0x0224) +#define U3D_RX2CSR2 (SSUSB_DEV_BASE+0x0228) +#define U3D_RX2CSR3 (SSUSB_DEV_BASE+0x022C) +#define U3D_RX3CSR0 (SSUSB_DEV_BASE+0x0230) +#define U3D_RX3CSR1 (SSUSB_DEV_BASE+0x0234) +#define U3D_RX3CSR2 (SSUSB_DEV_BASE+0x0238) +#define U3D_RX3CSR3 (SSUSB_DEV_BASE+0x023C) +#define U3D_RX4CSR0 (SSUSB_DEV_BASE+0x0240) +#define U3D_RX4CSR1 (SSUSB_DEV_BASE+0x0244) +#define U3D_RX4CSR2 (SSUSB_DEV_BASE+0x0248) +#define U3D_RX4CSR3 (SSUSB_DEV_BASE+0x024C) +#define U3D_RX5CSR0 (SSUSB_DEV_BASE+0x0250) +#define U3D_RX5CSR1 (SSUSB_DEV_BASE+0x0254) +#define U3D_RX5CSR2 (SSUSB_DEV_BASE+0x0258) +#define U3D_RX5CSR3 (SSUSB_DEV_BASE+0x025C) +#define U3D_RX6CSR0 (SSUSB_DEV_BASE+0x0260) +#define U3D_RX6CSR1 (SSUSB_DEV_BASE+0x0264) +#define U3D_RX6CSR2 (SSUSB_DEV_BASE+0x0268) +#define U3D_RX6CSR3 (SSUSB_DEV_BASE+0x026C) +#define U3D_RX7CSR0 (SSUSB_DEV_BASE+0x0270) +#define U3D_RX7CSR1 (SSUSB_DEV_BASE+0x0274) +#define U3D_RX7CSR2 (SSUSB_DEV_BASE+0x0278) +#define U3D_RX7CSR3 (SSUSB_DEV_BASE+0x027C) +#define U3D_RX8CSR0 (SSUSB_DEV_BASE+0x0280) +#define U3D_RX8CSR1 (SSUSB_DEV_BASE+0x0284) +#define U3D_RX8CSR2 (SSUSB_DEV_BASE+0x0288) +#define U3D_RX8CSR3 (SSUSB_DEV_BASE+0x028C) +#define U3D_RX9CSR0 (SSUSB_DEV_BASE+0x0290) +#define U3D_RX9CSR1 (SSUSB_DEV_BASE+0x0294) +#define U3D_RX9CSR2 (SSUSB_DEV_BASE+0x0298) +#define U3D_RX9CSR3 (SSUSB_DEV_BASE+0x029C) +#define U3D_RX10CSR0 (SSUSB_DEV_BASE+0x02A0) +#define U3D_RX10CSR1 (SSUSB_DEV_BASE+0x02A4) +#define U3D_RX10CSR2 (SSUSB_DEV_BASE+0x02A8) +#define U3D_RX10CSR3 (SSUSB_DEV_BASE+0x02AC) +#define U3D_RX11CSR0 (SSUSB_DEV_BASE+0x02B0) +#define U3D_RX11CSR1 (SSUSB_DEV_BASE+0x02B4) +#define U3D_RX11CSR2 (SSUSB_DEV_BASE+0x02B8) +#define U3D_RX11CSR3 (SSUSB_DEV_BASE+0x02BC) +#define U3D_RX12CSR0 (SSUSB_DEV_BASE+0x02C0) +#define U3D_RX12CSR1 (SSUSB_DEV_BASE+0x02C4) +#define U3D_RX12CSR2 (SSUSB_DEV_BASE+0x02C8) +#define U3D_RX12CSR3 (SSUSB_DEV_BASE+0x02CC) +#define U3D_RX13CSR0 (SSUSB_DEV_BASE+0x02D0) +#define U3D_RX13CSR1 (SSUSB_DEV_BASE+0x02D4) +#define U3D_RX13CSR2 (SSUSB_DEV_BASE+0x02D8) +#define U3D_RX13CSR3 (SSUSB_DEV_BASE+0x02DC) +#define U3D_RX14CSR0 (SSUSB_DEV_BASE+0x02E0) +#define U3D_RX14CSR1 (SSUSB_DEV_BASE+0x02E4) +#define U3D_RX14CSR2 (SSUSB_DEV_BASE+0x02E8) +#define U3D_RX14CSR3 (SSUSB_DEV_BASE+0x02EC) +#define U3D_RX15CSR0 (SSUSB_DEV_BASE+0x02F0) +#define U3D_RX15CSR1 (SSUSB_DEV_BASE+0x02F4) +#define U3D_RX15CSR2 (SSUSB_DEV_BASE+0x02F8) +#define U3D_RX15CSR3 (SSUSB_DEV_BASE+0x02FC) +#define U3D_FIFO0 (SSUSB_DEV_BASE+0x0300) +#define U3D_FIFO1 (SSUSB_DEV_BASE+0x0310) +#define U3D_FIFO2 (SSUSB_DEV_BASE+0x0320) +#define U3D_FIFO3 (SSUSB_DEV_BASE+0x0330) +#define U3D_FIFO4 (SSUSB_DEV_BASE+0x0340) +#define U3D_FIFO5 (SSUSB_DEV_BASE+0x0350) +#define U3D_FIFO6 (SSUSB_DEV_BASE+0x0360) +#define U3D_FIFO7 (SSUSB_DEV_BASE+0x0370) +#define U3D_FIFO8 (SSUSB_DEV_BASE+0x0380) +#define U3D_FIFO9 (SSUSB_DEV_BASE+0x0390) +#define U3D_FIFO10 (SSUSB_DEV_BASE+0x03A0) +#define U3D_FIFO11 (SSUSB_DEV_BASE+0x03B0) +#define U3D_FIFO12 (SSUSB_DEV_BASE+0x03C0) +#define U3D_FIFO13 (SSUSB_DEV_BASE+0x03D0) +#define U3D_FIFO14 (SSUSB_DEV_BASE+0x03E0) +#define U3D_FIFO15 (SSUSB_DEV_BASE+0x03F0) +#define U3D_QCR0 (SSUSB_DEV_BASE+0x0400) +#define U3D_QCR1 (SSUSB_DEV_BASE+0x0404) +#define U3D_QCR2 (SSUSB_DEV_BASE+0x0408) +#define U3D_QCR3 (SSUSB_DEV_BASE+0x040C) +#define U3D_QGCSR (SSUSB_DEV_BASE+0x0410) +#define U3D_TXQCSR1 (SSUSB_DEV_BASE+0x0510) +#define U3D_TXQSAR1 (SSUSB_DEV_BASE+0x0514) +#define U3D_TXQCPR1 (SSUSB_DEV_BASE+0x0518) +#define U3D_TXQCSR2 (SSUSB_DEV_BASE+0x0520) +#define U3D_TXQSAR2 (SSUSB_DEV_BASE+0x0524) +#define U3D_TXQCPR2 (SSUSB_DEV_BASE+0x0528) +#define U3D_TXQCSR3 (SSUSB_DEV_BASE+0x0530) +#define U3D_TXQSAR3 (SSUSB_DEV_BASE+0x0534) +#define U3D_TXQCPR3 (SSUSB_DEV_BASE+0x0538) +#define U3D_TXQCSR4 (SSUSB_DEV_BASE+0x0540) +#define U3D_TXQSAR4 (SSUSB_DEV_BASE+0x0544) +#define U3D_TXQCPR4 (SSUSB_DEV_BASE+0x0548) +#define U3D_TXQCSR5 (SSUSB_DEV_BASE+0x0550) +#define U3D_TXQSAR5 (SSUSB_DEV_BASE+0x0554) +#define U3D_TXQCPR5 (SSUSB_DEV_BASE+0x0558) +#define U3D_TXQCSR6 (SSUSB_DEV_BASE+0x0560) +#define U3D_TXQSAR6 (SSUSB_DEV_BASE+0x0564) +#define U3D_TXQCPR6 (SSUSB_DEV_BASE+0x0568) +#define U3D_TXQCSR7 (SSUSB_DEV_BASE+0x0570) +#define U3D_TXQSAR7 (SSUSB_DEV_BASE+0x0574) +#define U3D_TXQCPR7 (SSUSB_DEV_BASE+0x0578) +#define U3D_TXQCSR8 (SSUSB_DEV_BASE+0x0580) +#define U3D_TXQSAR8 (SSUSB_DEV_BASE+0x0584) +#define U3D_TXQCPR8 (SSUSB_DEV_BASE+0x0588) +#define U3D_TXQCSR9 (SSUSB_DEV_BASE+0x0590) +#define U3D_TXQSAR9 (SSUSB_DEV_BASE+0x0594) +#define U3D_TXQCPR9 (SSUSB_DEV_BASE+0x0598) +#define U3D_TXQCSR10 (SSUSB_DEV_BASE+0x05A0) +#define U3D_TXQSAR10 (SSUSB_DEV_BASE+0x05A4) +#define U3D_TXQCPR10 (SSUSB_DEV_BASE+0x05A8) +#define U3D_TXQCSR11 (SSUSB_DEV_BASE+0x05B0) +#define U3D_TXQSAR11 (SSUSB_DEV_BASE+0x05B4) +#define U3D_TXQCPR11 (SSUSB_DEV_BASE+0x05B8) +#define U3D_TXQCSR12 (SSUSB_DEV_BASE+0x05C0) +#define U3D_TXQSAR12 (SSUSB_DEV_BASE+0x05C4) +#define U3D_TXQCPR12 (SSUSB_DEV_BASE+0x05C8) +#define U3D_TXQCSR13 (SSUSB_DEV_BASE+0x05D0) +#define U3D_TXQSAR13 (SSUSB_DEV_BASE+0x05D4) +#define U3D_TXQCPR13 (SSUSB_DEV_BASE+0x05D8) +#define U3D_TXQCSR14 (SSUSB_DEV_BASE+0x05E0) +#define U3D_TXQSAR14 (SSUSB_DEV_BASE+0x05E4) +#define U3D_TXQCPR14 (SSUSB_DEV_BASE+0x05E8) +#define U3D_TXQCSR15 (SSUSB_DEV_BASE+0x05F0) +#define U3D_TXQSAR15 (SSUSB_DEV_BASE+0x05F4) +#define U3D_TXQCPR15 (SSUSB_DEV_BASE+0x05F8) +#define U3D_RXQCSR1 (SSUSB_DEV_BASE+0x0610) +#define U3D_RXQSAR1 (SSUSB_DEV_BASE+0x0614) +#define U3D_RXQCPR1 (SSUSB_DEV_BASE+0x0618) +#define U3D_RXQLDPR1 (SSUSB_DEV_BASE+0x061C) +#define U3D_RXQCSR2 (SSUSB_DEV_BASE+0x0620) +#define U3D_RXQSAR2 (SSUSB_DEV_BASE+0x0624) +#define U3D_RXQCPR2 (SSUSB_DEV_BASE+0x0628) +#define U3D_RXQLDPR2 (SSUSB_DEV_BASE+0x062C) +#define U3D_RXQCSR3 (SSUSB_DEV_BASE+0x0630) +#define U3D_RXQSAR3 (SSUSB_DEV_BASE+0x0634) +#define U3D_RXQCPR3 (SSUSB_DEV_BASE+0x0638) +#define U3D_RXQLDPR3 (SSUSB_DEV_BASE+0x063C) +#define U3D_RXQCSR4 (SSUSB_DEV_BASE+0x0640) +#define U3D_RXQSAR4 (SSUSB_DEV_BASE+0x0644) +#define U3D_RXQCPR4 (SSUSB_DEV_BASE+0x0648) +#define U3D_RXQLDPR4 (SSUSB_DEV_BASE+0x064C) +#define U3D_RXQCSR5 (SSUSB_DEV_BASE+0x0650) +#define U3D_RXQSAR5 (SSUSB_DEV_BASE+0x0654) +#define U3D_RXQCPR5 (SSUSB_DEV_BASE+0x0658) +#define U3D_RXQLDPR5 (SSUSB_DEV_BASE+0x065C) +#define U3D_RXQCSR6 (SSUSB_DEV_BASE+0x0660) +#define U3D_RXQSAR6 (SSUSB_DEV_BASE+0x0664) +#define U3D_RXQCPR6 (SSUSB_DEV_BASE+0x0668) +#define U3D_RXQLDPR6 (SSUSB_DEV_BASE+0x066C) +#define U3D_RXQCSR7 (SSUSB_DEV_BASE+0x0670) +#define U3D_RXQSAR7 (SSUSB_DEV_BASE+0x0674) +#define U3D_RXQCPR7 (SSUSB_DEV_BASE+0x0678) +#define U3D_RXQLDPR7 (SSUSB_DEV_BASE+0x067C) +#define U3D_RXQCSR8 (SSUSB_DEV_BASE+0x0680) +#define U3D_RXQSAR8 (SSUSB_DEV_BASE+0x0684) +#define U3D_RXQCPR8 (SSUSB_DEV_BASE+0x0688) +#define U3D_RXQLDPR8 (SSUSB_DEV_BASE+0x068C) +#define U3D_RXQCSR9 (SSUSB_DEV_BASE+0x0690) +#define U3D_RXQSAR9 (SSUSB_DEV_BASE+0x0694) +#define U3D_RXQCPR9 (SSUSB_DEV_BASE+0x0698) +#define U3D_RXQLDPR9 (SSUSB_DEV_BASE+0x069C) +#define U3D_RXQCSR10 (SSUSB_DEV_BASE+0x06A0) +#define U3D_RXQSAR10 (SSUSB_DEV_BASE+0x06A4) +#define U3D_RXQCPR10 (SSUSB_DEV_BASE+0x06A8) +#define U3D_RXQLDPR10 (SSUSB_DEV_BASE+0x06AC) +#define U3D_RXQCSR11 (SSUSB_DEV_BASE+0x06B0) +#define U3D_RXQSAR11 (SSUSB_DEV_BASE+0x06B4) +#define U3D_RXQCPR11 (SSUSB_DEV_BASE+0x06B8) +#define U3D_RXQLDPR11 (SSUSB_DEV_BASE+0x06BC) +#define U3D_RXQCSR12 (SSUSB_DEV_BASE+0x06C0) +#define U3D_RXQSAR12 (SSUSB_DEV_BASE+0x06C4) +#define U3D_RXQCPR12 (SSUSB_DEV_BASE+0x06C8) +#define U3D_RXQLDPR12 (SSUSB_DEV_BASE+0x06CC) +#define U3D_RXQCSR13 (SSUSB_DEV_BASE+0x06D0) +#define U3D_RXQSAR13 (SSUSB_DEV_BASE+0x06D4) +#define U3D_RXQCPR13 (SSUSB_DEV_BASE+0x06D8) +#define U3D_RXQLDPR13 (SSUSB_DEV_BASE+0x06DC) +#define U3D_RXQCSR14 (SSUSB_DEV_BASE+0x06E0) +#define U3D_RXQSAR14 (SSUSB_DEV_BASE+0x06E4) +#define U3D_RXQCPR14 (SSUSB_DEV_BASE+0x06E8) +#define U3D_RXQLDPR14 (SSUSB_DEV_BASE+0x06EC) +#define U3D_RXQCSR15 (SSUSB_DEV_BASE+0x06F0) +#define U3D_RXQSAR15 (SSUSB_DEV_BASE+0x06F4) +#define U3D_RXQCPR15 (SSUSB_DEV_BASE+0x06F8) +#define U3D_RXQLDPR15 (SSUSB_DEV_BASE+0x06FC) +#define U3D_QISAR0 (SSUSB_DEV_BASE+0x0700) +#define U3D_QIER0 (SSUSB_DEV_BASE+0x0704) +#define U3D_QIESR0 (SSUSB_DEV_BASE+0x0708) +#define U3D_QIECR0 (SSUSB_DEV_BASE+0x070C) +#define U3D_QISAR1 (SSUSB_DEV_BASE+0x0710) +#define U3D_QIER1 (SSUSB_DEV_BASE+0x0714) +#define U3D_QIESR1 (SSUSB_DEV_BASE+0x0718) +#define U3D_QIECR1 (SSUSB_DEV_BASE+0x071C) +#define U3D_QEMIR (SSUSB_DEV_BASE+0x0740) +#define U3D_QEMIER (SSUSB_DEV_BASE+0x0744) +#define U3D_QEMIESR (SSUSB_DEV_BASE+0x0748) +#define U3D_QEMIECR (SSUSB_DEV_BASE+0x074C) +#define U3D_TQERRIR0 (SSUSB_DEV_BASE+0x0780) +#define U3D_TQERRIER0 (SSUSB_DEV_BASE+0x0784) +#define U3D_TQERRIESR0 (SSUSB_DEV_BASE+0x0788) +#define U3D_TQERRIECR0 (SSUSB_DEV_BASE+0x078C) +#define U3D_RQERRIR0 (SSUSB_DEV_BASE+0x07C0) +#define U3D_RQERRIER0 (SSUSB_DEV_BASE+0x07C4) +#define U3D_RQERRIESR0 (SSUSB_DEV_BASE+0x07C8) +#define U3D_RQERRIECR0 (SSUSB_DEV_BASE+0x07CC) +#define U3D_RQERRIR1 (SSUSB_DEV_BASE+0x07D0) +#define U3D_RQERRIER1 (SSUSB_DEV_BASE+0x07D4) +#define U3D_RQERRIESR1 (SSUSB_DEV_BASE+0x07D8) +#define U3D_RQERRIECR1 (SSUSB_DEV_BASE+0x07DC) +#define U3D_CAP_EP0FFSZ (SSUSB_DEV_BASE+0x0C04) +#define U3D_CAP_EPNTXFFSZ (SSUSB_DEV_BASE+0x0C08) +#define U3D_CAP_EPNRXFFSZ (SSUSB_DEV_BASE+0x0C0C) +#define U3D_CAP_EPINFO (SSUSB_DEV_BASE+0x0C10) +#define U3D_CAP_TX_SLOT1 (SSUSB_DEV_BASE+0x0C20) +#define U3D_CAP_TX_SLOT2 (SSUSB_DEV_BASE+0x0C24) +#define U3D_CAP_TX_SLOT3 (SSUSB_DEV_BASE+0x0C28) +#define U3D_CAP_TX_SLOT4 (SSUSB_DEV_BASE+0x0C2C) +#define U3D_CAP_RX_SLOT1 (SSUSB_DEV_BASE+0x0C30) +#define U3D_CAP_RX_SLOT2 (SSUSB_DEV_BASE+0x0C34) +#define U3D_CAP_RX_SLOT3 (SSUSB_DEV_BASE+0x0C38) +#define U3D_CAP_RX_SLOT4 (SSUSB_DEV_BASE+0x0C3C) +#define U3D_MISC_CTRL (SSUSB_DEV_BASE+0x0C84) + +/* SSUSB_DEV FIELD DEFINITION */ + +/* U3D_LV1ISR */ +#define EP_CTRL_INTR (0x1<<5) /* 5:5 */ +#define MAC2_INTR (0x1<<4) /* 4:4 */ +#define DMA_INTR (0x1<<3) /* 3:3 */ +#define MAC3_INTR (0x1<<2) /* 2:2 */ +#define QMU_INTR (0x1<<1) /* 1:1 */ +#define BMU_INTR (0x1<<0) /* 0:0 */ + +/* U3D_LV1IER */ +#define LV1IER (0xffffffff<<0) /* 31:0 */ + +/* U3D_LV1IESR */ +#define LV1IESR (0xffffffff<<0) /* 31:0 */ + +/* U3D_LV1IECR */ +#define LV1IECR (0xffffffff<<0) /* 31:0 */ + +/* U3D_AXI_WR_DMA_CFG */ +#define AXI_WR_ULTRA_NUM (0xff<<24) /* 31:24 */ +#define AXI_WR_PRE_ULTRA_NUM (0xff<<16) /* 23:16 */ +#define AXI_WR_ULTRA_EN (0x1<<0) /* 0:0 */ + +/* U3D_AXI_RD_DMA_CFG */ +#define AXI_RD_ULTRA_NUM (0xff<<24) /* 31:24 */ +#define AXI_RD_PRE_ULTRA_NUM (0xff<<16) /* 23:16 */ +#define AXI_RD_ULTRA_EN (0x1<<0) /* 0:0 */ + +/* U3D_MAC_U1_EN_CTRL */ +#define EXIT_BY_ERDY_DIS (0x1<<31) /* 31:31 */ +#define ACCEPT_BMU_RX_EMPTY_CHK (0x1<<20) /* 20:20 */ +#define ACCEPT_BMU_TX_EMPTY_CHK (0x1<<19) /* 19:19 */ +#define ACCEPT_RXQ_INACTIVE_CHK (0x1<<18) /* 18:18 */ +#define ACCEPT_TXQ_INACTIVE_CHK (0x1<<17) /* 17:17 */ +#define ACCEPT_EP0_INACTIVE_CHK (0x1<<16) /* 16:16 */ +#define REQUEST_BMU_RX_EMPTY_CHK (0x1<<4) /* 4:4 */ +#define REQUEST_BMU_TX_EMPTY_CHK (0x1<<3) /* 3:3 */ +#define REQUEST_RXQ_INACTIVE_CHK (0x1<<2) /* 2:2 */ +#define REQUEST_TXQ_INACTIVE_CHK (0x1<<1) /* 1:1 */ +#define REQUEST_EP0_INACTIVE_CHK (0x1<<0) /* 0:0 */ + +/* U3D_MAC_U2_EN_CTRL */ +#define EXIT_BY_ERDY_DIS (0x1<<31) /* 31:31 */ +#define ACCEPT_BMU_RX_EMPTY_CHK (0x1<<20) /* 20:20 */ +#define ACCEPT_BMU_TX_EMPTY_CHK (0x1<<19) /* 19:19 */ +#define ACCEPT_RXQ_INACTIVE_CHK (0x1<<18) /* 18:18 */ +#define ACCEPT_TXQ_INACTIVE_CHK (0x1<<17) /* 17:17 */ +#define ACCEPT_EP0_INACTIVE_CHK (0x1<<16) /* 16:16 */ +#define REQUEST_BMU_RX_EMPTY_CHK (0x1<<4) /* 4:4 */ +#define REQUEST_BMU_TX_EMPTY_CHK (0x1<<3) /* 3:3 */ +#define REQUEST_RXQ_INACTIVE_CHK (0x1<<2) /* 2:2 */ +#define REQUEST_TXQ_INACTIVE_CHK (0x1<<1) /* 1:1 */ +#define REQUEST_EP0_INACTIVE_CHK (0x1<<0) /* 0:0 */ + +/* U3D_SRAM_DBG_CTRL */ +#define EPNRX_SRAM_DEBUG_MODE (0x1<<2) /* 2:2 */ +#define EPNTX_SRAM_DEBUG_MODE (0x1<<1) /* 1:1 */ +#define EP0_SRAM_DEBUG_MODE (0x1<<0) /* 0:0 */ + +/* U3D_SRAM_DBG_CTRL_1 */ +#define SRAM_DEBUG_FIFOSEGSIZE (0xf<<24) /* 27:24 */ +#define SRAM_DEBUG_SLOT (0x3f<<16) /* 21:16 */ +#define SRAM_DEBUG_DP_COUNT (0x7ff<<0) /* 10:0 */ + +/* U3D_RISC_SIZE */ +#define RISC_SIZE (0x3<<0) /* 1:0 */ + +/* U3D_WRBUF_ERR_STS */ +#define RX_RDBUF_ERR_STS (0x7fff<<17) /* 31:17 */ +#define TX_WRBUF_ERR_STS (0x7fff<<1) /* 15:1 */ + +/* U3D_BUF_ERR_EN */ +#define RX_RDBUF_ERR_EN (0x7fff<<17) /* 31:17 */ +#define TX_WRBUF_ERR_EN (0x7fff<<1) /* 15:1 */ + +/* U3D_EPISR */ +#define EPRISR (0x7fff<<17) /* 31:17 */ +#define SETUPENDISR (0x1<<16) /* 16:16 */ +#define EPTISR (0x7fff<<1) /* 15:1 */ +#define EP0ISR (0x1<<0) /* 0:0 */ + +/* U3D_EPIER */ +#define EPRIER (0x7fff<<17) /* 31:17 */ +#define SETUPENDIER (0x1<<16) /* 16:16 */ +#define EPTIER (0x7fff<<1) /* 15:1 */ +#define EP0IER (0x1<<0) /* 0:0 */ + +/* U3D_EPIESR */ +#define EPRIESR (0x7fff<<17) /* 31:17 */ +#define SETUPENDIESR (0x1<<16) /* 16:16 */ +#define EPTIESR (0x7fff<<1) /* 15:1 */ +#define EP0IESR (0x1<<0) /* 0:0 */ + +/* U3D_EPIECR */ +#define EPRISR (0x7fff<<17) /* 31:17 */ +#define SETUPENDIECR (0x1<<16) /* 16:16 */ +#define EPTIECR (0x7fff<<1) /* 15:1 */ +#define EP0IECR (0x1<<0) /* 0:0 */ + +/* U3D_DMAISR */ +#define RXDMAISR (0x1<<2) /* 2:2 */ +#define TXDMAISR (0x1<<1) /* 1:1 */ +#define EP0DMAISR (0x1<<0) /* 0:0 */ + +/* U3D_DMAIER */ +#define RXDMAIER (0x1<<2) /* 2:2 */ +#define TXDMAIER (0x1<<1) /* 1:1 */ +#define EP0DMAER (0x1<<0) /* 0:0 */ + +/* U3D_DMAIESR */ +#define RXDMAIESR (0x1<<2) /* 2:2 */ +#define TXDMAIESR (0x1<<1) /* 1:1 */ +#define EP0DMAIESR (0x1<<0) /* 0:0 */ + +/* U3D_DMAIECR */ +#define RXDMAIECR (0x1<<2) /* 2:2 */ +#define TXDMAIECR (0x1<<1) /* 1:1 */ +#define EP0DMAIECR (0x1<<0) /* 0:0 */ + +/* U3D_EP0DMACTRL */ +#define FFSTRADDR0 (0xffff<<16) /* 31:16 */ +#define ENDPNT (0xf<<4) /* 7:4 */ +#define INTEN (0x1<<3) /* 3:3 */ +#define DMA_DIR (0x1<<1) /* 1:1 */ +#define DMA_EN (0x1<<0) /* 0:0 */ + +/* U3D_EP0DMASTRADDR */ +#define DMASTRADDR0 (0xffffffff<<0) /* 31:0 */ + +/* U3D_EP0DMATFRCOUNT */ +#define DMATFRCNT0 (0x7ff<<0) /* 10:0 */ + +/* U3D_EP0DMARLCOUNT */ +#define EP0_DMALIMITER (0x7<<28) /* 30:28 */ +#define DMA_FAKE (0x1<<27) /* 27:27 */ +#define DMA_BURST (0x3<<24) /* 25:24 */ +#define AXI_DMA_OUTSTAND_NUM (0xf<<20) /* 23:20 */ +#define AXI_DMA_COHERENCE (0x1<<19) /* 19:19 */ +#define AXI_DMA_IOMMU (0x1<<18) /* 18:18 */ +#define AXI_DMA_CACHEABLE (0x1<<17) /* 17:17 */ +#define AXI_DMA_ULTRA_EN (0x1<<16) /* 16:16 */ +#define AXI_DMA_ULTRA_NUM (0xff<<8) /* 15:8 */ +#define AXI_DMA_PRE_ULTRA_NUM (0xff<<0) /* 7:0 */ + +/* U3D_TXDMACTRL */ +#define FFSTRADDR (0xffff<<16) /* 31:16 */ +#define ENDPNT (0xf<<4) /* 7:4 */ +#define INTEN (0x1<<3) /* 3:3 */ +#define DMA_DIR (0x1<<1) /* 1:1 */ +#define DMA_EN (0x1<<0) /* 0:0 */ + +/* U3D_TXDMASTRADDR */ +#define DMASTRADDR (0xffffffff<<0) /* 31:0 */ + +/* U3D_TXDMATRDCNT */ +#define DMATFRCNT (0x7ff<<0) /* 10:0 */ + +/* U3D_TXDMARLCOUNT */ +#define DMALIMITER (0x7<<28) /* 30:28 */ +#define DMA_FAKE (0x1<<27) /* 27:27 */ +#define DMA_BURST (0x3<<24) /* 25:24 */ +#define AXI_DMA_OUTSTAND_NUM (0xf<<20) /* 23:20 */ +#define AXI_DMA_COHERENCE (0x1<<19) /* 19:19 */ +#define AXI_DMA_IOMMU (0x1<<18) /* 18:18 */ +#define AXI_DMA_CACHEABLE (0x1<<17) /* 17:17 */ +#define AXI_DMA_ULTRA_EN (0x1<<16) /* 16:16 */ +#define AXI_DMA_ULTRA_NUM (0xff<<8) /* 15:8 */ +#define AXI_DMA_PRE_ULTRA_NUM (0xff<<0) /* 7:0 */ + +/* U3D_RXDMACTRL */ +#define FFSTRADDR (0xffff<<16) /* 31:16 */ +#define ENDPNT (0xf<<4) /* 7:4 */ +#define INTEN (0x1<<3) /* 3:3 */ +#define DMA_DIR (0x1<<1) /* 1:1 */ +#define DMA_EN (0x1<<0) /* 0:0 */ + +/* U3D_RXDMASTRADDR */ +#define DMASTRADDR (0xffffffff<<0) /* 31:0 */ + +/* U3D_RXDMATRDCNT */ +#define DMATFRCNT (0x7ff<<0) /* 10:0 */ + +/* U3D_RXDMARLCOUNT */ +#define DMA_NON_BUF (0x1<<31) /* 31:31 */ +#define DMALIMITER (0x7<<28) /* 30:28 */ +#define DMA_FAKE (0x1<<27) /* 27:27 */ +#define DMA_BURST (0x3<<24) /* 25:24 */ +#define AXI_DMA_OUTSTAND_NUM (0xf<<20) /* 23:20 */ +#define AXI_DMA_COHERENCE (0x1<<19) /* 19:19 */ +#define AXI_DMA_IOMMU (0x1<<18) /* 18:18 */ +#define AXI_DMA_CACHEABLE (0x1<<17) /* 17:17 */ +#define AXI_DMA_ULTRA_EN (0x1<<16) /* 16:16 */ +#define AXI_DMA_ULTRA_NUM (0xff<<8) /* 15:8 */ +#define AXI_DMA_PRE_ULTRA_NUM (0xff<<0) /* 7:0 */ + +/* U3D_EP0CSR */ +#define EP0_EP_RESET (0x1<<31) /* 31:31 */ +#define EP0_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define EP0_AUTOSET (0x1<<29) /* 29:29 */ +#define EP0_DMAREQEN (0x1<<28) /* 28:28 */ +#define EP0_SENDSTALL (0x1<<25) /* 25:25 */ +#define EP0_FIFOFULL (0x1<<23) /* 23:23 */ +#define EP0_SENTSTALL (0x1<<22) /* 22:22 */ +#define EP0_DPHTX (0x1<<20) /* 20:20 */ +#define EP0_DATAEND (0x1<<19) /* 19:19 */ +#define EP0_TXPKTRDY (0x1<<18) /* 18:18 */ +#define EP0_SETUPPKTRDY (0x1<<17) /* 17:17 */ +#define EP0_RXPKTRDY (0x1<<16) /* 16:16 */ +#define EP0_MAXPKTSZ0 (0x3ff<<0) /* 9:0 */ + +/* U3D_RXCOUNT0 */ +#define EP0_RX_COUNT (0x3ff<<0) /* 9:0 */ + +/* U3D_RESERVED */ + +/* U3D_TX1CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX1CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX1CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX2CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX2CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX2CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX3CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX3CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX3CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX4CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX4CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX4CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX5CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX5CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX5CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX6CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX6CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX6CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX7CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX7CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX7CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX8CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX8CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX8CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX9CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX9CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX9CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX10CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX10CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX10CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX11CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX11CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX11CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX12CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX12CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX12CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX13CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX13CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX13CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX14CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX14CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX14CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_TX15CSR0 */ +#define TX_EP_RESET (0x1<<31) /* 31:31 */ +#define TX_AUTOSET (0x1<<30) /* 30:30 */ +#define TX_DMAREQEN (0x1<<29) /* 29:29 */ +#define TX_FIFOFULL (0x1<<25) /* 25:25 */ +#define TX_FIFOEMPTY (0x1<<24) /* 24:24 */ +#define TX_SENTSTALL (0x1<<22) /* 22:22 */ +#define TX_SENDSTALL (0x1<<21) /* 21:21 */ +#define TX_TXPKTRDY (0x1<<16) /* 16:16 */ +#define TX_TXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_TX15CSR1 */ +#define TX_MULT (0x3<<22) /* 23:22 */ +#define TX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define TX_SLOT (0x3f<<8) /* 13:8 */ +#define TXTYPE (0x3<<4) /* 5:4 */ +#define SS_TX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_TX15CSR2 */ +#define TXBINTERVAL (0xff<<24) /* 31:24 */ +#define TXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define TXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX1CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX1CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX1CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX1CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX2CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX2CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX2CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX2CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX3CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX3CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX3CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX3CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX4CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX4CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX4CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX4CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX5CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX5CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX5CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX5CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX6CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX6CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX6CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX6CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX7CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX7CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX7CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX7CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX8CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX8CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX8CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX8CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX9CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX9CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX9CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX9CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX10CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX10CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX10CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX10CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX11CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX11CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX11CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX11CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX12CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX12CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX12CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX12CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX13CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX13CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX13CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX13CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX14CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX14CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX14CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX14CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_RX15CSR0 */ +#define RX_EP_RESET (0x1<<31) /* 31:31 */ +#define RX_AUTOCLEAR (0x1<<30) /* 30:30 */ +#define RX_DMAREQEN (0x1<<29) /* 29:29 */ +#define RX_SENTSTALL (0x1<<22) /* 22:22 */ +#define RX_SENDSTALL (0x1<<21) /* 21:21 */ +#define RX_FIFOFULL (0x1<<18) /* 18:18 */ +#define RX_FIFOEMPTY (0x1<<17) /* 17:17 */ +#define RX_RXPKTRDY (0x1<<16) /* 16:16 */ +#define RX_RXMAXPKTSZ (0x7ff<<0) /* 10:0 */ + +/* U3D_RX15CSR1 */ +#define RX_MULT (0x3<<22) /* 23:22 */ +#define RX_MAX_PKT (0x3f<<16) /* 21:16 */ +#define RX_SLOT (0x3f<<8) /* 13:8 */ +#define RX_TYPE (0x3<<4) /* 5:4 */ +#define SS_RX_BURST (0xf<<0) /* 3:0 */ + +/* U3D_RX15CSR2 */ +#define RXBINTERVAL (0xff<<24) /* 31:24 */ +#define RXFIFOSEGSIZE (0xf<<16) /* 19:16 */ +#define RXFIFOADDR (0x1fff<<0) /* 12:0 */ + +/* U3D_RX15CSR3 */ +#define EP_RX_COUNT (0x7ff<<16) /* 26:16 */ + +/* U3D_FIFO0 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO1 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO2 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO3 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO4 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO5 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO6 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO7 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO8 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO9 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO10 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO11 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO12 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO13 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO14 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_FIFO15 */ +#define BYTE3 (0xff<<24) /* 31:24 */ +#define BYTE2 (0xff<<16) /* 23:16 */ +#define BYTE1 (0xff<<8) /* 15:8 */ +#define BYTE0 (0xff<<0) /* 7:0 */ + +/* U3D_QCR0 */ +#define RXQ_CS_EN (0x7fff<<17) /* 31:17 */ +#define TXQ_CS_EN (0x7fff<<1) /* 15:1 */ +#define CS16B_EN (0x1<<0) /* 0:0 */ + +/* U3D_QCR1 */ +#define CFG_TX_ZLP_GPD (0x7fff<<1) /* 15:1 */ + +/* U3D_QCR2 */ +#define CFG_TX_ZLP (0x7fff<<1) /* 15:1 */ + +/* U3D_QCR3 */ +#define CFG_RX_COZ (0x7fff<<17) /* 31:17 */ +#define CFG_RX_ZLP (0x7fff<<1) /* 15:1 */ + +/* U3D_QGCSR */ +#define RXQ_EN (0x7fff<<17) /* 31:17 */ +#define TXQ_EN (0x7fff<<1) /* 15:1 */ + +/* U3D_TXQCSR1 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR1 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR1 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR2 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR2 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR2 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR3 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR3 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR3 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR4 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR4 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR4 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR5 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR5 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR5 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR6 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR6 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR6 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR7 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR7 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR7 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR8 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR8 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR8 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR9 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR9 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR9 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR10 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR10 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR10 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR11 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR11 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR11 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR12 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR12 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR12 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR13 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR13 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR13 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR14 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR14 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR14 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCSR15 */ +#define TXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define TXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define TXQ_EPQ_STATE (0xf<<8) /* 11:8 */ +#define TXQ_STOP (0x1<<2) /* 2:2 */ +#define TXQ_RESUME (0x1<<1) /* 1:1 */ +#define TXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_TXQSAR15 */ +#define TXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_TXQCPR15 */ +#define TXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR1 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR1 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR1 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR1 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR2 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR2 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR2 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR2 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR3 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR3 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR3 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR3 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR4 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR4 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR4 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR4 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR5 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR5 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR5 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR5 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR6 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR6 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR6 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR6 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR7 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR7 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR7 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR7 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR8 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR8 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR8 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR8 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR9 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR9 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR9 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR9 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR10 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR10 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR10 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR10 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR11 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR11 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR11 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR11 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR12 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR12 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR12 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR12 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR13 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR13 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR13 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR13 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR14 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR14 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR14 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR14 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCSR15 */ +#define RXQ_DMGR_DMSM_CS (0xf<<16) /* 19:16 */ +#define RXQ_ACTIVE (0x1<<15) /* 15:15 */ +#define RXQ_EPQ_STATE (0x1f<<8) /* 12:8 */ +#define RXQ_STOP (0x1<<2) /* 2:2 */ +#define RXQ_RESUME (0x1<<1) /* 1:1 */ +#define RXQ_START (0x1<<0) /* 0:0 */ + +/* U3D_RXQSAR15 */ +#define RXQ_START_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQCPR15 */ +#define RXQ_CUR_GPD_ADDR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_RXQLDPR15 */ +#define RXQ_LAST_DONE_PTR (0x3fffffff<<2) /* 31:2 */ + +/* U3D_QISAR0 */ +#define RXQ_DONE_INT (0x7fff<<17) /* 31:17 */ +#define TXQ_DONE_INT (0x7fff<<1) /* 15:1 */ + +/* U3D_QIER0 */ +#define RXQ_DONE_IER (0x7fff<<17) /* 31:17 */ +#define TXQ_DONE_IER (0x7fff<<1) /* 15:1 */ + +/* U3D_QIESR0 */ +#define RXQ_DONE_IESR (0x7fff<<17) /* 31:17 */ +#define TXQ_DONE_IESR (0x7fff<<1) /* 15:1 */ + +/* U3D_QIECR0 */ +#define RXQ_DONE_IECR (0x7fff<<17) /* 31:17 */ +#define TXQ_DONE_IECR (0x7fff<<1) /* 15:1 */ + +/* U3D_QISAR1 */ +#define RXQ_ZLPERR_INT (0x1<<20) /* 20:20 */ +#define RXQ_LENERR_INT (0x1<<18) /* 18:18 */ +#define RXQ_CSERR_INT (0x1<<17) /* 17:17 */ +#define RXQ_EMPTY_INT (0x1<<16) /* 16:16 */ +#define TXQ_LENERR_INT (0x1<<2) /* 2:2 */ +#define TXQ_CSERR_INT (0x1<<1) /* 1:1 */ +#define TXQ_EMPTY_INT (0x1<<0) /* 0:0 */ + +/* U3D_QIER1 */ +#define RXQ_ZLPERR_IER (0x1<<20) /* 20:20 */ +#define RXQ_LENERR_IER (0x1<<18) /* 18:18 */ +#define RXQ_CSERR_IER (0x1<<17) /* 17:17 */ +#define RXQ_EMPTY_IER (0x1<<16) /* 16:16 */ +#define TXQ_LENERR_IER (0x1<<2) /* 2:2 */ +#define TXQ_CSERR_IER (0x1<<1) /* 1:1 */ +#define TXQ_EMPTY_IER (0x1<<0) /* 0:0 */ + +/* U3D_QIESR1 */ +#define RXQ_ZLPERR_IESR (0x1<<20) /* 20:20 */ +#define RXQ_LENERR_IESR (0x1<<18) /* 18:18 */ +#define RXQ_CSERR_IESR (0x1<<17) /* 17:17 */ +#define RXQ_EMPTY_IESR (0x1<<16) /* 16:16 */ +#define TXQ_LENERR_IESR (0x1<<2) /* 2:2 */ +#define TXQ_CSERR_IESR (0x1<<1) /* 1:1 */ +#define TXQ_EMPTY_IESR (0x1<<0) /* 0:0 */ + +/* U3D_QIECR1 */ +#define RXQ_ZLPERR_IECR (0x1<<20) /* 20:20 */ +#define RXQ_LENERR_IECR (0x1<<18) /* 18:18 */ +#define RXQ_CSERR_IECR (0x1<<17) /* 17:17 */ +#define RXQ_EMPTY_IECR (0x1<<16) /* 16:16 */ +#define TXQ_LENERR_IECR (0x1<<2) /* 2:2 */ +#define TXQ_CSERR_IECR (0x1<<1) /* 1:1 */ +#define TXQ_EMPTY_IECR (0x1<<0) /* 0:0 */ + +/* U3D_QEMIR */ +#define RXQ_EMPTY_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_EMPTY_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_QEMIER */ +#define RXQ_EMPTY_IER_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_EMPTY_IER_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_QEMIESR */ +#define RXQ_EMPTY_IESR_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_EMPTY_IESR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_QEMIECR */ +#define RXQ_EMPTY_IECR_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_EMPTY_IECR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_TQERRIR0 */ +#define TXQ_LENERR_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_CSERR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_TQERRIER0 */ +#define TXQ_LENERR_IER_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_CSERR_IER_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_TQERRIESR0 */ +#define TXQ_LENERR_IESR_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_CSERR_IESR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_TQERRIECR0 */ +#define TXQ_LENERR_IECR_MASK (0x7fff<<17) /* 31:17 */ +#define TXQ_CSERR_IECR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_RQERRIR0 */ +#define RXQ_LENERR_MASK (0x7fff<<17) /* 31:17 */ +#define RXQ_CSERR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_RQERRIER0 */ +#define RXQ_LENERR_IER_MASK (0x7fff<<17) /* 31:17 */ +#define RXQ_CSERR_IER_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_RQERRIESR0 */ +#define RXQ_LENERR_IESR_MASK (0x7fff<<17) /* 31:17 */ +#define RXQ_CSERR_IESR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_RQERRIECR0 */ +#define RXQ_LENERR_IECR_MASK (0x7fff<<17) /* 31:17 */ +#define RXQ_CSERR_IECR_MASK (0x7fff<<1) /* 15:1 */ + +/* U3D_RQERRIR1 */ +#define RXQ_ZLPERR_MASK (0x7fff<<17) /* 31:17 */ + +/* U3D_RQERRIER1 */ +#define RXQ_ZLPERR_IER_MASK (0x7fff<<17) /* 31:17 */ + +/* U3D_RQERRIESR1 */ +#define RXQ_ZLPERR_IESR_MASK (0x7fff<<17) /* 31:17 */ + +/* U3D_RQERRIECR1 */ +#define RXQ_ZLPERR_IECR_MASK (0x7fff<<17) /* 31:17 */ + +/* U3D_CAP_EP0FFSZ */ +#define CAP_EP0FFSZ (0xffffffff<<0) /* 31:0 */ + +/* U3D_CAP_EPNTXFFSZ */ +#define CAP_EPNTXFFSZ (0xffffffff<<0) /* 31:0 */ + +/* U3D_CAP_EPNRXFFSZ */ +#define CAP_EPNRXFFSZ (0xffffffff<<0) /* 31:0 */ + +/* U3D_CAP_EPINFO */ +#define CAP_RX_EP_NUM (0x1f<<8) /* 12:8 */ +#define CAP_TX_EP_NUM (0x1f<<0) /* 4:0 */ + +/* U3D_CAP_TX_SLOT1 */ +#define CAP_TX_SLOT3 (0x3f<<24) /* 29:24 */ +#define CAP_TX_SLOT2 (0x3f<<16) /* 21:16 */ +#define CAP_TX_SLOT1 (0x3f<<8) /* 13:8 */ +#define RSV (0x3f<<0) /* 5:0 */ + +/* U3D_CAP_TX_SLOT2 */ +#define CAP_TX_SLOT7 (0x3f<<24) /* 29:24 */ +#define CAP_TX_SLOT6 (0x3f<<16) /* 21:16 */ +#define CAP_TX_SLOT5 (0x3f<<8) /* 13:8 */ +#define CAP_TX_SLOT4 (0x3f<<0) /* 5:0 */ + +/* U3D_CAP_TX_SLOT3 */ +#define CAP_TX_SLOT11 (0x3f<<24) /* 29:24 */ +#define CAP_TX_SLOT10 (0x3f<<16) /* 21:16 */ +#define CAP_TX_SLOT9 (0x3f<<8) /* 13:8 */ +#define CAP_TX_SLOT8 (0x3f<<0) /* 5:0 */ + +/* U3D_CAP_TX_SLOT4 */ +#define CAP_TX_SLOT15 (0x3f<<24) /* 29:24 */ +#define CAP_TX_SLOT14 (0x3f<<16) /* 21:16 */ +#define CAP_TX_SLOT13 (0x3f<<8) /* 13:8 */ +#define CAP_TX_SLOT12 (0x3f<<0) /* 5:0 */ + +/* U3D_CAP_RX_SLOT1 */ +#define CAP_RX_SLOT3 (0x3f<<24) /* 29:24 */ +#define CAP_RX_SLOT2 (0x3f<<16) /* 21:16 */ +#define CAP_RX_SLOT1 (0x3f<<8) /* 13:8 */ +#define RSV (0x3f<<0) /* 5:0 */ + +/* U3D_CAP_RX_SLOT2 */ +#define CAP_RX_SLOT7 (0x3f<<24) /* 29:24 */ +#define CAP_RX_SLOT6 (0x3f<<16) /* 21:16 */ +#define CAP_RX_SLOT5 (0x3f<<8) /* 13:8 */ +#define CAP_RX_SLOT4 (0x3f<<0) /* 5:0 */ + +/* U3D_CAP_RX_SLOT3 */ +#define CAP_RX_SLOT11 (0x3f<<24) /* 29:24 */ +#define CAP_RX_SLOT10 (0x3f<<16) /* 21:16 */ +#define CAP_RX_SLOT9 (0x3f<<8) /* 13:8 */ +#define CAP_RX_SLOT8 (0x3f<<0) /* 5:0 */ + +/* U3D_CAP_RX_SLOT4 */ +#define CAP_RX_SLOT15 (0x3f<<24) /* 29:24 */ +#define CAP_RX_SLOT14 (0x3f<<16) /* 21:16 */ +#define CAP_RX_SLOT13 (0x3f<<8) /* 13:8 */ +#define CAP_RX_SLOT12 (0x3f<<0) /* 5:0 */ + +/* U3D_MISC_CTRL */ +#define DMA_BUS_CK_GATE_DIS (0x1<<2) /* 2:2 */ +#define VBUS_ON (0x1<<1) /* 1:1 */ +#define VBUS_FRC_EN (0x1<<0) /* 0:0 */ + + +/* SSUSB_DEV FIELD OFFSET DEFINITION */ + +/* U3D_LV1ISR */ +#define EP_CTRL_INTR_OFST (5) +#define MAC2_INTR_OFST (4) +#define DMA_INTR_OFST (3) +#define MAC3_INTR_OFST (2) +#define QMU_INTR_OFST (1) +#define BMU_INTR_OFST (0) + +/* U3D_LV1IER */ +#define LV1IER_OFST (0) + +/* U3D_LV1IESR */ +#define LV1IESR_OFST (0) + +/* U3D_LV1IECR */ +#define LV1IECR_OFST (0) + +/* U3D_AXI_WR_DMA_CFG */ +#define AXI_WR_ULTRA_NUM_OFST (24) +#define AXI_WR_PRE_ULTRA_NUM_OFST (16) +#define AXI_WR_ULTRA_EN_OFST (0) + +/* U3D_AXI_RD_DMA_CFG */ +#define AXI_RD_ULTRA_NUM_OFST (24) +#define AXI_RD_PRE_ULTRA_NUM_OFST (16) +#define AXI_RD_ULTRA_EN_OFST (0) + +/* U3D_MAC_U1_EN_CTRL */ +#define EXIT_BY_ERDY_DIS_OFST (31) +#define ACCEPT_BMU_RX_EMPTY_CHK_OFST (20) +#define ACCEPT_BMU_TX_EMPTY_CHK_OFST (19) +#define ACCEPT_RXQ_INACTIVE_CHK_OFST (18) +#define ACCEPT_TXQ_INACTIVE_CHK_OFST (17) +#define ACCEPT_EP0_INACTIVE_CHK_OFST (16) +#define REQUEST_BMU_RX_EMPTY_CHK_OFST (4) +#define REQUEST_BMU_TX_EMPTY_CHK_OFST (3) +#define REQUEST_RXQ_INACTIVE_CHK_OFST (2) +#define REQUEST_TXQ_INACTIVE_CHK_OFST (1) +#define REQUEST_EP0_INACTIVE_CHK_OFST (0) + +/* U3D_MAC_U2_EN_CTRL */ +#define EXIT_BY_ERDY_DIS_OFST (31) +#define ACCEPT_BMU_RX_EMPTY_CHK_OFST (20) +#define ACCEPT_BMU_TX_EMPTY_CHK_OFST (19) +#define ACCEPT_RXQ_INACTIVE_CHK_OFST (18) +#define ACCEPT_TXQ_INACTIVE_CHK_OFST (17) +#define ACCEPT_EP0_INACTIVE_CHK_OFST (16) +#define REQUEST_BMU_RX_EMPTY_CHK_OFST (4) +#define REQUEST_BMU_TX_EMPTY_CHK_OFST (3) +#define REQUEST_RXQ_INACTIVE_CHK_OFST (2) +#define REQUEST_TXQ_INACTIVE_CHK_OFST (1) +#define REQUEST_EP0_INACTIVE_CHK_OFST (0) + +/* U3D_SRAM_DBG_CTRL */ +#define EPNRX_SRAM_DEBUG_MODE_OFST (2) +#define EPNTX_SRAM_DEBUG_MODE_OFST (1) +#define EP0_SRAM_DEBUG_MODE_OFST (0) + +/* U3D_SRAM_DBG_CTRL_1 */ +#define SRAM_DEBUG_FIFOSEGSIZE_OFST (24) +#define SRAM_DEBUG_SLOT_OFST (16) +#define SRAM_DEBUG_DP_COUNT_OFST (0) + +/* U3D_RISC_SIZE */ +#define RISC_SIZE_OFST (0) + +/* U3D_WRBUF_ERR_STS */ +#define RX_RDBUF_ERR_STS_OFST (17) +#define TX_WRBUF_ERR_STS_OFST (1) + +/* U3D_BUF_ERR_EN */ +#define RX_RDBUF_ERR_EN_OFST (17) +#define TX_WRBUF_ERR_EN_OFST (1) + +/* U3D_EPISR */ +#define EPRISR_OFST (17) +#define SETUPENDISR_OFST (16) +#define EPTISR_OFST (1) +#define EP0ISR_OFST (0) + +/* U3D_EPIER */ +#define EPRIER_OFST (17) +#define SETUPENDIER_OFST (16) +#define EPTIER_OFST (1) +#define EP0IER_OFST (0) + +/* U3D_EPIESR */ +#define EPRIESR_OFST (17) +#define SETUPENDIESR_OFST (16) +#define EPTIESR_OFST (1) +#define EP0IESR_OFST (0) + +/* U3D_EPIECR */ +#define EPRISR_OFST (17) +#define SETUPENDIECR_OFST (16) +#define EPTIECR_OFST (1) +#define EP0IECR_OFST (0) + +/* U3D_DMAISR */ +#define RXDMAISR_OFST (2) +#define TXDMAISR_OFST (1) +#define EP0DMAISR_OFST (0) + +/* U3D_DMAIER */ +#define RXDMAIER_OFST (2) +#define TXDMAIER_OFST (1) +#define EP0DMAER_OFST (0) + +/* U3D_DMAIESR */ +#define RXDMAIESR_OFST (2) +#define TXDMAIESR_OFST (1) +#define EP0DMAIESR_OFST (0) + +/* U3D_DMAIECR */ +#define RXDMAIECR_OFST (2) +#define TXDMAIECR_OFST (1) +#define EP0DMAIECR_OFST (0) + +/* U3D_EP0DMACTRL */ +#define FFSTRADDR0_OFST (16) +#define ENDPNT_OFST (4) +#define INTEN_OFST (3) +#define DMA_DIR_OFST (1) +#define DMA_EN_OFST (0) + +/* U3D_EP0DMASTRADDR */ +#define DMASTRADDR0_OFST (0) + +/* U3D_EP0DMATFRCOUNT */ +#define DMATFRCNT0_OFST (0) + +/* U3D_EP0DMARLCOUNT */ +#define EP0_DMALIMITER_OFST (28) +#define DMA_FAKE_OFST (27) +#define DMA_BURST_OFST (24) +#define AXI_DMA_OUTSTAND_NUM_OFST (20) +#define AXI_DMA_COHERENCE_OFST (19) +#define AXI_DMA_IOMMU_OFST (18) +#define AXI_DMA_CACHEABLE_OFST (17) +#define AXI_DMA_ULTRA_EN_OFST (16) +#define AXI_DMA_ULTRA_NUM_OFST (8) +#define AXI_DMA_PRE_ULTRA_NUM_OFST (0) + +/* U3D_TXDMACTRL */ +#define FFSTRADDR_OFST (16) +#define ENDPNT_OFST (4) +#define INTEN_OFST (3) +#define DMA_DIR_OFST (1) +#define DMA_EN_OFST (0) + +/* U3D_TXDMASTRADDR */ +#define DMASTRADDR_OFST (0) + +/* U3D_TXDMATRDCNT */ +#define DMATFRCNT_OFST (0) + +/* U3D_TXDMARLCOUNT */ +#define DMALIMITER_OFST (28) +#define DMA_FAKE_OFST (27) +#define DMA_BURST_OFST (24) +#define AXI_DMA_OUTSTAND_NUM_OFST (20) +#define AXI_DMA_COHERENCE_OFST (19) +#define AXI_DMA_IOMMU_OFST (18) +#define AXI_DMA_CACHEABLE_OFST (17) +#define AXI_DMA_ULTRA_EN_OFST (16) +#define AXI_DMA_ULTRA_NUM_OFST (8) +#define AXI_DMA_PRE_ULTRA_NUM_OFST (0) + +/* U3D_RXDMACTRL */ +#define FFSTRADDR_OFST (16) +#define ENDPNT_OFST (4) +#define INTEN_OFST (3) +#define DMA_DIR_OFST (1) +#define DMA_EN_OFST (0) + +/* U3D_RXDMASTRADDR */ +#define DMASTRADDR_OFST (0) + +/* U3D_RXDMATRDCNT */ +#define DMATFRCNT_OFST (0) + +/* U3D_RXDMARLCOUNT */ +#define DMA_NON_BUF_OFST (31) +#define DMALIMITER_OFST (28) +#define DMA_FAKE_OFST (27) +#define DMA_BURST_OFST (24) +#define AXI_DMA_OUTSTAND_NUM_OFST (20) +#define AXI_DMA_COHERENCE_OFST (19) +#define AXI_DMA_IOMMU_OFST (18) +#define AXI_DMA_CACHEABLE_OFST (17) +#define AXI_DMA_ULTRA_EN_OFST (16) +#define AXI_DMA_ULTRA_NUM_OFST (8) +#define AXI_DMA_PRE_ULTRA_NUM_OFST (0) + +/* U3D_EP0CSR */ +#define EP0_EP_RESET_OFST (31) +#define EP0_AUTOCLEAR_OFST (30) +#define EP0_AUTOSET_OFST (29) +#define EP0_DMAREQEN_OFST (28) +#define EP0_SENDSTALL_OFST (25) +#define EP0_FIFOFULL_OFST (23) +#define EP0_SENTSTALL_OFST (22) +#define EP0_DPHTX_OFST (20) +#define EP0_DATAEND_OFST (19) +#define EP0_TXPKTRDY_OFST (18) +#define EP0_SETUPPKTRDY_OFST (17) +#define EP0_RXPKTRDY_OFST (16) +#define EP0_MAXPKTSZ0_OFST (0) + +/* U3D_RXCOUNT0 */ +#define EP0_RX_COUNT_OFST (0) + +/* U3D_RESERVED */ + +/* U3D_TX1CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX1CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX1CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX2CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX2CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX2CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX3CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX3CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX3CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX4CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX4CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX4CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX5CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX5CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX5CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX6CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX6CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX6CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX7CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX7CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX7CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX8CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX8CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX8CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX9CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX9CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX9CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX10CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX10CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX10CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX11CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX11CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX11CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX12CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX12CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX12CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX13CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX13CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX13CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX14CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX14CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX14CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_TX15CSR0 */ +#define TX_EP_RESET_OFST (31) +#define TX_AUTOSET_OFST (30) +#define TX_DMAREQEN_OFST (29) +#define TX_FIFOFULL_OFST (25) +#define TX_FIFOEMPTY_OFST (24) +#define TX_SENTSTALL_OFST (22) +#define TX_SENDSTALL_OFST (21) +#define TX_TXPKTRDY_OFST (16) +#define TX_TXMAXPKTSZ_OFST (0) + +/* U3D_TX15CSR1 */ +#define TX_MULT_OFST (22) +#define TX_MAX_PKT_OFST (16) +#define TX_SLOT_OFST (8) +#define TXTYPE_OFST (4) +#define SS_TX_BURST_OFST (0) + +/* U3D_TX15CSR2 */ +#define TXBINTERVAL_OFST (24) +#define TXFIFOSEGSIZE_OFST (16) +#define TXFIFOADDR_OFST (0) + +/* U3D_RX1CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX1CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX1CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX1CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX2CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX2CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX2CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX2CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX3CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX3CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX3CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX3CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX4CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX4CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX4CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX4CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX5CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX5CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX5CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX5CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX6CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX6CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX6CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX6CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX7CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX7CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX7CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX7CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX8CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX8CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX8CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX8CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX9CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX9CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX9CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX9CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX10CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX10CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX10CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX10CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX11CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX11CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX11CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX11CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX12CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX12CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX12CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX12CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX13CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX13CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX13CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX13CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX14CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX14CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX14CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX14CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_RX15CSR0 */ +#define RX_EP_RESET_OFST (31) +#define RX_AUTOCLEAR_OFST (30) +#define RX_DMAREQEN_OFST (29) +#define RX_SENTSTALL_OFST (22) +#define RX_SENDSTALL_OFST (21) +#define RX_FIFOFULL_OFST (18) +#define RX_FIFOEMPTY_OFST (17) +#define RX_RXPKTRDY_OFST (16) +#define RX_RXMAXPKTSZ_OFST (0) + +/* U3D_RX15CSR1 */ +#define RX_MULT_OFST (22) +#define RX_MAX_PKT_OFST (16) +#define RX_SLOT_OFST (8) +#define RX_TYPE_OFST (4) +#define SS_RX_BURST_OFST (0) + +/* U3D_RX15CSR2 */ +#define RXBINTERVAL_OFST (24) +#define RXFIFOSEGSIZE_OFST (16) +#define RXFIFOADDR_OFST (0) + +/* U3D_RX15CSR3 */ +#define EP_RX_COUNT_OFST (16) + +/* U3D_FIFO0 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO1 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO2 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO3 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO4 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO5 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO6 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO7 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO8 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO9 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO10 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO11 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO12 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO13 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO14 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_FIFO15 */ +#define BYTE3_OFST (24) +#define BYTE2_OFST (16) +#define BYTE1_OFST (8) +#define BYTE0_OFST (0) + +/* U3D_QCR0 */ +#define RXQ_CS_EN_OFST (17) +#define TXQ_CS_EN_OFST (1) +#define CS16B_EN_OFST (0) + +/* U3D_QCR1 */ +#define CFG_TX_ZLP_GPD_OFST (1) + +/* U3D_QCR2 */ +#define CFG_TX_ZLP_OFST (1) + +/* U3D_QCR3 */ +#define CFG_RX_COZ_OFST (17) +#define CFG_RX_ZLP_OFST (1) + +/* U3D_QGCSR */ +#define RXQ_EN_OFST (17) +#define TXQ_EN_OFST (1) + +/* U3D_TXQCSR1 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR1 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR1 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR2 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR2 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR2 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR3 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR3 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR3 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR4 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR4 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR4 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR5 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR5 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR5 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR6 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR6 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR6 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR7 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR7 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR7 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR8 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR8 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR8 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR9 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR9 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR9 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR10 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR10 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR10 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR11 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR11 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR11 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR12 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR12 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR12 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR13 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR13 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR13 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR14 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR14 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR14 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_TXQCSR15 */ +#define TXQ_DMGR_DMSM_CS_OFST (16) +#define TXQ_ACTIVE_OFST (15) +#define TXQ_EPQ_STATE_OFST (8) +#define TXQ_STOP_OFST (2) +#define TXQ_RESUME_OFST (1) +#define TXQ_START_OFST (0) + +/* U3D_TXQSAR15 */ +#define TXQ_START_ADDR_OFST (2) + +/* U3D_TXQCPR15 */ +#define TXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQCSR1 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR1 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR1 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR1 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR2 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR2 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR2 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR2 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR3 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR3 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR3 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR3 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR4 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR4 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR4 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR4 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR5 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR5 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR5 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR5 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR6 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR6 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR6 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR6 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR7 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR7 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR7 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR7 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR8 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR8 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR8 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR8 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR9 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR9 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR9 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR9 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR10 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR10 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR10 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR10 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR11 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR11 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR11 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR11 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR12 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR12 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR12 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR12 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR13 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR13 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR13 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR13 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR14 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR14 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR14 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR14 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_RXQCSR15 */ +#define RXQ_DMGR_DMSM_CS_OFST (16) +#define RXQ_ACTIVE_OFST (15) +#define RXQ_EPQ_STATE_OFST (8) +#define RXQ_STOP_OFST (2) +#define RXQ_RESUME_OFST (1) +#define RXQ_START_OFST (0) + +/* U3D_RXQSAR15 */ +#define RXQ_START_ADDR_OFST (2) + +/* U3D_RXQCPR15 */ +#define RXQ_CUR_GPD_ADDR_OFST (2) + +/* U3D_RXQLDPR15 */ +#define RXQ_LAST_DONE_PTR_OFST (2) + +/* U3D_QISAR0 */ +#define RXQ_DONE_INT_OFST (17) +#define TXQ_DONE_INT_OFST (1) + +/* U3D_QIER0 */ +#define RXQ_DONE_IER_OFST (17) +#define TXQ_DONE_IER_OFST (1) + +/* U3D_QIESR0 */ +#define RXQ_DONE_IESR_OFST (17) +#define TXQ_DONE_IESR_OFST (1) + +/* U3D_QIECR0 */ +#define RXQ_DONE_IECR_OFST (17) +#define TXQ_DONE_IECR_OFST (1) + +/* U3D_QISAR1 */ +#define RXQ_ZLPERR_INT_OFST (20) +#define RXQ_LENERR_INT_OFST (18) +#define RXQ_CSERR_INT_OFST (17) +#define RXQ_EMPTY_INT_OFST (16) +#define TXQ_LENERR_INT_OFST (2) +#define TXQ_CSERR_INT_OFST (1) +#define TXQ_EMPTY_INT_OFST (0) + +/* U3D_QIER1 */ +#define RXQ_ZLPERR_IER_OFST (20) +#define RXQ_LENERR_IER_OFST (18) +#define RXQ_CSERR_IER_OFST (17) +#define RXQ_EMPTY_IER_OFST (16) +#define TXQ_LENERR_IER_OFST (2) +#define TXQ_CSERR_IER_OFST (1) +#define TXQ_EMPTY_IER_OFST (0) + +/* U3D_QIESR1 */ +#define RXQ_ZLPERR_IESR_OFST (20) +#define RXQ_LENERR_IESR_OFST (18) +#define RXQ_CSERR_IESR_OFST (17) +#define RXQ_EMPTY_IESR_OFST (16) +#define TXQ_LENERR_IESR_OFST (2) +#define TXQ_CSERR_IESR_OFST (1) +#define TXQ_EMPTY_IESR_OFST (0) + +/* U3D_QIECR1 */ +#define RXQ_ZLPERR_IECR_OFST (20) +#define RXQ_LENERR_IECR_OFST (18) +#define RXQ_CSERR_IECR_OFST (17) +#define RXQ_EMPTY_IECR_OFST (16) +#define TXQ_LENERR_IECR_OFST (2) +#define TXQ_CSERR_IECR_OFST (1) +#define TXQ_EMPTY_IECR_OFST (0) + +/* U3D_QEMIR */ +#define RXQ_EMPTY_MASK_OFST (17) +#define TXQ_EMPTY_MASK_OFST (1) + +/* U3D_QEMIER */ +#define RXQ_EMPTY_IER_MASK_OFST (17) +#define TXQ_EMPTY_IER_MASK_OFST (1) + +/* U3D_QEMIESR */ +#define RXQ_EMPTY_IESR_MASK_OFST (17) +#define TXQ_EMPTY_IESR_MASK_OFST (1) + +/* U3D_QEMIECR */ +#define RXQ_EMPTY_IECR_MASK_OFST (17) +#define TXQ_EMPTY_IECR_MASK_OFST (1) + +/* U3D_TQERRIR0 */ +#define TXQ_LENERR_MASK_OFST (17) +#define TXQ_CSERR_MASK_OFST (1) + +/* U3D_TQERRIER0 */ +#define TXQ_LENERR_IER_MASK_OFST (17) +#define TXQ_CSERR_IER_MASK_OFST (1) + +/* U3D_TQERRIESR0 */ +#define TXQ_LENERR_IESR_MASK_OFST (17) +#define TXQ_CSERR_IESR_MASK_OFST (1) + +/* U3D_TQERRIECR0 */ +#define TXQ_LENERR_IECR_MASK_OFST (17) +#define TXQ_CSERR_IECR_MASK_OFST (1) + +/* U3D_RQERRIR0 */ +#define RXQ_LENERR_MASK_OFST (17) +#define RXQ_CSERR_MASK_OFST (1) + +/* U3D_RQERRIER0 */ +#define RXQ_LENERR_IER_MASK_OFST (17) +#define RXQ_CSERR_IER_MASK_OFST (1) + +/* U3D_RQERRIESR0 */ +#define RXQ_LENERR_IESR_MASK_OFST (17) +#define RXQ_CSERR_IESR_MASK_OFST (1) + +/* U3D_RQERRIECR0 */ +#define RXQ_LENERR_IECR_MASK_OFST (17) +#define RXQ_CSERR_IECR_MASK_OFST (1) + +/* U3D_RQERRIR1 */ +#define RXQ_ZLPERR_MASK_OFST (17) + +/* U3D_RQERRIER1 */ +#define RXQ_ZLPERR_IER_MASK_OFST (17) + +/* U3D_RQERRIESR1 */ +#define RXQ_ZLPERR_IESR_MASK_OFST (17) + +/* U3D_RQERRIECR1 */ +#define RXQ_ZLPERR_IECR_MASK_OFST (17) + +/* U3D_CAP_EP0FFSZ */ +#define CAP_EP0FFSZ_OFST (0) + +/* U3D_CAP_EPNTXFFSZ */ +#define CAP_EPNTXFFSZ_OFST (0) + +/* U3D_CAP_EPNRXFFSZ */ +#define CAP_EPNRXFFSZ_OFST (0) + +/* U3D_CAP_EPINFO */ +#define CAP_RX_EP_NUM_OFST (8) +#define CAP_TX_EP_NUM_OFST (0) + +/* U3D_CAP_TX_SLOT1 */ +#define CAP_TX_SLOT3_OFST (24) +#define CAP_TX_SLOT2_OFST (16) +#define CAP_TX_SLOT1_OFST (8) +#define RSV_OFST (0) + +/* U3D_CAP_TX_SLOT2 */ +#define CAP_TX_SLOT7_OFST (24) +#define CAP_TX_SLOT6_OFST (16) +#define CAP_TX_SLOT5_OFST (8) +#define CAP_TX_SLOT4_OFST (0) + +/* U3D_CAP_TX_SLOT3 */ +#define CAP_TX_SLOT11_OFST (24) +#define CAP_TX_SLOT10_OFST (16) +#define CAP_TX_SLOT9_OFST (8) +#define CAP_TX_SLOT8_OFST (0) + +/* U3D_CAP_TX_SLOT4 */ +#define CAP_TX_SLOT15_OFST (24) +#define CAP_TX_SLOT14_OFST (16) +#define CAP_TX_SLOT13_OFST (8) +#define CAP_TX_SLOT12_OFST (0) + +/* U3D_CAP_RX_SLOT1 */ +#define CAP_RX_SLOT3_OFST (24) +#define CAP_RX_SLOT2_OFST (16) +#define CAP_RX_SLOT1_OFST (8) +#define RSV_OFST (0) + +/* U3D_CAP_RX_SLOT2 */ +#define CAP_RX_SLOT7_OFST (24) +#define CAP_RX_SLOT6_OFST (16) +#define CAP_RX_SLOT5_OFST (8) +#define CAP_RX_SLOT4_OFST (0) + +/* U3D_CAP_RX_SLOT3 */ +#define CAP_RX_SLOT11_OFST (24) +#define CAP_RX_SLOT10_OFST (16) +#define CAP_RX_SLOT9_OFST (8) +#define CAP_RX_SLOT8_OFST (0) + +/* U3D_CAP_RX_SLOT4 */ +#define CAP_RX_SLOT15_OFST (24) +#define CAP_RX_SLOT14_OFST (16) +#define CAP_RX_SLOT13_OFST (8) +#define CAP_RX_SLOT12_OFST (0) + +/* U3D_MISC_CTRL */ +#define DMA_BUS_CK_GATE_DIS_OFST (2) +#define VBUS_ON_OFST (1) +#define VBUS_FRC_EN_OFST (0) + +/* //////////////////////////////////////////////////////////////////// */ diff --git a/drivers/misc/mediatek/mu3d/hal/ssusb_epctl_csr_c_header.h b/drivers/misc/mediatek/mu3d/hal/ssusb_epctl_csr_c_header.h new file mode 100644 index 000000000000..59bca9b25da3 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/ssusb_epctl_csr_c_header.h @@ -0,0 +1,187 @@ +/* SSUSB_EPCTL_CSR REGISTER DEFINITION */ + +#define U3D_DEVICE_CONF (SSUSB_EPCTL_CSR_BASE+0x0000) +#define U3D_EP_RST (SSUSB_EPCTL_CSR_BASE+0x0004) +#define U3D_USB3_ERDY_TIMING_PARAMETER (SSUSB_EPCTL_CSR_BASE+0x0008) +#define U3D_USB3_EPCTRL_CAP (SSUSB_EPCTL_CSR_BASE+0x000C) +#define U3D_USB2_ISOINEP_INCOMP_INTR (SSUSB_EPCTL_CSR_BASE+0x0010) +#define U3D_USB2_ISOOUTEP_INCOMP_ERR (SSUSB_EPCTL_CSR_BASE+0x0014) +#define U3D_ISO_UNDERRUN_INTR (SSUSB_EPCTL_CSR_BASE+0x0018) +#define U3D_ISO_OVERRUN_INTR (SSUSB_EPCTL_CSR_BASE+0x001C) +#define U3D_USB2_RX_EP_DATAERR_INTR (SSUSB_EPCTL_CSR_BASE+0x0020) +#define U3D_USB2_EPCTRL_CAP (SSUSB_EPCTL_CSR_BASE+0x0024) +#define U3D_USB2_EPCTL_LPM (SSUSB_EPCTL_CSR_BASE+0x0028) +#define U3D_USB3_SW_ERDY (SSUSB_EPCTL_CSR_BASE+0x0030) +#define U3D_EP_FLOW_CTRL (SSUSB_EPCTL_CSR_BASE+0x0040) +#define U3D_USB3_EP_ACT (SSUSB_EPCTL_CSR_BASE+0x0044) +#define U3D_USB3_EP_PACKET_PENDING (SSUSB_EPCTL_CSR_BASE+0x0048) +#define U3D_DEV_LINK_INTR_ENABLE (SSUSB_EPCTL_CSR_BASE+0x0050) +#define U3D_DEV_LINK_INTR (SSUSB_EPCTL_CSR_BASE+0x0054) +#define U3D_USB2_EPCTL_LPM_FC_CHK (SSUSB_EPCTL_CSR_BASE+0x0060) +#define U3D_DEVICE_MONITOR (SSUSB_EPCTL_CSR_BASE+0x0064) + +/* SSUSB_EPCTL_CSR FIELD DEFINITION */ + +/* U3D_DEVICE_CONF */ +#define DEV_ADDR (0x7f<<24) /* 30:24 */ +#define HW_USB2_3_SEL (0x1<<18) /* 18:18 */ +#define SW_USB2_3_SEL_EN (0x1<<17) /* 17:17 */ +#define SW_USB2_3_SEL (0x1<<16) /* 16:16 */ +#define SSUSB_DEV_SPEED (0x7<<0) /* 2:0 */ + +/* U3D_EP_RST */ +#define EP_IN_RST (0x7fff<<17) /* 31:17 */ +#define EP_OUT_RST (0x7fff<<1) /* 15:1 */ +#define EP0_RST (0x1<<0) /* 0:0 */ + +/* U3D_USB3_ERDY_TIMING_PARAMETER */ +#define ERDY_TIMEOUT_VALUE (0x3ff<<0) /* 9:0 */ + +/* U3D_USB3_EPCTRL_CAP */ +#define TX_NUMP_0_EN (0x1<<4) /* 4:4 */ +#define SEND_STALL_CLR_PP_EN (0x1<<3) /* 3:3 */ +#define USB3_ISO_CRC_CHK_DIS (0x1<<2) /* 2:2 */ +#define SET_EOB_EN (0x1<<1) /* 1:1 */ +#define TX_BURST_EN (0x1<<0) /* 0:0 */ + +/* U3D_USB2_ISOINEP_INCOMP_INTR */ +#define USB2_ISOINEP_INCOMP_INTR_EN (0x7fff<<17) /* 31:17 */ +#define USB2_ISOINEP_INCOMP_INTR (0x7fff<<1) /* 15:1 */ + +/* U3D_USB2_ISOOUTEP_INCOMP_ERR */ +#define USB2_ISOOUTEP_INCOMP_INTR_EN (0x7fff<<17) /* 31:17 */ +#define USB2_ISOOUTEP_INCOMP_INTR (0x7fff<<1) /* 15:1 */ + +/* U3D_ISO_UNDERRUN_INTR */ +#define ISOIN_UNDERRUN_INTR_EN (0x7fff<<17) /* 31:17 */ +#define ISOIN_UNDERRUN_INTR (0x7fff<<1) /* 15:1 */ + +/* U3D_ISO_OVERRUN_INTR */ +#define ISOOUT_OVERRUN_INTR_EN (0x7fff<<17) /* 31:17 */ +#define ISOOUT_OVERRUN_INTR (0x7fff<<1) /* 15:1 */ + +/* U3D_USB2_RX_EP_DATAERR_INTR */ +#define USB2_RX_EP_DATAERR_INTR_EN (0xffff<<16) /* 31:16 */ +#define USB2_RX_EP_DATAERR_INTR (0xffff<<0) /* 15:0 */ + +/* U3D_USB2_EPCTRL_CAP */ +#define USB2_ISO_CRC_CHK_DIS (0x1<<0) /* 0:0 */ + +/* U3D_USB2_EPCTL_LPM */ +#define L1_EXIT_EP_OUT_CHK (0x7fff<<17) /* 31:17 */ +#define L1_EXIT_EP_IN_CHK (0x7fff<<1) /* 15:1 */ +#define L1_EXIT_EP0_CHK (0x1<<0) /* 0:0 */ + +/* U3D_USB3_SW_ERDY */ +#define SW_ERDY_EP_NUM (0xf<<2) /* 5:2 */ +#define SW_ERDY_EP_DIR (0x1<<1) /* 1:1 */ +#define SW_SEND_ERDY (0x1<<0) /* 0:0 */ + +/* U3D_EP_FLOW_CTRL */ +#define EP_OUT_FC (0xffff<<16) /* 31:16 */ +#define EP_IN_FC (0xffff<<0) /* 15:0 */ + +/* U3D_USB3_EP_ACT */ +#define EP_IN_ACT (0xffff<<0) /* 15:0 */ + +/* U3D_USB3_EP_PACKET_PENDING */ +#define EP_OUT_PP (0xffff<<16) /* 31:16 */ +#define EP_IN_PP (0xffff<<0) /* 15:0 */ + +/* U3D_DEV_LINK_INTR_ENABLE */ +#define SSUSB_DEV_SPEED_CHG_INTR_EN (0x1<<0) /* 0:0 */ + +/* U3D_DEV_LINK_INTR */ +#define SSUSB_DEV_SPEED_CHG_INTR (0x1<<0) /* 0:0 */ + +/* U3D_USB2_EPCTL_LPM_FC_CHK */ +#define L1_EXIT_EP_OUT_FC_CHK (0x7fff<<17) /* 31:17 */ +#define L1_EXIT_EP_IN_FC_CHK (0x7fff<<1) /* 15:1 */ +#define L1_EXIT_EP0_FC_CHK (0x1<<0) /* 0:0 */ + +/* U3D_DEVICE_MONITOR */ +#define CUR_DEV_ADDR (0x7f<<0) /* 6:0 */ + + +/* SSUSB_EPCTL_CSR FIELD OFFSET DEFINITION */ + +/* U3D_DEVICE_CONF */ +#define DEV_ADDR_OFST (24) +#define HW_USB2_3_SEL_OFST (18) +#define SW_USB2_3_SEL_EN_OFST (17) +#define SW_USB2_3_SEL_OFST (16) +#define SSUSB_DEV_SPEED_OFST (0) + +/* U3D_EP_RST */ +#define EP_IN_RST_OFST (17) +#define EP_OUT_RST_OFST (1) +#define EP0_RST_OFST (0) + +/* U3D_USB3_ERDY_TIMING_PARAMETER */ +#define ERDY_TIMEOUT_VALUE_OFST (0) + +/* U3D_USB3_EPCTRL_CAP */ +#define SEND_STALL_CLR_PP_EN_OFST (3) +#define USB3_ISO_CRC_CHK_DIS_OFST (2) +#define SET_EOB_EN_OFST (1) +#define TX_BURST_EN_OFST (0) + +/* U3D_USB2_ISOINEP_INCOMP_INTR */ +#define USB2_ISOINEP_INCOMP_INTR_EN_OFST (17) +#define USB2_ISOINEP_INCOMP_INTR_OFST (1) + +/* U3D_USB2_ISOOUTEP_INCOMP_ERR */ +#define USB2_ISOOUTEP_INCOMP_INTR_EN_OFST (17) +#define USB2_ISOOUTEP_INCOMP_INTR_OFST (1) + +/* U3D_ISO_UNDERRUN_INTR */ +#define ISOIN_UNDERRUN_INTR_EN_OFST (17) +#define ISOIN_UNDERRUN_INTR_OFST (1) + +/* U3D_ISO_OVERRUN_INTR */ +#define ISOOUT_OVERRUN_INTR_EN_OFST (17) +#define ISOOUT_OVERRUN_INTR_OFST (1) + +/* U3D_USB2_RX_EP_DATAERR_INTR */ +#define USB2_RX_EP_DATAERR_INTR_EN_OFST (16) +#define USB2_RX_EP_DATAERR_INTR_OFST (0) + +/* U3D_USB2_EPCTRL_CAP */ +#define USB2_ISO_CRC_CHK_DIS_OFST (0) + +/* U3D_USB2_EPCTL_LPM */ +#define L1_EXIT_EP_OUT_CHK_OFST (17) +#define L1_EXIT_EP_IN_CHK_OFST (1) +#define L1_EXIT_EP0_CHK_OFST (0) + +/* U3D_USB3_SW_ERDY */ +#define SW_ERDY_EP_NUM_OFST (2) +#define SW_ERDY_EP_DIR_OFST (1) +#define SW_SEND_ERDY_OFST (0) + +/* U3D_EP_FLOW_CTRL */ +#define EP_OUT_FC_OFST (16) +#define EP_IN_FC_OFST (0) + +/* U3D_USB3_EP_ACT */ +#define EP_IN_ACT_OFST (0) + +/* U3D_USB3_EP_PACKET_PENDING */ +#define EP_OUT_PP_OFST (16) +#define EP_IN_PP_OFST (0) + +/* U3D_DEV_LINK_INTR_ENABLE */ +#define SSUSB_DEV_SPEED_CHG_INTR_EN_OFST (0) + +/* U3D_DEV_LINK_INTR */ +#define SSUSB_DEV_SPEED_CHG_INTR_OFST (0) + +/* U3D_USB2_EPCTL_LPM_FC_CHK */ +#define L1_EXIT_EP_OUT_FC_CHK_OFST (17) +#define L1_EXIT_EP_IN_FC_CHK_OFST (1) +#define L1_EXIT_EP0_FC_CHK_OFST (0) + +/* U3D_DEVICE_MONITOR */ +#define CUR_DEV_ADDR_OFST (0) + +/* //////////////////////////////////////////////////////////////////// */ diff --git a/drivers/misc/mediatek/mu3d/hal/ssusb_sifslv_ippc_c_header.h b/drivers/misc/mediatek/mu3d/hal/ssusb_sifslv_ippc_c_header.h new file mode 100644 index 000000000000..925eaf441a4f --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/ssusb_sifslv_ippc_c_header.h @@ -0,0 +1,728 @@ +/* SSUSB_SIFSLV_IPPC REGISTER DEFINITION */ + +#define U3D_SSUSB_IP_PW_CTRL0 (SSUSB_SIFSLV_IPPC_BASE+0x0000) +#define U3D_SSUSB_IP_PW_CTRL1 (SSUSB_SIFSLV_IPPC_BASE+0x0004) +#define U3D_SSUSB_IP_PW_CTRL2 (SSUSB_SIFSLV_IPPC_BASE+0x0008) +#define U3D_SSUSB_IP_PW_CTRL3 (SSUSB_SIFSLV_IPPC_BASE+0x000C) +#define U3D_SSUSB_IP_PW_STS1 (SSUSB_SIFSLV_IPPC_BASE+0x0010) +#define U3D_SSUSB_IP_PW_STS2 (SSUSB_SIFSLV_IPPC_BASE+0x0014) +#define U3D_SSUSB_OTG_STS (SSUSB_SIFSLV_IPPC_BASE+0x0018) +#define U3D_SSUSB_OTG_STS_CLR (SSUSB_SIFSLV_IPPC_BASE+0x001C) +#define U3D_SSUSB_IP_MAC_CAP (SSUSB_SIFSLV_IPPC_BASE+0x0020) +#define U3D_SSUSB_IP_XHCI_CAP (SSUSB_SIFSLV_IPPC_BASE+0x0024) +#define U3D_SSUSB_IP_DEV_CAP (SSUSB_SIFSLV_IPPC_BASE+0x0028) +#define U3D_SSUSB_OTG_INT_EN (SSUSB_SIFSLV_IPPC_BASE+0x002C) + +#if (defined(SUPPORT_U3) || defined(CONFIG_MTK_FPGA)) +#define U3D_SSUSB_U3_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE+0x0030) +#define U3D_SSUSB_U3_CTRL_1P (SSUSB_SIFSLV_IPPC_BASE+0x0038) +#define U3D_SSUSB_U3_CTRL_2P (SSUSB_SIFSLV_IPPC_BASE+0x0040) +#define U3D_SSUSB_U3_CTRL_3P (SSUSB_SIFSLV_IPPC_BASE+0x0048) +#endif +#define U3D_SSUSB_U2_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE+0x0050) +#ifdef SUPPORT_U3 +#define U3D_SSUSB_U2_CTRL_1P (SSUSB_SIFSLV_IPPC_BASE+0x0058) +#define U3D_SSUSB_U2_CTRL_2P (SSUSB_SIFSLV_IPPC_BASE+0x0060) +#define U3D_SSUSB_U2_CTRL_3P (SSUSB_SIFSLV_IPPC_BASE+0x0068) +#define U3D_SSUSB_U2_CTRL_4P (SSUSB_SIFSLV_IPPC_BASE+0x0070) +#define U3D_SSUSB_U2_CTRL_5P (SSUSB_SIFSLV_IPPC_BASE+0x0078) +#endif +#define U3D_SSUSB_U2_PHY_PLL (SSUSB_SIFSLV_IPPC_BASE+0x007C) +#define U3D_SSUSB_DMA_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x0080) +#define U3D_SSUSB_MAC_CK_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x0084) +#define U3D_SSUSB_CSR_CK_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x0088) +#define U3D_SSUSB_REF_CK_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x008C) +#define U3D_SSUSB_XHCI_CK_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x0090) +#define U3D_SSUSB_XHCI_RST_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x0094) +#define U3D_SSUSB_DEV_RST_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x0098) +#define U3D_SSUSB_SYS_CK_CTRL (SSUSB_SIFSLV_IPPC_BASE+0x009C) +#define U3D_SSUSB_HW_ID (SSUSB_SIFSLV_IPPC_BASE+0x00A0) +#define U3D_SSUSB_HW_SUB_ID (SSUSB_SIFSLV_IPPC_BASE+0x00A4) +#define U3D_SSUSB_PRB_CTRL0 (SSUSB_SIFSLV_IPPC_BASE+0x00B0) +#define U3D_SSUSB_PRB_CTRL1 (SSUSB_SIFSLV_IPPC_BASE+0x00B4) +#define U3D_SSUSB_PRB_CTRL2 (SSUSB_SIFSLV_IPPC_BASE+0x00B8) +#define U3D_SSUSB_PRB_CTRL3 (SSUSB_SIFSLV_IPPC_BASE+0x00BC) +#define U3D_SSUSB_PRB_CTRL4 (SSUSB_SIFSLV_IPPC_BASE+0x00C0) +#define U3D_SSUSB_PRB_CTRL5 (SSUSB_SIFSLV_IPPC_BASE+0x00C4) +#define U3D_SSUSB_IP_SPARE0 (SSUSB_SIFSLV_IPPC_BASE+0x00C8) +#define U3D_SSUSB_IP_SPARE1 (SSUSB_SIFSLV_IPPC_BASE+0x00CC) +#define U3D_SSUSB_FPGA_I2C_OUT_0P (SSUSB_SIFSLV_IPPC_BASE+0x00D0) +#define U3D_SSUSB_FPGA_I2C_IN_0P (SSUSB_SIFSLV_IPPC_BASE+0x00D4) +#define U3D_SSUSB_FPGA_I2C_OUT_1P (SSUSB_SIFSLV_IPPC_BASE+0x00D8) +#define U3D_SSUSB_FPGA_I2C_IN_1P (SSUSB_SIFSLV_IPPC_BASE+0x00DC) +#define U3D_SSUSB_FPGA_I2C_OUT_2P (SSUSB_SIFSLV_IPPC_BASE+0x00E0) +#define U3D_SSUSB_FPGA_I2C_IN_2P (SSUSB_SIFSLV_IPPC_BASE+0x00E4) +#define U3D_SSUSB_FPGA_I2C_OUT_3P (SSUSB_SIFSLV_IPPC_BASE+0x00E8) +#define U3D_SSUSB_FPGA_I2C_IN_3P (SSUSB_SIFSLV_IPPC_BASE+0x00EC) +#define U3D_SSUSB_FPGA_I2C_OUT_4P (SSUSB_SIFSLV_IPPC_BASE+0x00F0) +#define U3D_SSUSB_FPGA_I2C_IN_4P (SSUSB_SIFSLV_IPPC_BASE+0x00F4) +#define U3D_SSUSB_IP_SLV_TMOUT (SSUSB_SIFSLV_IPPC_BASE+0x00F8) + +/* SSUSB_SIFSLV_IPPC FIELD DEFINITION */ + +/* U3D_SSUSB_IP_PW_CTRL0 */ +#define SSUSB_AHB_SLV_AUTO_RSP (0x1<<17) /* 17:17 */ +#define SSUSB_IP_SW_RST_CK_GATE_EN (0x1<<16) /* 16:16 */ +#define SSUSB_IP_U2_ENTER_SLEEP_CNT (0xff<<8) /* 15:8 */ +#define SSUSB_IP_SW_RST (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_IP_PW_CTRL1 */ +#define SSUSB_IP_HOST_PDN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_IP_PW_CTRL2 */ +#define SSUSB_IP_DEV_PDN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_IP_PW_CTRL3 */ +#define SSUSB_IP_PCIE_PDN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_IP_PW_STS1 */ +#define SSUSB_IP_REF_CK_DIS_STS (0x1<<31) /* 31:31 */ +#define SSUSB_IP_SLEEP_STS (0x1<<30) /* 30:30 */ +#define SSUSB_U2_MAC_RST_B_STS_5P (0x1<<29) /* 29:29 */ +#define SSUSB_U2_MAC_RST_B_STS_4P (0x1<<28) /* 28:28 */ +#define SSUSB_U2_MAC_RST_B_STS_3P (0x1<<27) /* 27:27 */ +#define SSUSB_U2_MAC_RST_B_STS_2P (0x1<<26) /* 26:26 */ +#define SSUSB_U2_MAC_RST_B_STS_1P (0x1<<25) /* 25:25 */ +#define SSUSB_U2_MAC_RST_B_STS (0x1<<24) /* 24:24 */ +#define SSUSB_U3_MAC_RST_B_STS_3P (0x1<<19) /* 19:19 */ +#define SSUSB_U3_MAC_RST_B_STS_2P (0x1<<18) /* 18:18 */ +#define SSUSB_U3_MAC_RST_B_STS_1P (0x1<<17) /* 17:17 */ +#define SSUSB_U3_MAC_RST_B_STS (0x1<<16) /* 16:16 */ +#define SSUSB_DEV_DRAM_RST_B_STS (0x1<<13) /* 13:13 */ +#define SSUSB_XHCI_DRAM_RST_B_STS (0x1<<12) /* 12:12 */ +#define SSUSB_XHCI_RST_B_STS (0x1<<11) /* 11:11 */ +#define SSUSB_SYS125_RST_B_STS (0x1<<10) /* 10:10 */ +#define SSUSB_SYS60_RST_B_STS (0x1<<9) /* 9:9 */ +#define SSUSB_REF_RST_B_STS (0x1<<8) /* 8:8 */ +#define SSUSB_DEV_RST_B_STS (0x1<<3) /* 3:3 */ +#define SSUSB_DEV_BMU_RST_B_STS (0x1<<2) /* 2:2 */ +#define SSUSB_DEV_QMU_RST_B_STS (0x1<<1) /* 1:1 */ +#define SSUSB_SYSPLL_STABLE (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_IP_PW_STS2 */ +#define SSUSB_U2_MAC_SYS_RST_B_STS_5P (0x1<<5) /* 5:5 */ +#define SSUSB_U2_MAC_SYS_RST_B_STS_4P (0x1<<4) /* 4:4 */ +#define SSUSB_U2_MAC_SYS_RST_B_STS_3P (0x1<<3) /* 3:3 */ +#define SSUSB_U2_MAC_SYS_RST_B_STS_2P (0x1<<2) /* 2:2 */ +#define SSUSB_U2_MAC_SYS_RST_B_STS_1P (0x1<<1) /* 1:1 */ +#define SSUSB_U2_MAC_SYS_RST_B_STS (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_OTG_STS */ +#define SSUSB_XHCI_MAS_DMA_REQ (0x1<<14) /* 14:14 */ +#define SSUSB_DEV_DMA_REQ (0x1<<13) /* 13:13 */ +#define SSUSB_AVALID_STS (0x1<<12) /* 12:12 */ +#define SSUSB_SRP_REQ_INTR (0x1<<11) /* 11:11 */ +#define SSUSB_IDDIG (0x1<<10) /* 10:10 */ +#define SSUSB_VBUS_VALID (0x1<<9) /* 9:9 */ +#define SSUSB_HOST_DEV_MODE (0x1<<8) /* 8:8 */ +#define SSUSB_DEV_USBRST_INTR (0x1<<7) /* 7:7 */ +#define VBUS_CHG_INTR (0x1<<6) /* 6:6 */ +#define SSUSB_CHG_B_ROLE_B (0x1<<5) /* 5:5 */ +#define SSUSB_CHG_A_ROLE_B (0x1<<4) /* 4:4 */ +#define SSUSB_ATTACH_B_ROLE (0x1<<3) /* 3:3 */ +#define SSUSB_CHG_B_ROLE_A (0x1<<2) /* 2:2 */ +#define SSUSB_CHG_A_ROLE_A (0x1<<1) /* 1:1 */ +#define SSUSB_ATTACH_A_ROLE (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_OTG_STS_CLR */ +#define SSUSB_SRP_REQ_INTR_CLR (0x1<<11) /* 11:11 */ +#define SSUSB_DEV_USBRST_INTR_CLR (0x1<<7) /* 7:7 */ +#define SSUSB_VBUS_INTR_CLR (0x1<<6) /* 6:6 */ +#define SSUSB_CHG_B_ROLE_B_CLR (0x1<<5) /* 5:5 */ +#define SSUSB_CHG_A_ROLE_B_CLR (0x1<<4) /* 4:4 */ +#define SSUSB_ATTACH_B_ROLE_CLR (0x1<<3) /* 3:3 */ +#define SSUSB_CHG_B_ROLE_A_CLR (0x1<<2) /* 2:2 */ +#define SSUSB_CHG_A_ROLE_A_CLR (0x1<<1) /* 1:1 */ +#define SSUSB_ATTACH_A_ROLE_CLR (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_IP_MAC_CAP */ +#define SSUSB_IP_MAC_U2_PORT_NO (0xff<<8) /* 15:8 */ +#define SSUSB_IP_MAC_U3_PORT_NO (0xff<<0) /* 7:0 */ + +/* U3D_SSUSB_IP_XHCI_CAP */ +#define SSUSB_IP_XHCI_U2_PORT_NO (0xff<<8) /* 15:8 */ +#define SSUSB_IP_XHCI_U3_PORT_NO (0xff<<0) /* 7:0 */ + +/* U3D_SSUSB_IP_DEV_CAP */ +#define SSUSB_IP_DEV_U2_PORT_NO (0xff<<8) /* 15:8 */ +#define SSUSB_IP_DEV_U3_PORT_NO (0xff<<0) /* 7:0 */ + +/* U3D_SSUSB_OTG_INT_EN */ +#define SSUSB_DEV_USBRST_INT_EN (0x1<<8) /* 8:8 */ +#define SSUSB_VBUS_CHG_INT_A_EN (0x1<<7) /* 7:7 */ +#define SSUSB_VBUS_CHG_INT_B_EN (0x1<<6) /* 6:6 */ +#define SSUSB_CHG_B_ROLE_B_INT_EN (0x1<<5) /* 5:5 */ +#define SSUSB_CHG_A_ROLE_B_INT_EN (0x1<<4) /* 4:4 */ +#define SSUSB_ATTACH_B_ROLE_INT_EN (0x1<<3) /* 3:3 */ +#define SSUSB_CHG_B_ROLE_A_INT_EN (0x1<<2) /* 2:2 */ +#define SSUSB_CHG_A_ROLE_A_INT_EN (0x1<<1) /* 1:1 */ +#define SSUSB_ATTACH_A_ROLE_INT_EN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U3_CTRL_0P */ +#define SSUSB_U3_PORT_PHYD_RST (0x1<<5) /* 5:5 */ +#define SSUSB_U3_PORT_MAC_RST (0x1<<4) /* 4:4 */ +#define SSUSB_U3_PORT_U2_CG_EN (0x1<<3) /* 3:3 */ +#define SSUSB_U3_PORT_HOST_SEL (0x1<<2) /* 2:2 */ +#define SSUSB_U3_PORT_PDN (0x1<<1) /* 1:1 */ +#define SSUSB_U3_PORT_DIS (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U3_CTRL_1P */ +#define SSUSB_U3_PORT_PHYD_RST_1P (0x1<<5) /* 5:5 */ +#define SSUSB_U3_PORT_MAC_RST_1P (0x1<<4) /* 4:4 */ +#define SSUSB_U3_PORT_U2_CG_EN_1P (0x1<<3) /* 3:3 */ +#define SSUSB_U3_PORT_HOST_SEL_1P (0x1<<2) /* 2:2 */ +#define SSUSB_U3_PORT_PDN_1P (0x1<<1) /* 1:1 */ +#define SSUSB_U3_PORT_DIS_1P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U3_CTRL_2P */ +#define SSUSB_U3_PORT_PHYD_RST_2P (0x1<<5) /* 5:5 */ +#define SSUSB_U3_PORT_MAC_RST_2P (0x1<<4) /* 4:4 */ +#define SSUSB_U3_PORT_U2_CG_EN_2P (0x1<<3) /* 3:3 */ +#define SSUSB_U3_PORT_HOST_SEL_2P (0x1<<2) /* 2:2 */ +#define SSUSB_U3_PORT_PDN_2P (0x1<<1) /* 1:1 */ +#define SSUSB_U3_PORT_DIS_2P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U3_CTRL_3P */ +#define SSUSB_U3_PORT_PHYD_RST_3P (0x1<<5) /* 5:5 */ +#define SSUSB_U3_PORT_MAC_RST_3P (0x1<<4) /* 4:4 */ +#define SSUSB_U3_PORT_U2_CG_EN_3P (0x1<<3) /* 3:3 */ +#define SSUSB_U3_PORT_HOST_SEL_3P (0x1<<2) /* 2:2 */ +#define SSUSB_U3_PORT_PDN_3P (0x1<<1) /* 1:1 */ +#define SSUSB_U3_PORT_DIS_3P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U2_CTRL_0P */ +#define SSUSB_U2_PORT_OTG_HOST_VBUSVALID_SEL (0x1<<9) /* 9:9 */ +#define SSUSB_U2_PORT_OTG_MAC_AUTO_SEL (0x1<<8) /* 8:8 */ +#define SSUSB_U2_PORT_OTG_SEL (0x1<<7) /* 7:7 */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL (0x1<<6) /* 6:6 */ +#define SSUSB_U2_PORT_PHYD_RST (0x1<<5) /* 5:5 */ +#define SSUSB_U2_PORT_MAC_RST (0x1<<4) /* 4:4 */ +#define SSUSB_U2_PORT_U2_CG_EN (0x1<<3) /* 3:3 */ +#define SSUSB_U2_PORT_HOST_SEL (0x1<<2) /* 2:2 */ +#define SSUSB_U2_PORT_PDN (0x1<<1) /* 1:1 */ +#define SSUSB_U2_PORT_DIS (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U2_CTRL_1P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_1P (0x1<<6) /* 6:6 */ +#define SSUSB_U2_PORT_PHYD_RST_1P (0x1<<5) /* 5:5 */ +#define SSUSB_U2_PORT_MAC_RST_1P (0x1<<4) /* 4:4 */ +#define SSUSB_U2_PORT_U2_CG_EN_1P (0x1<<3) /* 3:3 */ +#define SSUSB_U2_PORT_HOST_SEL_1P (0x1<<2) /* 2:2 */ +#define SSUSB_U2_PORT_PDN_1P (0x1<<1) /* 1:1 */ +#define SSUSB_U2_PORT_DIS_1P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U2_CTRL_2P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_2P (0x1<<6) /* 6:6 */ +#define SSUSB_U2_PORT_PHYD_RST_2P (0x1<<5) /* 5:5 */ +#define SSUSB_U2_PORT_MAC_RST_2P (0x1<<4) /* 4:4 */ +#define SSUSB_U2_PORT_U2_CG_EN_2P (0x1<<3) /* 3:3 */ +#define SSUSB_U2_PORT_HOST_SEL_2P (0x1<<2) /* 2:2 */ +#define SSUSB_U2_PORT_PDN_2P (0x1<<1) /* 1:1 */ +#define SSUSB_U2_PORT_DIS_2P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U2_CTRL_3P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_3P (0x1<<6) /* 6:6 */ +#define SSUSB_U2_PORT_PHYD_RST_3P (0x1<<5) /* 5:5 */ +#define SSUSB_U2_PORT_MAC_RST_3P (0x1<<4) /* 4:4 */ +#define SSUSB_U2_PORT_U2_CG_EN_3P (0x1<<3) /* 3:3 */ +#define SSUSB_U2_PORT_HOST_SEL_3P (0x1<<2) /* 2:2 */ +#define SSUSB_U2_PORT_PDN_3P (0x1<<1) /* 1:1 */ +#define SSUSB_U2_PORT_DIS_3P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U2_CTRL_4P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_4P (0x1<<6) /* 6:6 */ +#define SSUSB_U2_PORT_PHYD_RST_4P (0x1<<5) /* 5:5 */ +#define SSUSB_U2_PORT_MAC_RST_4P (0x1<<4) /* 4:4 */ +#define SSUSB_U2_PORT_U2_CG_EN_4P (0x1<<3) /* 3:3 */ +#define SSUSB_U2_PORT_HOST_SEL_4P (0x1<<2) /* 2:2 */ +#define SSUSB_U2_PORT_PDN_4P (0x1<<1) /* 1:1 */ +#define SSUSB_U2_PORT_DIS_4P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U2_CTRL_5P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_5P (0x1<<6) /* 6:6 */ +#define SSUSB_U2_PORT_PHYD_RST_5P (0x1<<5) /* 5:5 */ +#define SSUSB_U2_PORT_MAC_RST_5P (0x1<<4) /* 4:4 */ +#define SSUSB_U2_PORT_U2_CG_EN_5P (0x1<<3) /* 3:3 */ +#define SSUSB_U2_PORT_HOST_SEL_5P (0x1<<2) /* 2:2 */ +#define SSUSB_U2_PORT_PDN_5P (0x1<<1) /* 1:1 */ +#define SSUSB_U2_PORT_DIS_5P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_U2_PHY_PLL */ +#define SSUSB_SYSPLL_USE (0x1<<30) /* 30:30 */ +#define RG_SSUSB_U2_PLL_STB (0x1<<29) /* 29:29 */ +#define SSUSB_U2_FORCE_PLL_STB (0x1<<28) /* 28:28 */ +#define SSUSB_U2_PORT_PHY_CK_DEB_TIMER (0xf<<24) /* 27:24 */ +#define SSUSB_U2_PORT_LPM_PLL_STABLE_TIMER (0xff<<16) /* 23:16 */ +#define SSUSB_U2_PORT_PLL_STABLE_TIMER (0xff<<8) /* 15:8 */ +#define SSUSB_U2_PORT_1US_TIMER (0xff<<0) /* 7:0 */ + +/* U3D_SSUSB_DMA_CTRL */ +#define SSUSB_IP_DMA_BUS_CK_GATE_DIS (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_MAC_CK_CTRL */ +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME (0xff<<16) /* 23:16 */ +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME (0xff<<8) /* 15:8 */ +#define SSUSB_PHY_REF_CK_DIV2 (0x1<<4) /* 4:4 */ +#define SSUSB_MAC3_SYS_CK_GATE_MODE (0x3<<2) /* 3:2 */ +#define SSUSB_MAC2_SYS_CK_GATE_MODE (0x3<<0) /* 1:0 */ + +/* U3D_SSUSB_CSR_CK_CTRL */ +#define SSUSB_SIFSLV_MCU_BUS_CK_GATE_EN (0x1<<1) /* 1:1 */ +#define SSUSB_CSR_MCU_BUS_CK_GATE_EN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_REF_CK_CTRL */ +#define SSUSB_REF_MAC2_CK_GATE_EN (0x1<<4) /* 4:4 */ +#define SSUSB_REF_MAC3_CK_GATE_EN (0x1<<3) /* 3:3 */ +#define SSUSB_REF_CK_GATE_EN (0x1<<2) /* 2:2 */ +#define SSUSB_REF_PHY_CK_GATE_EN (0x1<<1) /* 1:1 */ +#define SSUSB_REF_MAC_CK_GATE_EN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_XHCI_CK_CTRL */ +#define SSUSB_XACT3_XHCI_CK_GATE_MASK_TIME (0xff<<8) /* 15:8 */ +#define SSUSB_XACT3_XHCI_CK_GATE_MODE (0x3<<4) /* 5:4 */ +#define SSUSB_XHCI_CK_DIV2_EN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_XHCI_RST_CTRL */ +#define SSUSB_XHCI_SW_DRAM_RST (0x1<<4) /* 4:4 */ +#define SSUSB_XHCI_SW_SYS60_RST (0x1<<3) /* 3:3 */ +#define SSUSB_XHCI_SW_SYS125_RST (0x1<<2) /* 2:2 */ +#define SSUSB_XHCI_SW_XHCI_RST (0x1<<1) /* 1:1 */ +#define SSUSB_XHCI_SW_RST (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_DEV_RST_CTRL */ +#define SSUSB_DEV_SW_DRAM_RST (0x1<<3) /* 3:3 */ +#define SSUSB_DEV_SW_QMU_RST (0x1<<2) /* 2:2 */ +#define SSUSB_DEV_SW_BMU_RST (0x1<<1) /* 1:1 */ +#define SSUSB_DEV_SW_RST (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_SYS_CK_CTRL */ +#define SSUSB_SYS60_CK_EXT_SEL (0x1<<2) /* 2:2 */ +#define SSUSB_SYS_CK_EXT_SEL (0x1<<1) /* 1:1 */ +#define SSUSB_SYS_CK_DIV2_EN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_HW_ID */ +#define SSUSB_HW_ID (0xffffffff<<0) /* 31:0 */ + +/* U3D_SSUSB_HW_SUB_ID */ +#define SSUSB_HW_SUB_ID (0xffffffff<<0) /* 31:0 */ + +/* U3D_SSUSB_PRB_CTRL0 */ +#define PRB_BYTE3_EN (0x1<<3) /* 3:3 */ +#define PRB_BYTE2_EN (0x1<<2) /* 2:2 */ +#define PRB_BYTE1_EN (0x1<<1) /* 1:1 */ +#define PRB_BYTE0_EN (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_PRB_CTRL1 */ +#define PRB_BYTE1_SEL (0xffff<<16) /* 31:16 */ +#define PRB_BYTE0_SEL (0xffff<<0) /* 15:0 */ + +/* U3D_SSUSB_PRB_CTRL2 */ +#define PRB_BYTE3_SEL (0xffff<<16) /* 31:16 */ +#define PRB_BYTE2_SEL (0xffff<<0) /* 15:0 */ + +/* U3D_SSUSB_PRB_CTRL3 */ +#define PRB_BYTE3_MODULE_SEL (0xff<<24) /* 31:24 */ +#define PRB_BYTE2_MODULE_SEL (0xff<<16) /* 23:16 */ +#define PRB_BYTE1_MODULE_SEL (0xff<<8) /* 15:8 */ +#define PRB_BYTE0_MODULE_SEL (0xff<<0) /* 7:0 */ + +/* U3D_SSUSB_PRB_CTRL4 */ +#define SW_PRB_OUT (0xffffffff<<0) /* 31:0 */ + +/* U3D_SSUSB_PRB_CTRL5 */ +#define PRB_RD_DATA (0xffffffff<<0) /* 31:0 */ + +/* U3D_SSUSB_IP_SPARE0 */ +#define SSUSB_IP_SPARE0 (0xffffffff<<0) /* 31:0 */ + +/* U3D_SSUSB_IP_SPARE1 */ +#define SSUSB_IP_SPARE1 (0xffffffff<<0) /* 31:0 */ + +/* U3D_SSUSB_FPGA_I2C_OUT_0P */ +#define SSUSB_FPGA_I2C_SCL_OEN_0P (0x1<<3) /* 3:3 */ +#define SSUSB_FPGA_I2C_SCL_OUT_0P (0x1<<2) /* 2:2 */ +#define SSUSB_FPGA_I2C_SDA_OEN_0P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_OUT_0P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_IN_0P */ +#define SSUSB_FPGA_I2C_SCL_IN_0P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_IN_0P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_OUT_1P */ +#define SSUSB_FPGA_I2C_SCL_OEN_1P (0x1<<3) /* 3:3 */ +#define SSUSB_FPGA_I2C_SCL_OUT_1P (0x1<<2) /* 2:2 */ +#define SSUSB_FPGA_I2C_SDA_OEN_1P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_OUT_1P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_IN_1P */ +#define SSUSB_FPGA_I2C_SCL_IN_1P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_IN_1P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_OUT_2P */ +#define SSUSB_FPGA_I2C_SCL_OEN_2P (0x1<<3) /* 3:3 */ +#define SSUSB_FPGA_I2C_SCL_OUT_2P (0x1<<2) /* 2:2 */ +#define SSUSB_FPGA_I2C_SDA_OEN_2P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_OUT_2P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_IN_2P */ +#define SSUSB_FPGA_I2C_SCL_IN_2P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_IN_2P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_OUT_3P */ +#define SSUSB_FPGA_I2C_SCL_OEN_3P (0x1<<3) /* 3:3 */ +#define SSUSB_FPGA_I2C_SCL_OUT_3P (0x1<<2) /* 2:2 */ +#define SSUSB_FPGA_I2C_SDA_OEN_3P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_OUT_3P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_IN_3P */ +#define SSUSB_FPGA_I2C_SCL_IN_3P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_IN_3P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_OUT_4P */ +#define SSUSB_FPGA_I2C_SCL_OEN_4P (0x1<<3) /* 3:3 */ +#define SSUSB_FPGA_I2C_SCL_OUT_4P (0x1<<2) /* 2:2 */ +#define SSUSB_FPGA_I2C_SDA_OEN_4P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_OUT_4P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_FPGA_I2C_IN_4P */ +#define SSUSB_FPGA_I2C_SCL_IN_4P (0x1<<1) /* 1:1 */ +#define SSUSB_FPGA_I2C_SDA_IN_4P (0x1<<0) /* 0:0 */ + +/* U3D_SSUSB_IP_SLV_TMOUT */ +#define SSUSB_IP_SLV_TMOUT (0xffffffff<<0) /* 31:0 */ + + +/* SSUSB_SIFSLV_IPPC FIELD OFFSET DEFINITION */ + +/* U3D_SSUSB_IP_PW_CTRL0 */ +#define SSUSB_AHB_SLV_AUTO_RSP_OFST (17) +#define SSUSB_IP_SW_RST_CK_GATE_EN_OFST (16) +#define SSUSB_IP_U2_ENTER_SLEEP_CNT_OFST (8) +#define SSUSB_IP_SW_RST_OFST (0) + +/* U3D_SSUSB_IP_PW_CTRL1 */ +#define SSUSB_IP_HOST_PDN_OFST (0) + +/* U3D_SSUSB_IP_PW_CTRL2 */ +#define SSUSB_IP_DEV_PDN_OFST (0) + +/* U3D_SSUSB_IP_PW_CTRL3 */ +#define SSUSB_IP_PCIE_PDN_OFST (0) + +/* U3D_SSUSB_IP_PW_STS1 */ +#define SSUSB_IP_REF_CK_DIS_STS_OFST (31) +#define SSUSB_IP_SLEEP_STS_OFST (30) +#define SSUSB_U2_MAC_RST_B_STS_5P_OFST (29) +#define SSUSB_U2_MAC_RST_B_STS_4P_OFST (28) +#define SSUSB_U2_MAC_RST_B_STS_3P_OFST (27) +#define SSUSB_U2_MAC_RST_B_STS_2P_OFST (26) +#define SSUSB_U2_MAC_RST_B_STS_1P_OFST (25) +#define SSUSB_U2_MAC_RST_B_STS_OFST (24) +#define SSUSB_U3_MAC_RST_B_STS_3P_OFST (19) +#define SSUSB_U3_MAC_RST_B_STS_2P_OFST (18) +#define SSUSB_U3_MAC_RST_B_STS_1P_OFST (17) +#define SSUSB_U3_MAC_RST_B_STS_OFST (16) +#define SSUSB_DEV_DRAM_RST_B_STS_OFST (13) +#define SSUSB_XHCI_DRAM_RST_B_STS_OFST (12) +#define SSUSB_XHCI_RST_B_STS_OFST (11) +#define SSUSB_SYS125_RST_B_STS_OFST (10) +#define SSUSB_SYS60_RST_B_STS_OFST (9) +#define SSUSB_REF_RST_B_STS_OFST (8) +#define SSUSB_DEV_RST_B_STS_OFST (3) +#define SSUSB_DEV_BMU_RST_B_STS_OFST (2) +#define SSUSB_DEV_QMU_RST_B_STS_OFST (1) +#define SSUSB_SYSPLL_STABLE_OFST (0) + +/* U3D_SSUSB_IP_PW_STS2 */ +#define SSUSB_U2_MAC_SYS_RST_B_STS_5P_OFST (5) +#define SSUSB_U2_MAC_SYS_RST_B_STS_4P_OFST (4) +#define SSUSB_U2_MAC_SYS_RST_B_STS_3P_OFST (3) +#define SSUSB_U2_MAC_SYS_RST_B_STS_2P_OFST (2) +#define SSUSB_U2_MAC_SYS_RST_B_STS_1P_OFST (1) +#define SSUSB_U2_MAC_SYS_RST_B_STS_OFST (0) + +/* U3D_SSUSB_OTG_STS */ +#define SSUSB_XHCI_MAS_DMA_REQ_OFST (14) +#define SSUSB_DEV_DMA_REQ_OFST (13) +#define SSUSB_AVALID_STS_OFST (12) +#define SSUSB_SRP_REQ_INTR_OFST (11) +#define SSUSB_IDDIG_OFST (10) +#define SSUSB_VBUS_VALID_OFST (9) +#define SSUSB_HOST_DEV_MODE_OFST (8) +#define SSUSB_DEV_USBRST_INTR_OFST (7) +#define VBUS_CHG_INTR_OFST (6) +#define SSUSB_CHG_B_ROLE_B_OFST (5) +#define SSUSB_CHG_A_ROLE_B_OFST (4) +#define SSUSB_ATTACH_B_ROLE_OFST (3) +#define SSUSB_CHG_B_ROLE_A_OFST (2) +#define SSUSB_CHG_A_ROLE_A_OFST (1) +#define SSUSB_ATTACH_A_ROLE_OFST (0) + +/* U3D_SSUSB_OTG_STS_CLR */ +#define SSUSB_SRP_REQ_INTR_CLR_OFST (11) +#define SSUSB_DEV_USBRST_INTR_CLR_OFST (7) +#define SSUSB_VBUS_INTR_CLR_OFST (6) +#define SSUSB_CHG_B_ROLE_B_CLR_OFST (5) +#define SSUSB_CHG_A_ROLE_B_CLR_OFST (4) +#define SSUSB_ATTACH_B_ROLE_CLR_OFST (3) +#define SSUSB_CHG_B_ROLE_A_CLR_OFST (2) +#define SSUSB_CHG_A_ROLE_A_CLR_OFST (1) +#define SSUSB_ATTACH_A_ROLE_CLR_OFST (0) + +/* U3D_SSUSB_IP_MAC_CAP */ +#define SSUSB_IP_MAC_U2_PORT_NO_OFST (8) +#define SSUSB_IP_MAC_U3_PORT_NO_OFST (0) + +/* U3D_SSUSB_IP_XHCI_CAP */ +#define SSUSB_IP_XHCI_U2_PORT_NO_OFST (8) +#define SSUSB_IP_XHCI_U3_PORT_NO_OFST (0) + +/* U3D_SSUSB_IP_DEV_CAP */ +#define SSUSB_IP_DEV_U2_PORT_NO_OFST (8) +#define SSUSB_IP_DEV_U3_PORT_NO_OFST (0) + +/* U3D_SSUSB_OTG_INT_EN */ +#define SSUSB_DEV_USBRST_INT_EN_OFST (8) +#define SSUSB_VBUS_CHG_INT_A_EN_OFST (7) +#define SSUSB_VBUS_CHG_INT_B_EN_OFST (6) +#define SSUSB_CHG_B_ROLE_B_INT_EN_OFST (5) +#define SSUSB_CHG_A_ROLE_B_INT_EN_OFST (4) +#define SSUSB_ATTACH_B_ROLE_INT_EN_OFST (3) +#define SSUSB_CHG_B_ROLE_A_INT_EN_OFST (2) +#define SSUSB_CHG_A_ROLE_A_INT_EN_OFST (1) +#define SSUSB_ATTACH_A_ROLE_INT_EN_OFST (0) + +/* U3D_SSUSB_U3_CTRL_0P */ +#define SSUSB_U3_PORT_PHYD_RST_OFST (5) +#define SSUSB_U3_PORT_MAC_RST_OFST (4) +#define SSUSB_U3_PORT_U2_CG_EN_OFST (3) +#define SSUSB_U3_PORT_HOST_SEL_OFST (2) +#define SSUSB_U3_PORT_PDN_OFST (1) +#define SSUSB_U3_PORT_DIS_OFST (0) + +/* U3D_SSUSB_U3_CTRL_1P */ +#define SSUSB_U3_PORT_PHYD_RST_1P_OFST (5) +#define SSUSB_U3_PORT_MAC_RST_1P_OFST (4) +#define SSUSB_U3_PORT_U2_CG_EN_1P_OFST (3) +#define SSUSB_U3_PORT_HOST_SEL_1P_OFST (2) +#define SSUSB_U3_PORT_PDN_1P_OFST (1) +#define SSUSB_U3_PORT_DIS_1P_OFST (0) + +/* U3D_SSUSB_U3_CTRL_2P */ +#define SSUSB_U3_PORT_PHYD_RST_2P_OFST (5) +#define SSUSB_U3_PORT_MAC_RST_2P_OFST (4) +#define SSUSB_U3_PORT_U2_CG_EN_2P_OFST (3) +#define SSUSB_U3_PORT_HOST_SEL_2P_OFST (2) +#define SSUSB_U3_PORT_PDN_2P_OFST (1) +#define SSUSB_U3_PORT_DIS_2P_OFST (0) + +/* U3D_SSUSB_U3_CTRL_3P */ +#define SSUSB_U3_PORT_PHYD_RST_3P_OFST (5) +#define SSUSB_U3_PORT_MAC_RST_3P_OFST (4) +#define SSUSB_U3_PORT_U2_CG_EN_3P_OFST (3) +#define SSUSB_U3_PORT_HOST_SEL_3P_OFST (2) +#define SSUSB_U3_PORT_PDN_3P_OFST (1) +#define SSUSB_U3_PORT_DIS_3P_OFST (0) + +/* U3D_SSUSB_U2_CTRL_0P */ +#define SSUSB_U2_PORT_OTG_HOST_VBUSVALID_SEL_OFST (9) +#define SSUSB_U2_PORT_OTG_MAC_AUTO_SEL_OFST (8) +#define SSUSB_U2_PORT_OTG_SEL_OFST (7) +#define SSUSB_U2_PORT_PLL_STABLE_SEL_OFST (6) +#define SSUSB_U2_PORT_PHYD_RST_OFST (5) +#define SSUSB_U2_PORT_MAC_RST_OFST (4) +#define SSUSB_U2_PORT_U2_CG_EN_OFST (3) +#define SSUSB_U2_PORT_HOST_SEL_OFST (2) +#define SSUSB_U2_PORT_PDN_OFST (1) +#define SSUSB_U2_PORT_DIS_OFST (0) + +/* U3D_SSUSB_U2_CTRL_1P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_1P_OFST (6) +#define SSUSB_U2_PORT_PHYD_RST_1P_OFST (5) +#define SSUSB_U2_PORT_MAC_RST_1P_OFST (4) +#define SSUSB_U2_PORT_U2_CG_EN_1P_OFST (3) +#define SSUSB_U2_PORT_HOST_SEL_1P_OFST (2) +#define SSUSB_U2_PORT_PDN_1P_OFST (1) +#define SSUSB_U2_PORT_DIS_1P_OFST (0) + +/* U3D_SSUSB_U2_CTRL_2P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_2P_OFST (6) +#define SSUSB_U2_PORT_PHYD_RST_2P_OFST (5) +#define SSUSB_U2_PORT_MAC_RST_2P_OFST (4) +#define SSUSB_U2_PORT_U2_CG_EN_2P_OFST (3) +#define SSUSB_U2_PORT_HOST_SEL_2P_OFST (2) +#define SSUSB_U2_PORT_PDN_2P_OFST (1) +#define SSUSB_U2_PORT_DIS_2P_OFST (0) + +/* U3D_SSUSB_U2_CTRL_3P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_3P_OFST (6) +#define SSUSB_U2_PORT_PHYD_RST_3P_OFST (5) +#define SSUSB_U2_PORT_MAC_RST_3P_OFST (4) +#define SSUSB_U2_PORT_U2_CG_EN_3P_OFST (3) +#define SSUSB_U2_PORT_HOST_SEL_3P_OFST (2) +#define SSUSB_U2_PORT_PDN_3P_OFST (1) +#define SSUSB_U2_PORT_DIS_3P_OFST (0) + +/* U3D_SSUSB_U2_CTRL_4P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_4P_OFST (6) +#define SSUSB_U2_PORT_PHYD_RST_4P_OFST (5) +#define SSUSB_U2_PORT_MAC_RST_4P_OFST (4) +#define SSUSB_U2_PORT_U2_CG_EN_4P_OFST (3) +#define SSUSB_U2_PORT_HOST_SEL_4P_OFST (2) +#define SSUSB_U2_PORT_PDN_4P_OFST (1) +#define SSUSB_U2_PORT_DIS_4P_OFST (0) + +/* U3D_SSUSB_U2_CTRL_5P */ +#define SSUSB_U2_PORT_PLL_STABLE_SEL_5P_OFST (6) +#define SSUSB_U2_PORT_PHYD_RST_5P_OFST (5) +#define SSUSB_U2_PORT_MAC_RST_5P_OFST (4) +#define SSUSB_U2_PORT_U2_CG_EN_5P_OFST (3) +#define SSUSB_U2_PORT_HOST_SEL_5P_OFST (2) +#define SSUSB_U2_PORT_PDN_5P_OFST (1) +#define SSUSB_U2_PORT_DIS_5P_OFST (0) + +/* U3D_SSUSB_U2_PHY_PLL */ +#define SSUSB_SYSPLL_USE_OFST (30) +#define RG_SSUSB_U2_PLL_STB_OFST (29) +#define SSUSB_U2_FORCE_PLL_STB_OFST (28) +#define SSUSB_U2_PORT_PHY_CK_DEB_TIMER_OFST (24) +#define SSUSB_U2_PORT_LPM_PLL_STABLE_TIMER_OFST (16) +#define SSUSB_U2_PORT_PLL_STABLE_TIMER_OFST (8) +#define SSUSB_U2_PORT_1US_TIMER_OFST (0) + +/* U3D_SSUSB_DMA_CTRL */ +#define SSUSB_IP_DMA_BUS_CK_GATE_DIS_OFST (0) + +/* U3D_SSUSB_MAC_CK_CTRL */ +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_OFST (16) +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_OFST (8) +#define SSUSB_PHY_REF_CK_DIV2_OFST (4) +#define SSUSB_MAC3_SYS_CK_GATE_MODE_OFST (2) +#define SSUSB_MAC2_SYS_CK_GATE_MODE_OFST (0) + +/* U3D_SSUSB_CSR_CK_CTRL */ +#define SSUSB_SIFSLV_MCU_BUS_CK_GATE_EN_OFST (1) +#define SSUSB_CSR_MCU_BUS_CK_GATE_EN_OFST (0) + +/* U3D_SSUSB_REF_CK_CTRL */ +#define SSUSB_REF_MAC2_CK_GATE_EN_OFST (4) +#define SSUSB_REF_MAC3_CK_GATE_EN_OFST (3) +#define SSUSB_REF_CK_GATE_EN_OFST (2) +#define SSUSB_REF_PHY_CK_GATE_EN_OFST (1) +#define SSUSB_REF_MAC_CK_GATE_EN_OFST (0) + +/* U3D_SSUSB_XHCI_CK_CTRL */ +#define SSUSB_XACT3_XHCI_CK_GATE_MASK_TIME_OFST (8) +#define SSUSB_XACT3_XHCI_CK_GATE_MODE_OFST (4) +#define SSUSB_XHCI_CK_DIV2_EN_OFST (0) + +/* U3D_SSUSB_XHCI_RST_CTRL */ +#define SSUSB_XHCI_SW_DRAM_RST_OFST (4) +#define SSUSB_XHCI_SW_SYS60_RST_OFST (3) +#define SSUSB_XHCI_SW_SYS125_RST_OFST (2) +#define SSUSB_XHCI_SW_XHCI_RST_OFST (1) +#define SSUSB_XHCI_SW_RST_OFST (0) + +/* U3D_SSUSB_DEV_RST_CTRL */ +#define SSUSB_DEV_SW_DRAM_RST_OFST (3) +#define SSUSB_DEV_SW_QMU_RST_OFST (2) +#define SSUSB_DEV_SW_BMU_RST_OFST (1) +#define SSUSB_DEV_SW_RST_OFST (0) + +/* U3D_SSUSB_SYS_CK_CTRL */ +#define SSUSB_SYS60_CK_EXT_SEL_OFST (2) +#define SSUSB_SYS_CK_EXT_SEL_OFST (1) +#define SSUSB_SYS_CK_DIV2_EN_OFST (0) + +/* U3D_SSUSB_HW_ID */ +#define SSUSB_HW_ID_OFST (0) + +/* U3D_SSUSB_HW_SUB_ID */ +#define SSUSB_HW_SUB_ID_OFST (0) + +/* U3D_SSUSB_PRB_CTRL0 */ +#define PRB_BYTE3_EN_OFST (3) +#define PRB_BYTE2_EN_OFST (2) +#define PRB_BYTE1_EN_OFST (1) +#define PRB_BYTE0_EN_OFST (0) + +/* U3D_SSUSB_PRB_CTRL1 */ +#define PRB_BYTE1_SEL_OFST (16) +#define PRB_BYTE0_SEL_OFST (0) + +/* U3D_SSUSB_PRB_CTRL2 */ +#define PRB_BYTE3_SEL_OFST (16) +#define PRB_BYTE2_SEL_OFST (0) + +/* U3D_SSUSB_PRB_CTRL3 */ +#define PRB_BYTE3_MODULE_SEL_OFST (24) +#define PRB_BYTE2_MODULE_SEL_OFST (16) +#define PRB_BYTE1_MODULE_SEL_OFST (8) +#define PRB_BYTE0_MODULE_SEL_OFST (0) + +/* U3D_SSUSB_PRB_CTRL4 */ +#define SW_PRB_OUT_OFST (0) + +/* U3D_SSUSB_PRB_CTRL5 */ +#define PRB_RD_DATA_OFST (0) + +/* U3D_SSUSB_IP_SPARE0 */ +#define SSUSB_IP_SPARE0_OFST (0) + +/* U3D_SSUSB_IP_SPARE1 */ +#define SSUSB_IP_SPARE1_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_OUT_0P */ +#define SSUSB_FPGA_I2C_SCL_OEN_0P_OFST (3) +#define SSUSB_FPGA_I2C_SCL_OUT_0P_OFST (2) +#define SSUSB_FPGA_I2C_SDA_OEN_0P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_OUT_0P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_IN_0P */ +#define SSUSB_FPGA_I2C_SCL_IN_0P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_IN_0P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_OUT_1P */ +#define SSUSB_FPGA_I2C_SCL_OEN_1P_OFST (3) +#define SSUSB_FPGA_I2C_SCL_OUT_1P_OFST (2) +#define SSUSB_FPGA_I2C_SDA_OEN_1P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_OUT_1P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_IN_1P */ +#define SSUSB_FPGA_I2C_SCL_IN_1P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_IN_1P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_OUT_2P */ +#define SSUSB_FPGA_I2C_SCL_OEN_2P_OFST (3) +#define SSUSB_FPGA_I2C_SCL_OUT_2P_OFST (2) +#define SSUSB_FPGA_I2C_SDA_OEN_2P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_OUT_2P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_IN_2P */ +#define SSUSB_FPGA_I2C_SCL_IN_2P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_IN_2P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_OUT_3P */ +#define SSUSB_FPGA_I2C_SCL_OEN_3P_OFST (3) +#define SSUSB_FPGA_I2C_SCL_OUT_3P_OFST (2) +#define SSUSB_FPGA_I2C_SDA_OEN_3P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_OUT_3P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_IN_3P */ +#define SSUSB_FPGA_I2C_SCL_IN_3P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_IN_3P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_OUT_4P */ +#define SSUSB_FPGA_I2C_SCL_OEN_4P_OFST (3) +#define SSUSB_FPGA_I2C_SCL_OUT_4P_OFST (2) +#define SSUSB_FPGA_I2C_SDA_OEN_4P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_OUT_4P_OFST (0) + +/* U3D_SSUSB_FPGA_I2C_IN_4P */ +#define SSUSB_FPGA_I2C_SCL_IN_4P_OFST (1) +#define SSUSB_FPGA_I2C_SDA_IN_4P_OFST (0) + +/* U3D_SSUSB_IP_SLV_TMOUT */ +#define SSUSB_IP_SLV_TMOUT_OFST (0) + +/* //////////////////////////////////////////////////////////////////// */ diff --git a/drivers/misc/mediatek/mu3d/hal/ssusb_usb2_csr_c_header.h b/drivers/misc/mediatek/mu3d/hal/ssusb_usb2_csr_c_header.h new file mode 100644 index 000000000000..0bf2c144a7d8 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/ssusb_usb2_csr_c_header.h @@ -0,0 +1,294 @@ +/* SSUSB_USB2_CSR REGISTER DEFINITION */ + +#define U3D_XHCI_PORT_CTRL (SSUSB_USB2_CSR_BASE+0x0000) +#define U3D_POWER_MANAGEMENT (SSUSB_USB2_CSR_BASE+0x0004) +#define U3D_TIMING_TEST_MODE (SSUSB_USB2_CSR_BASE+0x0008) +#define U3D_DEVICE_CONTROL (SSUSB_USB2_CSR_BASE+0x000C) +#define U3D_POWER_UP_COUNTER (SSUSB_USB2_CSR_BASE+0x0010) +#define U3D_USB2_TEST_MODE (SSUSB_USB2_CSR_BASE+0x0014) +#define U3D_COMMON_USB_INTR_ENABLE (SSUSB_USB2_CSR_BASE+0x0018) +#define U3D_COMMON_USB_INTR (SSUSB_USB2_CSR_BASE+0x001C) +#define U3D_USB_BUS_PERFORMANCE (SSUSB_USB2_CSR_BASE+0x0020) +#define U3D_LINK_RESET_INFO (SSUSB_USB2_CSR_BASE+0x0024) +#define U3D_RESET_RESUME_TIME_VALUE (SSUSB_USB2_CSR_BASE+0x0034) +#define U3D_UTMI_SIGNAL_SEL (SSUSB_USB2_CSR_BASE+0x0038) +#define U3D_USB20_FRAME_NUM (SSUSB_USB2_CSR_BASE+0x003C) +#define U3D_USB20_TIMING_PARAMETER (SSUSB_USB2_CSR_BASE+0x0040) +#define U3D_USB20_LPM_PARAMETER (SSUSB_USB2_CSR_BASE+0x0044) +#define U3D_USB20_LPM_ENTRY_COUNT (SSUSB_USB2_CSR_BASE+0x0048) +#define U3D_USB20_MISC_CONTROL (SSUSB_USB2_CSR_BASE+0x004C) +#define U3D_USB20_LPM_TIMING_PARAM (SSUSB_USB2_CSR_BASE+0x0050) +#define U3D_USB20_OPSTATE (SSUSB_USB2_CSR_BASE+0x0060) + +/* SSUSB_USB2_CSR FIELD DEFINITION */ + +/* U3D_XHCI_PORT_CTRL */ +#define GO_POLLING (0x1<<7) /* 7:7 */ + +/* U3D_POWER_MANAGEMENT */ +#define LPM_BESL_STALL (0x1<<14) /* 14:14 */ +#define LPM_BESLD_STALL (0x1<<13) /* 13:13 */ +#define BC12_EN (0x1<<12) /* 12:12 */ +#define LPM_RWP (0x1<<11) /* 11:11 */ +#define LPM_HRWE (0x1<<10) /* 10:10 */ +#define LPM_MODE (0x3<<8) /* 9:8 */ +#define ISO_UPDATE (0x1<<7) /* 7:7 */ +#define SOFT_CONN (0x1<<6) /* 6:6 */ +#define HS_ENABLE (0x1<<5) /* 5:5 */ +#define HS_MODE (0x1<<4) /* 4:4 */ +#define BUS_RESET (0x1<<3) /* 3:3 */ +#define RESUME (0x1<<2) /* 2:2 */ +#define SUSPEND (0x1<<1) /* 1:1 */ +#define SUSPENDM_ENABLE (0x1<<0) /* 0:0 */ + +/* U3D_TIMING_TEST_MODE */ +#define FS_DIS_SEL (0xf<<4) /* 7:4 */ +#define PHY_CLK_VALID (0x1<<3) /* 3:3 */ +#define FS_DIS_NE (0x1<<2) /* 2:2 */ +#define TM1 (0x1<<0) /* 0:0 */ + +/* U3D_DEVICE_CONTROL */ +#define HW_AUTO_SENDRST_EN (0x1<<8) /* 8:8 */ +#define B_DEV (0x1<<7) /* 7:7 */ +#define FS_DEV (0x1<<6) /* 6:6 */ +#define LS_DEV (0x1<<5) /* 5:5 */ +#define VBUS (0x3<<3) /* 4:3 */ +#define HOSTMODE (0x1<<2) /* 2:2 */ +#define HOSTREQ (0x1<<1) /* 1:1 */ +#define SESSION (0x1<<0) /* 0:0 */ + +/* U3D_POWER_UP_COUNTER */ +#define LPM_HUBDRVRMP_TIME (0xffff<<8) /* 23:8 */ +#define PWR_UP_CNT_LMT (0xf<<0) /* 3:0 */ + +/* U3D_USB2_TEST_MODE */ +#define U2U3_AUTO_SWITCH (0x1<<10) /* 10:10 */ +#define HOST_FORCE_EN (0x1<<9) /* 9:9 */ +#define LPM_FORCE_STALL (0x1<<8) /* 8:8 */ +#define FORCE_HOST (0x1<<7) /* 7:7 */ +#define FIFO_ACCESS (0x1<<6) /* 6:6 */ +#define FORCE_FS (0x1<<5) /* 5:5 */ +#define FORCE_HS (0x1<<4) /* 4:4 */ +#define TEST_PACKET_MODE (0x1<<3) /* 3:3 */ +#define TEST_K_MODE (0x1<<2) /* 2:2 */ +#define TEST_J_MODE (0x1<<1) /* 1:1 */ +#define TEST_SE0_NAK_MODE (0x1<<0) /* 0:0 */ + +/* U3D_COMMON_USB_INTR_ENABLE */ +#define LPM_RESUME_INTR_EN (0x1<<9) /* 9:9 */ +#define LPM_INTR_EN (0x1<<8) /* 8:8 */ +#define VBUSERR_INTR_EN (0x1<<7) /* 7:7 */ +#define SESSION_REQ_INTR_EN (0x1<<6) /* 6:6 */ +#define DISCONN_INTR_EN (0x1<<5) /* 5:5 */ +#define CONN_INTR_EN (0x1<<4) /* 4:4 */ +#define SOF_INTR_EN (0x1<<3) /* 3:3 */ +#define RESET_INTR_EN (0x1<<2) /* 2:2 */ +#define RESUME_INTR_EN (0x1<<1) /* 1:1 */ +#define SUSPEND_INTR_EN (0x1<<0) /* 0:0 */ + +/* U3D_COMMON_USB_INTR */ +#define LPM_RESUME_INTR (0x1<<9) /* 9:9 */ +#define LPM_INTR (0x1<<8) /* 8:8 */ +#define VBUSERR_INTR (0x1<<7) /* 7:7 */ +#define SESSION_REQ_INTR (0x1<<6) /* 6:6 */ +#define DISCONN_INTR (0x1<<5) /* 5:5 */ +#define CONN_INTR (0x1<<4) /* 4:4 */ +#define SOF_INTR (0x1<<3) /* 3:3 */ +#define RESET_INTR (0x1<<2) /* 2:2 */ +#define RESUME_INTR (0x1<<1) /* 1:1 */ +#define SUSPEND_INTR (0x1<<0) /* 0:0 */ + +/* U3D_USB_BUS_PERFORMANCE */ +#define XFER_START_FROM_SOF (0x1<<24) /* 24:24 */ +#define VBUSERR_MODE (0x1<<23) /* 23:23 */ +#define TX_FLUSH_EN (0x1<<22) /* 22:22 */ +#define NOISE_STILL_SOF (0x1<<21) /* 21:21 */ +#define UNDO_SRP_FIX (0x1<<19) /* 19:19 */ +#define OTG_DEGLITCH_DISABLE (0x1<<18) /* 18:18 */ +#define SWRST (0x1<<17) /* 17:17 */ +#define DIS_USB_RESET (0x1<<16) /* 16:16 */ +#define SOFT_DEBOUCE (0x1<<0) /* 0:0 */ + +/* U3D_LINK_RESET_INFO */ +#define WTWRSM (0xf<<28) /* 31:28 */ +#define WTRSMK (0xf<<24) /* 27:24 */ +#define WRFSSE0 (0xf<<20) /* 23:20 */ +#define WTCHRP (0xf<<16) /* 19:16 */ +#define VPLEN (0xff<<8) /* 15:8 */ +#define WTCON (0xf<<4) /* 7:4 */ +#define WTID (0xf<<0) /* 3:0 */ + +/* U3D_RESET_RESUME_TIME_VALUE */ +#define USB20_RESET_TIME_VALUE (0xffff<<0) /* 15:0 */ + +/* U3D_UTMI_SIGNAL_SEL */ +#define TX_SIGNAL_SEL (0x3<<2) /* 3:2 */ +#define RX_SIGNAL_SEL (0x3<<0) /* 1:0 */ + +/* U3D_USB20_FRAME_NUM */ +#define FRAME_NUMBER (0x7ff<<0) /* 10:0 */ + +/* U3D_USB20_TIMING_PARAMETER */ +#define CHOPPER_DELAY_TIME (0xff<<16) /* 23:16 */ +#define SOFTCON_DELAY_TIME (0xff<<8) /* 15:8 */ +#define TIME_VALUE_1US (0xff<<0) /* 7:0 */ + +/* U3D_USB20_LPM_PARAMETER */ +#define BESLCK_U3 (0xf<<12) /* 15:12 */ +#define BESLCK (0xf<<8) /* 11:8 */ +#define BESLDCK (0xf<<4) /* 7:4 */ +#define BESL (0xf<<0) /* 3:0 */ + +/* U3D_USB20_LPM_ENTRY_COUNT */ +#define LPM_EXIT_COUNT (0xff<<16) /* 23:16 */ +#define LPM_EXIT_COUNT_RESET (0x1<<9) /* 9:9 */ +#define LPM_ENTRY_COUNT_RESET (0x1<<8) /* 8:8 */ +#define LPM_ENTRY_COUNT (0xff<<0) /* 7:0 */ + +/* U3D_USB20_MISC_CONTROL */ +#define LPM_U3_ACK_EN (0x1<<0) /* 0:0 */ + +/* U3D_USB20_LPM_TIMING_PARAM */ +#define LPM_L1_TOKENRETRY (0x1ff<<16) /* 24:16 */ +#define LPM_L1_RESIDENCY (0xfff<<0) /* 11:0 */ + +/* U3D_USB20_OPSTATE */ +#define OPSTATE_SYS (0x3f<<0) /* 5:0 */ + + +/* SSUSB_USB2_CSR FIELD OFFSET DEFINITION */ + +/* U3D_XHCI_PORT_CTRL */ +#define GO_POLLING_OFST (7) + +/* U3D_POWER_MANAGEMENT */ +#define LPM_BESL_STALL_OFST (14) +#define LPM_BESLD_STALL_OFST (13) +#define BC12_EN_OFST (12) +#define LPM_RWP_OFST (11) +#define LPM_HRWE_OFST (10) +#define LPM_MODE_OFST (8) +#define ISO_UPDATE_OFST (7) +#define SOFT_CONN_OFST (6) +#define HS_ENABLE_OFST (5) +#define HS_MODE_OFST (4) +#define BUS_RESET_OFST (3) +#define RESUME_OFST (2) +#define SUSPEND_OFST (1) +#define SUSPENDM_ENABLE_OFST (0) + +/* U3D_TIMING_TEST_MODE */ +#define FS_DIS_SEL_OFST (4) +#define PHY_CLK_VALID_OFST (3) +#define FS_DIS_NE_OFST (2) +#define TM1_OFST (0) + +/* U3D_DEVICE_CONTROL */ +#define HW_AUTO_SENDRST_EN_OFST (8) +#define B_DEV_OFST (7) +#define FS_DEV_OFST (6) +#define LS_DEV_OFST (5) +#define VBUS_OFST (3) +#define HOSTMODE_OFST (2) +#define HOSTREQ_OFST (1) +#define SESSION_OFST (0) + +/* U3D_POWER_UP_COUNTER */ +#define LPM_HUBDRVRMP_TIME_OFST (8) +#define PWR_UP_CNT_LMT_OFST (0) + +/* U3D_USB2_TEST_MODE */ +#define U2U3_AUTO_SWITCH_OFST (10) +#define HOST_FORCE_EN_OFST (9) +#define LPM_FORCE_STALL_OFST (8) +#define FORCE_HOST_OFST (7) +#define FIFO_ACCESS_OFST (6) +#define FORCE_FS_OFST (5) +#define FORCE_HS_OFST (4) +#define TEST_PACKET_MODE_OFST (3) +#define TEST_K_MODE_OFST (2) +#define TEST_J_MODE_OFST (1) +#define TEST_SE0_NAK_MODE_OFST (0) + +/* U3D_COMMON_USB_INTR_ENABLE */ +#define LPM_RESUME_INTR_EN_OFST (9) +#define LPM_INTR_EN_OFST (8) +#define VBUSERR_INTR_EN_OFST (7) +#define SESSION_REQ_INTR_EN_OFST (6) +#define DISCONN_INTR_EN_OFST (5) +#define CONN_INTR_EN_OFST (4) +#define SOF_INTR_EN_OFST (3) +#define RESET_INTR_EN_OFST (2) +#define RESUME_INTR_EN_OFST (1) +#define SUSPEND_INTR_EN_OFST (0) + +/* U3D_COMMON_USB_INTR */ +#define LPM_RESUME_INTR_OFST (9) +#define LPM_INTR_OFST (8) +#define VBUSERR_INTR_OFST (7) +#define SESSION_REQ_INTR_OFST (6) +#define DISCONN_INTR_OFST (5) +#define CONN_INTR_OFST (4) +#define SOF_INTR_OFST (3) +#define RESET_INTR_OFST (2) +#define RESUME_INTR_OFST (1) +#define SUSPEND_INTR_OFST (0) + +/* U3D_USB_BUS_PERFORMANCE */ +#define XFER_START_FROM_SOF_OFST (24) +#define VBUSERR_MODE_OFST (23) +#define TX_FLUSH_EN_OFST (22) +#define NOISE_STILL_SOF_OFST (21) +#define UNDO_SRP_FIX_OFST (19) +#define OTG_DEGLITCH_DISABLE_OFST (18) +#define SWRST_OFST (17) +#define DIS_USB_RESET_OFST (16) +#define SOFT_DEBOUCE_OFST (0) + +/* U3D_LINK_RESET_INFO */ +#define WTWRSM_OFST (28) +#define WTRSMK_OFST (24) +#define WRFSSE0_OFST (20) +#define WTCHRP_OFST (16) +#define VPLEN_OFST (8) +#define WTCON_OFST (4) +#define WTID_OFST (0) + +/* U3D_RESET_RESUME_TIME_VALUE */ +#define USB20_RESET_TIME_VALUE_OFST (0) + +/* U3D_UTMI_SIGNAL_SEL */ +#define TX_SIGNAL_SEL_OFST (2) +#define RX_SIGNAL_SEL_OFST (0) + +/* U3D_USB20_FRAME_NUM */ +#define FRAME_NUMBER_OFST (0) + +/* U3D_USB20_TIMING_PARAMETER */ +#define CHOPPER_DELAY_TIME_OFST (16) +#define SOFTCON_DELAY_TIME_OFST (8) +#define TIME_VALUE_1US_OFST (0) + +/* U3D_USB20_LPM_PARAMETER */ +#define BESLCK_U3_OFST (12) +#define BESLCK_OFST (8) +#define BESLDCK_OFST (4) +#define BESL_OFST (0) + +/* U3D_USB20_LPM_ENTRY_COUNT */ +#define LPM_EXIT_COUNT_OFST (16) +#define LPM_EXIT_COUNT_RESET_OFST (9) +#define LPM_ENTRY_COUNT_RESET_OFST (8) +#define LPM_ENTRY_COUNT_OFST (0) + +/* U3D_USB20_MISC_CONTROL */ +#define LPM_U3_ACK_EN_OFST (0) + +/* U3D_USB20_LPM_TIMING_PARAM */ +#define LPM_L1_TOKENRETRY_OFST (16) +#define LPM_L1_RESIDENCY_OFST (0) + +/* U3D_USB20_OPSTATE */ +#define OPSTATE_SYS_OFST (0) + +/* //////////////////////////////////////////////////////////////////// */ diff --git a/drivers/misc/mediatek/mu3d/hal/ssusb_usb3_mac_csr_c_header.h b/drivers/misc/mediatek/mu3d/hal/ssusb_usb3_mac_csr_c_header.h new file mode 100644 index 000000000000..485ac5704c97 --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/ssusb_usb3_mac_csr_c_header.h @@ -0,0 +1,423 @@ +/* SSUSB_USB3_MAC_CSR REGISTER DEFINITION */ + +#define U3D_TS_CONFIG (SSUSB_USB3_MAC_CSR_BASE+0x0000) +#define U3D_PIPE (SSUSB_USB3_MAC_CSR_BASE+0x0004) +#define U3D_LTSSM_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x000C) +#define U3D_LTSSM_CTRL (SSUSB_USB3_MAC_CSR_BASE+0x0010) +#define U3D_LTSSM_INFO (SSUSB_USB3_MAC_CSR_BASE+0x0014) +#define U3D_USB3_CONFIG (SSUSB_USB3_MAC_CSR_BASE+0x001C) +#define U3D_USB3_U1_STATE_INFO (SSUSB_USB3_MAC_CSR_BASE+0x0050) +#define U3D_USB3_U2_STATE_INFO (SSUSB_USB3_MAC_CSR_BASE+0x0054) +#define U3D_UX_LFPS_TIMING_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x007C) +#define U3D_U1_LFPS_TIMING_PARAMETER_2 (SSUSB_USB3_MAC_CSR_BASE+0x0080) +#define U3D_U2_LB_LFPS_TIMING_PARAMETER_1 (SSUSB_USB3_MAC_CSR_BASE+0x0084) +#define U3D_U2_LB_LFPS_TIMING_PARAMETER_2 (SSUSB_USB3_MAC_CSR_BASE+0x0088) +#define U3D_U3_LFPS_TIMING_PARAMETER_1 (SSUSB_USB3_MAC_CSR_BASE+0x008C) +#define U3D_U3_LFPS_TIMING_PARAMETER_2 (SSUSB_USB3_MAC_CSR_BASE+0x0090) +#define U3D_PING_LFPS_TIMING_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x0094) +#define U3D_POLLING_LFPS_TIMING_PARAMETER_1 (SSUSB_USB3_MAC_CSR_BASE+0x0098) +#define U3D_POLLING_LFPS_TIMING_PARAMETER_2 (SSUSB_USB3_MAC_CSR_BASE+0x009C) +#define U3D_UX_EXIT_LFPS_TIMING_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x00A0) +#define U3D_P3_TIMING_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x00A4) +#define U3D_WARM_RESET_TIMING_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x00A8) +#define U3D_UX_EXIT_TIMING_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x00AC) +#define U3D_REF_CK_PARAMETER (SSUSB_USB3_MAC_CSR_BASE+0x00B0) +#define U3D_LTSSM_TIMING_PARAMETER_1 (SSUSB_USB3_MAC_CSR_BASE+0x010C) +#define U3D_LTSSM_TIMING_PARAMETER_2 (SSUSB_USB3_MAC_CSR_BASE+0x0110) +#define U3D_LTSSM_TIMING_PARAMETER_3 (SSUSB_USB3_MAC_CSR_BASE+0x0114) +#define U3D_LTSSM_TIMING_PARAMETER_4 (SSUSB_USB3_MAC_CSR_BASE+0x0118) +#define U3D_LTSSM_TIMING_PARAMETER_5 (SSUSB_USB3_MAC_CSR_BASE+0x011C) +#define U3D_LTSSM_RXDETECT_CTRL (SSUSB_USB3_MAC_CSR_BASE+0x0120) +#define U3D_PIPE_RXDATA_ERR_INTR_ENABLE (SSUSB_USB3_MAC_CSR_BASE+0x0128) +#define U3D_PIPE_RXDATA_ERR_INTR (SSUSB_USB3_MAC_CSR_BASE+0x012C) +#define U3D_PIPE_LATCH_SELECT (SSUSB_USB3_MAC_CSR_BASE+0x0130) +#define U3D_LINK_STATE_MACHINE (SSUSB_USB3_MAC_CSR_BASE+0x0134) +#define U3D_MAC_FAST_SIMULATION (SSUSB_USB3_MAC_CSR_BASE+0x0138) +#define U3D_LTSSM_INTR_ENABLE (SSUSB_USB3_MAC_CSR_BASE+0x013C) +#define U3D_LTSSM_INTR (SSUSB_USB3_MAC_CSR_BASE+0x0140) +#define U3D_SKP_CNT (SSUSB_USB3_MAC_CSR_BASE+0x0148) + +/* SSUSB_USB3_MAC_CSR FIELD DEFINITION */ + +/* U3D_TS_CONFIG */ +#define TS_CONFIG_DISABLE_SCRAMBLING (0x1<<0) /* 0:0 */ + +/* U3D_PIPE */ +#define CP_TXDEEMPH_WITHOUT (0x3<<6) /* 7:6 */ +#define CP_TXDEEMPH_WITH (0x3<<4) /* 5:4 */ +#define CP_TXDEEMPH (0x3<<2) /* 3:2 */ +#define PIPE_TXDEEMPH (0x3<<0) /* 1:0 */ + +/* U3D_LTSSM_PARAMETER */ +#define DISABLE_NUM (0xf<<24) /* 27:24 */ +#define RXDETECT_NUM (0x1f<<16) /* 20:16 */ +#define TX_TSEQ_NUM (0xffff<<0) /* 15:0 */ + +/* U3D_LTSSM_CTRL */ +#define FORCE_POLLING_FAIL (0x1<<4) /* 4:4 */ +#define FORCE_RXDETECT_FAIL (0x1<<3) /* 3:3 */ +#define SOFT_U3_EXIT_EN (0x1<<2) /* 2:2 */ +#define COMPLIANCE_EN (0x1<<1) /* 1:1 */ +#define U1_GO_U2_EN (0x1<<0) /* 0:0 */ + +/* U3D_LTSSM_INFO */ +#define CLR_PWR_CHG_TMOUT_FLAG (0x1<<26) /* 26:26 */ +#define CLR_DISABLE_CNT (0x1<<25) /* 25:25 */ +#define CLR_RXDETECT_CNT (0x1<<24) /* 24:24 */ +#define PWR_CHG_TMOUT_FLAG (0x1<<16) /* 16:16 */ +#define DISABLE_CNT (0xf<<8) /* 11:8 */ +#define RXDETECT_CNT (0x1f<<0) /* 4:0 */ + +/* U3D_USB3_CONFIG */ +#define USB3_EN (0x1<<0) /* 0:0 */ + +/* U3D_USB3_U1_STATE_INFO */ +#define CLR_USB3_U1_CNT (0x1<<16) /* 16:16 */ +#define USB3_U1_CNT (0xffff<<0) /* 15:0 */ + +/* U3D_USB3_U2_STATE_INFO */ +#define CLR_USB3_U2_CNT (0x1<<16) /* 16:16 */ +#define USB3_U2_CNT (0xffff<<0) /* 15:0 */ + +/* U3D_UX_LFPS_TIMING_PARAMETER */ +#define UX_EXIT_T12_T11_MINUS_300NS (0xff<<0) /* 7:0 */ + +/* U3D_U1_LFPS_TIMING_PARAMETER_2 */ +#define U1_EXIT_NO_LFPS_TMOUT (0xfff<<16) /* 27:16 */ +#define U1_EXIT_T13_T11 (0xff<<8) /* 15:8 */ +#define U1_EXIT_T12_T10 (0xff<<0) /* 7:0 */ + +/* U3D_U2_LB_LFPS_TIMING_PARAMETER_1 */ +#define U2_LB_EXIT_T13_T11 (0xfff<<16) /* 27:16 */ +#define U2_LB_EXIT_T12_T10 (0xfff<<0) /* 11:0 */ + +/* U3D_U2_LB_LFPS_TIMING_PARAMETER_2 */ +#define U2_LB_EXIT_NO_LFPS_TMOUT (0xfff<<0) /* 11:0 */ + +/* U3D_U3_LFPS_TIMING_PARAMETER_1 */ +#define U3_EXIT_T13_T11 (0x3fff<<16) /* 29:16 */ +#define U3_EXIT_T12_T10 (0x3fff<<0) /* 13:0 */ + +/* U3D_U3_LFPS_TIMING_PARAMETER_2 */ +#define SEND_U3_EXIT_LFPS_WAIT_CYCLE (0xff<<16) /* 23:16 */ +#define U3_EXIT_NO_LFPS_TMOUT (0x3fff<<0) /* 13:0 */ + +/* U3D_PING_LFPS_TIMING_PARAMETER */ +#define TX_PING_LFPS_TBURST (0x3f<<16) /* 21:16 */ +#define RX_PING_LFPS_TBURST_MAX (0x3f<<8) /* 13:8 */ +#define RX_PING_LFPS_TBURST_MIN (0xf<<0) /* 3:0 */ + +/* U3D_POLLING_LFPS_TIMING_PARAMETER_1 */ +#define RX_POLLING_LFPS_TBURST_MAX (0xff<<8) /* 15:8 */ +#define RX_POLLING_LFPS_TBURST_MIN (0x7f<<0) /* 6:0 */ + +/* U3D_POLLING_LFPS_TIMING_PARAMETER_2 */ +#define TX_POLLING_LFPS_NUM (0x1f<<16) /* 20:16 */ +#define TX_POLLING_LFPS_TREPEAT (0xf<<8) /* 11:8 */ +#define TX_POLLING_LFPS_TBURST (0xff<<0) /* 7:0 */ + +/* U3D_UX_EXIT_LFPS_TIMING_PARAMETER */ +#define RX_UX_EXIT_LFPS_REF (0xff<<8) /* 15:8 */ +#define RX_UX_EXIT_LFPS_PIPE (0xff<<0) /* 7:0 */ + +/* U3D_P3_TIMING_PARAMETER */ +#define P3_ENTER_CYCLE (0xf<<20) /* 23:20 */ +#define P3_EXIT_CYCLE (0xf<<16) /* 19:16 */ + +/* U3D_WARM_RESET_TIMING_PARAMETER */ +#define TRESET_TBURST (0xff<<8) /* 15:8 */ +#define TRESETDELAY (0x3f<<0) /* 5:0 */ + +/* U3D_UX_EXIT_TIMING_PARAMETER */ +#define UX_EXIT_TIMER (0xfffff<<0) /* 19:0 */ + +/* U3D_REF_CK_PARAMETER */ +#define REF_1000NS (0xff<<0) /* 7:0 */ + +/* U3D_LTSSM_TIMING_PARAMETER_1 */ +#define MAC_6MS (0xf<<16) /* 19:16 */ +#define MAC_2MS (0xff<<0) /* 7:0 */ + +/* U3D_LTSSM_TIMING_PARAMETER_2 */ +#define MAC_100MS (0xff<<16) /* 23:16 */ +#define MAC_12MS (0x1f<<0) /* 4:0 */ + +/* U3D_LTSSM_TIMING_PARAMETER_3 */ +#define MAC_360MS (0x3ff<<16) /* 25:16 */ +#define MAC_300MS (0x3ff<<0) /* 9:0 */ + +/* U3D_LTSSM_TIMING_PARAMETER_4 */ +#define MAC_200MS (0xff<<0) /* 7:0 */ + +/* U3D_LTSSM_TIMING_PARAMETER_5 */ +#define POWER_CHANGE_TIMEOUT_VALUE (0x3ff<<16) /* 25:16 */ +#define RXDETECT_TIMEOUT_VALUE (0x3ff<<0) /* 9:0 */ + +/* U3D_LTSSM_RXDETECT_CTRL */ +#define RXDETECT_WAIT_TIME (0xff<<8) /* 15:8 */ +#define RXDETECT_WAIT_EN (0x1<<0) /* 0:0 */ + +/* U3D_PIPE_RXDATA_ERR_INTR_ENABLE */ +#define DEC_8B10B_ERR_INTR_EN (0x1<<2) /* 2:2 */ +#define DISPARITY_ERR_INTR_EN (0x1<<1) /* 1:1 */ +#define EBUF_ERR_INTR_EN (0x1<<0) /* 0:0 */ + +/* U3D_PIPE_RXDATA_ERR_INTR */ +#define DEC_8B10B_ERR_INTR (0x1<<2) /* 2:2 */ +#define DISPARITY_ERR_INTR (0x1<<1) /* 1:1 */ +#define EBUF_ERR_INTR (0x1<<0) /* 0:0 */ + +/* U3D_PIPE_LATCH_SELECT */ +#define TX_SIGNAL_SEL (0x3<<2) /* 3:2 */ +#define RX_SIGNAL_SEL (0x3<<0) /* 1:0 */ + +/* U3D_LINK_STATE_MACHINE */ +#define VBUS_DBC_CYCLE (0xffff<<16) /* 31:16 */ +#define VBUS_VALID (0x1<<8) /* 8:8 */ +#define LTSSM (0x1f<<0) /* 4:0 */ + +/* U3D_MAC_FAST_SIMULATION */ +#define FORCE_U0_TO_U3 (0x1<<5) /* 5:5 */ +#define FORCE_U0_TO_U2 (0x1<<4) /* 4:4 */ +#define FORCE_U0_TO_U1 (0x1<<3) /* 3:3 */ +#define MAC_SPEED_MS_TO_US (0x1<<2) /* 2:2 */ +#define BYPASS_WARM_RESET (0x1<<1) /* 1:1 */ + +/* U3D_LTSSM_INTR_ENABLE */ +#define U3_RESUME_INTR_EN (0x1<<18) /* 18:18 */ +#define U3_LFPS_TMOUT_INTR_EN (0x1<<17) /* 17:17 */ +#define VBUS_FALL_INTR_EN (0x1<<16) /* 16:16 */ +#define VBUS_RISE_INTR_EN (0x1<<15) /* 15:15 */ +#define RXDET_SUCCESS_INTR_EN (0x1<<14) /* 14:14 */ +#define EXIT_U3_INTR_EN (0x1<<13) /* 13:13 */ +#define EXIT_U2_INTR_EN (0x1<<12) /* 12:12 */ +#define EXIT_U1_INTR_EN (0x1<<11) /* 11:11 */ +#define ENTER_U3_INTR_EN (0x1<<10) /* 10:10 */ +#define ENTER_U2_INTR_EN (0x1<<9) /* 9:9 */ +#define ENTER_U1_INTR_EN (0x1<<8) /* 8:8 */ +#define ENTER_U0_INTR_EN (0x1<<7) /* 7:7 */ +#define RECOVERY_INTR_EN (0x1<<6) /* 6:6 */ +#define WARM_RST_INTR_EN (0x1<<5) /* 5:5 */ +#define HOT_RST_INTR_EN (0x1<<4) /* 4:4 */ +#define LOOPBACK_INTR_EN (0x1<<3) /* 3:3 */ +#define COMPLIANCE_INTR_EN (0x1<<2) /* 2:2 */ +#define SS_DISABLE_INTR_EN (0x1<<1) /* 1:1 */ +#define SS_INACTIVE_INTR_EN (0x1<<0) /* 0:0 */ + +/* U3D_LTSSM_INTR */ +#define U3_RESUME_INTR (0x1<<18) /* 18:18 */ +#define U3_LFPS_TMOUT_INTR (0x1<<17) /* 17:17 */ +#define VBUS_FALL_INTR (0x1<<16) /* 16:16 */ +#define VBUS_RISE_INTR (0x1<<15) /* 15:15 */ +#define RXDET_SUCCESS_INTR (0x1<<14) /* 14:14 */ +#define EXIT_U3_INTR (0x1<<13) /* 13:13 */ +#define EXIT_U2_INTR (0x1<<12) /* 12:12 */ +#define EXIT_U1_INTR (0x1<<11) /* 11:11 */ +#define ENTER_U3_INTR (0x1<<10) /* 10:10 */ +#define ENTER_U2_INTR (0x1<<9) /* 9:9 */ +#define ENTER_U1_INTR (0x1<<8) /* 8:8 */ +#define ENTER_U0_INTR (0x1<<7) /* 7:7 */ +#define RECOVERY_INTR (0x1<<6) /* 6:6 */ +#define WARM_RST_INTR (0x1<<5) /* 5:5 */ +#define HOT_RST_INTR (0x1<<4) /* 4:4 */ +#define LOOPBACK_INTR (0x1<<3) /* 3:3 */ +#define COMPLIANCE_INTR (0x1<<2) /* 2:2 */ +#define SS_DISABLE_INTR (0x1<<1) /* 1:1 */ +#define SS_INACTIVE_INTR (0x1<<0) /* 0:0 */ + +/* U3D_SKP_CNT */ +#define SKP_SYMBOL_NUM (0x7f<<0) /* 6:0 */ + + +/* SSUSB_USB3_MAC_CSR FIELD OFFSET DEFINITION */ + +/* U3D_TS_CONFIG */ +#define TS_CONFIG_DISABLE_SCRAMBLING_OFST (0) + +/* U3D_PIPE */ +#define CP_TXDEEMPH_WITHOUT_OFST (6) +#define CP_TXDEEMPH_WITH_OFST (4) +#define CP_TXDEEMPH_OFST (2) +#define PIPE_TXDEEMPH_OFST (0) + +/* U3D_LTSSM_PARAMETER */ +#define DISABLE_NUM_OFST (24) +#define RXDETECT_NUM_OFST (16) +#define TX_TSEQ_NUM_OFST (0) + +/* U3D_LTSSM_CTRL */ +#define FORCE_POLLING_FAIL_OFST (4) +#define FORCE_RXDETECT_FAIL_OFST (3) +#define SOFT_U3_EXIT_EN_OFST (2) +#define COMPLIANCE_EN_OFST (1) +#define U1_GO_U2_EN_OFST (0) + +/* U3D_LTSSM_INFO */ +#define CLR_PWR_CHG_TMOUT_FLAG_OFST (26) +#define CLR_DISABLE_CNT_OFST (25) +#define CLR_RXDETECT_CNT_OFST (24) +#define PWR_CHG_TMOUT_FLAG_OFST (16) +#define DISABLE_CNT_OFST (8) +#define RXDETECT_CNT_OFST (0) + +/* U3D_USB3_CONFIG */ +#define USB3_EN_OFST (0) + +/* U3D_USB3_U1_STATE_INFO */ +#define CLR_USB3_U1_CNT_OFST (16) +#define USB3_U1_CNT_OFST (0) + +/* U3D_USB3_U2_STATE_INFO */ +#define CLR_USB3_U2_CNT_OFST (16) +#define USB3_U2_CNT_OFST (0) + +/* U3D_UX_LFPS_TIMING_PARAMETER */ +#define UX_EXIT_T12_T11_MINUS_300NS_OFST (0) + +/* U3D_U1_LFPS_TIMING_PARAMETER_2 */ +#define U1_EXIT_NO_LFPS_TMOUT_OFST (16) +#define U1_EXIT_T13_T11_OFST (8) +#define U1_EXIT_T12_T10_OFST (0) + +/* U3D_U2_LB_LFPS_TIMING_PARAMETER_1 */ +#define U2_LB_EXIT_T13_T11_OFST (16) +#define U2_LB_EXIT_T12_T10_OFST (0) + +/* U3D_U2_LB_LFPS_TIMING_PARAMETER_2 */ +#define U2_LB_EXIT_NO_LFPS_TMOUT_OFST (0) + +/* U3D_U3_LFPS_TIMING_PARAMETER_1 */ +#define U3_EXIT_T13_T11_OFST (16) +#define U3_EXIT_T12_T10_OFST (0) + +/* U3D_U3_LFPS_TIMING_PARAMETER_2 */ +#define SEND_U3_EXIT_LFPS_WAIT_CYCLE_OFST (16) +#define U3_EXIT_NO_LFPS_TMOUT_OFST (0) + +/* U3D_PING_LFPS_TIMING_PARAMETER */ +#define TX_PING_LFPS_TBURST_OFST (16) +#define RX_PING_LFPS_TBURST_MAX_OFST (8) +#define RX_PING_LFPS_TBURST_MIN_OFST (0) + +/* U3D_POLLING_LFPS_TIMING_PARAMETER_1 */ +#define RX_POLLING_LFPS_TBURST_MAX_OFST (8) +#define RX_POLLING_LFPS_TBURST_MIN_OFST (0) + +/* U3D_POLLING_LFPS_TIMING_PARAMETER_2 */ +#define TX_POLLING_LFPS_NUM_OFST (16) +#define TX_POLLING_LFPS_TREPEAT_OFST (8) +#define TX_POLLING_LFPS_TBURST_OFST (0) + +/* U3D_UX_EXIT_LFPS_TIMING_PARAMETER */ +#define RX_UX_EXIT_LFPS_REF_OFST (8) +#define RX_UX_EXIT_LFPS_PIPE_OFST (0) + +/* U3D_P3_TIMING_PARAMETER */ +#define P3_ENTER_CYCLE_OFST (20) +#define P3_EXIT_CYCLE_OFST (16) + +/* U3D_WARM_RESET_TIMING_PARAMETER */ +#define TRESET_TBURST_OFST (8) +#define TRESETDELAY_OFST (0) + +/* U3D_UX_EXIT_TIMING_PARAMETER */ +#define UX_EXIT_TIMER_OFST (0) + +/* U3D_REF_CK_PARAMETER */ +#define REF_1000NS_OFST (0) + +/* U3D_LTSSM_TIMING_PARAMETER_1 */ +#define MAC_6MS_OFST (16) +#define MAC_2MS_OFST (0) + +/* U3D_LTSSM_TIMING_PARAMETER_2 */ +#define MAC_100MS_OFST (16) +#define MAC_12MS_OFST (0) + +/* U3D_LTSSM_TIMING_PARAMETER_3 */ +#define MAC_360MS_OFST (16) +#define MAC_300MS_OFST (0) + +/* U3D_LTSSM_TIMING_PARAMETER_4 */ +#define MAC_200MS_OFST (0) + +/* U3D_LTSSM_TIMING_PARAMETER_5 */ +#define POWER_CHANGE_TIMEOUT_VALUE_OFST (16) +#define RXDETECT_TIMEOUT_VALUE_OFST (0) + +/* U3D_LTSSM_RXDETECT_CTRL */ +#define RXDETECT_WAIT_TIME_OFST (8) +#define RXDETECT_WAIT_EN_OFST (0) + +/* U3D_PIPE_RXDATA_ERR_INTR_ENABLE */ +#define DEC_8B10B_ERR_INTR_EN_OFST (2) +#define DISPARITY_ERR_INTR_EN_OFST (1) +#define EBUF_ERR_INTR_EN_OFST (0) + +/* U3D_PIPE_RXDATA_ERR_INTR */ +#define DEC_8B10B_ERR_INTR_OFST (2) +#define DISPARITY_ERR_INTR_OFST (1) +#define EBUF_ERR_INTR_OFST (0) + +/* U3D_PIPE_LATCH_SELECT */ +#define TX_SIGNAL_SEL_OFST (2) +#define RX_SIGNAL_SEL_OFST (0) + +/* U3D_LINK_STATE_MACHINE */ +#define VBUS_DBC_CYCLE_OFST (16) +#define VBUS_VALID_OFST (8) +#define LTSSM_OFST (0) + +/* U3D_MAC_FAST_SIMULATION */ +#define FORCE_U0_TO_U3_OFST (5) +#define FORCE_U0_TO_U2_OFST (4) +#define FORCE_U0_TO_U1_OFST (3) +#define MAC_SPEED_MS_TO_US_OFST (2) +#define BYPASS_WARM_RESET_OFST (1) + +/* U3D_LTSSM_INTR_ENABLE */ +#define U3_RESUME_INTR_EN_OFST (18) +#define U3_LFPS_TMOUT_INTR_EN_OFST (17) +#define VBUS_FALL_INTR_EN_OFST (16) +#define VBUS_RISE_INTR_EN_OFST (15) +#define RXDET_SUCCESS_INTR_EN_OFST (14) +#define EXIT_U3_INTR_EN_OFST (13) +#define EXIT_U2_INTR_EN_OFST (12) +#define EXIT_U1_INTR_EN_OFST (11) +#define ENTER_U3_INTR_EN_OFST (10) +#define ENTER_U2_INTR_EN_OFST (9) +#define ENTER_U1_INTR_EN_OFST (8) +#define ENTER_U0_INTR_EN_OFST (7) +#define RECOVERY_INTR_EN_OFST (6) +#define WARM_RST_INTR_EN_OFST (5) +#define HOT_RST_INTR_EN_OFST (4) +#define LOOPBACK_INTR_EN_OFST (3) +#define COMPLIANCE_INTR_EN_OFST (2) +#define SS_DISABLE_INTR_EN_OFST (1) +#define SS_INACTIVE_INTR_EN_OFST (0) + +/* U3D_LTSSM_INTR */ +#define U3_RESUME_INTR_OFST (18) +#define U3_LFPS_TMOUT_INTR_OFST (17) +#define VBUS_FALL_INTR_OFST (16) +#define VBUS_RISE_INTR_OFST (15) +#define RXDET_SUCCESS_INTR_OFST (14) +#define EXIT_U3_INTR_OFST (13) +#define EXIT_U2_INTR_OFST (12) +#define EXIT_U1_INTR_OFST (11) +#define ENTER_U3_INTR_OFST (10) +#define ENTER_U2_INTR_OFST (9) +#define ENTER_U1_INTR_OFST (8) +#define ENTER_U0_INTR_OFST (7) +#define RECOVERY_INTR_OFST (6) +#define WARM_RST_INTR_OFST (5) +#define HOT_RST_INTR_OFST (4) +#define LOOPBACK_INTR_OFST (3) +#define COMPLIANCE_INTR_OFST (2) +#define SS_DISABLE_INTR_OFST (1) +#define SS_INACTIVE_INTR_OFST (0) + +/* U3D_SKP_CNT */ +#define SKP_SYMBOL_NUM_OFST (0) + +/* //////////////////////////////////////////////////////////////////// */ diff --git a/drivers/misc/mediatek/mu3d/hal/ssusb_usb3_sys_csr_c_header.h b/drivers/misc/mediatek/mu3d/hal/ssusb_usb3_sys_csr_c_header.h new file mode 100644 index 000000000000..cab95f96496f --- /dev/null +++ b/drivers/misc/mediatek/mu3d/hal/ssusb_usb3_sys_csr_c_header.h @@ -0,0 +1,318 @@ +/* SSUSB_USB3_SYS_CSR REGISTER DEFINITION */ + +#define U3D_LINK_HP_TIMER (SSUSB_USB3_SYS_CSR_BASE+0x0200) +#define U3D_LINK_CMD_TIMER (SSUSB_USB3_SYS_CSR_BASE+0x0204) +#define U3D_LINK_PM_TIMER (SSUSB_USB3_SYS_CSR_BASE+0x0208) +#define U3D_LINK_UX_INACT_TIMER (SSUSB_USB3_SYS_CSR_BASE+0x020C) +#define U3D_LINK_POWER_CONTROL (SSUSB_USB3_SYS_CSR_BASE+0x0210) +#define U3D_LINK_ERR_COUNT (SSUSB_USB3_SYS_CSR_BASE+0x0214) +#define U3D_LTSSM_TRANSITION (SSUSB_USB3_SYS_CSR_BASE+0x0218) +#define U3D_LINK_RETRY_CTRL (SSUSB_USB3_SYS_CSR_BASE+0x0220) +#define U3D_SYS_FAST_SIMULATIION (SSUSB_USB3_SYS_CSR_BASE+0x0224) +#define U3D_LINK_CAPABILITY_CTRL (SSUSB_USB3_SYS_CSR_BASE+0x0228) +#define U3D_LINK_DEBUG_INFO (SSUSB_USB3_SYS_CSR_BASE+0x022C) +#define U3D_USB3_U1_REJECT (SSUSB_USB3_SYS_CSR_BASE+0x0240) +#define U3D_USB3_U2_REJECT (SSUSB_USB3_SYS_CSR_BASE+0x0244) +#define U3D_DEV_NOTIF_0 (SSUSB_USB3_SYS_CSR_BASE+0x0290) +#define U3D_DEV_NOTIF_1 (SSUSB_USB3_SYS_CSR_BASE+0x0294) +#define U3D_VENDOR_DEV_TEST (SSUSB_USB3_SYS_CSR_BASE+0x0298) +#define U3D_VENDOR_DEF_DATA_LOW (SSUSB_USB3_SYS_CSR_BASE+0x029C) +#define U3D_VENDOR_DEF_DATA_HIGH (SSUSB_USB3_SYS_CSR_BASE+0x02A0) +#define U3D_HOST_SET_PORT_CTRL (SSUSB_USB3_SYS_CSR_BASE+0x02A4) +#define U3D_LINK_CAP_CONTROL (SSUSB_USB3_SYS_CSR_BASE+0x02AC) +#define U3D_PORT_CONF_TIMEOUT (SSUSB_USB3_SYS_CSR_BASE+0x02B0) +#define U3D_TIMING_PULSE_CTRL (SSUSB_USB3_SYS_CSR_BASE+0x02B4) +#define U3D_ISO_TIMESTAMP (SSUSB_USB3_SYS_CSR_BASE+0x02B8) +#define U3D_RECEIVE_PKT_INTR_EN (SSUSB_USB3_SYS_CSR_BASE+0x02C0) +#define U3D_RECEIVE_PKT_INTR (SSUSB_USB3_SYS_CSR_BASE+0x02C4) +#define U3D_CRC_ERR_INTR_EN (SSUSB_USB3_SYS_CSR_BASE+0x02C8) +#define U3D_CRC_ERR_INTR (SSUSB_USB3_SYS_CSR_BASE+0x02CC) +#define U3D_PORT_STATUS_INTR_EN (SSUSB_USB3_SYS_CSR_BASE+0x02D0) +#define U3D_PORT_STATUS_INTR (SSUSB_USB3_SYS_CSR_BASE+0x02D4) +#define U3D_RECOVERY_COUNT (SSUSB_USB3_SYS_CSR_BASE+0x02D8) +#define U3D_T2R_LOOPBACK_TEST (SSUSB_USB3_SYS_CSR_BASE+0x02DC) + +/* SSUSB_USB3_SYS_CSR FIELD DEFINITION */ + +/* U3D_LINK_HP_TIMER */ +#define CHP_TIMEOUT_VALUE (0x7f<<8) /* 14:8 */ +#define PHP_TIMEOUT_VALUE (0xf<<0) /* 3:0 */ + +/* U3D_LINK_CMD_TIMER */ +#define NO_LC_TIMEOUT_VALUE (0xf<<8) /* 11:8 */ +#define LDN_TIMEOUT_VALUE (0xf<<4) /* 7:4 */ +#define LUP_TIMEOUT_VALUE (0xf<<0) /* 3:0 */ + +/* U3D_LINK_PM_TIMER */ +#define LPMA_SENT_CNT_VALUE (0xf<<16) /* 19:16 */ +#define PM_ENTRY_TIMEOUT_VALUE (0xf<<8) /* 11:8 */ +#define PM_LC_TIMEOUT_VALUE (0xf<<0) /* 3:0 */ + +/* U3D_LINK_UX_INACT_TIMER */ +#define DEV_U2_INACT_TIMEOUT_VALUE (0xff<<16) /* 23:16 */ +#define U2_INACT_TIMEOUT_VALUE (0xff<<8) /* 15:8 */ +#define U1_INACT_TIMEOUT_VALUE (0xff<<0) /* 7:0 */ + +/* U3D_LINK_POWER_CONTROL */ +#define SW_U2_ACCEPT_ENABLE (0x1<<9) /* 9:9 */ +#define SW_U1_ACCEPT_ENABLE (0x1<<8) /* 8:8 */ +#define UX_EXIT (0x1<<5) /* 5:5 */ +#define LGO_U3 (0x1<<4) /* 4:4 */ +#define LGO_U2 (0x1<<3) /* 3:3 */ +#define LGO_U1 (0x1<<2) /* 2:2 */ +#define SW_U2_REQUEST_ENABLE (0x1<<1) /* 1:1 */ +#define SW_U1_REQUEST_ENABLE (0x1<<0) /* 0:0 */ + +/* U3D_LINK_ERR_COUNT */ +#define CLR_LINK_ERR_CNT (0x1<<16) /* 16:16 */ +#define LINK_ERROR_COUNT (0xffff<<0) /* 15:0 */ + +/* U3D_LTSSM_TRANSITION */ +#define GO_HOT_RESET (0x1<<3) /* 3:3 */ +#define GO_WARM_RESET (0x1<<2) /* 2:2 */ +#define GO_RXDETECT (0x1<<1) /* 1:1 */ +#define GO_SS_DISABLE (0x1<<0) /* 0:0 */ + +/* U3D_LINK_RETRY_CTRL */ +#define TX_LRTY_DPP_EN (0x1<<0) /* 0:0 */ + +/* U3D_SYS_FAST_SIMULATIION */ +#define SYS_SPEED_MS_TO_US (0x1<<0) /* 0:0 */ + +/* U3D_LINK_CAPABILITY_CTRL */ +#define INSERT_CRC32_ERR_DP_NUM (0xff<<16) /* 23:16 */ +#define INSERT_CRC32_ERR_EN (0x1<<8) /* 8:8 */ +#define ZLP_CRC32_CHK_DIS (0x1<<0) /* 0:0 */ + +/* U3D_LINK_DEBUG_INFO */ +#define CLR_TX_DATALEN_OVER_1024 (0x1<<1) /* 1:1 */ +#define TX_DATALEN_OVER_1024 (0x1<<0) /* 0:0 */ + +/* U3D_USB3_U1_REJECT */ +#define CLR_USB3_U1_REJECT_CNT (0x1<<16) /* 16:16 */ +#define USB3_U1_REJECT_CNT (0xffff<<0) /* 15:0 */ + +/* U3D_USB3_U2_REJECT */ +#define CLR_USB3_U2_REJECT_CNT (0x1<<16) /* 16:16 */ +#define USB3_U2_REJECT_CNT (0xffff<<0) /* 15:0 */ + +/* U3D_DEV_NOTIF_0 */ +#define DEV_NOTIF_TYPE_SPECIFIC_LOW (0xffffff<<8) /* 31:8 */ +#define DEV_NOTIF_TYPE (0xf<<4) /* 7:4 */ +#define SEND_DEV_NOTIF (0x1<<0) /* 0:0 */ + +/* U3D_DEV_NOTIF_1 */ +#define DEV_NOTIF_TYPE_SPECIFIC_HIGH (0xffffffff<<0) /* 31:0 */ + +/* U3D_VENDOR_DEV_TEST */ +#define VENDOR_DEV_TEST_VALUE (0xff<<16) /* 23:16 */ +#define SEND_VENDOR_DEV_TEST (0x1<<0) /* 0:0 */ + +/* U3D_VENDOR_DEF_DATA_LOW */ +#define VENDOR_DEF_DATA_LOW (0xffffffff<<0) /* 31:0 */ + +/* U3D_VENDOR_DEF_DATA_HIGH */ +#define VENDOR_DEF_DATA_HIGH (0xffffffff<<0) /* 31:0 */ + +/* U3D_HOST_SET_PORT_CTRL */ +#define SEND_U2_INACT_TIMEOUT (0x1<<2) /* 2:2 */ +#define FORCE_LINK_PM_ACPT (0x1<<1) /* 1:1 */ +#define SEND_SET_LINK_FUNC (0x1<<0) /* 0:0 */ + +/* U3D_LINK_CAP_CONTROL */ +#define TIEBREAKER (0xf<<16) /* 19:16 */ +#define NUM_HP_BUF (0xff<<8) /* 15:8 */ +#define LINK_SPEED (0xff<<0) /* 7:0 */ + +/* U3D_PORT_CONF_TIMEOUT */ +#define TPORT_CONF_TIMEOUT_VALUE (0x1f<<0) /* 4:0 */ + +/* U3D_TIMING_PULSE_CTRL */ +#define CNT_1MS_VALUE (0xf<<28) /* 31:28 */ +#define CNT_100US_VALUE (0xf<<24) /* 27:24 */ +#define CNT_10US_VALUE (0xf<<20) /* 23:20 */ +#define CNT_1US_VALUE (0xff<<0) /* 7:0 */ + +/* U3D_ISO_TIMESTAMP */ +#define ISO_TIMESTAMP (0x7ffffff<<0) /* 26:0 */ + +/* U3D_RECEIVE_PKT_INTR_EN */ +#define RECV_SET_LINK_FUNC_INTR_EN (0x1<<2) /* 2:2 */ +#define RECV_U2_INACT_INTR_EN (0x1<<1) /* 1:1 */ +#define RECV_ITP_INTR_EN (0x1<<0) /* 0:0 */ + +/* U3D_RECEIVE_PKT_INTR */ +#define RECV_SET_LINK_FUNC_INTR (0x1<<2) /* 2:2 */ +#define RECV_U2_INACT_INTR (0x1<<1) /* 1:1 */ +#define RECV_ITP_INTR (0x1<<0) /* 0:0 */ + +/* U3D_CRC_ERR_INTR_EN */ +#define CRC16_ERR_INTR_EN (0x1<<2) /* 2:2 */ +#define CRC5_ERR_INTR_EN (0x1<<1) /* 1:1 */ +#define CRC32_ERR_INTR_EN (0x1<<0) /* 0:0 */ + +/* U3D_CRC_ERR_INTR */ +#define CRC16_ERR_INTR (0x1<<2) /* 2:2 */ +#define CRC5_ERR_INTR (0x1<<1) /* 1:1 */ +#define CRC32_ERR_INTR (0x1<<0) /* 0:0 */ + +/* U3D_PORT_STATUS_INTR_EN */ +#define LMP_ADV_ERR_INTR_EN (0x1<<2) /* 2:2 */ +#define LMP_ADV_DONE_INTR_EN (0x1<<1) /* 1:1 */ +#define LINK_ADV_DONE_INTR_EN (0x1<<0) /* 0:0 */ + +/* U3D_PORT_STATUS_INTR */ +#define LMP_ADV_ERR_INTR (0x1<<2) /* 2:2 */ +#define LMP_ADV_DONE_INTR (0x1<<1) /* 1:1 */ +#define LINK_ADV_DONE_INTR (0x1<<0) /* 0:0 */ + +/* U3D_RECOVERY_COUNT */ +#define CLR_RECOV_CNT (0x1<<16) /* 16:16 */ +#define RECOV_CNT (0xffff<<0) /* 15:0 */ + +/* U3D_T2R_LOOPBACK_TEST */ +#define T2R_LOOPBACK (0x1<<0) /* 0:0 */ + + +/* SSUSB_USB3_SYS_CSR FIELD OFFSET DEFINITION */ + +/* U3D_LINK_HP_TIMER */ +#define CHP_TIMEOUT_VALUE_OFST (8) +#define PHP_TIMEOUT_VALUE_OFST (0) + +/* U3D_LINK_CMD_TIMER */ +#define NO_LC_TIMEOUT_VALUE_OFST (8) +#define LDN_TIMEOUT_VALUE_OFST (4) +#define LUP_TIMEOUT_VALUE_OFST (0) + +/* U3D_LINK_PM_TIMER */ +#define LPMA_SENT_CNT_VALUE_OFST (16) +#define PM_ENTRY_TIMEOUT_VALUE_OFST (8) +#define PM_LC_TIMEOUT_VALUE_OFST (0) + +/* U3D_LINK_UX_INACT_TIMER */ +#define DEV_U2_INACT_TIMEOUT_VALUE_OFST (16) +#define U2_INACT_TIMEOUT_VALUE_OFST (8) +#define U1_INACT_TIMEOUT_VALUE_OFST (0) + +/* U3D_LINK_POWER_CONTROL */ +#define SW_U2_ACCEPT_ENABLE_OFST (9) +#define SW_U1_ACCEPT_ENABLE_OFST (8) +#define UX_EXIT_OFST (5) +#define LGO_U3_OFST (4) +#define LGO_U2_OFST (3) +#define LGO_U1_OFST (2) +#define SW_U2_REQUEST_ENABLE_OFST (1) +#define SW_U1_REQUEST_ENABLE_OFST (0) + +/* U3D_LINK_ERR_COUNT */ +#define CLR_LINK_ERR_CNT_OFST (16) +#define LINK_ERROR_COUNT_OFST (0) + +/* U3D_LTSSM_TRANSITION */ +#define GO_HOT_RESET_OFST (3) +#define GO_WARM_RESET_OFST (2) +#define GO_RXDETECT_OFST (1) +#define GO_SS_DISABLE_OFST (0) + +/* U3D_LINK_RETRY_CTRL */ +#define TX_LRTY_DPP_EN_OFST (0) + +/* U3D_SYS_FAST_SIMULATIION */ +#define SYS_SPEED_MS_TO_US_OFST (0) + +/* U3D_LINK_CAPABILITY_CTRL */ +#define INSERT_CRC32_ERR_DP_NUM_OFST (16) +#define INSERT_CRC32_ERR_EN_OFST (8) +#define ZLP_CRC32_CHK_DIS_OFST (0) + +/* U3D_LINK_DEBUG_INFO */ +#define CLR_TX_DATALEN_OVER_1024_OFST (1) +#define TX_DATALEN_OVER_1024_OFST (0) + +/* U3D_USB3_U1_REJECT */ +#define CLR_USB3_U1_REJECT_CNT_OFST (16) +#define USB3_U1_REJECT_CNT_OFST (0) + +/* U3D_USB3_U2_REJECT */ +#define CLR_USB3_U2_REJECT_CNT_OFST (16) +#define USB3_U2_REJECT_CNT_OFST (0) + +/* U3D_DEV_NOTIF_0 */ +#define DEV_NOTIF_TYPE_SPECIFIC_LOW_OFST (8) +#define DEV_NOTIF_TYPE_OFST (4) +#define SEND_DEV_NOTIF_OFST (0) + +/* U3D_DEV_NOTIF_1 */ +#define DEV_NOTIF_TYPE_SPECIFIC_HIGH_OFST (0) + +/* U3D_VENDOR_DEV_TEST */ +#define VENDOR_DEV_TEST_VALUE_OFST (16) +#define SEND_VENDOR_DEV_TEST_OFST (0) + +/* U3D_VENDOR_DEF_DATA_LOW */ +#define VENDOR_DEF_DATA_LOW_OFST (0) + +/* U3D_VENDOR_DEF_DATA_HIGH */ +#define VENDOR_DEF_DATA_HIGH_OFST (0) + +/* U3D_HOST_SET_PORT_CTRL */ +#define SEND_U2_INACT_TIMEOUT_OFST (2) +#define FORCE_LINK_PM_ACPT_OFST (1) +#define SEND_SET_LINK_FUNC_OFST (0) + +/* U3D_LINK_CAP_CONTROL */ +#define TIEBREAKER_OFST (16) +#define NUM_HP_BUF_OFST (8) +#define LINK_SPEED_OFST (0) + +/* U3D_PORT_CONF_TIMEOUT */ +#define TPORT_CONF_TIMEOUT_VALUE_OFST (0) + +/* U3D_TIMING_PULSE_CTRL */ +#define CNT_1MS_VALUE_OFST (28) +#define CNT_100US_VALUE_OFST (24) +#define CNT_10US_VALUE_OFST (20) +#define CNT_1US_VALUE_OFST (0) + +/* U3D_ISO_TIMESTAMP */ +#define ISO_TIMESTAMP_OFST (0) + +/* U3D_RECEIVE_PKT_INTR_EN */ +#define RECV_SET_LINK_FUNC_INTR_EN_OFST (2) +#define RECV_U2_INACT_INTR_EN_OFST (1) +#define RECV_ITP_INTR_EN_OFST (0) + +/* U3D_RECEIVE_PKT_INTR */ +#define RECV_SET_LINK_FUNC_INTR_OFST (2) +#define RECV_U2_INACT_INTR_OFST (1) +#define RECV_ITP_INTR_OFST (0) + +/* U3D_CRC_ERR_INTR_EN */ +#define CRC16_ERR_INTR_EN_OFST (2) +#define CRC5_ERR_INTR_EN_OFST (1) +#define CRC32_ERR_INTR_EN_OFST (0) + +/* U3D_CRC_ERR_INTR */ +#define CRC16_ERR_INTR_OFST (2) +#define CRC5_ERR_INTR_OFST (1) +#define CRC32_ERR_INTR_OFST (0) + +/* U3D_PORT_STATUS_INTR_EN */ +#define LMP_ADV_ERR_INTR_EN_OFST (2) +#define LMP_ADV_DONE_INTR_EN_OFST (1) +#define LINK_ADV_DONE_INTR_EN_OFST (0) + +/* U3D_PORT_STATUS_INTR */ +#define LMP_ADV_ERR_INTR_OFST (2) +#define LMP_ADV_DONE_INTR_OFST (1) +#define LINK_ADV_DONE_INTR_OFST (0) + +/* U3D_RECOVERY_COUNT */ +#define CLR_RECOV_CNT_OFST (16) +#define RECOV_CNT_OFST (0) + +/* U3D_T2R_LOOPBACK_TEST */ +#define T2R_LOOPBACK_OFST (0) + +/* //////////////////////////////////////////////////////////////////// */ diff --git a/drivers/misc/mediatek/mu3phy/Kconfig b/drivers/misc/mediatek/mu3phy/Kconfig new file mode 100644 index 000000000000..e937e81e5b89 --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/Kconfig @@ -0,0 +1,89 @@ +# +# USB3.0 PHY +# + +config MU3_PHY + bool "MU3 PHY" + default n + ---help--- + Enables support Mediatek MU3 PHY for SSUSB or XHCI. + It support in-circuit PHY and external PHY. + Say Y here if your system using SSUSB MAC and PHY. + If unsure, say N. + +config U3_PHY_GPIO_SUPPORT + bool "MU3 PHY registers access by I2C" + depends on MU3_PHY + default n + ---help--- + Enables support for read/write PHY registers by I2C. + This driver provides interface to interact with USB 2.0 and + USB 3.0 PHY that is part of the Mediatek SOC. + Say Y here if your system using external Mediatek USB PHY. + If unsure, say N. + +config U3_PHY_AHB_SUPPORT + bool "MU3 PHY registers access by AHB" + depends on MU3_PHY + default n + ---help--- + Enables support for read/write PHY registers by internal AHB. + This driver provides interface to interact with USB 2.0 and + USB 3.0 PHY that is part of the Mediatek SOC. + Say Y here if your system using external USB Mediatek PHY. + If unsure, say N. + +config PROJECT_PHY + bool "MU3 ASIC PHY support" + depends on MU3_PHY + default n + ---help--- + Enables support for ASIC PHY. + This driver provides interface to interact with USB 2.0 and + USB 3.0 PHY that is part of the Mediatek SOC. + Say Y here if your system using in-circuit Mediatek USB PHY. + If unsure, say N. + +config C60802_SUPPORT + bool "MU3 PHY C60802 support" + depends on MU3_PHY + default n + ---help--- + Enables support for external PHY(Ver C). + This driver provides interface to interact with USB 2.0 and + USB 3.0 PHY that is part of the Mediatek SOC. + Say Y here if your system using external Mediatek USB PHY. + If unsure, say N. + +config D60802_SUPPORT + bool "MU3 PHY D60802 support" + depends on MU3_PHY + default n + ---help--- + Enables support for external PHY(Ver D). + This driver provides interface to interact with USB 2.0 and + USB 3.0 PHY that is part of the Mediatek SOC. + Say Y here if your system using external Mediatek USB PHY. + If unsure, say N. + +config E60802_SUPPORT + bool "MU3 PHY E60802 support" + depends on MU3_PHY + default n + ---help--- + Enables support for external PHY(Ver E). + This driver provides interface to interact with USB 2.0 and + USB 3.0 PHY that is part of the Mediatek SOC. + Say Y here if your system using external Mediatek USB PHY. + If unsure, say N. + +config A60810_SUPPORT + bool "MU3 PHY A60810 support" + depends on MU3_PHY + default n + ---help--- + Enables support for external PHY(Ver A). + This driver provides interface to interact with USB 2.0 and + USB 3.0 PHY that is part of the Mediatek SOC. + Say Y here if your system using external Mediatek USB PHY. + If unsure, say N. diff --git a/drivers/misc/mediatek/mu3phy/Makefile b/drivers/misc/mediatek/mu3phy/Makefile new file mode 100644 index 000000000000..f92166737c40 --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/Makefile @@ -0,0 +1,18 @@ +ccflags-y += -I$(srctree)/drivers/misc/mediatek/mu3d/drv \ + -I$(srctree)/drivers/misc/mediatek/mu3d/hal \ + -I$(srctree)/drivers/misc/mediatek/mu3phy/$(CONFIG_MTK_PLATFORM) + +ifeq ($(CONFIG_USB_DEBUG),y) + EXTRA_CFLAGS += -DDEBUG +endif + +obj-$(CONFIG_MU3_PHY) := mu3phy.o +mu3phy-$(CONFIG_MU3_PHY) := mtk-phy.o +mu3phy-$(CONFIG_U3_PHY_GPIO_SUPPORT) += mtk-phy-gpio.o +mu3phy-$(CONFIG_U3_PHY_AHB_SUPPORT) += mtk-phy-ahb.o +mu3phy-$(CONFIG_C60802_SUPPORT) += mtk-phy-c60802.o +mu3phy-$(CONFIG_D60802_SUPPORT) += mtk-phy-d60802.o +mu3phy-$(CONFIG_E60802_SUPPORT) += mtk-phy-e60802.o +mu3phy-$(CONFIG_A60810_SUPPORT) += mtk-phy-a60810.o + +obj-$(CONFIG_MU3_PHY) += $(subst ",,$(CONFIG_MTK_PLATFORM))/
\ No newline at end of file diff --git a/drivers/misc/mediatek/mu3phy/mtk-phy-a60810.c b/drivers/misc/mediatek/mu3phy/mtk-phy-a60810.c new file mode 100644 index 000000000000..e7bc43390bfa --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/mtk-phy-a60810.c @@ -0,0 +1,596 @@ +#include <linux/mu3phy/mtk-phy.h> + +#ifdef CONFIG_A60810_SUPPORT +#include <linux/mu3phy/mtk-phy-a60810.h> + +PHY_INT32 phy_init_a60810(struct u3phy_info *info) +{ + /* BANK 0x00 */ + /* for U2 hS eye diagram */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr1) + , A60810_RG_USB20_TERM_VREF_SEL_OFST, A60810_RG_USB20_TERM_VREF_SEL, + 0x05); + /* for U2 hS eye diagram */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr1) + , A60810_RG_USB20_VRT_VREF_SEL_OFST, A60810_RG_USB20_VRT_VREF_SEL, 0x05); + /* for U2 sensititvity */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr6) + , A60810_RG_USB20_SQTH_OFST, A60810_RG_USB20_SQTH, 0x04); + + /* BANK 0x10 */ + /* disable ssusb_p3_entry to work around resume from P3 bug */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->phyd_lfps0) + , A60810_RG_SSUSB_P3_ENTRY_OFST, A60810_RG_SSUSB_P3_ENTRY, 0x00); + /* force disable ssusb_p3_entry to work around resume from P3 bug */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->phyd_lfps0) + , A60810_RG_SSUSB_P3_ENTRY_SEL_OFST, A60810_RG_SSUSB_P3_ENTRY_SEL, 0x01); + + + /* BANK 0x40 */ + /* fine tune SSC delta1 to let SSC min average ~0ppm */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg19) + , A60810_RG_SSUSB_PLL_SSC_DELTA1_U3_OFST, + A60810_RG_SSUSB_PLL_SSC_DELTA1_U3, 0x46); + /* U3PhyWriteField32(((phys_addr_t)&info->u3phya_da_regs_a->reg19) */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg21) + , A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H_OFST, + A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H, 0x40); + + + /* fine tune SSC delta to let SSC min average ~0ppm */ + + /* Fine tune SYSPLL to improve phase noise */ + /* I2C 60 0x08[01:00] 0x03 RW RG_SSUSB_PLL_BC_U3 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg4) + , A60810_RG_SSUSB_PLL_BC_U3_OFST, A60810_RG_SSUSB_PLL_BC_U3, 0x3); + /* I2C 60 0x08[12:10] 0x03 RW RG_SSUSB_PLL_DIVEN_U3 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg4) + , A60810_RG_SSUSB_PLL_DIVEN_U3_OFST, A60810_RG_SSUSB_PLL_DIVEN_U3, 0x3); + /* I2C 60 0x0C[03:00] 0x01 RW RG_SSUSB_PLL_IC_U3 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg5) + , A60810_RG_SSUSB_PLL_IC_U3_OFST, A60810_RG_SSUSB_PLL_IC_U3, 0x1); + /* I2C 60 0x0C[23:22] 0x01 RW RG_SSUSB_PLL_BR_U3 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg5) + , A60810_RG_SSUSB_PLL_BR_U3_OFST, A60810_RG_SSUSB_PLL_BR_U3, 0x1); + /* I2C 60 0x10[03:00] 0x01 RW RG_SSUSB_PLL_IR_U3 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg6) + , A60810_RG_SSUSB_PLL_IR_U3_OFST, A60810_RG_SSUSB_PLL_IR_U3, 0x1); + /* I2C 60 0x14[03:00] 0x0F RW RG_SSUSB_PLL_BP_U3 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_da_regs_a->reg7) +/* // , A60810_RG_SSUSB_PLL_BP_U3, A60810_RG_SSUSB_PLL_BP_U3, 0xF); */ + , A60810_RG_SSUSB_PLL_BP_U3_OFST, A60810_RG_SSUSB_PLL_BP_U3, 0x0f); + + /* BANK 0x60 */ + /* force xtal pwd mode enable */ + U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2) + , A60810_RG_SSUSB_FORCE_XTAL_PWD_OFST, A60810_RG_SSUSB_FORCE_XTAL_PWD, + 0x1); + /* force bias pwd mode enable */ + U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2) + , A60810_RG_SSUSB_FORCE_BIAS_PWD_OFST, A60810_RG_SSUSB_FORCE_BIAS_PWD, + 0x1); + /* force xtal pwd mode off to work around xtal drv de */ + U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2) + , A60810_RG_SSUSB_XTAL_PWD_OFST, A60810_RG_SSUSB_XTAL_PWD, 0x0); + /* force bias pwd mode off to work around xtal drv de */ + U3PhyWriteField32(((phys_addr_t) &info->spllc_regs_a->u3d_xtalctl_2) + , A60810_RG_SSUSB_BIAS_PWD_OFST, A60810_RG_SSUSB_BIAS_PWD, 0x0); + + /* ******** test chip settings *********** */ + /* BANK 0x00 */ + /* slew rate setting */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5) + , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL, 0x4); + + /* BANK 0x50 */ + + /* Write Phase Scan Result */ + /* PIPE setting BANK5 */ + /* PIPE drv = 2 */ + U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2, 0x10); + /* PIPE phase */ + /* U3PhyWriteReg8(((phys_addr_t)&info->sifslv_chip_regs_a->gpio_ctla)+3, 0xdc); */ + U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3, 0x24); + + return PHY_TRUE; +} + +#define PHY_DRV_SHIFT 3 +#define PHY_PHASE_SHIFT 3 +#define PHY_PHASE_DRV_SHIFT 1 +PHY_INT32 phy_change_pipe_phase_a60810(struct u3phy_info *info, PHY_INT32 phy_drv, + PHY_INT32 pipe_phase) +{ + PHY_INT32 drv_reg_value; + PHY_INT32 phase_reg_value; + PHY_INT32 temp; + + pr_debug("phy_change_pipe_phase_a60810: %d", pipe_phase); + + drv_reg_value = phy_drv << PHY_DRV_SHIFT; + phase_reg_value = (pipe_phase << PHY_PHASE_SHIFT) | (phy_drv << PHY_PHASE_DRV_SHIFT); + temp = U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2); + temp &= ~(0x3 << PHY_DRV_SHIFT); + temp |= drv_reg_value; + U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2, temp); + + pr_debug("gpio_clta+2=0x%x\n", + U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 2)); + + temp = U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3); + temp &= ~((0x3 << PHY_PHASE_DRV_SHIFT) | (0x1f << PHY_PHASE_SHIFT)); + temp |= phase_reg_value; + U3PhyWriteReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3, temp); + + pr_debug("gpio_clta+3=0x%x\n", + U3PhyReadReg8(((phys_addr_t) &info->sifslv_chip_regs_a->gpio_ctla) + 3)); + + return PHY_TRUE; +} + +/* -------------------------------------------------------- */ +/* Function : fgEyeScanHelper_CheckPtInRegion() */ +/* Description : Check if the test point is in a rectangle region. */ +/* If it is in the rectangle, also check if this point */ +/* is on the multiple of deltaX and deltaY. */ +/* Parameter : strucScanRegion * prEye - the region */ +/* BYTE bX */ +/* BYTE bY */ +/* Return : BYTE - TRUE : This point needs to be tested */ +/* FALSE: This point will be omitted */ +/* Note : First check within the rectangle. */ +/* Secondly, use modulous to check if the point will be tested. */ +/* -------------------------------------------------------- */ +static PHY_INT8 fgEyeScanHelper_CheckPtInRegion(struct strucScanRegion *prEye, PHY_INT8 bX, + PHY_INT8 bY) +{ + PHY_INT8 fgValid = true; + + + /* / Be careful, the axis origin is on the TOP-LEFT corner. */ + /* / Therefore the top-left point has the minimum X and Y */ + /* / Botton-right point is the maximum X and Y */ + if ((prEye->bX_tl <= bX) && (bX <= prEye->bX_br) + && (prEye->bY_tl <= bY) && (bY <= prEye->bX_br)) { + /* With the region, now check whether or not the input test point is */ + /* on the multiples of X and Y */ + /* Do not have to worry about negative value, because we have already */ + /* check the input bX, and bY is within the region. */ + if (((bX - prEye->bX_tl) % (prEye->bDeltaX)) + || ((bY - prEye->bY_tl) % (prEye->bDeltaY))) { + /* if the division will have remainder, that means */ + /* the input test point is on the multiples of X and Y */ + fgValid = false; + } else { + } + } else { + + fgValid = false; + } + return fgValid; +} + +/* -------------------------------------------------------- */ +/* Function : EyeScanHelper_RunTest() */ +/* Description : Enable the test, and wait til it is completed */ +/* Parameter : None */ +/* Return : None */ +/* Note : None */ +/* -------------------------------------------------------- */ +static void EyeScanHelper_RunTest(struct u3phy_info *info) +{ + /* Disable the test */ + /* RG_SSUSB_RX_EYE_CNT_EN = 0 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_CNT_EN_OFST, A60810_RG_SSUSB_EQ_EYE_CNT_EN, 0); + + /* Run the test */ + /* RG_SSUSB_RX_EYE_CNT_EN = 1 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_CNT_EN_OFST, A60810_RG_SSUSB_EQ_EYE_CNT_EN, 1); + + /* Wait til it's done */ + /* RGS_SSUSB_RX_EYE_CNT_RDY */ + while (!U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->phya_rx_mon5) + , A60810_RGS_SSUSB_EQ_EYE_CNT_RDY_OFST, + A60810_RGS_SSUSB_EQ_EYE_CNT_RDY)) + NULL; +} + +/* -------------------------------------------------------- */ +/* Function : fgEyeScanHelper_CalNextPoint() */ +/* Description : Calcualte the test point for the measurement */ +/* Parameter : None */ +/* Return : BOOL - TRUE : the next point is within the */ +/* boundaryof HW limit */ +/* FALSE: the next point is out of the HW limit */ +/* Note : The next point is obtained by calculating */ +/* from the bottom left of the region rectangle */ +/* and then scanning up until it reaches the upper */ +/* limit. At this time, the x will increment, and */ +/* start scanning downwards until the y hits the */ +/* zero. */ +/* -------------------------------------------------------- */ +static PHY_INT8 fgEyeScanHelper_CalNextPoint(void) +{ + if (((_bYcurr == MAX_Y) && (_eScanDir == SCAN_DN)) + || ((_bYcurr == MIN_Y) && (_eScanDir == SCAN_UP)) + ) { + /* / Reaches the limit of Y axis */ + /* / Increment X */ + _bXcurr++; + _fgXChged = true; + _eScanDir = (_eScanDir == SCAN_UP) ? SCAN_DN : SCAN_UP; + + if (_bXcurr > MAX_X) + return false; + + } else { + _bYcurr = (_eScanDir == SCAN_DN) ? _bYcurr + 1 : _bYcurr - 1; + _fgXChged = false; + } + return PHY_TRUE; +} + +PHY_INT32 eyescan_init_a60810(struct u3phy_info *info) +{ + /* initial PHY setting */ + U3PhyWriteField32(((phys_addr_t) &info->u3phya_regs_a->reg9) + , A60810_RG_SSUSB_CDR_EPEN_OFST, A60810_RG_SSUSB_CDR_EPEN, 1); + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->phyd_mix3) + , A60810_RG_SSUSB_FORCE_CDR_PI_PWD_OFST, A60810_RG_SSUSB_FORCE_CDR_PI_PWD, + 1); + + return PHY_TRUE; +} + +PHY_INT32 phy_eyescan_a60810(struct u3phy_info *info, PHY_INT32 x_t1, PHY_INT32 y_t1, + PHY_INT32 x_br, PHY_INT32 y_br, PHY_INT32 delta_x, PHY_INT32 delta_y, + PHY_INT32 eye_cnt, PHY_INT32 num_cnt, PHY_INT32 PI_cal_en, + PHY_INT32 num_ignore_cnt) +{ + PHY_INT32 cOfst = 0; + PHY_UINT8 bIdxX = 0; + PHY_UINT8 bIdxY = 0; + PHY_UINT8 bIdxCycCnt = 0; + PHY_INT8 fgValid; + PHY_INT8 cX; + PHY_INT8 cY; + PHY_UINT8 bExtendCnt; + PHY_INT8 isContinue; + phys_addr_t wErr0 = 0, wErr1 = 0; + + _rEye1.bX_tl = x_t1; + _rEye1.bY_tl = y_t1; + _rEye1.bX_br = x_br; + _rEye1.bY_br = y_br; + _rEye1.bDeltaX = delta_x; + _rEye1.bDeltaY = delta_y; + + _rEye2.bX_tl = x_t1; + _rEye2.bY_tl = y_t1; + _rEye2.bX_br = x_br; + _rEye2.bY_br = y_br; + _rEye2.bDeltaX = delta_x; + _rEye2.bDeltaY = delta_y; + + _rTestCycle.wEyeCnt = eye_cnt; + _rTestCycle.bNumOfEyeCnt = num_cnt; + _rTestCycle.bNumOfIgnoreCnt = num_ignore_cnt; + _rTestCycle.bPICalEn = PI_cal_en; + + _bXcurr = 0; + _bYcurr = 0; + _eScanDir = SCAN_DN; + _fgXChged = false; + + pr_debug("x_t1: %x, y_t1: %x, x_br: %x, y_br: %x, delta_x: %x, delta_y: %x\n", + x_t1, y_t1, x_br, y_br, delta_x, delta_y); + pr_debug("eye_cnt: %x, num_cnt: %x, PI_cal_en: %x, num_ignore_cnt: %x\n", + eye_cnt, num_cnt, PI_cal_en, num_ignore_cnt); + + /* force SIGDET to OFF */ + /* RG_SSUSB_RX_SIGDET_SEL = 1 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0) + , A60810_RG_SSUSB_RX_SIGDET_EN_SEL_OFST, A60810_RG_SSUSB_RX_SIGDET_EN_SEL, + 1); + /* RG_SSUSB_RX_SIGDET_EN = 0 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0) + , A60810_RG_SSUSB_RX_SIGDET_EN_OFST, A60810_RG_SSUSB_RX_SIGDET_EN, 0); + /* RG_SSUSB_RX_SIGDET = 0 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye1) + , A60810_RG_SSUSB_EQ_SIGDET_OFST, A60810_RG_SSUSB_EQ_SIGDET, 0); + + /* RX_TRI_DET_EN to Disable */ + /* RG_SSUSB_RX_TRI_DET_EN = 0 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq3) + , A60810_RG_SSUSB_EQ_TRI_DET_EN_OFST, A60810_RG_SSUSB_EQ_TRI_DET_EN, 0); + + /* RG_SSUSB_EYE_MON_EN = 1 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_MON_EN_OFST, A60810_RG_SSUSB_EQ_EYE_MON_EN, 1); + /* RG_SSUSB_RX_EYE_XOFFSET = 0 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST, A60810_RG_SSUSB_EQ_EYE_XOFFSET, 0); + /* RG_SSUSB_RX_EYE0_Y = 0 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y, 0); + /* RG_SSUSB_RX_EYE1_Y = 0 */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y, 0); + + + if (PI_cal_en) { + /* PI Calibration */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0) + , A60810_RG_SSUSB_RX_PI_CAL_EN_SEL_OFST, + A60810_RG_SSUSB_RX_PI_CAL_EN_SEL, 1); + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0) + , A60810_RG_SSUSB_RX_PI_CAL_EN_OFST, A60810_RG_SSUSB_RX_PI_CAL_EN, + 0); + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0) + , A60810_RG_SSUSB_RX_PI_CAL_EN_OFST, A60810_RG_SSUSB_RX_PI_CAL_EN, + 1); + + DRV_UDELAY(20); + + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_bank2_regs_a->b2_phyd_misc0) + , A60810_RG_SSUSB_RX_PI_CAL_EN_OFST, A60810_RG_SSUSB_RX_PI_CAL_EN, + 0); + + _bPIResult = U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->phya_rx_mon5) + , A60810_RGS_SSUSB_EQ_PILPO_OFST, + A60810_RGS_SSUSB_EQ_PILPO); + + pr_debug("PI result: %d\n", _bPIResult); + } + /* Read Initial DAC */ + /* Set CYCLE */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye3) + , A60810_RG_SSUSB_EQ_EYE_CNT_OFST, A60810_RG_SSUSB_EQ_EYE_CNT, eye_cnt); + + /* Eye Monitor Feature */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye1) + , A60810_RG_SSUSB_EQ_EYE_MASK_OFST, A60810_RG_SSUSB_EQ_EYE_MASK, 0x3ff); + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_MON_EN_OFST, A60810_RG_SSUSB_EQ_EYE_MON_EN, 1); + + /* Move X,Y to the top-left corner */ + for (cOfst = 0; cOfst >= -64; cOfst--) { + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST, + A60810_RG_SSUSB_EQ_EYE_XOFFSET, cOfst); + } + for (cOfst = 0; cOfst < 64; cOfst++) { + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y, + cOfst); + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y, + cOfst); + } + /* ClearErrorResult */ + for (bIdxCycCnt = 0; bIdxCycCnt < CYCLE_COUNT_MAX; bIdxCycCnt++) { + for (bIdxX = 0; bIdxX < ERRCNT_MAX; bIdxX++) { + for (bIdxY = 0; bIdxY < ERRCNT_MAX; bIdxY++) { + pwErrCnt0[bIdxCycCnt][bIdxX][bIdxY] = 0; + pwErrCnt1[bIdxCycCnt][bIdxX][bIdxY] = 0; + } + } + } + isContinue = true; + while (isContinue) { + pr_debug("_bXcurr: %d, _bYcurr: %d\n", _bXcurr, _bYcurr); + /* The point is within the boundary, then let's check if it is within */ + /* the testing region. */ + /* The point is only test-able if one of the eye region */ + /* includes this point. */ + fgValid = fgEyeScanHelper_CheckPtInRegion(&_rEye1, _bXcurr, _bYcurr) + || fgEyeScanHelper_CheckPtInRegion(&_rEye2, _bXcurr, _bYcurr); + /* Translate bX and bY to 2's complement from where the origin was on the */ + /* top left corner. */ + /* 0x40 and 0x3F needs a bit of thinking!!!! >"< */ + cX = (_bXcurr ^ 0x40); + cY = (_bYcurr ^ 0x3F); + + /* Set X if necessary */ + if (_fgXChged == true) { + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST, + A60810_RG_SSUSB_EQ_EYE_XOFFSET, cX); + } + /* Set Y */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y, cY); + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y, cY); + + /* / Test this point! */ + if (fgValid) { + for (bExtendCnt = 0; bExtendCnt < num_ignore_cnt; bExtendCnt++) { + /* run test */ + EyeScanHelper_RunTest(info); + } + for (bExtendCnt = 0; bExtendCnt < num_cnt; bExtendCnt++) { + EyeScanHelper_RunTest(info); + wErr0 = + U3PhyReadField32(((phys_addr_t) &info-> + u3phyd_regs_a->phya_rx_mon3) + , + A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0_OFST, + A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0); + wErr1 = + U3PhyReadField32(((phys_addr_t) &info-> + u3phyd_regs_a->phya_rx_mon4) + , + A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1_OFST, + A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1); + + pwErrCnt0[bExtendCnt][_bXcurr][_bYcurr] = wErr0; + pwErrCnt1[bExtendCnt][_bXcurr][_bYcurr] = wErr1; + + /* EyeScanHelper_GetResult(&_rRes.pwErrCnt0[bCnt], &_rRes.pwErrCnt1[bCnt]); */ + /* pr_debug("cnt[%d] cur_x,y [0x%x][0x%x], cX,cY [0x%x][0x%x], ErrCnt[%d][%d]\n", + bExtendCnt, _bXcurr, _bYcurr, cX, cY, + pwErrCnt0[bExtendCnt][_bXcurr][_bYcurr], + pwErrCnt1[bExtendCnt][_bXcurr][_bYcurr]); */ + } + /* pr_debug("cur_x,y [0x%x][0x%x], cX,cY [0x%x][0x%x], ErrCnt[%d][%d]\n", + _bXcurr, _bYcurr, cX, cY, pwErrCnt0[0][_bXcurr][_bYcurr], + pwErrCnt1[0][_bXcurr][_bYcurr]); */ + } else { + + } + if (fgEyeScanHelper_CalNextPoint() == false) { +#if 1 + pr_debug("Xcurr [0x%x] Ycurr [0x%x]\n", _bXcurr, _bYcurr); + pr_debug("XcurrREG [0x%x] YcurrREG [0x%x]\n", cX, cY); +#endif + pr_debug("end of eye scan\n"); + isContinue = false; + } + } + pr_debug("CurX [0x%x] CurY [0x%x]\n", + U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0), + A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST, + A60810_RG_SSUSB_EQ_EYE_XOFFSET) + , U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0), + A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y)); + + /* Move X,Y to the top-left corner */ + for (cOfst = 63; cOfst >= 0; cOfst--) { + /* RG_SSUSB_RX_EYE_XOFFSET */ + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST, + A60810_RG_SSUSB_EQ_EYE_XOFFSET, cOfst); + } + for (cOfst = 63; cOfst >= 0; cOfst--) { + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y, + cOfst); + U3PhyWriteField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0) + , A60810_RG_SSUSB_EQ_EYE1_Y_OFST, A60810_RG_SSUSB_EQ_EYE1_Y, + cOfst); + + } + pr_debug("CurX [0x%x] CurY [0x%x]\n", + U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0), + A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST, + A60810_RG_SSUSB_EQ_EYE_XOFFSET) + , U3PhyReadField32(((phys_addr_t) &info->u3phyd_regs_a->eq_eye0), + A60810_RG_SSUSB_EQ_EYE0_Y_OFST, A60810_RG_SSUSB_EQ_EYE0_Y)); + + pr_debug("PI result: %d\n", _bPIResult); + pr_debug("pwErrCnt0 addr: %p\n", pwErrCnt0); + pr_debug("pwErrCnt1 addr: %p\n", pwErrCnt1); + return PHY_TRUE; +} + +PHY_INT32 u2_connect_a60810(struct u3phy_info *info) +{ + /* for better LPM BESL value */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->u2phydcr1) + , A60810_RG_USB20_SW_PLLMODE_OFST, A60810_RG_USB20_SW_PLLMODE, 0x1); + return PHY_TRUE; +} + +PHY_INT32 u2_disconnect_a60810(struct u3phy_info *info) +{ + /* for better LPM BESL value */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->u2phydcr1) + , A60810_RG_USB20_SW_PLLMODE_OFST, A60810_RG_USB20_SW_PLLMODE, 0x0); + return PHY_TRUE; +} + +PHY_INT32 u2_save_cur_en_a60810(struct u3phy_info *info) +{ + return PHY_TRUE; +} + +PHY_INT32 u2_save_cur_re_a60810(struct u3phy_info *info) +{ + return PHY_TRUE; +} + +PHY_INT32 u2_slew_rate_calibration_a60810(struct u3phy_info *info) +{ + PHY_INT32 i = 0; + PHY_INT32 fgRet = 0; + PHY_INT32 u4FmOut = 0; + PHY_INT32 u4Tmp = 0; + + /* => RG_USB20_HSTX_SRCAL_EN = 1 */ + /* enable HS TX SR calibration */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5) + , A60810_RG_USB20_HSTX_SRCAL_EN_OFST, A60810_RG_USB20_HSTX_SRCAL_EN, 1); + DRV_MSLEEP(1); + + /* => RG_FRCK_EN = 1 */ + /* Enable free run clock */ + U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmmonr1) + , A60810_RG_FRCK_EN_OFST, A60810_RG_FRCK_EN, 0x1); + + /* => RG_CYCLECNT = 0x400 */ + /* Setting cyclecnt = 0x400 */ + U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmcr0) + , A60810_RG_CYCLECNT_OFST, A60810_RG_CYCLECNT, 0x400); + + /* => RG_FREQDET_EN = 1 */ + /* Enable frequency meter */ + U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmcr0) + , A60810_RG_FREQDET_EN_OFST, A60810_RG_FREQDET_EN, 0x1); + + /* wait for FM detection done, set 10ms timeout */ + for (i = 0; i < 10; i++) { + /* => u4FmOut = USB_FM_OUT */ + /* read FM_OUT */ + u4FmOut = U3PhyReadReg32(((phys_addr_t) &info->sifslv_fm_regs_a->fmmonr0)); + pr_debug("FM_OUT value: u4FmOut = %d(0x%08X)\n", u4FmOut, u4FmOut); + + /* check if FM detection done */ + if (u4FmOut != 0) { + fgRet = 0; + pr_debug("FM detection done! loop = %d\n", i); + + break; + } + + fgRet = 1; + DRV_MSLEEP(1); + } + /* => RG_FREQDET_EN = 0 */ + /* disable frequency meter */ + U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmcr0) + , A60810_RG_FREQDET_EN_OFST, A60810_RG_FREQDET_EN, 0); + + /* => RG_FRCK_EN = 0 */ + /* disable free run clock */ + U3PhyWriteField32(((phys_addr_t) &info->sifslv_fm_regs_a->fmmonr1) + , A60810_RG_FRCK_EN_OFST, A60810_RG_FRCK_EN, 0); + + /* => RG_USB20_HSTX_SRCAL_EN = 0 */ + /* disable HS TX SR calibration */ + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5) + , A60810_RG_USB20_HSTX_SRCAL_EN_OFST, A60810_RG_USB20_HSTX_SRCAL_EN, 0); + DRV_MSLEEP(1); + + if (u4FmOut == 0) { + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5) + , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL, + 0x4); + + fgRet = 1; + } else { + /* set reg = (1024/FM_OUT) * REF_CK * U2_SR_COEF_A60810 / 1000 (round to the nearest digits) */ + u4Tmp = (((1024 * REF_CK * U2_SR_COEF_A60810) / u4FmOut) + 500) / 1000; + pr_debug("SR calibration value u1SrCalVal = %d\n", (PHY_UINT8) u4Tmp); + U3PhyWriteField32(((phys_addr_t) &info->u2phy_regs_a->usbphyacr5) + , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL, + u4Tmp); + } + + return fgRet; +} + + +#endif diff --git a/drivers/misc/mediatek/mu3phy/mtk-phy-a60810.h b/drivers/misc/mediatek/mu3phy/mtk-phy-a60810.h new file mode 100644 index 000000000000..ec80b68aa124 --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/mtk-phy-a60810.h @@ -0,0 +1,3124 @@ +#ifdef CONFIG_A60810_SUPPORT +#ifndef __MTK_PHY_A60810_H +#define __MTK_PHY_A60810_H + +#define U2_SR_COEF_A60810 22 + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct u2phy_reg_a { + /* 0x0 */ + PHY_LE32 usbphyacr0; + PHY_LE32 usbphyacr1; + PHY_LE32 usbphyacr2; + PHY_LE32 reserve0; + /* 0x10 */ + PHY_LE32 usbphyacr4; + PHY_LE32 usbphyacr5; + PHY_LE32 usbphyacr6; + PHY_LE32 u2phyacr3; + /* 0x20 */ + PHY_LE32 u2phyacr4; + PHY_LE32 u2phyamon0; + PHY_LE32 reserve1[2]; + /* 0x30~0x50 */ + PHY_LE32 reserve2[12]; + /* 0x60 */ + PHY_LE32 u2phydcr0; + PHY_LE32 u2phydcr1; + PHY_LE32 u2phydtm0; + PHY_LE32 u2phydtm1; + /* 0x70 */ + PHY_LE32 u2phydmon0; + PHY_LE32 u2phydmon1; + PHY_LE32 u2phydmon2; + PHY_LE32 u2phydmon3; + /* 0x80 */ + PHY_LE32 u2phybc12c; + PHY_LE32 u2phybc12c1; + PHY_LE32 reserve3[2]; + /* 0x90~0xd0 */ + PHY_LE32 reserve4[20]; + /* 0xe0 */ + PHY_LE32 regfppc; + PHY_LE32 reserve5[3]; + /* 0xf0 */ + PHY_LE32 versionc; + PHY_LE32 reserve6[2]; + PHY_LE32 regfcom; +}; + +/* U3D_USBPHYACR0 */ +#define A60810_RG_USB20_MPX_OUT_SEL (0x7<<28) /* 30:28 */ +#define A60810_RG_USB20_TX_PH_ROT_SEL (0x7<<24) /* 26:24 */ +#define A60810_RG_USB20_PLL_DIVEN (0x7<<20) /* 22:20 */ +#define A60810_RG_USB20_PLL_BR (0x1<<18) /* 18:18 */ +#define A60810_RG_USB20_PLL_BP (0x1<<17) /* 17:17 */ +#define A60810_RG_USB20_PLL_BLP (0x1<<16) /* 16:16 */ +#define A60810_RG_USB20_USBPLL_FORCE_ON (0x1<<15) /* 15:15 */ +#define A60810_RG_USB20_PLL_FBDIV (0x7f<<8) /* 14:8 */ +#define A60810_RG_USB20_PLL_PREDIV (0x3<<6) /* 7:6 */ +#define A60810_RG_USB20_INTR_EN (0x1<<5) /* 5:5 */ +#define A60810_RG_USB20_REF_EN (0x1<<4) /* 4:4 */ +#define A60810_RG_USB20_BGR_DIV (0x3<<2) /* 3:2 */ +#define A60810_RG_SIFSLV_CHP_EN (0x1<<1) /* 1:1 */ +#define A60810_RG_SIFSLV_BGR_EN (0x1<<0) /* 0:0 */ + +/* U3D_USBPHYACR1 */ +#define A60810_RG_USB20_INTR_CAL (0x1f<<19) /* 23:19 */ +#define A60810_RG_USB20_OTG_VBUSTH (0x7<<16) /* 18:16 */ +#define A60810_RG_USB20_VRT_VREF_SEL (0x7<<12) /* 14:12 */ +#define A60810_RG_USB20_TERM_VREF_SEL (0x7<<8) /* 10:8 */ +#define A60810_RG_USB20_MPX_SEL (0xff<<0) /* 7:0 */ + +/* U3D_USBPHYACR2 */ +#define A60810_RG_SIFSLV_MAC_BANDGAP_EN (0x1<<17) /* 17:17 */ +#define A60810_RG_SIFSLV_MAC_CHOPPER_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_USB20_CLKREF_REV (0xffff<<0) /* 15:0 */ + +/* U3D_USBPHYACR4 */ +#define A60810_RG_USB20_DP_ABIST_SOURCE_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_USB20_DP_ABIST_SELE (0xf<<24) /* 27:24 */ +#define A60810_RG_USB20_ICUSB_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_USB20_LS_CR (0x7<<12) /* 14:12 */ +#define A60810_RG_USB20_FS_CR (0x7<<8) /* 10:8 */ +#define A60810_RG_USB20_LS_SR (0x7<<4) /* 6:4 */ +#define A60810_RG_USB20_FS_SR (0x7<<0) /* 2:0 */ + +/* U3D_USBPHYACR5 */ +#define A60810_RG_USB20_DISC_FIT_EN (0x1<<28) /* 28:28 */ +#define A60810_RG_USB20_INIT_SQ_EN_DG (0x3<<26) /* 27:26 */ +#define A60810_RG_USB20_HSTX_TMODE_SEL (0x3<<24) /* 25:24 */ +#define A60810_RG_USB20_SQD (0x3<<22) /* 23:22 */ +#define A60810_RG_USB20_DISCD (0x3<<20) /* 21:20 */ +#define A60810_RG_USB20_HSTX_TMODE_EN (0x1<<19) /* 19:19 */ +#define A60810_RG_USB20_PHYD_MONEN (0x1<<18) /* 18:18 */ +#define A60810_RG_USB20_INLPBK_EN (0x1<<17) /* 17:17 */ +#define A60810_RG_USB20_CHIRP_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_USB20_HSTX_SRCAL_EN (0x1<<15) /* 15:15 */ +#define A60810_RG_USB20_HSTX_SRCTRL (0x7<<12) /* 14:12 */ +#define A60810_RG_USB20_HS_100U_U3_EN (0x1<<11) /* 11:11 */ +#define A60810_RG_USB20_GBIAS_ENB (0x1<<10) /* 10:10 */ +#define A60810_RG_USB20_DM_ABIST_SOURCE_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_USB20_DM_ABIST_SELE (0xf<<0) /* 3:0 */ + +/* U3D_USBPHYACR6 */ +#define A60810_RG_USB20_PHY_REV (0xff<<24) /* 31:24 */ +#define A60810_RG_USB20_BC11_SW_EN (0x1<<23) /* 23:23 */ +#define A60810_RG_USB20_SR_CLK_SEL (0x1<<22) /* 22:22 */ +#define A60810_RG_USB20_OTG_VBUSCMP_EN (0x1<<20) /* 20:20 */ +#define A60810_RG_USB20_OTG_ABIST_EN (0x1<<19) /* 19:19 */ +#define A60810_RG_USB20_OTG_ABIST_SELE (0x7<<16) /* 18:16 */ +#define A60810_RG_USB20_HSRX_MMODE_SELE (0x3<<12) /* 13:12 */ +#define A60810_RG_USB20_HSRX_BIAS_EN_SEL (0x3<<9) /* 10:9 */ +#define A60810_RG_USB20_HSRX_TMODE_EN (0x1<<8) /* 8:8 */ +#define A60810_RG_USB20_DISCTH (0xf<<4) /* 7:4 */ +#define A60810_RG_USB20_SQTH (0xf<<0) /* 3:0 */ + +/* U3D_U2PHYACR3 */ +#define A60810_RG_USB20_HSTX_DBIST (0xf<<28) /* 31:28 */ +#define A60810_RG_USB20_HSTX_BIST_EN (0x1<<26) /* 26:26 */ +#define A60810_RG_USB20_HSTX_I_EN_MODE (0x3<<24) /* 25:24 */ +#define A60810_RG_USB20_USB11_TMODE_EN (0x1<<19) /* 19:19 */ +#define A60810_RG_USB20_TMODE_FS_LS_TX_EN (0x1<<18) /* 18:18 */ +#define A60810_RG_USB20_TMODE_FS_LS_RCV_EN (0x1<<17) /* 17:17 */ +#define A60810_RG_USB20_TMODE_FS_LS_MODE (0x1<<16) /* 16:16 */ +#define A60810_RG_USB20_HS_TERM_EN_MODE (0x3<<13) /* 14:13 */ +#define A60810_RG_USB20_PUPD_BIST_EN (0x1<<12) /* 12:12 */ +#define A60810_RG_USB20_EN_PU_DM (0x1<<11) /* 11:11 */ +#define A60810_RG_USB20_EN_PD_DM (0x1<<10) /* 10:10 */ +#define A60810_RG_USB20_EN_PU_DP (0x1<<9) /* 9:9 */ +#define A60810_RG_USB20_EN_PD_DP (0x1<<8) /* 8:8 */ + +/* U3D_U2PHYACR4 */ +#define A60810_RG_USB20_DP_100K_MODE (0x1<<18) /* 18:18 */ +#define A60810_RG_USB20_DM_100K_EN (0x1<<17) /* 17:17 */ +#define A60810_USB20_DP_100K_EN (0x1<<16) /* 16:16 */ +#define A60810_USB20_GPIO_DM_I (0x1<<15) /* 15:15 */ +#define A60810_USB20_GPIO_DP_I (0x1<<14) /* 14:14 */ +#define A60810_USB20_GPIO_DM_OE (0x1<<13) /* 13:13 */ +#define A60810_USB20_GPIO_DP_OE (0x1<<12) /* 12:12 */ +#define A60810_RG_USB20_GPIO_CTL (0x1<<9) /* 9:9 */ +#define A60810_USB20_GPIO_MODE (0x1<<8) /* 8:8 */ +#define A60810_RG_USB20_TX_BIAS_EN (0x1<<5) /* 5:5 */ +#define A60810_RG_USB20_TX_VCMPDN_EN (0x1<<4) /* 4:4 */ +#define A60810_RG_USB20_HS_SQ_EN_MODE (0x3<<2) /* 3:2 */ +#define A60810_RG_USB20_HS_RCV_EN_MODE (0x3<<0) /* 1:0 */ + +/* U3D_U2PHYAMON0 */ +#define A60810_RGO_USB20_GPIO_DM_O (0x1<<1) /* 1:1 */ +#define A60810_RGO_USB20_GPIO_DP_O (0x1<<0) /* 0:0 */ + +/* U3D_U2PHYDCR0 */ +#define A60810_RG_USB20_CDR_TST (0x3<<30) /* 31:30 */ +#define A60810_RG_USB20_GATED_ENB (0x1<<29) /* 29:29 */ +#define A60810_RG_USB20_TESTMODE (0x3<<26) /* 27:26 */ +#define A60810_RG_SIFSLV_USB20_PLL_STABLE (0x1<<25) /* 25:25 */ +#define A60810_RG_SIFSLV_USB20_PLL_FORCE_ON (0x1<<24) /* 24:24 */ +#define A60810_RG_USB20_PHYD_RESERVE (0xffff<<8) /* 23:8 */ +#define A60810_RG_USB20_EBTHRLD (0x1<<7) /* 7:7 */ +#define A60810_RG_USB20_EARLY_HSTX_I (0x1<<6) /* 6:6 */ +#define A60810_RG_USB20_TX_TST (0x1<<5) /* 5:5 */ +#define A60810_RG_USB20_NEGEDGE_ENB (0x1<<4) /* 4:4 */ +#define A60810_RG_USB20_CDR_FILT (0xf<<0) /* 3:0 */ + +/* U3D_U2PHYDCR1 */ +#define A60810_RG_USB20_PROBE_SEL (0xff<<24) /* 31:24 */ +#define A60810_RG_USB20_DRVVBUS (0x1<<23) /* 23:23 */ +#define A60810_RG_DEBUG_EN (0x1<<22) /* 22:22 */ +#define A60810_RG_USB20_OTG_PROBE (0x3<<20) /* 21:20 */ +#define A60810_RG_USB20_SW_PLLMODE (0x3<<18) /* 19:18 */ +#define A60810_RG_USB20_BERTH (0x3<<16) /* 17:16 */ +#define A60810_RG_USB20_LBMODE (0x3<<13) /* 14:13 */ +#define A60810_RG_USB20_FORCE_TAP (0x1<<12) /* 12:12 */ +#define A60810_RG_USB20_TAPSEL (0xfff<<0) /* 11:0 */ + +/* U3D_U2PHYDTM0 */ +#define A60810_RG_UART_MODE (0x3<<30) /* 31:30 */ +#define A60810_FORCE_UART_I (0x1<<29) /* 29:29 */ +#define A60810_FORCE_UART_BIAS_EN (0x1<<28) /* 28:28 */ +#define A60810_FORCE_UART_TX_OE (0x1<<27) /* 27:27 */ +#define A60810_FORCE_UART_EN (0x1<<26) /* 26:26 */ +#define A60810_FORCE_USB_CLKEN (0x1<<25) /* 25:25 */ +#define A60810_FORCE_DRVVBUS (0x1<<24) /* 24:24 */ +#define A60810_FORCE_DATAIN (0x1<<23) /* 23:23 */ +#define A60810_FORCE_TXVALID (0x1<<22) /* 22:22 */ +#define A60810_FORCE_DM_PULLDOWN (0x1<<21) /* 21:21 */ +#define A60810_FORCE_DP_PULLDOWN (0x1<<20) /* 20:20 */ +#define A60810_FORCE_XCVRSEL (0x1<<19) /* 19:19 */ +#define A60810_FORCE_SUSPENDM (0x1<<18) /* 18:18 */ +#define A60810_FORCE_TERMSEL (0x1<<17) /* 17:17 */ +#define A60810_FORCE_OPMODE (0x1<<16) /* 16:16 */ +#define A60810_UTMI_MUXSEL (0x1<<15) /* 15:15 */ +#define A60810_RG_RESET (0x1<<14) /* 14:14 */ +#define A60810_RG_DATAIN (0xf<<10) /* 13:10 */ +#define A60810_RG_TXVALIDH (0x1<<9) /* 9:9 */ +#define A60810_RG_TXVALID (0x1<<8) /* 8:8 */ +#define A60810_RG_DMPULLDOWN (0x1<<7) /* 7:7 */ +#define A60810_RG_DPPULLDOWN (0x1<<6) /* 6:6 */ +#define A60810_RG_XCVRSEL (0x3<<4) /* 5:4 */ +#define A60810_RG_SUSPENDM (0x1<<3) /* 3:3 */ +#define A60810_RG_TERMSEL (0x1<<2) /* 2:2 */ +#define A60810_RG_OPMODE (0x3<<0) /* 1:0 */ + +/* U3D_U2PHYDTM1 */ +#define A60810_RG_USB20_PRBS7_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_USB20_PRBS7_BITCNT (0x3f<<24) /* 29:24 */ +#define A60810_RG_USB20_CLK48M_EN (0x1<<23) /* 23:23 */ +#define A60810_RG_USB20_CLK60M_EN (0x1<<22) /* 22:22 */ +#define A60810_RG_UART_I (0x1<<19) /* 19:19 */ +#define A60810_RG_UART_BIAS_EN (0x1<<18) /* 18:18 */ +#define A60810_RG_UART_TX_OE (0x1<<17) /* 17:17 */ +#define A60810_RG_UART_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_IP_U2_PORT_POWER (0x1<<15) /* 15:15 */ +#define A60810_FORCE_IP_U2_PORT_POWER (0x1<<14) /* 14:14 */ +#define A60810_FORCE_VBUSVALID (0x1<<13) /* 13:13 */ +#define A60810_FORCE_SESSEND (0x1<<12) /* 12:12 */ +#define A60810_FORCE_BVALID (0x1<<11) /* 11:11 */ +#define A60810_FORCE_AVALID (0x1<<10) /* 10:10 */ +#define A60810_FORCE_IDDIG (0x1<<9) /* 9:9 */ +#define A60810_FORCE_IDPULLUP (0x1<<8) /* 8:8 */ +#define A60810_RG_VBUSVALID (0x1<<5) /* 5:5 */ +#define A60810_RG_SESSEND (0x1<<4) /* 4:4 */ +#define A60810_RG_BVALID (0x1<<3) /* 3:3 */ +#define A60810_RG_AVALID (0x1<<2) /* 2:2 */ +#define A60810_RG_IDDIG (0x1<<1) /* 1:1 */ +#define A60810_RG_IDPULLUP (0x1<<0) /* 0:0 */ + +/* U3D_U2PHYDMON0 */ +#define A60810_RG_USB20_PRBS7_BERTH (0xff<<0) /* 7:0 */ + +/* U3D_U2PHYDMON1 */ +#define A60810_USB20_UART_O (0x1<<31) /* 31:31 */ +#define A60810_RGO_USB20_LB_PASS (0x1<<30) /* 30:30 */ +#define A60810_RGO_USB20_LB_DONE (0x1<<29) /* 29:29 */ +#define A60810_AD_USB20_BVALID (0x1<<28) /* 28:28 */ +#define A60810_USB20_IDDIG (0x1<<27) /* 27:27 */ +#define A60810_AD_USB20_VBUSVALID (0x1<<26) /* 26:26 */ +#define A60810_AD_USB20_SESSEND (0x1<<25) /* 25:25 */ +#define A60810_AD_USB20_AVALID (0x1<<24) /* 24:24 */ +#define A60810_USB20_LINE_STATE (0x3<<22) /* 23:22 */ +#define A60810_USB20_HST_DISCON (0x1<<21) /* 21:21 */ +#define A60810_USB20_TX_READY (0x1<<20) /* 20:20 */ +#define A60810_USB20_RX_ERROR (0x1<<19) /* 19:19 */ +#define A60810_USB20_RX_ACTIVE (0x1<<18) /* 18:18 */ +#define A60810_USB20_RX_VALIDH (0x1<<17) /* 17:17 */ +#define A60810_USB20_RX_VALID (0x1<<16) /* 16:16 */ +#define A60810_USB20_DATA_OUT (0xffff<<0) /* 15:0 */ + +/* U3D_U2PHYDMON2 */ +#define A60810_RGO_TXVALID_CNT (0xff<<24) /* 31:24 */ +#define A60810_RGO_RXACTIVE_CNT (0xff<<16) /* 23:16 */ +#define A60810_RGO_USB20_LB_BERCNT (0xff<<8) /* 15:8 */ +#define A60810_USB20_PROBE_OUT (0xff<<0) /* 7:0 */ + +/* U3D_U2PHYDMON3 */ +#define A60810_RGO_USB20_PRBS7_ERRCNT (0xffff<<16) /* 31:16 */ +#define A60810_RGO_USB20_PRBS7_DONE (0x1<<3) /* 3:3 */ +#define A60810_RGO_USB20_PRBS7_LOCK (0x1<<2) /* 2:2 */ +#define A60810_RGO_USB20_PRBS7_PASS (0x1<<1) /* 1:1 */ +#define A60810_RGO_USB20_PRBS7_PASSTH (0x1<<0) /* 0:0 */ + +/* U3D_U2PHYBC12C */ +#define A60810_RG_SIFSLV_CHGDT_DEGLCH_CNT (0xf<<28) /* 31:28 */ +#define A60810_RG_SIFSLV_CHGDT_CTRL_CNT (0xf<<24) /* 27:24 */ +#define A60810_RG_SIFSLV_CHGDT_FORCE_MODE (0x1<<16) /* 16:16 */ +#define A60810_RG_CHGDT_ISRC_LEV (0x3<<14) /* 15:14 */ +#define A60810_RG_CHGDT_VDATSRC (0x1<<13) /* 13:13 */ +#define A60810_RG_CHGDT_BGVREF_SEL (0x7<<10) /* 12:10 */ +#define A60810_RG_CHGDT_RDVREF_SEL (0x3<<8) /* 9:8 */ +#define A60810_RG_CHGDT_ISRC_DP (0x1<<7) /* 7:7 */ +#define A60810_RG_SIFSLV_CHGDT_OPOUT_DM (0x1<<6) /* 6:6 */ +#define A60810_RG_CHGDT_VDAT_DM (0x1<<5) /* 5:5 */ +#define A60810_RG_CHGDT_OPOUT_DP (0x1<<4) /* 4:4 */ +#define A60810_RG_SIFSLV_CHGDT_VDAT_DP (0x1<<3) /* 3:3 */ +#define A60810_RG_SIFSLV_CHGDT_COMP_EN (0x1<<2) /* 2:2 */ +#define A60810_RG_SIFSLV_CHGDT_OPDRV_EN (0x1<<1) /* 1:1 */ +#define A60810_RG_CHGDT_EN (0x1<<0) /* 0:0 */ + +/* U3D_U2PHYBC12C1 */ +#define A60810_RG_CHGDT_REV (0xff<<0) /* 7:0 */ + +/* U3D_REGFPPC */ +#define A60810_USB11_OTG_REG (0x1<<4) /* 4:4 */ +#define A60810_USB20_OTG_REG (0x1<<3) /* 3:3 */ +#define A60810_CHGDT_REG (0x1<<2) /* 2:2 */ +#define A60810_USB11_REG (0x1<<1) /* 1:1 */ +#define A60810_USB20_REG (0x1<<0) /* 0:0 */ + +/* U3D_VERSIONC */ +#define A60810_VERSION_CODE_REGFILE (0xff<<24) /* 31:24 */ +#define A60810_USB11_VERSION_CODE (0xff<<16) /* 23:16 */ +#define A60810_VERSION_CODE_ANA (0xff<<8) /* 15:8 */ +#define A60810_VERSION_CODE_DIG (0xff<<0) /* 7:0 */ + +/* U3D_REGFCOM */ +#define A60810_RG_PAGE (0xff<<24) /* 31:24 */ +#define A60810_I2C_MODE (0x1<<16) /* 16:16 */ + +/* OFFSET */ + +/* U3D_USBPHYACR0 */ +#define A60810_RG_USB20_MPX_OUT_SEL_OFST (28) +#define A60810_RG_USB20_TX_PH_ROT_SEL_OFST (24) +#define A60810_RG_USB20_PLL_DIVEN_OFST (20) +#define A60810_RG_USB20_PLL_BR_OFST (18) +#define A60810_RG_USB20_PLL_BP_OFST (17) +#define A60810_RG_USB20_PLL_BLP_OFST (16) +#define A60810_RG_USB20_USBPLL_FORCE_ON_OFST (15) +#define A60810_RG_USB20_PLL_FBDIV_OFST (8) +#define A60810_RG_USB20_PLL_PREDIV_OFST (6) +#define A60810_RG_USB20_INTR_EN_OFST (5) +#define A60810_RG_USB20_REF_EN_OFST (4) +#define A60810_RG_USB20_BGR_DIV_OFST (2) +#define A60810_RG_SIFSLV_CHP_EN_OFST (1) +#define A60810_RG_SIFSLV_BGR_EN_OFST (0) + +/* U3D_USBPHYACR1 */ +#define A60810_RG_USB20_INTR_CAL_OFST (19) +#define A60810_RG_USB20_OTG_VBUSTH_OFST (16) +#define A60810_RG_USB20_VRT_VREF_SEL_OFST (12) +#define A60810_RG_USB20_TERM_VREF_SEL_OFST (8) +#define A60810_RG_USB20_MPX_SEL_OFST (0) + +/* U3D_USBPHYACR2 */ +#define A60810_RG_SIFSLV_MAC_BANDGAP_EN_OFST (17) +#define A60810_RG_SIFSLV_MAC_CHOPPER_EN_OFST (16) +#define A60810_RG_USB20_CLKREF_REV_OFST (0) + +/* U3D_USBPHYACR4 */ +#define A60810_RG_USB20_DP_ABIST_SOURCE_EN_OFST (31) +#define A60810_RG_USB20_DP_ABIST_SELE_OFST (24) +#define A60810_RG_USB20_ICUSB_EN_OFST (16) +#define A60810_RG_USB20_LS_CR_OFST (12) +#define A60810_RG_USB20_FS_CR_OFST (8) +#define A60810_RG_USB20_LS_SR_OFST (4) +#define A60810_RG_USB20_FS_SR_OFST (0) + +/* U3D_USBPHYACR5 */ +#define A60810_RG_USB20_DISC_FIT_EN_OFST (28) +#define A60810_RG_USB20_INIT_SQ_EN_DG_OFST (26) +#define A60810_RG_USB20_HSTX_TMODE_SEL_OFST (24) +#define A60810_RG_USB20_SQD_OFST (22) +#define A60810_RG_USB20_DISCD_OFST (20) +#define A60810_RG_USB20_HSTX_TMODE_EN_OFST (19) +#define A60810_RG_USB20_PHYD_MONEN_OFST (18) +#define A60810_RG_USB20_INLPBK_EN_OFST (17) +#define A60810_RG_USB20_CHIRP_EN_OFST (16) +#define A60810_RG_USB20_HSTX_SRCAL_EN_OFST (15) +#define A60810_RG_USB20_HSTX_SRCTRL_OFST (12) +#define A60810_RG_USB20_HS_100U_U3_EN_OFST (11) +#define A60810_RG_USB20_GBIAS_ENB_OFST (10) +#define A60810_RG_USB20_DM_ABIST_SOURCE_EN_OFST (7) +#define A60810_RG_USB20_DM_ABIST_SELE_OFST (0) + +/* U3D_USBPHYACR6 */ +#define A60810_RG_USB20_PHY_REV_OFST (24) +#define A60810_RG_USB20_BC11_SW_EN_OFST (23) +#define A60810_RG_USB20_SR_CLK_SEL_OFST (22) +#define A60810_RG_USB20_OTG_VBUSCMP_EN_OFST (20) +#define A60810_RG_USB20_OTG_ABIST_EN_OFST (19) +#define A60810_RG_USB20_OTG_ABIST_SELE_OFST (16) +#define A60810_RG_USB20_HSRX_MMODE_SELE_OFST (12) +#define A60810_RG_USB20_HSRX_BIAS_EN_SEL_OFST (9) +#define A60810_RG_USB20_HSRX_TMODE_EN_OFST (8) +#define A60810_RG_USB20_DISCTH_OFST (4) +#define A60810_RG_USB20_SQTH_OFST (0) + +/* U3D_U2PHYACR3 */ +#define A60810_RG_USB20_HSTX_DBIST_OFST (28) +#define A60810_RG_USB20_HSTX_BIST_EN_OFST (26) +#define A60810_RG_USB20_HSTX_I_EN_MODE_OFST (24) +#define A60810_RG_USB20_USB11_TMODE_EN_OFST (19) +#define A60810_RG_USB20_TMODE_FS_LS_TX_EN_OFST (18) +#define A60810_RG_USB20_TMODE_FS_LS_RCV_EN_OFST (17) +#define A60810_RG_USB20_TMODE_FS_LS_MODE_OFST (16) +#define A60810_RG_USB20_HS_TERM_EN_MODE_OFST (13) +#define A60810_RG_USB20_PUPD_BIST_EN_OFST (12) +#define A60810_RG_USB20_EN_PU_DM_OFST (11) +#define A60810_RG_USB20_EN_PD_DM_OFST (10) +#define A60810_RG_USB20_EN_PU_DP_OFST (9) +#define A60810_RG_USB20_EN_PD_DP_OFST (8) + +/* U3D_U2PHYACR4 */ +#define A60810_RG_USB20_DP_100K_MODE_OFST (18) +#define A60810_RG_USB20_DM_100K_EN_OFST (17) +#define A60810_USB20_DP_100K_EN_OFST (16) +#define A60810_USB20_GPIO_DM_I_OFST (15) +#define A60810_USB20_GPIO_DP_I_OFST (14) +#define A60810_USB20_GPIO_DM_OE_OFST (13) +#define A60810_USB20_GPIO_DP_OE_OFST (12) +#define A60810_RG_USB20_GPIO_CTL_OFST (9) +#define A60810_USB20_GPIO_MODE_OFST (8) +#define A60810_RG_USB20_TX_BIAS_EN_OFST (5) +#define A60810_RG_USB20_TX_VCMPDN_EN_OFST (4) +#define A60810_RG_USB20_HS_SQ_EN_MODE_OFST (2) +#define A60810_RG_USB20_HS_RCV_EN_MODE_OFST (0) + +/* U3D_U2PHYAMON0 */ +#define A60810_RGO_USB20_GPIO_DM_O_OFST (1) +#define A60810_RGO_USB20_GPIO_DP_O_OFST (0) + +/* U3D_U2PHYDCR0 */ +#define A60810_RG_USB20_CDR_TST_OFST (30) +#define A60810_RG_USB20_GATED_ENB_OFST (29) +#define A60810_RG_USB20_TESTMODE_OFST (26) +#define A60810_RG_SIFSLV_USB20_PLL_STABLE_OFST (25) +#define A60810_RG_SIFSLV_USB20_PLL_FORCE_ON_OFST (24) +#define A60810_RG_USB20_PHYD_RESERVE_OFST (8) +#define A60810_RG_USB20_EBTHRLD_OFST (7) +#define A60810_RG_USB20_EARLY_HSTX_I_OFST (6) +#define A60810_RG_USB20_TX_TST_OFST (5) +#define A60810_RG_USB20_NEGEDGE_ENB_OFST (4) +#define A60810_RG_USB20_CDR_FILT_OFST (0) + +/* U3D_U2PHYDCR1 */ +#define A60810_RG_USB20_PROBE_SEL_OFST (24) +#define A60810_RG_USB20_DRVVBUS_OFST (23) +#define A60810_RG_DEBUG_EN_OFST (22) +#define A60810_RG_USB20_OTG_PROBE_OFST (20) +#define A60810_RG_USB20_SW_PLLMODE_OFST (18) +#define A60810_RG_USB20_BERTH_OFST (16) +#define A60810_RG_USB20_LBMODE_OFST (13) +#define A60810_RG_USB20_FORCE_TAP_OFST (12) +#define A60810_RG_USB20_TAPSEL_OFST (0) + +/* U3D_U2PHYDTM0 */ +#define A60810_RG_UART_MODE_OFST (30) +#define A60810_FORCE_UART_I_OFST (29) +#define A60810_FORCE_UART_BIAS_EN_OFST (28) +#define A60810_FORCE_UART_TX_OE_OFST (27) +#define A60810_FORCE_UART_EN_OFST (26) +#define A60810_FORCE_USB_CLKEN_OFST (25) +#define A60810_FORCE_DRVVBUS_OFST (24) +#define A60810_FORCE_DATAIN_OFST (23) +#define A60810_FORCE_TXVALID_OFST (22) +#define A60810_FORCE_DM_PULLDOWN_OFST (21) +#define A60810_FORCE_DP_PULLDOWN_OFST (20) +#define A60810_FORCE_XCVRSEL_OFST (19) +#define A60810_FORCE_SUSPENDM_OFST (18) +#define A60810_FORCE_TERMSEL_OFST (17) +#define A60810_FORCE_OPMODE_OFST (16) +#define A60810_UTMI_MUXSEL_OFST (15) +#define A60810_RG_RESET_OFST (14) +#define A60810_RG_DATAIN_OFST (10) +#define A60810_RG_TXVALIDH_OFST (9) +#define A60810_RG_TXVALID_OFST (8) +#define A60810_RG_DMPULLDOWN_OFST (7) +#define A60810_RG_DPPULLDOWN_OFST (6) +#define A60810_RG_XCVRSEL_OFST (4) +#define A60810_RG_SUSPENDM_OFST (3) +#define A60810_RG_TERMSEL_OFST (2) +#define A60810_RG_OPMODE_OFST (0) + +/* U3D_U2PHYDTM1 */ +#define A60810_RG_USB20_PRBS7_EN_OFST (31) +#define A60810_RG_USB20_PRBS7_BITCNT_OFST (24) +#define A60810_RG_USB20_CLK48M_EN_OFST (23) +#define A60810_RG_USB20_CLK60M_EN_OFST (22) +#define A60810_RG_UART_I_OFST (19) +#define A60810_RG_UART_BIAS_EN_OFST (18) +#define A60810_RG_UART_TX_OE_OFST (17) +#define A60810_RG_UART_EN_OFST (16) +#define A60810_RG_IP_U2_PORT_POWER_OFST (15) +#define A60810_FORCE_IP_U2_PORT_POWER_OFST (14) +#define A60810_FORCE_VBUSVALID_OFST (13) +#define A60810_FORCE_SESSEND_OFST (12) +#define A60810_FORCE_BVALID_OFST (11) +#define A60810_FORCE_AVALID_OFST (10) +#define A60810_FORCE_IDDIG_OFST (9) +#define A60810_FORCE_IDPULLUP_OFST (8) +#define A60810_RG_VBUSVALID_OFST (5) +#define A60810_RG_SESSEND_OFST (4) +#define A60810_RG_BVALID_OFST (3) +#define A60810_RG_AVALID_OFST (2) +#define A60810_RG_IDDIG_OFST (1) +#define A60810_RG_IDPULLUP_OFST (0) + +/* U3D_U2PHYDMON0 */ +#define A60810_RG_USB20_PRBS7_BERTH_OFST (0) + +/* U3D_U2PHYDMON1 */ +#define A60810_USB20_UART_O_OFST (31) +#define A60810_RGO_USB20_LB_PASS_OFST (30) +#define A60810_RGO_USB20_LB_DONE_OFST (29) +#define A60810_AD_USB20_BVALID_OFST (28) +#define A60810_USB20_IDDIG_OFST (27) +#define A60810_AD_USB20_VBUSVALID_OFST (26) +#define A60810_AD_USB20_SESSEND_OFST (25) +#define A60810_AD_USB20_AVALID_OFST (24) +#define A60810_USB20_LINE_STATE_OFST (22) +#define A60810_USB20_HST_DISCON_OFST (21) +#define A60810_USB20_TX_READY_OFST (20) +#define A60810_USB20_RX_ERROR_OFST (19) +#define A60810_USB20_RX_ACTIVE_OFST (18) +#define A60810_USB20_RX_VALIDH_OFST (17) +#define A60810_USB20_RX_VALID_OFST (16) +#define A60810_USB20_DATA_OUT_OFST (0) + +/* U3D_U2PHYDMON2 */ +#define A60810_RGO_TXVALID_CNT_OFST (24) +#define A60810_RGO_RXACTIVE_CNT_OFST (16) +#define A60810_RGO_USB20_LB_BERCNT_OFST (8) +#define A60810_USB20_PROBE_OUT_OFST (0) + +/* U3D_U2PHYDMON3 */ +#define A60810_RGO_USB20_PRBS7_ERRCNT_OFST (16) +#define A60810_RGO_USB20_PRBS7_DONE_OFST (3) +#define A60810_RGO_USB20_PRBS7_LOCK_OFST (2) +#define A60810_RGO_USB20_PRBS7_PASS_OFST (1) +#define A60810_RGO_USB20_PRBS7_PASSTH_OFST (0) + +/* U3D_U2PHYBC12C */ +#define A60810_RG_SIFSLV_CHGDT_DEGLCH_CNT_OFST (28) +#define A60810_RG_SIFSLV_CHGDT_CTRL_CNT_OFST (24) +#define A60810_RG_SIFSLV_CHGDT_FORCE_MODE_OFST (16) +#define A60810_RG_CHGDT_ISRC_LEV_OFST (14) +#define A60810_RG_CHGDT_VDATSRC_OFST (13) +#define A60810_RG_CHGDT_BGVREF_SEL_OFST (10) +#define A60810_RG_CHGDT_RDVREF_SEL_OFST (8) +#define A60810_RG_CHGDT_ISRC_DP_OFST (7) +#define A60810_RG_SIFSLV_CHGDT_OPOUT_DM_OFST (6) +#define A60810_RG_CHGDT_VDAT_DM_OFST (5) +#define A60810_RG_CHGDT_OPOUT_DP_OFST (4) +#define A60810_RG_SIFSLV_CHGDT_VDAT_DP_OFST (3) +#define A60810_RG_SIFSLV_CHGDT_COMP_EN_OFST (2) +#define A60810_RG_SIFSLV_CHGDT_OPDRV_EN_OFST (1) +#define A60810_RG_CHGDT_EN_OFST (0) + +/* U3D_U2PHYBC12C1 */ +#define A60810_RG_CHGDT_REV_OFST (0) + +/* U3D_REGFPPC */ +#define A60810_USB11_OTG_REG_OFST (4) +#define A60810_USB20_OTG_REG_OFST (3) +#define A60810_CHGDT_REG_OFST (2) +#define A60810_USB11_REG_OFST (1) +#define A60810_USB20_REG_OFST (0) + +/* U3D_VERSIONC */ +#define A60810_VERSION_CODE_REGFILE_OFST (24) +#define A60810_USB11_VERSION_CODE_OFST (16) +#define A60810_VERSION_CODE_ANA_OFST (8) +#define A60810_VERSION_CODE_DIG_OFST (0) + +/* U3D_REGFCOM */ +#define A60810_RG_PAGE_OFST (24) +#define A60810_I2C_MODE_OFST (16) + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct u3phya_reg_a { + /* 0x0 */ + PHY_LE32 reg0; + PHY_LE32 reg1; + PHY_LE32 reg2; + PHY_LE32 reg3; + /* 0x10 */ + PHY_LE32 reg4; + PHY_LE32 reg5; + PHY_LE32 reg6; + PHY_LE32 reg7; + /* 0x20 */ + PHY_LE32 reg8; + PHY_LE32 reg9; + PHY_LE32 rega; + PHY_LE32 regb; + /* 0x30 */ + PHY_LE32 regc; +}; + +/* U3D_reg0 */ +#define A60810_RG_SSUSB_BGR_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_CHPEN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_BG_DIV (0x3<<28) /* 29:28 */ +#define A60810_RG_SSUSB_INTR_EN (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_MPX_EN (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_MPX_SEL (0xff<<16) /* 23:16 */ +#define A60810_RG_SSUSB_REF_EN (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_VRT_VREF_SEL (0xf<<11) /* 14:11 */ +#define A60810_RG_SSUSB_BG_MONEN (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_INT_BIAS_SEL (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_EXT_BIAS_SEL (0x1<<6) /* 6:6 */ +#define A60810_RG_PCIE_CLKDRV_OFFSET (0x3<<2) /* 3:2 */ +#define A60810_RG_PCIE_CLKDRV_SLEW (0x3<<0) /* 1:0 */ + +/* U3D_reg1 */ +#define A60810_RG_PCIE_CLKDRV_AMP (0x7<<29) /* 31:29 */ +#define A60810_RG_SSUSB_XTAL_TST_A2DCK_EN (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_XTAL_MON_EN (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_XTAL_HYS (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_XTAL_TOP_RESERVE (0xffff<<10) /* 25:10 */ +#define A60810_RG_SSUSB_SYSPLL_PREDIV (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_SYSPLL_POSDIV (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_SYSPLL_VCO_DIV_SEL (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_SYSPLL_VOD_EN (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_SYSPLL_RST_DLY (0x3<<2) /* 3:2 */ +#define A60810_RG_SSUSB_SYSPLL_BLP (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_SYSPLL_BP (0x1<<0) /* 0:0 */ + +/* U3D_reg2 */ +#define A60810_RG_SSUSB_SYSPLL_BR (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_SYSPLL_BC (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_SYSPLL_MONCK_EN (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_SYSPLL_MONVC_EN (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_SYSPLL_MONREF_EN (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_SYSPLL_SDM_IFM (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_SYSPLL_SDM_OUT (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_SYSPLL_BACK_EN (0x1<<24) /* 24:24 */ + +/* U3D_reg3 */ +#define A60810_RG_SSUSB_SYSPLL_FBDIV (0x7fffffff<<1) /* 31:1 */ +#define A60810_RG_SSUSB_SYSPLL_HR_EN (0x1<<0) /* 0:0 */ + +/* U3D_reg4 */ +#define A60810_RG_SSUSB_SYSPLL_SDM_DI_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_SYSPLL_SDM_DI_LS (0x3<<29) /* 30:29 */ +#define A60810_RG_SSUSB_SYSPLL_SDM_ORD (0x3<<27) /* 28:27 */ +#define A60810_RG_SSUSB_SYSPLL_SDM_MODE (0x3<<25) /* 26:25 */ +#define A60810_RG_SSUSB_SYSPLL_RESERVE (0xff<<17) /* 24:17 */ +#define A60810_RG_SSUSB_SYSPLL_TOP_RESERVE (0xffff<<1) /* 16:1 */ + +/* U3D_reg5 */ +#define A60810_RG_SSUSB_TX250MCK_INVB (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_IDRV_ITAILOP_EN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_IDRV_CALIB (0x3f<<24) /* 29:24 */ +#define A60810_RG_SSUSB_IDEM_BIAS (0xf<<20) /* 23:20 */ +#define A60810_RG_SSUSB_TX_R50_FON (0x1<<19) /* 19:19 */ +#define A60810_RG_SSUSB_TX_SR (0x7<<16) /* 18:16 */ +#define A60810_RG_SSUSB_RXDET_RSEL (0x3<<14) /* 15:14 */ +#define A60810_RG_SSUSB_RXDET_UPDN_FORCE (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_RXDET_UPDN_SEL (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_RXDET_VTHSEL_L (0x3<<10) /* 11:10 */ +#define A60810_RG_SSUSB_RXDET_VTHSEL_H (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_CKMON_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_TX_VLMON_EN (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_TX_VLMON_SEL (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_CKMON_SEL (0xf<<0) /* 3:0 */ + +/* U3D_reg6 */ +#define A60810_RG_SSUSB_TX_EIDLE_CM (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_RXLBTX_EN (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_TXLBRX_EN (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_RESERVE (0x3ff<<16) /* 25:16 */ +#define A60810_RG_SSUSB_PLL_POSDIV (0x3<<14) /* 15:14 */ +#define A60810_RG_SSUSB_PLL_AUTOK_LOAD (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_PLL_VOD_EN (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_PLL_MONREF_EN (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_PLL_MONCK_EN (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_PLL_MONVC_EN (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_PLL_RLH_EN (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_PLL_AUTOK_KS (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_PLL_AUTOK_KF (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_PLL_RST_DLY (0x3<<2) /* 3:2 */ + +/* U3D_reg7 */ +#define A60810_RG_SSUSB_PLL_RESERVE (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_PLL_SSC_PRD (0xffff<<0) /* 15:0 */ + +/* U3D_reg8 */ +#define A60810_RG_SSUSB_PLL_SSC_PHASE_INI (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_PLL_SSC_TRI_EN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_PLL_CLK_PH_INV (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_PLL_DDS_LPF_EN (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_PLL_DDS_RST_SEL (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_PLL_DDS_VADJ (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_PLL_DDS_MONEN (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_PLL_DDS_SEL_EXT (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_PLL_DDS_PI_PL_EN (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_PLL_DDS_FRAC_MUTE (0x7<<20) /* 22:20 */ +#define A60810_RG_SSUSB_PLL_DDS_HF_EN (0x1<<19) /* 19:19 */ +#define A60810_RG_SSUSB_PLL_DDS_C (0x7<<16) /* 18:16 */ +#define A60810_RG_SSUSB_PLL_DDS_PREDIV2 (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_LFPS_LPF (0x3<<13) /* 14:13 */ + +/* U3D_reg9 */ +#define A60810_RG_SSUSB_CDR_PD_DIV_BYPASS (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_CDR_PD_DIV_SEL (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_CDR_CPBIAS_SEL (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_CDR_OSCDET_EN (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_CDR_MONMUX (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_CDR_RST_DLY (0x3<<25) /* 26:25 */ +#define A60810_RG_SSUSB_CDR_RSTB_MANUAL (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_CDR_BYPASS (0x3<<22) /* 23:22 */ +#define A60810_RG_SSUSB_CDR_PI_SLEW (0x3<<20) /* 21:20 */ +#define A60810_RG_SSUSB_CDR_EPEN (0x1<<19) /* 19:19 */ +#define A60810_RG_SSUSB_CDR_AUTOK_LOAD (0x1<<18) /* 18:18 */ +#define A60810_RG_SSUSB_CDR_MONEN (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_CDR_MONEN_DIG (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_CDR_REGOD (0x3<<13) /* 14:13 */ +#define A60810_RG_SSUSB_CDR_AUTOK_KS (0x3<<11) /* 12:11 */ +#define A60810_RG_SSUSB_CDR_AUTOK_KF (0x3<<9) /* 10:9 */ +#define A60810_RG_SSUSB_RX_DAC_EN (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_RX_DAC_PWD (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_EQ_CURSEL (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_RX_DAC_MUX (0x1f<<1) /* 5:1 */ +#define A60810_RG_SSUSB_RX_R2T_EN (0x1<<0) /* 0:0 */ + +/* U3D_regA */ +#define A60810_RG_SSUSB_RX_T2R_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_RX_50_LOWER (0x7<<28) /* 30:28 */ +#define A60810_RG_SSUSB_RX_50_TAR (0x3<<26) /* 27:26 */ +#define A60810_RG_SSUSB_RX_SW_CTRL (0xf<<21) /* 24:21 */ +#define A60810_RG_PCIE_SIGDET_VTH (0x3<<19) /* 20:19 */ +#define A60810_RG_PCIE_SIGDET_LPF (0x3<<17) /* 18:17 */ +#define A60810_RG_SSUSB_LFPS_MON_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_RXAFE_DCMON_SEL (0xf<<12) /* 15:12 */ +#define A60810_RG_SSUSB_RX_P1_ENTRY_PASS (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_RX_PD_RST (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_RX_PD_RST_PASS (0x1<<9) /* 9:9 */ + +/* U3D_regB */ +#define A60810_RG_SSUSB_CDR_RESERVE (0xff<<24) /* 31:24 */ +#define A60810_RG_SSUSB_RXAFE_RESERVE (0xff<<16) /* 23:16 */ +#define A60810_RG_PCIE_RX_RESERVE (0xff<<8) /* 15:8 */ +#define A60810_RG_SSUSB_VRT_25M_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_RX_PD_PICAL_SWAP (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_RX_DAC_MEAS_EN (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_MPX_SEL_L0 (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_LFPS_SLCOUT_SEL (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_LFPS_CMPOUT_SEL (0x1<<2) /* 2:2 */ +#define A60810_RG_PCIE_SIGDET_HF (0x3<<0) /* 1:0 */ + +/* U3D_regC */ +#define A60810_RGS_SSUSB_RX_DEBUG_RESERVE (0xff<<0) /* 7:0 */ + +/* OFFSET */ + +/* U3D_reg0 */ +#define A60810_RG_SSUSB_BGR_EN_OFST (31) +#define A60810_RG_SSUSB_CHPEN_OFST (30) +#define A60810_RG_SSUSB_BG_DIV_OFST (28) +#define A60810_RG_SSUSB_INTR_EN_OFST (26) +#define A60810_RG_SSUSB_MPX_EN_OFST (24) +#define A60810_RG_SSUSB_MPX_SEL_OFST (16) +#define A60810_RG_SSUSB_REF_EN_OFST (15) +#define A60810_RG_SSUSB_VRT_VREF_SEL_OFST (11) +#define A60810_RG_SSUSB_BG_MONEN_OFST (8) +#define A60810_RG_SSUSB_INT_BIAS_SEL_OFST (7) +#define A60810_RG_SSUSB_EXT_BIAS_SEL_OFST (6) +#define A60810_RG_PCIE_CLKDRV_OFFSET_OFST (2) +#define A60810_RG_PCIE_CLKDRV_SLEW_OFST (0) + +/* U3D_reg1 */ +#define A60810_RG_PCIE_CLKDRV_AMP_OFST (29) +#define A60810_RG_SSUSB_XTAL_TST_A2DCK_EN_OFST (28) +#define A60810_RG_SSUSB_XTAL_MON_EN_OFST (27) +#define A60810_RG_SSUSB_XTAL_HYS_OFST (26) +#define A60810_RG_SSUSB_XTAL_TOP_RESERVE_OFST (10) +#define A60810_RG_SSUSB_SYSPLL_PREDIV_OFST (8) +#define A60810_RG_SSUSB_SYSPLL_POSDIV_OFST (6) +#define A60810_RG_SSUSB_SYSPLL_VCO_DIV_SEL_OFST (5) +#define A60810_RG_SSUSB_SYSPLL_VOD_EN_OFST (4) +#define A60810_RG_SSUSB_SYSPLL_RST_DLY_OFST (2) +#define A60810_RG_SSUSB_SYSPLL_BLP_OFST (1) +#define A60810_RG_SSUSB_SYSPLL_BP_OFST (0) + +/* U3D_reg2 */ +#define A60810_RG_SSUSB_SYSPLL_BR_OFST (31) +#define A60810_RG_SSUSB_SYSPLL_BC_OFST (30) +#define A60810_RG_SSUSB_SYSPLL_MONCK_EN_OFST (29) +#define A60810_RG_SSUSB_SYSPLL_MONVC_EN_OFST (28) +#define A60810_RG_SSUSB_SYSPLL_MONREF_EN_OFST (27) +#define A60810_RG_SSUSB_SYSPLL_SDM_IFM_OFST (26) +#define A60810_RG_SSUSB_SYSPLL_SDM_OUT_OFST (25) +#define A60810_RG_SSUSB_SYSPLL_BACK_EN_OFST (24) + +/* U3D_reg3 */ +#define A60810_RG_SSUSB_SYSPLL_FBDIV_OFST (1) +#define A60810_RG_SSUSB_SYSPLL_HR_EN_OFST (0) + +/* U3D_reg4 */ +#define A60810_RG_SSUSB_SYSPLL_SDM_DI_EN_OFST (31) +#define A60810_RG_SSUSB_SYSPLL_SDM_DI_LS_OFST (29) +#define A60810_RG_SSUSB_SYSPLL_SDM_ORD_OFST (27) +#define A60810_RG_SSUSB_SYSPLL_SDM_MODE_OFST (25) +#define A60810_RG_SSUSB_SYSPLL_RESERVE_OFST (17) +#define A60810_RG_SSUSB_SYSPLL_TOP_RESERVE_OFST (1) + +/* U3D_reg5 */ +#define A60810_RG_SSUSB_TX250MCK_INVB_OFST (31) +#define A60810_RG_SSUSB_IDRV_ITAILOP_EN_OFST (30) +#define A60810_RG_SSUSB_IDRV_CALIB_OFST (24) +#define A60810_RG_SSUSB_IDEM_BIAS_OFST (20) +#define A60810_RG_SSUSB_TX_R50_FON_OFST (19) +#define A60810_RG_SSUSB_TX_SR_OFST (16) +#define A60810_RG_SSUSB_RXDET_RSEL_OFST (14) +#define A60810_RG_SSUSB_RXDET_UPDN_FORCE_OFST (13) +#define A60810_RG_SSUSB_RXDET_UPDN_SEL_OFST (12) +#define A60810_RG_SSUSB_RXDET_VTHSEL_L_OFST (10) +#define A60810_RG_SSUSB_RXDET_VTHSEL_H_OFST (8) +#define A60810_RG_SSUSB_CKMON_EN_OFST (7) +#define A60810_RG_SSUSB_TX_VLMON_EN_OFST (6) +#define A60810_RG_SSUSB_TX_VLMON_SEL_OFST (4) +#define A60810_RG_SSUSB_CKMON_SEL_OFST (0) + +/* U3D_reg6 */ +#define A60810_RG_SSUSB_TX_EIDLE_CM_OFST (28) +#define A60810_RG_SSUSB_RXLBTX_EN_OFST (27) +#define A60810_RG_SSUSB_TXLBRX_EN_OFST (26) +#define A60810_RG_SSUSB_RESERVE_OFST (16) +#define A60810_RG_SSUSB_PLL_POSDIV_OFST (14) +#define A60810_RG_SSUSB_PLL_AUTOK_LOAD_OFST (13) +#define A60810_RG_SSUSB_PLL_VOD_EN_OFST (12) +#define A60810_RG_SSUSB_PLL_MONREF_EN_OFST (11) +#define A60810_RG_SSUSB_PLL_MONCK_EN_OFST (10) +#define A60810_RG_SSUSB_PLL_MONVC_EN_OFST (9) +#define A60810_RG_SSUSB_PLL_RLH_EN_OFST (8) +#define A60810_RG_SSUSB_PLL_AUTOK_KS_OFST (6) +#define A60810_RG_SSUSB_PLL_AUTOK_KF_OFST (4) +#define A60810_RG_SSUSB_PLL_RST_DLY_OFST (2) + +/* U3D_reg7 */ +#define A60810_RG_SSUSB_PLL_RESERVE_OFST (16) +#define A60810_RG_SSUSB_PLL_SSC_PRD_OFST (0) + +/* U3D_reg8 */ +#define A60810_RG_SSUSB_PLL_SSC_PHASE_INI_OFST (31) +#define A60810_RG_SSUSB_PLL_SSC_TRI_EN_OFST (30) +#define A60810_RG_SSUSB_PLL_CLK_PH_INV_OFST (29) +#define A60810_RG_SSUSB_PLL_DDS_LPF_EN_OFST (28) +#define A60810_RG_SSUSB_PLL_DDS_RST_SEL_OFST (27) +#define A60810_RG_SSUSB_PLL_DDS_VADJ_OFST (26) +#define A60810_RG_SSUSB_PLL_DDS_MONEN_OFST (25) +#define A60810_RG_SSUSB_PLL_DDS_SEL_EXT_OFST (24) +#define A60810_RG_SSUSB_PLL_DDS_PI_PL_EN_OFST (23) +#define A60810_RG_SSUSB_PLL_DDS_FRAC_MUTE_OFST (20) +#define A60810_RG_SSUSB_PLL_DDS_HF_EN_OFST (19) +#define A60810_RG_SSUSB_PLL_DDS_C_OFST (16) +#define A60810_RG_SSUSB_PLL_DDS_PREDIV2_OFST (15) +#define A60810_RG_SSUSB_LFPS_LPF_OFST (13) + +/* U3D_reg9 */ +#define A60810_RG_SSUSB_CDR_PD_DIV_BYPASS_OFST (31) +#define A60810_RG_SSUSB_CDR_PD_DIV_SEL_OFST (30) +#define A60810_RG_SSUSB_CDR_CPBIAS_SEL_OFST (29) +#define A60810_RG_SSUSB_CDR_OSCDET_EN_OFST (28) +#define A60810_RG_SSUSB_CDR_MONMUX_OFST (27) +#define A60810_RG_SSUSB_CDR_RST_DLY_OFST (25) +#define A60810_RG_SSUSB_CDR_RSTB_MANUAL_OFST (24) +#define A60810_RG_SSUSB_CDR_BYPASS_OFST (22) +#define A60810_RG_SSUSB_CDR_PI_SLEW_OFST (20) +#define A60810_RG_SSUSB_CDR_EPEN_OFST (19) +#define A60810_RG_SSUSB_CDR_AUTOK_LOAD_OFST (18) +#define A60810_RG_SSUSB_CDR_MONEN_OFST (16) +#define A60810_RG_SSUSB_CDR_MONEN_DIG_OFST (15) +#define A60810_RG_SSUSB_CDR_REGOD_OFST (13) +#define A60810_RG_SSUSB_CDR_AUTOK_KS_OFST (11) +#define A60810_RG_SSUSB_CDR_AUTOK_KF_OFST (9) +#define A60810_RG_SSUSB_RX_DAC_EN_OFST (8) +#define A60810_RG_SSUSB_RX_DAC_PWD_OFST (7) +#define A60810_RG_SSUSB_EQ_CURSEL_OFST (6) +#define A60810_RG_SSUSB_RX_DAC_MUX_OFST (1) +#define A60810_RG_SSUSB_RX_R2T_EN_OFST (0) + +/* U3D_regA */ +#define A60810_RG_SSUSB_RX_T2R_EN_OFST (31) +#define A60810_RG_SSUSB_RX_50_LOWER_OFST (28) +#define A60810_RG_SSUSB_RX_50_TAR_OFST (26) +#define A60810_RG_SSUSB_RX_SW_CTRL_OFST (21) +#define A60810_RG_PCIE_SIGDET_VTH_OFST (19) +#define A60810_RG_PCIE_SIGDET_LPF_OFST (17) +#define A60810_RG_SSUSB_LFPS_MON_EN_OFST (16) +#define A60810_RG_SSUSB_RXAFE_DCMON_SEL_OFST (12) +#define A60810_RG_SSUSB_RX_P1_ENTRY_PASS_OFST (11) +#define A60810_RG_SSUSB_RX_PD_RST_OFST (10) +#define A60810_RG_SSUSB_RX_PD_RST_PASS_OFST (9) + +/* U3D_regB */ +#define A60810_RG_SSUSB_CDR_RESERVE_OFST (24) +#define A60810_RG_SSUSB_RXAFE_RESERVE_OFST (16) +#define A60810_RG_PCIE_RX_RESERVE_OFST (8) +#define A60810_RG_SSUSB_VRT_25M_EN_OFST (7) +#define A60810_RG_SSUSB_RX_PD_PICAL_SWAP_OFST (6) +#define A60810_RG_SSUSB_RX_DAC_MEAS_EN_OFST (5) +#define A60810_RG_SSUSB_MPX_SEL_L0_OFST (4) +#define A60810_RG_SSUSB_LFPS_SLCOUT_SEL_OFST (3) +#define A60810_RG_SSUSB_LFPS_CMPOUT_SEL_OFST (2) +#define A60810_RG_PCIE_SIGDET_HF_OFST (0) + +/* U3D_regC */ +#define A60810_RGS_SSUSB_RX_DEBUG_RESERVE_OFST (0) + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct u3phya_da_reg_a { + /* 0x0 */ + PHY_LE32 reg0; + PHY_LE32 reg1; + PHY_LE32 reg4; + PHY_LE32 reg5; + /* 0x10 */ + PHY_LE32 reg6; + PHY_LE32 reg7; + PHY_LE32 reg8; + PHY_LE32 reg9; + /* 0x20 */ + PHY_LE32 reg10; + PHY_LE32 reg12; + PHY_LE32 reg13; + PHY_LE32 reg14; + /* 0x30 */ + PHY_LE32 reg15; + PHY_LE32 reg16; + PHY_LE32 reg19; + PHY_LE32 reg20; + /* 0x40 */ + PHY_LE32 reg21; + PHY_LE32 reg23; + PHY_LE32 reg25; + PHY_LE32 reg26; + /* 0x50 */ + PHY_LE32 reg28; + PHY_LE32 reg29; + PHY_LE32 reg30; + PHY_LE32 reg31; + /* 0x60 */ + PHY_LE32 reg32; + PHY_LE32 reg33; +}; + +/* U3D_reg0 */ +#define A60810_RG_PCIE_SPEED_PE2D (0x1<<24) /* 24:24 */ +#define A60810_RG_PCIE_SPEED_PE2H (0x1<<23) /* 23:23 */ +#define A60810_RG_PCIE_SPEED_PE1D (0x1<<22) /* 22:22 */ +#define A60810_RG_PCIE_SPEED_PE1H (0x1<<21) /* 21:21 */ +#define A60810_RG_PCIE_SPEED_U3 (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE2D (0x3<<18) /* 19:18 */ +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE2H (0x3<<16) /* 17:16 */ +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE1D (0x3<<14) /* 15:14 */ +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE1H (0x3<<12) /* 13:12 */ +#define A60810_RG_SSUSB_XTAL_EXT_EN_U3 (0x3<<10) /* 11:10 */ +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE2D (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE2H (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE1D (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE1H (0x3<<2) /* 3:2 */ +#define A60810_RG_SSUSB_CDR_REFCK_SEL_U3 (0x3<<0) /* 1:0 */ + +/* U3D_reg1 */ +#define A60810_RG_USB20_REFCK_SEL_PE2D (0x1<<30) /* 30:30 */ +#define A60810_RG_USB20_REFCK_SEL_PE2H (0x1<<29) /* 29:29 */ +#define A60810_RG_USB20_REFCK_SEL_PE1D (0x1<<28) /* 28:28 */ +#define A60810_RG_USB20_REFCK_SEL_PE1H (0x1<<27) /* 27:27 */ +#define A60810_RG_USB20_REFCK_SEL_U3 (0x1<<26) /* 26:26 */ +#define A60810_RG_PCIE_REFCK_DIV4_PE2D (0x1<<25) /* 25:25 */ +#define A60810_RG_PCIE_REFCK_DIV4_PE2H (0x1<<24) /* 24:24 */ +#define A60810_RG_PCIE_REFCK_DIV4_PE1D (0x1<<18) /* 18:18 */ +#define A60810_RG_PCIE_REFCK_DIV4_PE1H (0x1<<17) /* 17:17 */ +#define A60810_RG_PCIE_REFCK_DIV4_U3 (0x1<<16) /* 16:16 */ +#define A60810_RG_PCIE_MODE_PE2D (0x1<<8) /* 8:8 */ +#define A60810_RG_PCIE_MODE_PE2H (0x1<<3) /* 3:3 */ +#define A60810_RG_PCIE_MODE_PE1D (0x1<<2) /* 2:2 */ +#define A60810_RG_PCIE_MODE_PE1H (0x1<<1) /* 1:1 */ +#define A60810_RG_PCIE_MODE_U3 (0x1<<0) /* 0:0 */ + +/* U3D_reg4 */ +#define A60810_RG_SSUSB_PLL_DIVEN_PE2D (0x7<<22) /* 24:22 */ +#define A60810_RG_SSUSB_PLL_DIVEN_PE2H (0x7<<19) /* 21:19 */ +#define A60810_RG_SSUSB_PLL_DIVEN_PE1D (0x7<<16) /* 18:16 */ +#define A60810_RG_SSUSB_PLL_DIVEN_PE1H (0x7<<13) /* 15:13 */ +#define A60810_RG_SSUSB_PLL_DIVEN_U3 (0x7<<10) /* 12:10 */ +#define A60810_RG_SSUSB_PLL_BC_PE2D (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_PLL_BC_PE2H (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_PLL_BC_PE1D (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_PLL_BC_PE1H (0x3<<2) /* 3:2 */ +#define A60810_RG_SSUSB_PLL_BC_U3 (0x3<<0) /* 1:0 */ + +/* U3D_reg5 */ +#define A60810_RG_SSUSB_PLL_BR_PE2D (0x3<<30) /* 31:30 */ +#define A60810_RG_SSUSB_PLL_BR_PE2H (0x3<<28) /* 29:28 */ +#define A60810_RG_SSUSB_PLL_BR_PE1D (0x3<<26) /* 27:26 */ +#define A60810_RG_SSUSB_PLL_BR_PE1H (0x3<<24) /* 25:24 */ +#define A60810_RG_SSUSB_PLL_BR_U3 (0x3<<22) /* 23:22 */ +#define A60810_RG_SSUSB_PLL_IC_PE2D (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_PLL_IC_PE2H (0xf<<12) /* 15:12 */ +#define A60810_RG_SSUSB_PLL_IC_PE1D (0xf<<8) /* 11:8 */ +#define A60810_RG_SSUSB_PLL_IC_PE1H (0xf<<4) /* 7:4 */ +#define A60810_RG_SSUSB_PLL_IC_U3 (0xf<<0) /* 3:0 */ + +/* U3D_reg6 */ +#define A60810_RG_SSUSB_PLL_IR_PE2D (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_PLL_IR_PE2H (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_PLL_IR_PE1D (0xf<<8) /* 11:8 */ +#define A60810_RG_SSUSB_PLL_IR_PE1H (0xf<<4) /* 7:4 */ +#define A60810_RG_SSUSB_PLL_IR_U3 (0xf<<0) /* 3:0 */ + +/* U3D_reg7 */ +#define A60810_RG_SSUSB_PLL_BP_PE2D (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_PLL_BP_PE2H (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_PLL_BP_PE1D (0xf<<8) /* 11:8 */ +#define A60810_RG_SSUSB_PLL_BP_PE1H (0xf<<4) /* 7:4 */ +#define A60810_RG_SSUSB_PLL_BP_U3 (0xf<<0) /* 3:0 */ + +/* U3D_reg8 */ +#define A60810_RG_SSUSB_PLL_FBKSEL_PE2D (0x3<<24) /* 25:24 */ +#define A60810_RG_SSUSB_PLL_FBKSEL_PE2H (0x3<<16) /* 17:16 */ +#define A60810_RG_SSUSB_PLL_FBKSEL_PE1D (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_PLL_FBKSEL_PE1H (0x3<<2) /* 3:2 */ +#define A60810_RG_SSUSB_PLL_FBKSEL_U3 (0x3<<0) /* 1:0 */ + +/* U3D_reg9 */ +#define A60810_RG_SSUSB_PLL_FBKDIV_PE2H (0x7f<<24) /* 30:24 */ +#define A60810_RG_SSUSB_PLL_FBKDIV_PE1D (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_PLL_FBKDIV_PE1H (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_PLL_FBKDIV_U3 (0x7f<<0) /* 6:0 */ + +/* U3D_reg10 */ +#define A60810_RG_SSUSB_PLL_PREDIV_PE2D (0x3<<26) /* 27:26 */ +#define A60810_RG_SSUSB_PLL_PREDIV_PE2H (0x3<<24) /* 25:24 */ +#define A60810_RG_SSUSB_PLL_PREDIV_PE1D (0x3<<18) /* 19:18 */ +#define A60810_RG_SSUSB_PLL_PREDIV_PE1H (0x3<<16) /* 17:16 */ +#define A60810_RG_SSUSB_PLL_PREDIV_U3 (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_PLL_FBKDIV_PE2D (0x7f<<0) /* 6:0 */ + +/* U3D_reg12 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_U3 (0x7fffffff<<0) /* 30:0 */ + +/* U3D_reg13 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE1H (0x7fffffff<<0) /* 30:0 */ + +/* U3D_reg14 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE1D (0x7fffffff<<0) /* 30:0 */ + +/* U3D_reg15 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE2H (0x7fffffff<<0) /* 30:0 */ + +/* U3D_reg16 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE2D (0x7fffffff<<0) /* 30:0 */ + +/* U3D_reg19 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_U3 (0xffff<<0) /* 15:0 */ + +/* U3D_reg20 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE2H (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1D (0xffff<<0) /* 15:0 */ + +/* U3D_reg21 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_U3 (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE2D (0xffff<<0) /* 15:0 */ + +/* U3D_reg23 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE1D (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE1H (0xffff<<0) /* 15:0 */ + +/* U3D_reg25 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE2D (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE2H (0xffff<<0) /* 15:0 */ + +/* U3D_reg26 */ +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE2D (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE2H (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE1D (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE1H (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_PLL_REFCKDIV_U3 (0x1<<0) /* 0:0 */ + +/* U3D_reg28 */ +#define A60810_RG_SSUSB_CDR_BPA_PE2D (0x3<<24) /* 25:24 */ +#define A60810_RG_SSUSB_CDR_BPA_PE2H (0x3<<16) /* 17:16 */ +#define A60810_RG_SSUSB_CDR_BPA_PE1D (0x3<<10) /* 11:10 */ +#define A60810_RG_SSUSB_CDR_BPA_PE1H (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_CDR_BPA_U3 (0x3<<0) /* 1:0 */ + +/* U3D_reg29 */ +#define A60810_RG_SSUSB_CDR_BPB_PE2D (0x7<<24) /* 26:24 */ +#define A60810_RG_SSUSB_CDR_BPB_PE2H (0x7<<16) /* 18:16 */ +#define A60810_RG_SSUSB_CDR_BPB_PE1D (0x7<<6) /* 8:6 */ +#define A60810_RG_SSUSB_CDR_BPB_PE1H (0x7<<3) /* 5:3 */ +#define A60810_RG_SSUSB_CDR_BPB_U3 (0x7<<0) /* 2:0 */ + +/* U3D_reg30 */ +#define A60810_RG_SSUSB_CDR_BR_PE2D (0x7<<24) /* 26:24 */ +#define A60810_RG_SSUSB_CDR_BR_PE2H (0x7<<16) /* 18:16 */ +#define A60810_RG_SSUSB_CDR_BR_PE1D (0x7<<6) /* 8:6 */ +#define A60810_RG_SSUSB_CDR_BR_PE1H (0x7<<3) /* 5:3 */ +#define A60810_RG_SSUSB_CDR_BR_U3 (0x7<<0) /* 2:0 */ + +/* U3D_reg31 */ +#define A60810_RG_SSUSB_CDR_FBDIV_PE2H (0x7f<<24) /* 30:24 */ +#define A60810_RG_SSUSB_CDR_FBDIV_PE1D (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_CDR_FBDIV_PE1H (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_CDR_FBDIV_U3 (0x7f<<0) /* 6:0 */ + +/* U3D_reg32 */ +#define A60810_RG_SSUSB_EQ_RSTEP1_PE2D (0x3<<30) /* 31:30 */ +#define A60810_RG_SSUSB_EQ_RSTEP1_PE2H (0x3<<28) /* 29:28 */ +#define A60810_RG_SSUSB_EQ_RSTEP1_PE1D (0x3<<26) /* 27:26 */ +#define A60810_RG_SSUSB_EQ_RSTEP1_PE1H (0x3<<24) /* 25:24 */ +#define A60810_RG_SSUSB_EQ_RSTEP1_U3 (0x3<<22) /* 23:22 */ +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE2D (0x3<<20) /* 21:20 */ +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE2H (0x3<<18) /* 19:18 */ +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE1D (0x3<<16) /* 17:16 */ +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE1H (0x3<<14) /* 15:14 */ +#define A60810_RG_SSUSB_LFPS_DEGLITCH_U3 (0x3<<12) /* 13:12 */ +#define A60810_RG_SSUSB_CDR_KVSEL_PE2D (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_CDR_KVSEL_PE2H (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_CDR_KVSEL_PE1D (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_CDR_KVSEL_PE1H (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_CDR_KVSEL_U3 (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_CDR_FBDIV_PE2D (0x7f<<0) /* 6:0 */ + +/* U3D_reg33 */ +#define A60810_RG_SSUSB_RX_CMPWD_PE2D (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_RX_CMPWD_PE2H (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_RX_CMPWD_PE1D (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_RX_CMPWD_PE1H (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_RX_CMPWD_U3 (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_EQ_RSTEP2_PE2D (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_EQ_RSTEP2_PE2H (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_EQ_RSTEP2_PE1D (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_EQ_RSTEP2_PE1H (0x3<<2) /* 3:2 */ +#define A60810_RG_SSUSB_EQ_RSTEP2_U3 (0x3<<0) /* 1:0 */ + +/* OFFSET DEFINITION */ + +/* U3D_reg0 */ +#define A60810_RG_PCIE_SPEED_PE2D_OFST (24) +#define A60810_RG_PCIE_SPEED_PE2H_OFST (23) +#define A60810_RG_PCIE_SPEED_PE1D_OFST (22) +#define A60810_RG_PCIE_SPEED_PE1H_OFST (21) +#define A60810_RG_PCIE_SPEED_U3_OFST (20) +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE2D_OFST (18) +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE2H_OFST (16) +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE1D_OFST (14) +#define A60810_RG_SSUSB_XTAL_EXT_EN_PE1H_OFST (12) +#define A60810_RG_SSUSB_XTAL_EXT_EN_U3_OFST (10) +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE2D_OFST (8) +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE2H_OFST (6) +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE1D_OFST (4) +#define A60810_RG_SSUSB_CDR_REFCK_SEL_PE1H_OFST (2) +#define A60810_RG_SSUSB_CDR_REFCK_SEL_U3_OFST (0) + +/* U3D_reg1 */ +#define A60810_RG_USB20_REFCK_SEL_PE2D_OFST (30) +#define A60810_RG_USB20_REFCK_SEL_PE2H_OFST (29) +#define A60810_RG_USB20_REFCK_SEL_PE1D_OFST (28) +#define A60810_RG_USB20_REFCK_SEL_PE1H_OFST (27) +#define A60810_RG_USB20_REFCK_SEL_U3_OFST (26) +#define A60810_RG_PCIE_REFCK_DIV4_PE2D_OFST (25) +#define A60810_RG_PCIE_REFCK_DIV4_PE2H_OFST (24) +#define A60810_RG_PCIE_REFCK_DIV4_PE1D_OFST (18) +#define A60810_RG_PCIE_REFCK_DIV4_PE1H_OFST (17) +#define A60810_RG_PCIE_REFCK_DIV4_U3_OFST (16) +#define A60810_RG_PCIE_MODE_PE2D_OFST (8) +#define A60810_RG_PCIE_MODE_PE2H_OFST (3) +#define A60810_RG_PCIE_MODE_PE1D_OFST (2) +#define A60810_RG_PCIE_MODE_PE1H_OFST (1) +#define A60810_RG_PCIE_MODE_U3_OFST (0) + +/* U3D_reg4 */ +#define A60810_RG_SSUSB_PLL_DIVEN_PE2D_OFST (22) +#define A60810_RG_SSUSB_PLL_DIVEN_PE2H_OFST (19) +#define A60810_RG_SSUSB_PLL_DIVEN_PE1D_OFST (16) +#define A60810_RG_SSUSB_PLL_DIVEN_PE1H_OFST (13) +#define A60810_RG_SSUSB_PLL_DIVEN_U3_OFST (10) +#define A60810_RG_SSUSB_PLL_BC_PE2D_OFST (8) +#define A60810_RG_SSUSB_PLL_BC_PE2H_OFST (6) +#define A60810_RG_SSUSB_PLL_BC_PE1D_OFST (4) +#define A60810_RG_SSUSB_PLL_BC_PE1H_OFST (2) +#define A60810_RG_SSUSB_PLL_BC_U3_OFST (0) + +/* U3D_reg5 */ +#define A60810_RG_SSUSB_PLL_BR_PE2D_OFST (30) +#define A60810_RG_SSUSB_PLL_BR_PE2H_OFST (28) +#define A60810_RG_SSUSB_PLL_BR_PE1D_OFST (26) +#define A60810_RG_SSUSB_PLL_BR_PE1H_OFST (24) +#define A60810_RG_SSUSB_PLL_BR_U3_OFST (22) +#define A60810_RG_SSUSB_PLL_IC_PE2D_OFST (16) +#define A60810_RG_SSUSB_PLL_IC_PE2H_OFST (12) +#define A60810_RG_SSUSB_PLL_IC_PE1D_OFST (8) +#define A60810_RG_SSUSB_PLL_IC_PE1H_OFST (4) +#define A60810_RG_SSUSB_PLL_IC_U3_OFST (0) + +/* U3D_reg6 */ +#define A60810_RG_SSUSB_PLL_IR_PE2D_OFST (24) +#define A60810_RG_SSUSB_PLL_IR_PE2H_OFST (16) +#define A60810_RG_SSUSB_PLL_IR_PE1D_OFST (8) +#define A60810_RG_SSUSB_PLL_IR_PE1H_OFST (4) +#define A60810_RG_SSUSB_PLL_IR_U3_OFST (0) + +/* U3D_reg7 */ +#define A60810_RG_SSUSB_PLL_BP_PE2D_OFST (24) +#define A60810_RG_SSUSB_PLL_BP_PE2H_OFST (16) +#define A60810_RG_SSUSB_PLL_BP_PE1D_OFST (8) +#define A60810_RG_SSUSB_PLL_BP_PE1H_OFST (4) +#define A60810_RG_SSUSB_PLL_BP_U3_OFST (0) + +/* U3D_reg8 */ +#define A60810_RG_SSUSB_PLL_FBKSEL_PE2D_OFST (24) +#define A60810_RG_SSUSB_PLL_FBKSEL_PE2H_OFST (16) +#define A60810_RG_SSUSB_PLL_FBKSEL_PE1D_OFST (8) +#define A60810_RG_SSUSB_PLL_FBKSEL_PE1H_OFST (2) +#define A60810_RG_SSUSB_PLL_FBKSEL_U3_OFST (0) + +/* U3D_reg9 */ +#define A60810_RG_SSUSB_PLL_FBKDIV_PE2H_OFST (24) +#define A60810_RG_SSUSB_PLL_FBKDIV_PE1D_OFST (16) +#define A60810_RG_SSUSB_PLL_FBKDIV_PE1H_OFST (8) +#define A60810_RG_SSUSB_PLL_FBKDIV_U3_OFST (0) + +/* U3D_reg10 */ +#define A60810_RG_SSUSB_PLL_PREDIV_PE2D_OFST (26) +#define A60810_RG_SSUSB_PLL_PREDIV_PE2H_OFST (24) +#define A60810_RG_SSUSB_PLL_PREDIV_PE1D_OFST (18) +#define A60810_RG_SSUSB_PLL_PREDIV_PE1H_OFST (16) +#define A60810_RG_SSUSB_PLL_PREDIV_U3_OFST (8) +#define A60810_RG_SSUSB_PLL_FBKDIV_PE2D_OFST (0) + +/* U3D_reg12 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_U3_OFST (0) + +/* U3D_reg13 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE1H_OFST (0) + +/* U3D_reg14 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE1D_OFST (0) + +/* U3D_reg15 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE2H_OFST (0) + +/* U3D_reg16 */ +#define A60810_RG_SSUSB_PLL_PCW_NCPO_PE2D_OFST (0) + +/* U3D_reg19 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H_OFST (16) +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_U3_OFST (0) + +/* U3D_reg20 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE2H_OFST (16) +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1D_OFST (0) + +/* U3D_reg21 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_U3_OFST (16) +#define A60810_RG_SSUSB_PLL_SSC_DELTA1_PE2D_OFST (0) + +/* U3D_reg23 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE1D_OFST (16) +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE1H_OFST (0) + +/* U3D_reg25 */ +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE2D_OFST (16) +#define A60810_RG_SSUSB_PLL_SSC_DELTA_PE2H_OFST (0) + +/* U3D_reg26 */ +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE2D_OFST (25) +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE2H_OFST (24) +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE1D_OFST (16) +#define A60810_RG_SSUSB_PLL_REFCKDIV_PE1H_OFST (8) +#define A60810_RG_SSUSB_PLL_REFCKDIV_U3_OFST (0) + +/* U3D_reg28 */ +#define A60810_RG_SSUSB_CDR_BPA_PE2D_OFST (24) +#define A60810_RG_SSUSB_CDR_BPA_PE2H_OFST (16) +#define A60810_RG_SSUSB_CDR_BPA_PE1D_OFST (10) +#define A60810_RG_SSUSB_CDR_BPA_PE1H_OFST (8) +#define A60810_RG_SSUSB_CDR_BPA_U3_OFST (0) + +/* U3D_reg29 */ +#define A60810_RG_SSUSB_CDR_BPB_PE2D_OFST (24) +#define A60810_RG_SSUSB_CDR_BPB_PE2H_OFST (16) +#define A60810_RG_SSUSB_CDR_BPB_PE1D_OFST (6) +#define A60810_RG_SSUSB_CDR_BPB_PE1H_OFST (3) +#define A60810_RG_SSUSB_CDR_BPB_U3_OFST (0) + +/* U3D_reg30 */ +#define A60810_RG_SSUSB_CDR_BR_PE2D_OFST (24) +#define A60810_RG_SSUSB_CDR_BR_PE2H_OFST (16) +#define A60810_RG_SSUSB_CDR_BR_PE1D_OFST (6) +#define A60810_RG_SSUSB_CDR_BR_PE1H_OFST (3) +#define A60810_RG_SSUSB_CDR_BR_U3_OFST (0) + +/* U3D_reg31 */ +#define A60810_RG_SSUSB_CDR_FBDIV_PE2H_OFST (24) +#define A60810_RG_SSUSB_CDR_FBDIV_PE1D_OFST (16) +#define A60810_RG_SSUSB_CDR_FBDIV_PE1H_OFST (8) +#define A60810_RG_SSUSB_CDR_FBDIV_U3_OFST (0) + +/* U3D_reg32 */ +#define A60810_RG_SSUSB_EQ_RSTEP1_PE2D_OFST (30) +#define A60810_RG_SSUSB_EQ_RSTEP1_PE2H_OFST (28) +#define A60810_RG_SSUSB_EQ_RSTEP1_PE1D_OFST (26) +#define A60810_RG_SSUSB_EQ_RSTEP1_PE1H_OFST (24) +#define A60810_RG_SSUSB_EQ_RSTEP1_U3_OFST (22) +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE2D_OFST (20) +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE2H_OFST (18) +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE1D_OFST (16) +#define A60810_RG_SSUSB_LFPS_DEGLITCH_PE1H_OFST (14) +#define A60810_RG_SSUSB_LFPS_DEGLITCH_U3_OFST (12) +#define A60810_RG_SSUSB_CDR_KVSEL_PE2D_OFST (11) +#define A60810_RG_SSUSB_CDR_KVSEL_PE2H_OFST (10) +#define A60810_RG_SSUSB_CDR_KVSEL_PE1D_OFST (9) +#define A60810_RG_SSUSB_CDR_KVSEL_PE1H_OFST (8) +#define A60810_RG_SSUSB_CDR_KVSEL_U3_OFST (7) +#define A60810_RG_SSUSB_CDR_FBDIV_PE2D_OFST (0) + +/* U3D_reg33 */ +#define A60810_RG_SSUSB_RX_CMPWD_PE2D_OFST (26) +#define A60810_RG_SSUSB_RX_CMPWD_PE2H_OFST (25) +#define A60810_RG_SSUSB_RX_CMPWD_PE1D_OFST (24) +#define A60810_RG_SSUSB_RX_CMPWD_PE1H_OFST (23) +#define A60810_RG_SSUSB_RX_CMPWD_U3_OFST (16) +#define A60810_RG_SSUSB_EQ_RSTEP2_PE2D_OFST (8) +#define A60810_RG_SSUSB_EQ_RSTEP2_PE2H_OFST (6) +#define A60810_RG_SSUSB_EQ_RSTEP2_PE1D_OFST (4) +#define A60810_RG_SSUSB_EQ_RSTEP2_PE1H_OFST (2) +#define A60810_RG_SSUSB_EQ_RSTEP2_U3_OFST (0) + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct u3phyd_reg_a { + /* 0x0 */ + PHY_LE32 phyd_mix0; + PHY_LE32 phyd_mix1; + PHY_LE32 phyd_lfps0; + PHY_LE32 phyd_lfps1; + /* 0x10 */ + PHY_LE32 phyd_impcal0; + PHY_LE32 phyd_impcal1; + PHY_LE32 phyd_txpll0; + PHY_LE32 phyd_txpll1; + /* 0x20 */ + PHY_LE32 phyd_txpll2; + PHY_LE32 phyd_fl0; + PHY_LE32 phyd_mix2; + PHY_LE32 phyd_rx0; + /* 0x30 */ + PHY_LE32 phyd_t2rlb; + PHY_LE32 phyd_cppat; + PHY_LE32 phyd_mix3; + PHY_LE32 phyd_ebufctl; + /* 0x40 */ + PHY_LE32 phyd_pipe0; + PHY_LE32 phyd_pipe1; + PHY_LE32 phyd_mix4; + PHY_LE32 phyd_ckgen0; + /* 0x50 */ + PHY_LE32 phyd_mix5; + PHY_LE32 phyd_reserved; + PHY_LE32 phyd_cdr0; + PHY_LE32 phyd_cdr1; + /* 0x60 */ + PHY_LE32 phyd_pll_0; + PHY_LE32 phyd_pll_1; + PHY_LE32 phyd_bcn_det_1; + PHY_LE32 phyd_bcn_det_2; + /* 0x70 */ + PHY_LE32 eq0; + PHY_LE32 eq1; + PHY_LE32 eq2; + PHY_LE32 eq3; + /* 0x80 */ + PHY_LE32 eq_eye0; + PHY_LE32 eq_eye1; + PHY_LE32 eq_eye2; + PHY_LE32 eq_dfe0; + /* 0x90 */ + PHY_LE32 eq_dfe1; + PHY_LE32 eq_dfe2; + PHY_LE32 eq_dfe3; + PHY_LE32 reserve0; + /* 0xa0 */ + PHY_LE32 phyd_mon0; + PHY_LE32 phyd_mon1; + PHY_LE32 phyd_mon2; + PHY_LE32 phyd_mon3; + /* 0xb0 */ + PHY_LE32 phyd_mon4; + PHY_LE32 phyd_mon5; + PHY_LE32 phyd_mon6; + PHY_LE32 phyd_mon7; + /* 0xc0 */ + PHY_LE32 phya_rx_mon0; + PHY_LE32 phya_rx_mon1; + PHY_LE32 phya_rx_mon2; + PHY_LE32 phya_rx_mon3; + /* 0xd0 */ + PHY_LE32 phya_rx_mon4; + PHY_LE32 phya_rx_mon5; + PHY_LE32 phyd_cppat2; + PHY_LE32 eq_eye3; + /* 0xe0 */ + PHY_LE32 kband_out; + PHY_LE32 kband_out1; +}; + +/* U3D_PHYD_MIX0 */ +#define A60810_RG_SSUSB_P_P3_TX_NG (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_TSEQ_EN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_TSEQ_POLEN (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_TSEQ_POL (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_P_P3_PCLK_NG (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_TSEQ_TH (0x7<<24) /* 26:24 */ +#define A60810_RG_SSUSB_PRBS_BERTH (0xff<<16) /* 23:16 */ +#define A60810_RG_SSUSB_DISABLE_PHY_U2_ON (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_DISABLE_PHY_U2_OFF (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_PRBS_EN (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_BPSLOCK (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_RTCOMCNT (0xf<<8) /* 11:8 */ +#define A60810_RG_SSUSB_COMCNT (0xf<<4) /* 7:4 */ +#define A60810_RG_SSUSB_PRBSEL_CALIB (0xf<<0) /* 3:0 */ + +/* U3D_PHYD_MIX1 */ +#define A60810_RG_SSUSB_SLEEP_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_PRBSEL_PCS (0x7<<28) /* 30:28 */ +#define A60810_RG_SSUSB_TXLFPS_PRD (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_P_RX_P0S_CK (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_P_TX_P0S_CK (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_PDNCTL (0x3f<<16) /* 21:16 */ +#define A60810_RG_SSUSB_TX_DRV_EN (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_TX_DRV_SEL (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_TX_DRV_DLY (0x3f<<8) /* 13:8 */ +#define A60810_RG_SSUSB_BERT_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_SCP_TH (0x7<<4) /* 6:4 */ +#define A60810_RG_SSUSB_SCP_EN (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_RXANSIDEC_TEST (0x7<<0) /* 2:0 */ + +/* U3D_PHYD_LFPS0 */ +#define A60810_RG_SSUSB_LFPS_PWD (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_FORCE_LFPS_PWD (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_RXLFPS_OVF (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_P3_ENTRY_SEL (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_P3_ENTRY (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_RXLFPS_CDRSEL (0x3<<20) /* 21:20 */ +#define A60810_RG_SSUSB_RXLFPS_CDRTH (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_LOCK5G_BLOCK (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_TFIFO_EXT_D_SEL (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_TFIFO_NO_EXTEND (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_RXLFPS_LOB (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_TXLFPS_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_TXLFPS_SEL (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_RXLFPS_CDRLOCK (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_RXLFPS_UPB (0x1f<<0) /* 4:0 */ + +/* U3D_PHYD_LFPS1 */ +#define A60810_RG_SSUSB_RX_IMP_BIAS (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_TX_IMP_BIAS (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_FWAKE_TH (0x3f<<16) /* 21:16 */ +#define A60810_RG_SSUSB_P1_ENTRY_SEL (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_P1_ENTRY (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_RXLFPS_UDF (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_RXLFPS_P0IDLETH (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_IMPCAL0 */ +#define A60810_RG_SSUSB_FORCE_TX_IMPSEL (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_TX_IMPCAL_EN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_FORCE_TX_IMPCAL_EN (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_TX_IMPSEL (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_TX_IMPCAL_CALCYC (0x3f<<16) /* 21:16 */ +#define A60810_RG_SSUSB_TX_IMPCAL_STBCYC (0x1f<<10) /* 14:10 */ +#define A60810_RG_SSUSB_TX_IMPCAL_CYCCNT (0x3ff<<0) /* 9:0 */ + +/* U3D_PHYD_IMPCAL1 */ +#define A60810_RG_SSUSB_FORCE_RX_IMPSEL (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_RX_IMPCAL_EN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_FORCE_RX_IMPCAL_EN (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_RX_IMPSEL (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_RX_IMPCAL_CALCYC (0x3f<<16) /* 21:16 */ +#define A60810_RG_SSUSB_RX_IMPCAL_STBCYC (0x1f<<10) /* 14:10 */ +#define A60810_RG_SSUSB_RX_IMPCAL_CYCCNT (0x3ff<<0) /* 9:0 */ + +/* U3D_PHYD_TXPLL0 */ +#define A60810_RG_SSUSB_TXPLL_DDSEN_CYC (0x1f<<27) /* 31:27 */ +#define A60810_RG_SSUSB_TXPLL_ON (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_FORCE_TXPLLON (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_TXPLL_STBCYC (0x1ff<<16) /* 24:16 */ +#define A60810_RG_SSUSB_TXPLL_NCPOCHG_CYC (0xf<<12) /* 15:12 */ +#define A60810_RG_SSUSB_TXPLL_NCPOEN_CYC (0x3<<10) /* 11:10 */ +#define A60810_RG_SSUSB_TXPLL_DDSRSTB_CYC (0x7<<0) /* 2:0 */ + +/* U3D_PHYD_TXPLL1 */ +#define A60810_RG_SSUSB_PLL_NCPO_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_PLL_FIFO_START_MAN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_PLL_NCPO_CHG (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_PLL_DDS_RSTB (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_PLL_DDS_PWDB (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_PLL_DDSEN (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_PLL_AUTOK_VCO (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_PLL_PWD (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_RX_AFE_PWD (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_PLL_TCADJ (0x3f<<16) /* 21:16 */ +#define A60810_RG_SSUSB_FORCE_CDR_TCADJ (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_FORCE_CDR_AUTOK_VCO (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_FORCE_CDR_PWD (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_FORCE_PLL_NCPO_EN (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_FORCE_PLL_FIFO_START_MAN (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_FORCE_PLL_NCPO_CHG (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_FORCE_PLL_DDS_RSTB (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_FORCE_PLL_DDS_PWDB (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_FORCE_PLL_DDSEN (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_FORCE_PLL_TCADJ (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_FORCE_PLL_AUTOK_VCO (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_FORCE_PLL_PWD (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_FLT_1_DISPERR_B (0x1<<2) /* 2:2 */ + +/* U3D_PHYD_TXPLL2 */ +#define A60810_RG_SSUSB_TX_LFPS_EN (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_FORCE_TX_LFPS_EN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_TX_LFPS (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_FORCE_TX_LFPS (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_RXPLL_STB (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_TXPLL_STB (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_FORCE_RXPLL_STB (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_FORCE_TXPLL_STB (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_RXPLL_REFCKSEL (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_RXPLL_STBMODE (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_RXPLL_ON (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_FORCE_RXPLLON (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_FORCE_RX_AFE_PWD (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_CDR_AUTOK_VCO (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_CDR_PWD (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_CDR_TCADJ (0x3f<<0) /* 5:0 */ + +/* U3D_PHYD_FL0 */ +#define A60810_RG_SSUSB_RX_FL_TARGET (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RX_FL_CYCLECNT (0xffff<<0) /* 15:0 */ + +/* U3D_PHYD_MIX2 */ +#define A60810_RG_SSUSB_RX_EQ_RST (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_RX_EQ_RST_SEL (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_RXVAL_RST (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_RXVAL_CNT (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_CDROS_EN (0x1<<18) /* 18:18 */ +#define A60810_RG_SSUSB_CDR_LCKOP (0x3<<16) /* 17:16 */ +#define A60810_RG_SSUSB_RX_FL_LOCKTH (0xf<<8) /* 11:8 */ +#define A60810_RG_SSUSB_RX_FL_OFFSET (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_RX0 */ +#define A60810_RG_SSUSB_T2RLB_BERTH (0xff<<24) /* 31:24 */ +#define A60810_RG_SSUSB_T2RLB_PAT (0xff<<16) /* 23:16 */ +#define A60810_RG_SSUSB_T2RLB_EN (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_T2RLB_BPSCRAMB (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_T2RLB_SERIAL (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_T2RLB_MODE (0x3<<11) /* 12:11 */ +#define A60810_RG_SSUSB_RX_SAOSC_EN (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_RX_SAOSC_EN_SEL (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_RX_DFE_OPTION (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_RX_DFE_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_RX_DFE_EN_SEL (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_RX_EQ_EN (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_RX_EQ_EN_SEL (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_RX_SAOSC_RST (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_RX_SAOSC_RST_SEL (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_RX_DFE_RST (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_RX_DFE_RST_SEL (0x1<<0) /* 0:0 */ + +/* U3D_PHYD_T2RLB */ +#define A60810_RG_SSUSB_EQTRAIN_CH_MODE (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_PRB_OUT_CPPAT (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_BPANSIENC (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_VALID_EN (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_EBUF_SRST (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_K_EMP (0xf<<20) /* 23:20 */ +#define A60810_RG_SSUSB_K_FUL (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_T2RLB_BDATRST (0xf<<12) /* 15:12 */ +#define A60810_RG_SSUSB_P_T2RLB_SKP_EN (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_T2RLB_PATMODE (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_T2RLB_TSEQCNT (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_CPPAT */ +#define A60810_RG_SSUSB_CPPAT_PROGRAM_EN (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_CPPAT_TOZ (0x3<<21) /* 22:21 */ +#define A60810_RG_SSUSB_CPPAT_PRBS_EN (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_CPPAT_OUT_TMP2 (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_CPPAT_OUT_TMP1 (0xff<<8) /* 15:8 */ +#define A60810_RG_SSUSB_CPPAT_OUT_TMP0 (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_MIX3 */ +#define A60810_RG_SSUSB_CDR_TCADJ_MINUS (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_P_CDROS_EN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_P_P2_TX_DRV_DIS (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_CDR_TCADJ_OFFSET (0x7<<24) /* 26:24 */ +#define A60810_RG_SSUSB_PLL_TCADJ_MINUS (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_FORCE_PLL_BIAS_LPF_EN (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_PLL_BIAS_LPF_EN (0x1<<19) /* 19:19 */ +#define A60810_RG_SSUSB_PLL_TCADJ_OFFSET (0x7<<16) /* 18:16 */ +#define A60810_RG_SSUSB_FORCE_PLL_SSCEN (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_PLL_SSCEN (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_FORCE_CDR_PI_PWD (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_CDR_PI_PWD (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_CDR_PI_MODE (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_TXPLL_SSCEN_CYC (0x3ff<<0) /* 9:0 */ + +/* U3D_PHYD_EBUFCTL */ +#define A60810_RG_SSUSB_EBUFCTL (0xffffffff<<0) /* 31:0 */ + +/* U3D_PHYD_PIPE0 */ +#define A60810_RG_SSUSB_RXTERMINATION (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_RXEQTRAINING (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_RXPOLARITY (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_TXDEEMPH (0x3<<26) /* 27:26 */ +#define A60810_RG_SSUSB_POWERDOWN (0x3<<24) /* 25:24 */ +#define A60810_RG_SSUSB_TXONESZEROS (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_TXELECIDLE (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_TXDETECTRX (0x1<<21) /* 21:21 */ +#define A60810_RG_SSUSB_PIPE_SEL (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_TXDATAK (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_CDR_STABLE_SEL (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_CDR_STABLE (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_CDR_RSTB_SEL (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_CDR_RSTB (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_FRC_PIPE_POWERDOWN (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_P_TXBCN_DIS (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_P_ERROR_SEL (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_TXMARGIN (0x7<<1) /* 3:1 */ +#define A60810_RG_SSUSB_TXCOMPLIANCE (0x1<<0) /* 0:0 */ + +/* U3D_PHYD_PIPE1 */ +#define A60810_RG_SSUSB_TXDATA (0xffffffff<<0) /* 31:0 */ + +/* U3D_PHYD_MIX4 */ +#define A60810_RG_SSUSB_CDROS_CNT (0x3f<<24) /* 29:24 */ +#define A60810_RG_SSUSB_T2RLB_BER_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_T2RLB_BER_RATE (0xffff<<0) /* 15:0 */ + +/* U3D_PHYD_CKGEN0 */ +#define A60810_RG_SSUSB_RFIFO_IMPLAT (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_TFIFO_PSEL (0x7<<24) /* 26:24 */ +#define A60810_RG_SSUSB_CKGEN_PSEL (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_RXCK_INV (0x1<<0) /* 0:0 */ + +/* U3D_PHYD_MIX5 */ +#define A60810_RG_SSUSB_PRB_SEL (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RXPLL_STBCYC (0x7ff<<0) /* 10:0 */ + +/* U3D_PHYD_RESERVED */ +#define A60810_RG_SSUSB_PHYD_RESERVE (0xffffffff<<0) /* 31:0 */ + +/* U3D_PHYD_CDR0 */ +#define A60810_RG_SSUSB_CDR_BIC_LTR (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_CDR_BIC_LTD0 (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_CDR_BC_LTD1 (0x1f<<16) /* 20:16 */ +#define A60810_RG_SSUSB_CDR_BC_LTR (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_CDR_BC_LTD0 (0x1f<<0) /* 4:0 */ + +/* U3D_PHYD_CDR1 */ +#define A60810_RG_SSUSB_CDR_BIR_LTD1 (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_CDR_BIR_LTR (0x1f<<16) /* 20:16 */ +#define A60810_RG_SSUSB_CDR_BIR_LTD0 (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_CDR_BW_SEL (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_CDR_BIC_LTD1 (0xf<<0) /* 3:0 */ + +/* U3D_PHYD_PLL_0 */ +#define A60810_RG_SSUSB_FORCE_CDR_BAND_5G (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_FORCE_CDR_BAND_2P5G (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_FORCE_PLL_BAND_5G (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_FORCE_PLL_BAND_2P5G (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_P_EQ_T_SEL (0x3ff<<15) /* 24:15 */ +#define A60810_RG_SSUSB_PLL_ISO_EN_CYC (0x3ff<<5) /* 14:5 */ +#define A60810_RG_SSUSB_PLLBAND_RECAL (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_PLL_DDS_ISO_EN (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_FORCE_PLL_DDS_ISO_EN (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_PLL_DDS_PWR_ON (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_FORCE_PLL_DDS_PWR_ON (0x1<<0) /* 0:0 */ + +/* U3D_PHYD_PLL_1 */ +#define A60810_RG_SSUSB_CDR_BAND_5G (0xff<<24) /* 31:24 */ +#define A60810_RG_SSUSB_CDR_BAND_2P5G (0xff<<16) /* 23:16 */ +#define A60810_RG_SSUSB_PLL_BAND_5G (0xff<<8) /* 15:8 */ +#define A60810_RG_SSUSB_PLL_BAND_2P5G (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_BCN_DET_1 */ +#define A60810_RG_SSUSB_P_BCN_OBS_PRD (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_U_BCN_OBS_PRD (0xffff<<0) /* 15:0 */ + +/* U3D_PHYD_BCN_DET_2 */ +#define A60810_RG_SSUSB_P_BCN_OBS_SEL (0xfff<<16) /* 27:16 */ +#define A60810_RG_SSUSB_BCN_DET_DIS (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_U_BCN_OBS_SEL (0xfff<<0) /* 11:0 */ + +/* U3D_EQ0 */ +#define A60810_RG_SSUSB_EQ_DLHL_LFI (0x7f<<24) /* 30:24 */ +#define A60810_RG_SSUSB_EQ_DHHL_LFI (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_EQ_DD0HOS_LFI (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_EQ_DD0LOS_LFI (0x7f<<0) /* 6:0 */ + +/* U3D_EQ1 */ +#define A60810_RG_SSUSB_EQ_DD1HOS_LFI (0x7f<<24) /* 30:24 */ +#define A60810_RG_SSUSB_EQ_DD1LOS_LFI (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_EQ_DE0OS_LFI (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_EQ_DE1OS_LFI (0x7f<<0) /* 6:0 */ + +/* U3D_EQ2 */ +#define A60810_RG_SSUSB_EQ_DLHLOS_LFI (0x7f<<24) /* 30:24 */ +#define A60810_RG_SSUSB_EQ_DHHLOS_LFI (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_EQ_STOPTIME (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_EQ_DHHL_LF_SEL (0x7<<11) /* 13:11 */ +#define A60810_RG_SSUSB_EQ_DSAOS_LF_SEL (0x7<<8) /* 10:8 */ +#define A60810_RG_SSUSB_EQ_STARTTIME (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_EQ_DLEQ_LF_SEL (0x7<<3) /* 5:3 */ +#define A60810_RG_SSUSB_EQ_DLHL_LF_SEL (0x7<<0) /* 2:0 */ + +/* U3D_EQ3 */ +#define A60810_RG_SSUSB_EQ_DLEQ_LFI_GEN2 (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_EQ_DLEQ_LFI_GEN1 (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_EQ_DEYE0OS_LFI (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_EQ_DEYE1OS_LFI (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_EQ_TRI_DET_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_EQ_TRI_DET_TH (0x7f<<0) /* 6:0 */ + +/* U3D_EQ_EYE0 */ +#define A60810_RG_SSUSB_EQ_EYE_XOFFSET (0x7f<<25) /* 31:25 */ +#define A60810_RG_SSUSB_EQ_EYE_MON_EN (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_EQ_EYE0_Y (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_EQ_EYE1_Y (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_EQ_PILPO_ROUT (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_EQ_PI_KPGAIN (0x7<<4) /* 6:4 */ +#define A60810_RG_SSUSB_EQ_EYE_CNT_EN (0x1<<3) /* 3:3 */ + +/* U3D_EQ_EYE1 */ +#define A60810_RG_SSUSB_EQ_SIGDET (0x7f<<24) /* 30:24 */ +#define A60810_RG_SSUSB_EQ_EYE_MASK (0x3ff<<7) /* 16:7 */ + +/* U3D_EQ_EYE2 */ +#define A60810_RG_SSUSB_EQ_RX500M_CK_SEL (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_EQ_SD_CNT1 (0x3f<<24) /* 29:24 */ +#define A60810_RG_SSUSB_EQ_ISIFLAG_SEL (0x3<<22) /* 23:22 */ +#define A60810_RG_SSUSB_EQ_SD_CNT0 (0x3f<<16) /* 21:16 */ + +/* U3D_EQ_DFE0 */ +#define A60810_RG_SSUSB_EQ_LEQMAX (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_EQ_DFEX_EN (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_EQ_DFEX_LF_SEL (0x7<<24) /* 26:24 */ +#define A60810_RG_SSUSB_EQ_CHK_EYE_H (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_EQ_PIEYE_INI (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_EQ_PI90_INI (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_EQ_PI0_INI (0x7f<<0) /* 6:0 */ + +/* U3D_EQ_DFE1 */ +#define A60810_RG_SSUSB_EQ_REV (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_EQ_DFEYEN_DUR (0x7<<12) /* 14:12 */ +#define A60810_RG_SSUSB_EQ_DFEXEN_DUR (0x7<<8) /* 10:8 */ +#define A60810_RG_SSUSB_EQ_DFEX_RST (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_EQ_GATED_RXD_B (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_EQ_PI90CK_SEL (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_EQ_DFEX_DIS (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_EQ_DFEYEN_STOP_DIS (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_EQ_DFEXEN_SEL (0x1<<0) /* 0:0 */ + +/* U3D_EQ_DFE2 */ +#define A60810_RG_SSUSB_EQ_MON_SEL (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_EQ_LEQOSC_DLYCNT (0x7<<16) /* 18:16 */ +#define A60810_RG_SSUSB_EQ_DLEQOS_LFI (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_EQ_DFE_TOG (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_EQ_LEQ_STOP_TO (0x3<<0) /* 1:0 */ + +/* U3D_EQ_DFE3 */ +#define A60810_RG_SSUSB_EQ_RESERVED (0xffffffff<<0) /* 31:0 */ + +/* U3D_PHYD_MON0 */ +#define A60810_RGS_SSUSB_BERT_BERC (0xffff<<16) /* 31:16 */ +#define A60810_RGS_SSUSB_LFPS (0xf<<12) /* 15:12 */ +#define A60810_RGS_SSUSB_TRAINDEC (0x7<<8) /* 10:8 */ +#define A60810_RGS_SSUSB_SCP_PAT (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_MON1 */ +#define A60810_RGS_SSUSB_RX_FL_OUT (0xffff<<0) /* 15:0 */ + +/* U3D_PHYD_MON2 */ +#define A60810_RGS_SSUSB_T2RLB_ERRCNT (0xffff<<16) /* 31:16 */ +#define A60810_RGS_SSUSB_RETRACK (0xf<<12) /* 15:12 */ +#define A60810_RGS_SSUSB_RXPLL_LOCK (0x1<<10) /* 10:10 */ +#define A60810_RGS_SSUSB_CDR_VCOCAL_CPLT_D (0x1<<9) /* 9:9 */ +#define A60810_RGS_SSUSB_PLL_VCOCAL_CPLT_D (0x1<<8) /* 8:8 */ +#define A60810_RGS_SSUSB_PDNCTL (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_MON3 */ +#define A60810_RGS_SSUSB_TSEQ_ERRCNT (0xffff<<16) /* 31:16 */ +#define A60810_RGS_SSUSB_PRBS_ERRCNT (0xffff<<0) /* 15:0 */ + +/* U3D_PHYD_MON4 */ +#define A60810_RGS_SSUSB_RX_LSLOCK_CNT (0xf<<24) /* 27:24 */ +#define A60810_RGS_SSUSB_SCP_DETCNT (0xff<<16) /* 23:16 */ +#define A60810_RGS_SSUSB_TSEQ_DETCNT (0xffff<<0) /* 15:0 */ + +/* U3D_PHYD_MON5 */ +#define A60810_RGS_SSUSB_EBUFMSG (0xffff<<16) /* 31:16 */ +#define A60810_RGS_SSUSB_BERT_LOCK (0x1<<15) /* 15:15 */ +#define A60810_RGS_SSUSB_SCP_DET (0x1<<14) /* 14:14 */ +#define A60810_RGS_SSUSB_TSEQ_DET (0x1<<13) /* 13:13 */ +#define A60810_RGS_SSUSB_EBUF_UDF (0x1<<12) /* 12:12 */ +#define A60810_RGS_SSUSB_EBUF_OVF (0x1<<11) /* 11:11 */ +#define A60810_RGS_SSUSB_PRBS_PASSTH (0x1<<10) /* 10:10 */ +#define A60810_RGS_SSUSB_PRBS_PASS (0x1<<9) /* 9:9 */ +#define A60810_RGS_SSUSB_PRBS_LOCK (0x1<<8) /* 8:8 */ +#define A60810_RGS_SSUSB_T2RLB_ERR (0x1<<6) /* 6:6 */ +#define A60810_RGS_SSUSB_T2RLB_PASSTH (0x1<<5) /* 5:5 */ +#define A60810_RGS_SSUSB_T2RLB_PASS (0x1<<4) /* 4:4 */ +#define A60810_RGS_SSUSB_T2RLB_LOCK (0x1<<3) /* 3:3 */ +#define A60810_RGS_SSUSB_RX_IMPCAL_DONE (0x1<<2) /* 2:2 */ +#define A60810_RGS_SSUSB_TX_IMPCAL_DONE (0x1<<1) /* 1:1 */ +#define A60810_RGS_SSUSB_RXDETECTED (0x1<<0) /* 0:0 */ + +/* U3D_PHYD_MON6 */ +#define A60810_RGS_SSUSB_SIGCAL_DONE (0x1<<30) /* 30:30 */ +#define A60810_RGS_SSUSB_SIGCAL_CAL_OUT (0x1<<29) /* 29:29 */ +#define A60810_RGS_SSUSB_SIGCAL_OFFSET (0x1f<<24) /* 28:24 */ +#define A60810_RGS_SSUSB_RX_IMP_SEL (0x1f<<16) /* 20:16 */ +#define A60810_RGS_SSUSB_TX_IMP_SEL (0x1f<<8) /* 12:8 */ +#define A60810_RGS_SSUSB_TFIFO_MSG (0xf<<4) /* 7:4 */ +#define A60810_RGS_SSUSB_RFIFO_MSG (0xf<<0) /* 3:0 */ + +/* U3D_PHYD_MON7 */ +#define A60810_RGS_SSUSB_FT_OUT (0xff<<8) /* 15:8 */ +#define A60810_RGS_SSUSB_PRB_OUT (0xff<<0) /* 7:0 */ + +/* U3D_PHYA_RX_MON0 */ +#define A60810_RGS_SSUSB_EQ_DCLEQ (0xf<<24) /* 27:24 */ +#define A60810_RGS_SSUSB_EQ_DCD0H (0x7f<<16) /* 22:16 */ +#define A60810_RGS_SSUSB_EQ_DCD0L (0x7f<<8) /* 14:8 */ +#define A60810_RGS_SSUSB_EQ_DCD1H (0x7f<<0) /* 6:0 */ + +/* U3D_PHYA_RX_MON1 */ +#define A60810_RGS_SSUSB_EQ_DCD1L (0x7f<<24) /* 30:24 */ +#define A60810_RGS_SSUSB_EQ_DCE0 (0x7f<<16) /* 22:16 */ +#define A60810_RGS_SSUSB_EQ_DCE1 (0x7f<<8) /* 14:8 */ +#define A60810_RGS_SSUSB_EQ_DCHHL (0x7f<<0) /* 6:0 */ + +/* U3D_PHYA_RX_MON2 */ +#define A60810_RGS_SSUSB_EQ_LEQ_STOP (0x1<<31) /* 31:31 */ +#define A60810_RGS_SSUSB_EQ_DCLHL (0x7f<<24) /* 30:24 */ +#define A60810_RGS_SSUSB_EQ_STATUS (0xff<<16) /* 23:16 */ +#define A60810_RGS_SSUSB_EQ_DCEYE0 (0x7f<<8) /* 14:8 */ +#define A60810_RGS_SSUSB_EQ_DCEYE1 (0x7f<<0) /* 6:0 */ + +/* U3D_PHYA_RX_MON3 */ +#define A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0 (0xfffff<<0) /* 19:0 */ + +/* U3D_PHYA_RX_MON4 */ +#define A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1 (0xfffff<<0) /* 19:0 */ + +/* U3D_PHYA_RX_MON5 */ +#define A60810_RGS_SSUSB_EQ_DCLEQOS (0x1f<<8) /* 12:8 */ +#define A60810_RGS_SSUSB_EQ_EYE_CNT_RDY (0x1<<7) /* 7:7 */ +#define A60810_RGS_SSUSB_EQ_PILPO (0x7f<<0) /* 6:0 */ + +/* U3D_PHYD_CPPAT2 */ +#define A60810_RG_SSUSB_CPPAT_OUT_H_TMP2 (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_CPPAT_OUT_H_TMP1 (0xff<<8) /* 15:8 */ +#define A60810_RG_SSUSB_CPPAT_OUT_H_TMP0 (0xff<<0) /* 7:0 */ + +/* U3D_EQ_EYE3 */ +#define A60810_RG_SSUSB_EQ_LEQ_SHIFT (0x7<<24) /* 26:24 */ +#define A60810_RG_SSUSB_EQ_EYE_CNT (0xfffff<<0) /* 19:0 */ + +/* U3D_KBAND_OUT */ +#define A60810_RGS_SSUSB_CDR_BAND_5G (0xff<<24) /* 31:24 */ +#define A60810_RGS_SSUSB_CDR_BAND_2P5G (0xff<<16) /* 23:16 */ +#define A60810_RGS_SSUSB_PLL_BAND_5G (0xff<<8) /* 15:8 */ +#define A60810_RGS_SSUSB_PLL_BAND_2P5G (0xff<<0) /* 7:0 */ + +/* U3D_KBAND_OUT1 */ +#define A60810_RGS_SSUSB_CDR_VCOCAL_FAIL (0x1<<24) /* 24:24 */ +#define A60810_RGS_SSUSB_CDR_VCOCAL_STATE (0xff<<16) /* 23:16 */ +#define A60810_RGS_SSUSB_PLL_VCOCAL_FAIL (0x1<<8) /* 8:8 */ +#define A60810_RGS_SSUSB_PLL_VCOCAL_STATE (0xff<<0) /* 7:0 */ + +/* OFFSET */ + +/* U3D_PHYD_MIX0 */ +#define A60810_RG_SSUSB_P_P3_TX_NG_OFST (31) +#define A60810_RG_SSUSB_TSEQ_EN_OFST (30) +#define A60810_RG_SSUSB_TSEQ_POLEN_OFST (29) +#define A60810_RG_SSUSB_TSEQ_POL_OFST (28) +#define A60810_RG_SSUSB_P_P3_PCLK_NG_OFST (27) +#define A60810_RG_SSUSB_TSEQ_TH_OFST (24) +#define A60810_RG_SSUSB_PRBS_BERTH_OFST (16) +#define A60810_RG_SSUSB_DISABLE_PHY_U2_ON_OFST (15) +#define A60810_RG_SSUSB_DISABLE_PHY_U2_OFF_OFST (14) +#define A60810_RG_SSUSB_PRBS_EN_OFST (13) +#define A60810_RG_SSUSB_BPSLOCK_OFST (12) +#define A60810_RG_SSUSB_RTCOMCNT_OFST (8) +#define A60810_RG_SSUSB_COMCNT_OFST (4) +#define A60810_RG_SSUSB_PRBSEL_CALIB_OFST (0) + +/* U3D_PHYD_MIX1 */ +#define A60810_RG_SSUSB_SLEEP_EN_OFST (31) +#define A60810_RG_SSUSB_PRBSEL_PCS_OFST (28) +#define A60810_RG_SSUSB_TXLFPS_PRD_OFST (24) +#define A60810_RG_SSUSB_P_RX_P0S_CK_OFST (23) +#define A60810_RG_SSUSB_P_TX_P0S_CK_OFST (22) +#define A60810_RG_SSUSB_PDNCTL_OFST (16) +#define A60810_RG_SSUSB_TX_DRV_EN_OFST (15) +#define A60810_RG_SSUSB_TX_DRV_SEL_OFST (14) +#define A60810_RG_SSUSB_TX_DRV_DLY_OFST (8) +#define A60810_RG_SSUSB_BERT_EN_OFST (7) +#define A60810_RG_SSUSB_SCP_TH_OFST (4) +#define A60810_RG_SSUSB_SCP_EN_OFST (3) +#define A60810_RG_SSUSB_RXANSIDEC_TEST_OFST (0) + +/* U3D_PHYD_LFPS0 */ +#define A60810_RG_SSUSB_LFPS_PWD_OFST (30) +#define A60810_RG_SSUSB_FORCE_LFPS_PWD_OFST (29) +#define A60810_RG_SSUSB_RXLFPS_OVF_OFST (24) +#define A60810_RG_SSUSB_P3_ENTRY_SEL_OFST (23) +#define A60810_RG_SSUSB_P3_ENTRY_OFST (22) +#define A60810_RG_SSUSB_RXLFPS_CDRSEL_OFST (20) +#define A60810_RG_SSUSB_RXLFPS_CDRTH_OFST (16) +#define A60810_RG_SSUSB_LOCK5G_BLOCK_OFST (15) +#define A60810_RG_SSUSB_TFIFO_EXT_D_SEL_OFST (14) +#define A60810_RG_SSUSB_TFIFO_NO_EXTEND_OFST (13) +#define A60810_RG_SSUSB_RXLFPS_LOB_OFST (8) +#define A60810_RG_SSUSB_TXLFPS_EN_OFST (7) +#define A60810_RG_SSUSB_TXLFPS_SEL_OFST (6) +#define A60810_RG_SSUSB_RXLFPS_CDRLOCK_OFST (5) +#define A60810_RG_SSUSB_RXLFPS_UPB_OFST (0) + +/* U3D_PHYD_LFPS1 */ +#define A60810_RG_SSUSB_RX_IMP_BIAS_OFST (28) +#define A60810_RG_SSUSB_TX_IMP_BIAS_OFST (24) +#define A60810_RG_SSUSB_FWAKE_TH_OFST (16) +#define A60810_RG_SSUSB_P1_ENTRY_SEL_OFST (14) +#define A60810_RG_SSUSB_P1_ENTRY_OFST (13) +#define A60810_RG_SSUSB_RXLFPS_UDF_OFST (8) +#define A60810_RG_SSUSB_RXLFPS_P0IDLETH_OFST (0) + +/* U3D_PHYD_IMPCAL0 */ +#define A60810_RG_SSUSB_FORCE_TX_IMPSEL_OFST (31) +#define A60810_RG_SSUSB_TX_IMPCAL_EN_OFST (30) +#define A60810_RG_SSUSB_FORCE_TX_IMPCAL_EN_OFST (29) +#define A60810_RG_SSUSB_TX_IMPSEL_OFST (24) +#define A60810_RG_SSUSB_TX_IMPCAL_CALCYC_OFST (16) +#define A60810_RG_SSUSB_TX_IMPCAL_STBCYC_OFST (10) +#define A60810_RG_SSUSB_TX_IMPCAL_CYCCNT_OFST (0) + +/* U3D_PHYD_IMPCAL1 */ +#define A60810_RG_SSUSB_FORCE_RX_IMPSEL_OFST (31) +#define A60810_RG_SSUSB_RX_IMPCAL_EN_OFST (30) +#define A60810_RG_SSUSB_FORCE_RX_IMPCAL_EN_OFST (29) +#define A60810_RG_SSUSB_RX_IMPSEL_OFST (24) +#define A60810_RG_SSUSB_RX_IMPCAL_CALCYC_OFST (16) +#define A60810_RG_SSUSB_RX_IMPCAL_STBCYC_OFST (10) +#define A60810_RG_SSUSB_RX_IMPCAL_CYCCNT_OFST (0) + +/* U3D_PHYD_TXPLL0 */ +#define A60810_RG_SSUSB_TXPLL_DDSEN_CYC_OFST (27) +#define A60810_RG_SSUSB_TXPLL_ON_OFST (26) +#define A60810_RG_SSUSB_FORCE_TXPLLON_OFST (25) +#define A60810_RG_SSUSB_TXPLL_STBCYC_OFST (16) +#define A60810_RG_SSUSB_TXPLL_NCPOCHG_CYC_OFST (12) +#define A60810_RG_SSUSB_TXPLL_NCPOEN_CYC_OFST (10) +#define A60810_RG_SSUSB_TXPLL_DDSRSTB_CYC_OFST (0) + +/* U3D_PHYD_TXPLL1 */ +#define A60810_RG_SSUSB_PLL_NCPO_EN_OFST (31) +#define A60810_RG_SSUSB_PLL_FIFO_START_MAN_OFST (30) +#define A60810_RG_SSUSB_PLL_NCPO_CHG_OFST (28) +#define A60810_RG_SSUSB_PLL_DDS_RSTB_OFST (27) +#define A60810_RG_SSUSB_PLL_DDS_PWDB_OFST (26) +#define A60810_RG_SSUSB_PLL_DDSEN_OFST (25) +#define A60810_RG_SSUSB_PLL_AUTOK_VCO_OFST (24) +#define A60810_RG_SSUSB_PLL_PWD_OFST (23) +#define A60810_RG_SSUSB_RX_AFE_PWD_OFST (22) +#define A60810_RG_SSUSB_PLL_TCADJ_OFST (16) +#define A60810_RG_SSUSB_FORCE_CDR_TCADJ_OFST (15) +#define A60810_RG_SSUSB_FORCE_CDR_AUTOK_VCO_OFST (14) +#define A60810_RG_SSUSB_FORCE_CDR_PWD_OFST (13) +#define A60810_RG_SSUSB_FORCE_PLL_NCPO_EN_OFST (12) +#define A60810_RG_SSUSB_FORCE_PLL_FIFO_START_MAN_OFST (11) +#define A60810_RG_SSUSB_FORCE_PLL_NCPO_CHG_OFST (9) +#define A60810_RG_SSUSB_FORCE_PLL_DDS_RSTB_OFST (8) +#define A60810_RG_SSUSB_FORCE_PLL_DDS_PWDB_OFST (7) +#define A60810_RG_SSUSB_FORCE_PLL_DDSEN_OFST (6) +#define A60810_RG_SSUSB_FORCE_PLL_TCADJ_OFST (5) +#define A60810_RG_SSUSB_FORCE_PLL_AUTOK_VCO_OFST (4) +#define A60810_RG_SSUSB_FORCE_PLL_PWD_OFST (3) +#define A60810_RG_SSUSB_FLT_1_DISPERR_B_OFST (2) + +/* U3D_PHYD_TXPLL2 */ +#define A60810_RG_SSUSB_TX_LFPS_EN_OFST (31) +#define A60810_RG_SSUSB_FORCE_TX_LFPS_EN_OFST (30) +#define A60810_RG_SSUSB_TX_LFPS_OFST (29) +#define A60810_RG_SSUSB_FORCE_TX_LFPS_OFST (28) +#define A60810_RG_SSUSB_RXPLL_STB_OFST (27) +#define A60810_RG_SSUSB_TXPLL_STB_OFST (26) +#define A60810_RG_SSUSB_FORCE_RXPLL_STB_OFST (25) +#define A60810_RG_SSUSB_FORCE_TXPLL_STB_OFST (24) +#define A60810_RG_SSUSB_RXPLL_REFCKSEL_OFST (16) +#define A60810_RG_SSUSB_RXPLL_STBMODE_OFST (11) +#define A60810_RG_SSUSB_RXPLL_ON_OFST (10) +#define A60810_RG_SSUSB_FORCE_RXPLLON_OFST (9) +#define A60810_RG_SSUSB_FORCE_RX_AFE_PWD_OFST (8) +#define A60810_RG_SSUSB_CDR_AUTOK_VCO_OFST (7) +#define A60810_RG_SSUSB_CDR_PWD_OFST (6) +#define A60810_RG_SSUSB_CDR_TCADJ_OFST (0) + +/* U3D_PHYD_FL0 */ +#define A60810_RG_SSUSB_RX_FL_TARGET_OFST (16) +#define A60810_RG_SSUSB_RX_FL_CYCLECNT_OFST (0) + +/* U3D_PHYD_MIX2 */ +#define A60810_RG_SSUSB_RX_EQ_RST_OFST (31) +#define A60810_RG_SSUSB_RX_EQ_RST_SEL_OFST (30) +#define A60810_RG_SSUSB_RXVAL_RST_OFST (29) +#define A60810_RG_SSUSB_RXVAL_CNT_OFST (24) +#define A60810_RG_SSUSB_CDROS_EN_OFST (18) +#define A60810_RG_SSUSB_CDR_LCKOP_OFST (16) +#define A60810_RG_SSUSB_RX_FL_LOCKTH_OFST (8) +#define A60810_RG_SSUSB_RX_FL_OFFSET_OFST (0) + +/* U3D_PHYD_RX0 */ +#define A60810_RG_SSUSB_T2RLB_BERTH_OFST (24) +#define A60810_RG_SSUSB_T2RLB_PAT_OFST (16) +#define A60810_RG_SSUSB_T2RLB_EN_OFST (15) +#define A60810_RG_SSUSB_T2RLB_BPSCRAMB_OFST (14) +#define A60810_RG_SSUSB_T2RLB_SERIAL_OFST (13) +#define A60810_RG_SSUSB_T2RLB_MODE_OFST (11) +#define A60810_RG_SSUSB_RX_SAOSC_EN_OFST (10) +#define A60810_RG_SSUSB_RX_SAOSC_EN_SEL_OFST (9) +#define A60810_RG_SSUSB_RX_DFE_OPTION_OFST (8) +#define A60810_RG_SSUSB_RX_DFE_EN_OFST (7) +#define A60810_RG_SSUSB_RX_DFE_EN_SEL_OFST (6) +#define A60810_RG_SSUSB_RX_EQ_EN_OFST (5) +#define A60810_RG_SSUSB_RX_EQ_EN_SEL_OFST (4) +#define A60810_RG_SSUSB_RX_SAOSC_RST_OFST (3) +#define A60810_RG_SSUSB_RX_SAOSC_RST_SEL_OFST (2) +#define A60810_RG_SSUSB_RX_DFE_RST_OFST (1) +#define A60810_RG_SSUSB_RX_DFE_RST_SEL_OFST (0) + +/* U3D_PHYD_T2RLB */ +#define A60810_RG_SSUSB_EQTRAIN_CH_MODE_OFST (28) +#define A60810_RG_SSUSB_PRB_OUT_CPPAT_OFST (27) +#define A60810_RG_SSUSB_BPANSIENC_OFST (26) +#define A60810_RG_SSUSB_VALID_EN_OFST (25) +#define A60810_RG_SSUSB_EBUF_SRST_OFST (24) +#define A60810_RG_SSUSB_K_EMP_OFST (20) +#define A60810_RG_SSUSB_K_FUL_OFST (16) +#define A60810_RG_SSUSB_T2RLB_BDATRST_OFST (12) +#define A60810_RG_SSUSB_P_T2RLB_SKP_EN_OFST (10) +#define A60810_RG_SSUSB_T2RLB_PATMODE_OFST (8) +#define A60810_RG_SSUSB_T2RLB_TSEQCNT_OFST (0) + +/* U3D_PHYD_CPPAT */ +#define A60810_RG_SSUSB_CPPAT_PROGRAM_EN_OFST (24) +#define A60810_RG_SSUSB_CPPAT_TOZ_OFST (21) +#define A60810_RG_SSUSB_CPPAT_PRBS_EN_OFST (20) +#define A60810_RG_SSUSB_CPPAT_OUT_TMP2_OFST (16) +#define A60810_RG_SSUSB_CPPAT_OUT_TMP1_OFST (8) +#define A60810_RG_SSUSB_CPPAT_OUT_TMP0_OFST (0) + +/* U3D_PHYD_MIX3 */ +#define A60810_RG_SSUSB_CDR_TCADJ_MINUS_OFST (31) +#define A60810_RG_SSUSB_P_CDROS_EN_OFST (30) +#define A60810_RG_SSUSB_P_P2_TX_DRV_DIS_OFST (28) +#define A60810_RG_SSUSB_CDR_TCADJ_OFFSET_OFST (24) +#define A60810_RG_SSUSB_PLL_TCADJ_MINUS_OFST (23) +#define A60810_RG_SSUSB_FORCE_PLL_BIAS_LPF_EN_OFST (20) +#define A60810_RG_SSUSB_PLL_BIAS_LPF_EN_OFST (19) +#define A60810_RG_SSUSB_PLL_TCADJ_OFFSET_OFST (16) +#define A60810_RG_SSUSB_FORCE_PLL_SSCEN_OFST (15) +#define A60810_RG_SSUSB_PLL_SSCEN_OFST (14) +#define A60810_RG_SSUSB_FORCE_CDR_PI_PWD_OFST (13) +#define A60810_RG_SSUSB_CDR_PI_PWD_OFST (12) +#define A60810_RG_SSUSB_CDR_PI_MODE_OFST (11) +#define A60810_RG_SSUSB_TXPLL_SSCEN_CYC_OFST (0) + +/* U3D_PHYD_EBUFCTL */ +#define A60810_RG_SSUSB_EBUFCTL_OFST (0) + +/* U3D_PHYD_PIPE0 */ +#define A60810_RG_SSUSB_RXTERMINATION_OFST (30) +#define A60810_RG_SSUSB_RXEQTRAINING_OFST (29) +#define A60810_RG_SSUSB_RXPOLARITY_OFST (28) +#define A60810_RG_SSUSB_TXDEEMPH_OFST (26) +#define A60810_RG_SSUSB_POWERDOWN_OFST (24) +#define A60810_RG_SSUSB_TXONESZEROS_OFST (23) +#define A60810_RG_SSUSB_TXELECIDLE_OFST (22) +#define A60810_RG_SSUSB_TXDETECTRX_OFST (21) +#define A60810_RG_SSUSB_PIPE_SEL_OFST (20) +#define A60810_RG_SSUSB_TXDATAK_OFST (16) +#define A60810_RG_SSUSB_CDR_STABLE_SEL_OFST (15) +#define A60810_RG_SSUSB_CDR_STABLE_OFST (14) +#define A60810_RG_SSUSB_CDR_RSTB_SEL_OFST (13) +#define A60810_RG_SSUSB_CDR_RSTB_OFST (12) +#define A60810_RG_SSUSB_FRC_PIPE_POWERDOWN_OFST (11) +#define A60810_RG_SSUSB_P_TXBCN_DIS_OFST (6) +#define A60810_RG_SSUSB_P_ERROR_SEL_OFST (4) +#define A60810_RG_SSUSB_TXMARGIN_OFST (1) +#define A60810_RG_SSUSB_TXCOMPLIANCE_OFST (0) + +/* U3D_PHYD_PIPE1 */ +#define A60810_RG_SSUSB_TXDATA_OFST (0) + +/* U3D_PHYD_MIX4 */ +#define A60810_RG_SSUSB_CDROS_CNT_OFST (24) +#define A60810_RG_SSUSB_T2RLB_BER_EN_OFST (16) +#define A60810_RG_SSUSB_T2RLB_BER_RATE_OFST (0) + +/* U3D_PHYD_CKGEN0 */ +#define A60810_RG_SSUSB_RFIFO_IMPLAT_OFST (27) +#define A60810_RG_SSUSB_TFIFO_PSEL_OFST (24) +#define A60810_RG_SSUSB_CKGEN_PSEL_OFST (8) +#define A60810_RG_SSUSB_RXCK_INV_OFST (0) + +/* U3D_PHYD_MIX5 */ +#define A60810_RG_SSUSB_PRB_SEL_OFST (16) +#define A60810_RG_SSUSB_RXPLL_STBCYC_OFST (0) + +/* U3D_PHYD_RESERVED */ +#define A60810_RG_SSUSB_PHYD_RESERVE_OFST (0) + +/* U3D_PHYD_CDR0 */ +#define A60810_RG_SSUSB_CDR_BIC_LTR_OFST (28) +#define A60810_RG_SSUSB_CDR_BIC_LTD0_OFST (24) +#define A60810_RG_SSUSB_CDR_BC_LTD1_OFST (16) +#define A60810_RG_SSUSB_CDR_BC_LTR_OFST (8) +#define A60810_RG_SSUSB_CDR_BC_LTD0_OFST (0) + +/* U3D_PHYD_CDR1 */ +#define A60810_RG_SSUSB_CDR_BIR_LTD1_OFST (24) +#define A60810_RG_SSUSB_CDR_BIR_LTR_OFST (16) +#define A60810_RG_SSUSB_CDR_BIR_LTD0_OFST (8) +#define A60810_RG_SSUSB_CDR_BW_SEL_OFST (6) +#define A60810_RG_SSUSB_CDR_BIC_LTD1_OFST (0) + +/* U3D_PHYD_PLL_0 */ +#define A60810_RG_SSUSB_FORCE_CDR_BAND_5G_OFST (28) +#define A60810_RG_SSUSB_FORCE_CDR_BAND_2P5G_OFST (27) +#define A60810_RG_SSUSB_FORCE_PLL_BAND_5G_OFST (26) +#define A60810_RG_SSUSB_FORCE_PLL_BAND_2P5G_OFST (25) +#define A60810_RG_SSUSB_P_EQ_T_SEL_OFST (15) +#define A60810_RG_SSUSB_PLL_ISO_EN_CYC_OFST (5) +#define A60810_RG_SSUSB_PLLBAND_RECAL_OFST (4) +#define A60810_RG_SSUSB_PLL_DDS_ISO_EN_OFST (3) +#define A60810_RG_SSUSB_FORCE_PLL_DDS_ISO_EN_OFST (2) +#define A60810_RG_SSUSB_PLL_DDS_PWR_ON_OFST (1) +#define A60810_RG_SSUSB_FORCE_PLL_DDS_PWR_ON_OFST (0) + +/* U3D_PHYD_PLL_1 */ +#define A60810_RG_SSUSB_CDR_BAND_5G_OFST (24) +#define A60810_RG_SSUSB_CDR_BAND_2P5G_OFST (16) +#define A60810_RG_SSUSB_PLL_BAND_5G_OFST (8) +#define A60810_RG_SSUSB_PLL_BAND_2P5G_OFST (0) + +/* U3D_PHYD_BCN_DET_1 */ +#define A60810_RG_SSUSB_P_BCN_OBS_PRD_OFST (16) +#define A60810_RG_SSUSB_U_BCN_OBS_PRD_OFST (0) + +/* U3D_PHYD_BCN_DET_2 */ +#define A60810_RG_SSUSB_P_BCN_OBS_SEL_OFST (16) +#define A60810_RG_SSUSB_BCN_DET_DIS_OFST (12) +#define A60810_RG_SSUSB_U_BCN_OBS_SEL_OFST (0) + +/* U3D_EQ0 */ +#define A60810_RG_SSUSB_EQ_DLHL_LFI_OFST (24) +#define A60810_RG_SSUSB_EQ_DHHL_LFI_OFST (16) +#define A60810_RG_SSUSB_EQ_DD0HOS_LFI_OFST (8) +#define A60810_RG_SSUSB_EQ_DD0LOS_LFI_OFST (0) + +/* U3D_EQ1 */ +#define A60810_RG_SSUSB_EQ_DD1HOS_LFI_OFST (24) +#define A60810_RG_SSUSB_EQ_DD1LOS_LFI_OFST (16) +#define A60810_RG_SSUSB_EQ_DE0OS_LFI_OFST (8) +#define A60810_RG_SSUSB_EQ_DE1OS_LFI_OFST (0) + +/* U3D_EQ2 */ +#define A60810_RG_SSUSB_EQ_DLHLOS_LFI_OFST (24) +#define A60810_RG_SSUSB_EQ_DHHLOS_LFI_OFST (16) +#define A60810_RG_SSUSB_EQ_STOPTIME_OFST (14) +#define A60810_RG_SSUSB_EQ_DHHL_LF_SEL_OFST (11) +#define A60810_RG_SSUSB_EQ_DSAOS_LF_SEL_OFST (8) +#define A60810_RG_SSUSB_EQ_STARTTIME_OFST (6) +#define A60810_RG_SSUSB_EQ_DLEQ_LF_SEL_OFST (3) +#define A60810_RG_SSUSB_EQ_DLHL_LF_SEL_OFST (0) + +/* U3D_EQ3 */ +#define A60810_RG_SSUSB_EQ_DLEQ_LFI_GEN2_OFST (28) +#define A60810_RG_SSUSB_EQ_DLEQ_LFI_GEN1_OFST (24) +#define A60810_RG_SSUSB_EQ_DEYE0OS_LFI_OFST (16) +#define A60810_RG_SSUSB_EQ_DEYE1OS_LFI_OFST (8) +#define A60810_RG_SSUSB_EQ_TRI_DET_EN_OFST (7) +#define A60810_RG_SSUSB_EQ_TRI_DET_TH_OFST (0) + +/* U3D_EQ_EYE0 */ +#define A60810_RG_SSUSB_EQ_EYE_XOFFSET_OFST (25) +#define A60810_RG_SSUSB_EQ_EYE_MON_EN_OFST (24) +#define A60810_RG_SSUSB_EQ_EYE0_Y_OFST (16) +#define A60810_RG_SSUSB_EQ_EYE1_Y_OFST (8) +#define A60810_RG_SSUSB_EQ_PILPO_ROUT_OFST (7) +#define A60810_RG_SSUSB_EQ_PI_KPGAIN_OFST (4) +#define A60810_RG_SSUSB_EQ_EYE_CNT_EN_OFST (3) + +/* U3D_EQ_EYE1 */ +#define A60810_RG_SSUSB_EQ_SIGDET_OFST (24) +#define A60810_RG_SSUSB_EQ_EYE_MASK_OFST (7) + +/* U3D_EQ_EYE2 */ +#define A60810_RG_SSUSB_EQ_RX500M_CK_SEL_OFST (31) +#define A60810_RG_SSUSB_EQ_SD_CNT1_OFST (24) +#define A60810_RG_SSUSB_EQ_ISIFLAG_SEL_OFST (22) +#define A60810_RG_SSUSB_EQ_SD_CNT0_OFST (16) + +/* U3D_EQ_DFE0 */ +#define A60810_RG_SSUSB_EQ_LEQMAX_OFST (28) +#define A60810_RG_SSUSB_EQ_DFEX_EN_OFST (27) +#define A60810_RG_SSUSB_EQ_DFEX_LF_SEL_OFST (24) +#define A60810_RG_SSUSB_EQ_CHK_EYE_H_OFST (23) +#define A60810_RG_SSUSB_EQ_PIEYE_INI_OFST (16) +#define A60810_RG_SSUSB_EQ_PI90_INI_OFST (8) +#define A60810_RG_SSUSB_EQ_PI0_INI_OFST (0) + +/* U3D_EQ_DFE1 */ +#define A60810_RG_SSUSB_EQ_REV_OFST (16) +#define A60810_RG_SSUSB_EQ_DFEYEN_DUR_OFST (12) +#define A60810_RG_SSUSB_EQ_DFEXEN_DUR_OFST (8) +#define A60810_RG_SSUSB_EQ_DFEX_RST_OFST (7) +#define A60810_RG_SSUSB_EQ_GATED_RXD_B_OFST (6) +#define A60810_RG_SSUSB_EQ_PI90CK_SEL_OFST (4) +#define A60810_RG_SSUSB_EQ_DFEX_DIS_OFST (2) +#define A60810_RG_SSUSB_EQ_DFEYEN_STOP_DIS_OFST (1) +#define A60810_RG_SSUSB_EQ_DFEXEN_SEL_OFST (0) + +/* U3D_EQ_DFE2 */ +#define A60810_RG_SSUSB_EQ_MON_SEL_OFST (24) +#define A60810_RG_SSUSB_EQ_LEQOSC_DLYCNT_OFST (16) +#define A60810_RG_SSUSB_EQ_DLEQOS_LFI_OFST (8) +#define A60810_RG_SSUSB_EQ_DFE_TOG_OFST (2) +#define A60810_RG_SSUSB_EQ_LEQ_STOP_TO_OFST (0) + +/* U3D_EQ_DFE3 */ +#define A60810_RG_SSUSB_EQ_RESERVED_OFST (0) + +/* U3D_PHYD_MON0 */ +#define A60810_RGS_SSUSB_BERT_BERC_OFST (16) +#define A60810_RGS_SSUSB_LFPS_OFST (12) +#define A60810_RGS_SSUSB_TRAINDEC_OFST (8) +#define A60810_RGS_SSUSB_SCP_PAT_OFST (0) + +/* U3D_PHYD_MON1 */ +#define A60810_RGS_SSUSB_RX_FL_OUT_OFST (0) + +/* U3D_PHYD_MON2 */ +#define A60810_RGS_SSUSB_T2RLB_ERRCNT_OFST (16) +#define A60810_RGS_SSUSB_RETRACK_OFST (12) +#define A60810_RGS_SSUSB_RXPLL_LOCK_OFST (10) +#define A60810_RGS_SSUSB_CDR_VCOCAL_CPLT_D_OFST (9) +#define A60810_RGS_SSUSB_PLL_VCOCAL_CPLT_D_OFST (8) +#define A60810_RGS_SSUSB_PDNCTL_OFST (0) + +/* U3D_PHYD_MON3 */ +#define A60810_RGS_SSUSB_TSEQ_ERRCNT_OFST (16) +#define A60810_RGS_SSUSB_PRBS_ERRCNT_OFST (0) + +/* U3D_PHYD_MON4 */ +#define A60810_RGS_SSUSB_RX_LSLOCK_CNT_OFST (24) +#define A60810_RGS_SSUSB_SCP_DETCNT_OFST (16) +#define A60810_RGS_SSUSB_TSEQ_DETCNT_OFST (0) + +/* U3D_PHYD_MON5 */ +#define A60810_RGS_SSUSB_EBUFMSG_OFST (16) +#define A60810_RGS_SSUSB_BERT_LOCK_OFST (15) +#define A60810_RGS_SSUSB_SCP_DET_OFST (14) +#define A60810_RGS_SSUSB_TSEQ_DET_OFST (13) +#define A60810_RGS_SSUSB_EBUF_UDF_OFST (12) +#define A60810_RGS_SSUSB_EBUF_OVF_OFST (11) +#define A60810_RGS_SSUSB_PRBS_PASSTH_OFST (10) +#define A60810_RGS_SSUSB_PRBS_PASS_OFST (9) +#define A60810_RGS_SSUSB_PRBS_LOCK_OFST (8) +#define A60810_RGS_SSUSB_T2RLB_ERR_OFST (6) +#define A60810_RGS_SSUSB_T2RLB_PASSTH_OFST (5) +#define A60810_RGS_SSUSB_T2RLB_PASS_OFST (4) +#define A60810_RGS_SSUSB_T2RLB_LOCK_OFST (3) +#define A60810_RGS_SSUSB_RX_IMPCAL_DONE_OFST (2) +#define A60810_RGS_SSUSB_TX_IMPCAL_DONE_OFST (1) +#define A60810_RGS_SSUSB_RXDETECTED_OFST (0) + +/* U3D_PHYD_MON6 */ +#define A60810_RGS_SSUSB_SIGCAL_DONE_OFST (30) +#define A60810_RGS_SSUSB_SIGCAL_CAL_OUT_OFST (29) +#define A60810_RGS_SSUSB_SIGCAL_OFFSET_OFST (24) +#define A60810_RGS_SSUSB_RX_IMP_SEL_OFST (16) +#define A60810_RGS_SSUSB_TX_IMP_SEL_OFST (8) +#define A60810_RGS_SSUSB_TFIFO_MSG_OFST (4) +#define A60810_RGS_SSUSB_RFIFO_MSG_OFST (0) + +/* U3D_PHYD_MON7 */ +#define A60810_RGS_SSUSB_FT_OUT_OFST (8) +#define A60810_RGS_SSUSB_PRB_OUT_OFST (0) + +/* U3D_PHYA_RX_MON0 */ +#define A60810_RGS_SSUSB_EQ_DCLEQ_OFST (24) +#define A60810_RGS_SSUSB_EQ_DCD0H_OFST (16) +#define A60810_RGS_SSUSB_EQ_DCD0L_OFST (8) +#define A60810_RGS_SSUSB_EQ_DCD1H_OFST (0) + +/* U3D_PHYA_RX_MON1 */ +#define A60810_RGS_SSUSB_EQ_DCD1L_OFST (24) +#define A60810_RGS_SSUSB_EQ_DCE0_OFST (16) +#define A60810_RGS_SSUSB_EQ_DCE1_OFST (8) +#define A60810_RGS_SSUSB_EQ_DCHHL_OFST (0) + +/* U3D_PHYA_RX_MON2 */ +#define A60810_RGS_SSUSB_EQ_LEQ_STOP_OFST (31) +#define A60810_RGS_SSUSB_EQ_DCLHL_OFST (24) +#define A60810_RGS_SSUSB_EQ_STATUS_OFST (16) +#define A60810_RGS_SSUSB_EQ_DCEYE0_OFST (8) +#define A60810_RGS_SSUSB_EQ_DCEYE1_OFST (0) + +/* U3D_PHYA_RX_MON3 */ +#define A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_0_OFST (0) + +/* U3D_PHYA_RX_MON4 */ +#define A60810_RGS_SSUSB_EQ_EYE_MONITOR_ERRCNT_1_OFST (0) + +/* U3D_PHYA_RX_MON5 */ +#define A60810_RGS_SSUSB_EQ_DCLEQOS_OFST (8) +#define A60810_RGS_SSUSB_EQ_EYE_CNT_RDY_OFST (7) +#define A60810_RGS_SSUSB_EQ_PILPO_OFST (0) + +/* U3D_PHYD_CPPAT2 */ +#define A60810_RG_SSUSB_CPPAT_OUT_H_TMP2_OFST (16) +#define A60810_RG_SSUSB_CPPAT_OUT_H_TMP1_OFST (8) +#define A60810_RG_SSUSB_CPPAT_OUT_H_TMP0_OFST (0) + +/* U3D_EQ_EYE3 */ +#define A60810_RG_SSUSB_EQ_LEQ_SHIFT_OFST (24) +#define A60810_RG_SSUSB_EQ_EYE_CNT_OFST (0) + +/* U3D_KBAND_OUT */ +#define A60810_RGS_SSUSB_CDR_BAND_5G_OFST (24) +#define A60810_RGS_SSUSB_CDR_BAND_2P5G_OFST (16) +#define A60810_RGS_SSUSB_PLL_BAND_5G_OFST (8) +#define A60810_RGS_SSUSB_PLL_BAND_2P5G_OFST (0) + +/* U3D_KBAND_OUT1 */ +#define A60810_RGS_SSUSB_CDR_VCOCAL_FAIL_OFST (24) +#define A60810_RGS_SSUSB_CDR_VCOCAL_STATE_OFST (16) +#define A60810_RGS_SSUSB_PLL_VCOCAL_FAIL_OFST (8) +#define A60810_RGS_SSUSB_PLL_VCOCAL_STATE_OFST (0) + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct u3phyd_bank2_reg_a { + /* 0x0 */ + PHY_LE32 b2_phyd_top1; + PHY_LE32 b2_phyd_top2; + PHY_LE32 b2_phyd_top3; + PHY_LE32 b2_phyd_top4; + /* 0x10 */ + PHY_LE32 b2_phyd_top5; + PHY_LE32 b2_phyd_top6; + PHY_LE32 b2_phyd_top7; + PHY_LE32 b2_phyd_p_sigdet1; + /* 0x20 */ + PHY_LE32 b2_phyd_p_sigdet2; + PHY_LE32 b2_phyd_p_sigdet_cal1; + PHY_LE32 b2_phyd_rxdet1; + PHY_LE32 b2_phyd_rxdet2; + /* 0x30 */ + PHY_LE32 b2_phyd_misc0; + PHY_LE32 b2_phyd_misc2; + PHY_LE32 b2_phyd_misc3; + PHY_LE32 b2_phyd_l1ss; + /* 0x40 */ + PHY_LE32 b2_rosc_0; + PHY_LE32 b2_rosc_1; + PHY_LE32 b2_rosc_2; + PHY_LE32 b2_rosc_3; + /* 0x50 */ + PHY_LE32 b2_rosc_4; + PHY_LE32 b2_rosc_5; + PHY_LE32 b2_rosc_6; + PHY_LE32 b2_rosc_7; + /* 0x60 */ + PHY_LE32 b2_rosc_8; + PHY_LE32 b2_rosc_9; + PHY_LE32 b2_rosc_a; + PHY_LE32 reserve1; + /* 0x70~0xd0 */ + PHY_LE32 reserve2[28]; + /* 0xe0 */ + PHY_LE32 phyd_version; + PHY_LE32 phyd_model; +}; + +/* U3D_B2_PHYD_TOP1 */ +#define A60810_RG_SSUSB_PCIE2_K_EMP (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_PCIE2_K_FUL (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_TX_EIDLE_LP_EN (0x1<<17) /* 17:17 */ +#define A60810_RG_SSUSB_FORCE_TX_EIDLE_LP_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_SIGDET_EN (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_FORCE_SIGDET_EN (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_CLKRX_EN (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_FORCE_CLKRX_EN (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_CLKTX_EN (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_FORCE_CLKTX_EN (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_CLK_REQ_N_I (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_FORCE_CLK_REQ_N_I (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_RATE (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_FORCE_RATE (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_PCIE_MODE_SEL (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_FORCE_PCIE_MODE_SEL (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_PHY_MODE (0x3<<1) /* 2:1 */ +#define A60810_RG_SSUSB_FORCE_PHY_MODE (0x1<<0) /* 0:0 */ + +/* U3D_B2_PHYD_TOP2 */ +#define A60810_RG_SSUSB_FORCE_IDRV_6DB (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_IDRV_6DB (0x3f<<24) /* 29:24 */ +#define A60810_RG_SSUSB_FORCE_IDEM_3P5DB (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_IDEM_3P5DB (0x3f<<16) /* 21:16 */ +#define A60810_RG_SSUSB_FORCE_IDRV_3P5DB (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_IDRV_3P5DB (0x3f<<8) /* 13:8 */ +#define A60810_RG_SSUSB_FORCE_IDRV_0DB (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_IDRV_0DB (0x3f<<0) /* 5:0 */ + +/* U3D_B2_PHYD_TOP3 */ +#define A60810_RG_SSUSB_TX_BIASI (0x7<<25) /* 27:25 */ +#define A60810_RG_SSUSB_FORCE_TX_BIASI_EN (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_TX_BIASI_EN (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_FORCE_TX_BIASI (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_FORCE_IDEM_6DB (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_IDEM_6DB (0x3f<<0) /* 5:0 */ + +/* U3D_B2_PHYD_TOP4 */ +#define A60810_RG_SSUSB_G1_CDR_BIC_LTR (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_G1_CDR_BIC_LTD0 (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_G1_CDR_BC_LTD1 (0x1f<<16) /* 20:16 */ +#define A60810_RG_SSUSB_G1_L1SS_CDR_BW_SEL (0x3<<13) /* 14:13 */ +#define A60810_RG_SSUSB_G1_CDR_BC_LTR (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_G1_CDR_BW_SEL (0x3<<5) /* 6:5 */ +#define A60810_RG_SSUSB_G1_CDR_BC_LTD0 (0x1f<<0) /* 4:0 */ + +/* U3D_B2_PHYD_TOP5 */ +#define A60810_RG_SSUSB_G1_CDR_BIR_LTD1 (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_G1_CDR_BIR_LTR (0x1f<<16) /* 20:16 */ +#define A60810_RG_SSUSB_G1_CDR_BIR_LTD0 (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_G1_CDR_BIC_LTD1 (0xf<<0) /* 3:0 */ + +/* U3D_B2_PHYD_TOP6 */ +#define A60810_RG_SSUSB_G2_CDR_BIC_LTR (0xf<<28) /* 31:28 */ +#define A60810_RG_SSUSB_G2_CDR_BIC_LTD0 (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_G2_CDR_BC_LTD1 (0x1f<<16) /* 20:16 */ +#define A60810_RG_SSUSB_G2_L1SS_CDR_BW_SEL (0x3<<13) /* 14:13 */ +#define A60810_RG_SSUSB_G2_CDR_BC_LTR (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_G2_CDR_BW_SEL (0x3<<5) /* 6:5 */ +#define A60810_RG_SSUSB_G2_CDR_BC_LTD0 (0x1f<<0) /* 4:0 */ + +/* U3D_B2_PHYD_TOP7 */ +#define A60810_RG_SSUSB_G2_CDR_BIR_LTD1 (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_G2_CDR_BIR_LTR (0x1f<<16) /* 20:16 */ +#define A60810_RG_SSUSB_G2_CDR_BIR_LTD0 (0x1f<<8) /* 12:8 */ +#define A60810_RG_SSUSB_G2_CDR_BIC_LTD1 (0xf<<0) /* 3:0 */ + +/* U3D_B2_PHYD_P_SIGDET1 */ +#define A60810_RG_SSUSB_P_SIGDET_FLT_DIS (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_P_SIGDET_FLT_G2_DEAST_SEL (0x7f<<24) /* 30:24 */ +#define A60810_RG_SSUSB_P_SIGDET_FLT_G1_DEAST_SEL (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_P_SIGDET_FLT_P2_AST_SEL (0x7f<<8) /* 14:8 */ +#define A60810_RG_SSUSB_P_SIGDET_FLT_PX_AST_SEL (0x7f<<0) /* 6:0 */ + +/* U3D_B2_PHYD_P_SIGDET2 */ +#define A60810_RG_SSUSB_P_SIGDET_RX_VAL_S (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_P_SIGDET_L0S_DEAS_SEL (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_P_SIGDET_L0_EXIT_S (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_P_SIGDET_L0S_EXIT_T_S (0x3<<25) /* 26:25 */ +#define A60810_RG_SSUSB_P_SIGDET_L0S_EXIT_S (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_P_SIGDET_L0S_ENTRY_S (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_P_SIGDET_PRB_SEL (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_P_SIGDET_BK_SIG_T (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_P_SIGDET_P2_RXLFPS (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_P_SIGDET_NON_BK_AD (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_P_SIGDET_BK_B_RXEQ (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_P_SIGDET_G2_KO_SEL (0x3<<2) /* 3:2 */ +#define A60810_RG_SSUSB_P_SIGDET_G1_KO_SEL (0x3<<0) /* 1:0 */ + +/* U3D_B2_PHYD_P_SIGDET_CAL1 */ +#define A60810_RG_SSUSB_G2_2EIOS_DET_EN (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_P_SIGDET_CAL_OFFSET (0x1f<<24) /* 28:24 */ +#define A60810_RG_SSUSB_P_FORCE_SIGDET_CAL_OFFSET (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_P_SIGDET_CAL_EN (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_P_FORCE_SIGDET_CAL_EN (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_P_SIGDET_FLT_EN (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_P_SIGDET_SAMPLE_PRD (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_P_SIGDET_REK (0x1<<0) /* 0:0 */ + +/* U3D_B2_PHYD_RXDET1 */ +#define A60810_RG_SSUSB_RXDET_PRB_SEL (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_FORCE_CMDET (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_RXDET_EN (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_FORCE_RXDET_EN (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_RXDET_K_TWICE (0x1<<27) /* 27:27 */ +#define A60810_RG_SSUSB_RXDET_STB3_SET (0x1ff<<18) /* 26:18 */ +#define A60810_RG_SSUSB_RXDET_STB2_SET (0x1ff<<9) /* 17:9 */ +#define A60810_RG_SSUSB_RXDET_STB1_SET (0x1ff<<0) /* 8:0 */ + +/* U3D_B2_PHYD_RXDET2 */ +#define A60810_RG_SSUSB_PHYD_TRAINDEC_FORCE_CGEN (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_PHYD_BERTLB_FORCE_CGEN (0x1<<30) /* 30:30 */ +#define A60810_RG_SSUSB_PHYD_T2RLB_FORCE_CGEN (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_LCK2REF_EXT_EN (0x1<<28) /* 28:28 */ +#define A60810_RG_SSUSB_G2_LCK2REF_EXT_SEL (0xf<<24) /* 27:24 */ +#define A60810_RG_SSUSB_LCK2REF_EXT_SEL (0xf<<20) /* 23:20 */ +#define A60810_RG_SSUSB_PDN_T_SEL (0x3<<18) /* 19:18 */ +#define A60810_RG_SSUSB_RXDET_STB3_SET_P3 (0x1ff<<9) /* 17:9 */ +#define A60810_RG_SSUSB_RXDET_STB2_SET_P3 (0x1ff<<0) /* 8:0 */ + +/* U3D_B2_PHYD_MISC0 */ +#define A60810_RG_SSUSB_TX_EIDLE_LP_P0DLYCYC (0x3f<<26) /* 31:26 */ +#define A60810_RG_SSUSB_TX_SER_EN (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_FORCE_TX_SER_EN (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_TXPLL_REFCKSEL (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_FORCE_PLL_DDS_HF_EN (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_PLL_DDS_HF_EN_MAN (0x1<<21) /* 21:21 */ +#define A60810_RG_SSUSB_RXLFPS_ENTXDRV (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_RX_FL_UNLOCKTH (0xf<<16) /* 19:16 */ +#define A60810_RG_SSUSB_LFPS_PSEL (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_RX_SIGDET_EN (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_RX_SIGDET_EN_SEL (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_RX_PI_CAL_EN (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_RX_PI_CAL_EN_SEL (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_P3_CLS_CK_SEL (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_T2RLB_PSEL (0x3<<8) /* 9:8 */ +#define A60810_RG_SSUSB_PPCTL_PSEL (0x7<<5) /* 7:5 */ +#define A60810_RG_SSUSB_PHYD_TX_DATA_INV (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_BERTLB_PSEL (0x3<<2) /* 3:2 */ +#define A60810_RG_SSUSB_RETRACK_DIS (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_PPERRCNT_CLR (0x1<<0) /* 0:0 */ + +/* U3D_B2_PHYD_MISC2 */ +#define A60810_RG_SSUSB_FRC_PLL_DDS_PREDIV2 (0x1<<31) /* 31:31 */ +#define A60810_RG_SSUSB_FRC_PLL_DDS_IADJ (0xf<<27) /* 30:27 */ +#define A60810_RG_SSUSB_P_SIGDET_125FILTER (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_P_SIGDET_RST_FILTER (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_P_SIGDET_EID_USE_RAW (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_P_SIGDET_LTD_USE_RAW (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_EIDLE_BF_RXDET (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_EIDLE_LP_STBCYC (0x1ff<<13) /* 21:13 */ +#define A60810_RG_SSUSB_TX_EIDLE_LP_POSTDLY (0x3f<<7) /* 12:7 */ +#define A60810_RG_SSUSB_TX_EIDLE_LP_PREDLY (0x3f<<1) /* 6:1 */ +#define A60810_RG_SSUSB_TX_EIDLE_LP_EN_ADV (0x1<<0) /* 0:0 */ + +/* U3D_B2_PHYD_MISC3 */ +#define A60810_RGS_SSUSB_DDS_CALIB_C_STATE (0x7<<16) /* 18:16 */ +#define A60810_RGS_SSUSB_PPERRCNT (0xffff<<0) /* 15:0 */ + +/* U3D_B2_PHYD_L1SS */ +#define A60810_RG_SSUSB_L1SS_REV1 (0xff<<24) /* 31:24 */ +#define A60810_RG_SSUSB_L1SS_REV0 (0xff<<16) /* 23:16 */ +#define A60810_RG_SSUSB_P_LTD1_SLOCK_DIS (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_PLL_CNT_CLEAN_DIS (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_P_PLL_REK_SEL (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_TXDRV_MASKDLY (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_RXSTS_VAL (0x1<<7) /* 7:7 */ +#define A60810_RG_PCIE_PHY_CLKREQ_N_EN (0x1<<6) /* 6:6 */ +#define A60810_RG_PCIE_FORCE_PHY_CLKREQ_N_EN (0x1<<5) /* 5:5 */ +#define A60810_RG_PCIE_PHY_CLKREQ_N_OUT (0x1<<4) /* 4:4 */ +#define A60810_RG_PCIE_FORCE_PHY_CLKREQ_N_OUT (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_RXPLL_STB_PX0 (0x1<<2) /* 2:2 */ +#define A60810_RG_PCIE_L1SS_EN (0x1<<1) /* 1:1 */ +#define A60810_RG_PCIE_FORCE_L1SS_EN (0x1<<0) /* 0:0 */ + +/* U3D_B2_ROSC_0 */ +#define A60810_RG_SSUSB_RING_OSC_CNTEND (0x1ff<<23) /* 31:23 */ +#define A60810_RG_SSUSB_XTAL_OSC_CNTEND (0x7f<<16) /* 22:16 */ +#define A60810_RG_SSUSB_RING_OSC_EN (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_RING_OSC_FORCE_EN (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_FRC_RING_BYPASS_DET (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_RING_BYPASS_DET (0x1<<0) /* 0:0 */ + +/* U3D_B2_ROSC_1 */ +#define A60810_RG_SSUSB_RING_OSC_FRC_P3 (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_RING_OSC_P3 (0x1<<19) /* 19:19 */ +#define A60810_RG_SSUSB_RING_OSC_FRC_RECAL (0x3<<17) /* 18:17 */ +#define A60810_RG_SSUSB_RING_OSC_RECAL (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_RING_OSC_SEL (0xff<<8) /* 15:8 */ +#define A60810_RG_SSUSB_RING_OSC_FRC_SEL (0x1<<0) /* 0:0 */ + +/* U3D_B2_ROSC_2 */ +#define A60810_RG_SSUSB_RING_DET_STRCYC2 (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RING_DET_STRCYC1 (0xffff<<0) /* 15:0 */ + +/* U3D_B2_ROSC_3 */ +#define A60810_RG_SSUSB_RING_DET_DETWIN1 (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RING_DET_STRCYC3 (0xffff<<0) /* 15:0 */ + +/* U3D_B2_ROSC_4 */ +#define A60810_RG_SSUSB_RING_DET_DETWIN3 (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RING_DET_DETWIN2 (0xffff<<0) /* 15:0 */ + +/* U3D_B2_ROSC_5 */ +#define A60810_RG_SSUSB_RING_DET_LBOND1 (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RING_DET_UBOND1 (0xffff<<0) /* 15:0 */ + +/* U3D_B2_ROSC_6 */ +#define A60810_RG_SSUSB_RING_DET_LBOND2 (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RING_DET_UBOND2 (0xffff<<0) /* 15:0 */ + +/* U3D_B2_ROSC_7 */ +#define A60810_RG_SSUSB_RING_DET_LBOND3 (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_RING_DET_UBOND3 (0xffff<<0) /* 15:0 */ + +/* U3D_B2_ROSC_8 */ +#define A60810_RG_SSUSB_RING_RESERVE (0xffff<<16) /* 31:16 */ +#define A60810_RG_SSUSB_ROSC_PROB_SEL (0xf<<2) /* 5:2 */ +#define A60810_RG_SSUSB_RING_FREQMETER_EN (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_RING_DET_BPS_UBOND (0x1<<0) /* 0:0 */ + +/* U3D_B2_ROSC_9 */ +#define A60810_RGS_FM_RING_CNT (0xffff<<16) /* 31:16 */ +#define A60810_RGS_SSUSB_RING_OSC_STATE (0x3<<10) /* 11:10 */ +#define A60810_RGS_SSUSB_RING_OSC_STABLE (0x1<<9) /* 9:9 */ +#define A60810_RGS_SSUSB_RING_OSC_CAL_FAIL (0x1<<8) /* 8:8 */ +#define A60810_RGS_SSUSB_RING_OSC_CAL (0xff<<0) /* 7:0 */ + +/* U3D_B2_ROSC_A */ +#define A60810_RGS_SSUSB_ROSC_PROB_OUT (0xff<<0) /* 7:0 */ + +/* U3D_PHYD_VERSION */ +#define A60810_RGS_SSUSB_PHYD_VERSION (0xffffffff<<0) /* 31:0 */ + +/* U3D_PHYD_MODEL */ +#define A60810_RGS_SSUSB_PHYD_MODEL (0xffffffff<<0) /* 31:0 */ + +/* OFFSET */ + +/* U3D_B2_PHYD_TOP1 */ +#define A60810_RG_SSUSB_PCIE2_K_EMP_OFST (28) +#define A60810_RG_SSUSB_PCIE2_K_FUL_OFST (24) +#define A60810_RG_SSUSB_TX_EIDLE_LP_EN_OFST (17) +#define A60810_RG_SSUSB_FORCE_TX_EIDLE_LP_EN_OFST (16) +#define A60810_RG_SSUSB_SIGDET_EN_OFST (15) +#define A60810_RG_SSUSB_FORCE_SIGDET_EN_OFST (14) +#define A60810_RG_SSUSB_CLKRX_EN_OFST (13) +#define A60810_RG_SSUSB_FORCE_CLKRX_EN_OFST (12) +#define A60810_RG_SSUSB_CLKTX_EN_OFST (11) +#define A60810_RG_SSUSB_FORCE_CLKTX_EN_OFST (10) +#define A60810_RG_SSUSB_CLK_REQ_N_I_OFST (9) +#define A60810_RG_SSUSB_FORCE_CLK_REQ_N_I_OFST (8) +#define A60810_RG_SSUSB_RATE_OFST (6) +#define A60810_RG_SSUSB_FORCE_RATE_OFST (5) +#define A60810_RG_SSUSB_PCIE_MODE_SEL_OFST (4) +#define A60810_RG_SSUSB_FORCE_PCIE_MODE_SEL_OFST (3) +#define A60810_RG_SSUSB_PHY_MODE_OFST (1) +#define A60810_RG_SSUSB_FORCE_PHY_MODE_OFST (0) + +/* U3D_B2_PHYD_TOP2 */ +#define A60810_RG_SSUSB_FORCE_IDRV_6DB_OFST (30) +#define A60810_RG_SSUSB_IDRV_6DB_OFST (24) +#define A60810_RG_SSUSB_FORCE_IDEM_3P5DB_OFST (22) +#define A60810_RG_SSUSB_IDEM_3P5DB_OFST (16) +#define A60810_RG_SSUSB_FORCE_IDRV_3P5DB_OFST (14) +#define A60810_RG_SSUSB_IDRV_3P5DB_OFST (8) +#define A60810_RG_SSUSB_FORCE_IDRV_0DB_OFST (6) +#define A60810_RG_SSUSB_IDRV_0DB_OFST (0) + +/* U3D_B2_PHYD_TOP3 */ +#define A60810_RG_SSUSB_TX_BIASI_OFST (25) +#define A60810_RG_SSUSB_FORCE_TX_BIASI_EN_OFST (24) +#define A60810_RG_SSUSB_TX_BIASI_EN_OFST (16) +#define A60810_RG_SSUSB_FORCE_TX_BIASI_OFST (13) +#define A60810_RG_SSUSB_FORCE_IDEM_6DB_OFST (8) +#define A60810_RG_SSUSB_IDEM_6DB_OFST (0) + +/* U3D_B2_PHYD_TOP4 */ +#define A60810_RG_SSUSB_G1_CDR_BIC_LTR_OFST (28) +#define A60810_RG_SSUSB_G1_CDR_BIC_LTD0_OFST (24) +#define A60810_RG_SSUSB_G1_CDR_BC_LTD1_OFST (16) +#define A60810_RG_SSUSB_G1_L1SS_CDR_BW_SEL_OFST (13) +#define A60810_RG_SSUSB_G1_CDR_BC_LTR_OFST (8) +#define A60810_RG_SSUSB_G1_CDR_BW_SEL_OFST (5) +#define A60810_RG_SSUSB_G1_CDR_BC_LTD0_OFST (0) + +/* U3D_B2_PHYD_TOP5 */ +#define A60810_RG_SSUSB_G1_CDR_BIR_LTD1_OFST (24) +#define A60810_RG_SSUSB_G1_CDR_BIR_LTR_OFST (16) +#define A60810_RG_SSUSB_G1_CDR_BIR_LTD0_OFST (8) +#define A60810_RG_SSUSB_G1_CDR_BIC_LTD1_OFST (0) + +/* U3D_B2_PHYD_TOP6 */ +#define A60810_RG_SSUSB_G2_CDR_BIC_LTR_OFST (28) +#define A60810_RG_SSUSB_G2_CDR_BIC_LTD0_OFST (24) +#define A60810_RG_SSUSB_G2_CDR_BC_LTD1_OFST (16) +#define A60810_RG_SSUSB_G2_L1SS_CDR_BW_SEL_OFST (13) +#define A60810_RG_SSUSB_G2_CDR_BC_LTR_OFST (8) +#define A60810_RG_SSUSB_G2_CDR_BW_SEL_OFST (5) +#define A60810_RG_SSUSB_G2_CDR_BC_LTD0_OFST (0) + +/* U3D_B2_PHYD_TOP7 */ +#define A60810_RG_SSUSB_G2_CDR_BIR_LTD1_OFST (24) +#define A60810_RG_SSUSB_G2_CDR_BIR_LTR_OFST (16) +#define A60810_RG_SSUSB_G2_CDR_BIR_LTD0_OFST (8) +#define A60810_RG_SSUSB_G2_CDR_BIC_LTD1_OFST (0) + +/* U3D_B2_PHYD_P_SIGDET1 */ +#define A60810_RG_SSUSB_P_SIGDET_FLT_DIS_OFST (31) +#define A60810_RG_SSUSB_P_SIGDET_FLT_G2_DEAST_SEL_OFST (24) +#define A60810_RG_SSUSB_P_SIGDET_FLT_G1_DEAST_SEL_OFST (16) +#define A60810_RG_SSUSB_P_SIGDET_FLT_P2_AST_SEL_OFST (8) +#define A60810_RG_SSUSB_P_SIGDET_FLT_PX_AST_SEL_OFST (0) + +/* U3D_B2_PHYD_P_SIGDET2 */ +#define A60810_RG_SSUSB_P_SIGDET_RX_VAL_S_OFST (29) +#define A60810_RG_SSUSB_P_SIGDET_L0S_DEAS_SEL_OFST (28) +#define A60810_RG_SSUSB_P_SIGDET_L0_EXIT_S_OFST (27) +#define A60810_RG_SSUSB_P_SIGDET_L0S_EXIT_T_S_OFST (25) +#define A60810_RG_SSUSB_P_SIGDET_L0S_EXIT_S_OFST (24) +#define A60810_RG_SSUSB_P_SIGDET_L0S_ENTRY_S_OFST (16) +#define A60810_RG_SSUSB_P_SIGDET_PRB_SEL_OFST (10) +#define A60810_RG_SSUSB_P_SIGDET_BK_SIG_T_OFST (8) +#define A60810_RG_SSUSB_P_SIGDET_P2_RXLFPS_OFST (6) +#define A60810_RG_SSUSB_P_SIGDET_NON_BK_AD_OFST (5) +#define A60810_RG_SSUSB_P_SIGDET_BK_B_RXEQ_OFST (4) +#define A60810_RG_SSUSB_P_SIGDET_G2_KO_SEL_OFST (2) +#define A60810_RG_SSUSB_P_SIGDET_G1_KO_SEL_OFST (0) + +/* U3D_B2_PHYD_P_SIGDET_CAL1 */ +#define A60810_RG_SSUSB_G2_2EIOS_DET_EN_OFST (29) +#define A60810_RG_SSUSB_P_SIGDET_CAL_OFFSET_OFST (24) +#define A60810_RG_SSUSB_P_FORCE_SIGDET_CAL_OFFSET_OFST (16) +#define A60810_RG_SSUSB_P_SIGDET_CAL_EN_OFST (8) +#define A60810_RG_SSUSB_P_FORCE_SIGDET_CAL_EN_OFST (3) +#define A60810_RG_SSUSB_P_SIGDET_FLT_EN_OFST (2) +#define A60810_RG_SSUSB_P_SIGDET_SAMPLE_PRD_OFST (1) +#define A60810_RG_SSUSB_P_SIGDET_REK_OFST (0) + +/* U3D_B2_PHYD_RXDET1 */ +#define A60810_RG_SSUSB_RXDET_PRB_SEL_OFST (31) +#define A60810_RG_SSUSB_FORCE_CMDET_OFST (30) +#define A60810_RG_SSUSB_RXDET_EN_OFST (29) +#define A60810_RG_SSUSB_FORCE_RXDET_EN_OFST (28) +#define A60810_RG_SSUSB_RXDET_K_TWICE_OFST (27) +#define A60810_RG_SSUSB_RXDET_STB3_SET_OFST (18) +#define A60810_RG_SSUSB_RXDET_STB2_SET_OFST (9) +#define A60810_RG_SSUSB_RXDET_STB1_SET_OFST (0) + +/* U3D_B2_PHYD_RXDET2 */ +#define A60810_RG_SSUSB_PHYD_TRAINDEC_FORCE_CGEN_OFST (31) +#define A60810_RG_SSUSB_PHYD_BERTLB_FORCE_CGEN_OFST (30) +#define A60810_RG_SSUSB_PHYD_T2RLB_FORCE_CGEN_OFST (29) +#define A60810_RG_SSUSB_LCK2REF_EXT_EN_OFST (28) +#define A60810_RG_SSUSB_G2_LCK2REF_EXT_SEL_OFST (24) +#define A60810_RG_SSUSB_LCK2REF_EXT_SEL_OFST (20) +#define A60810_RG_SSUSB_PDN_T_SEL_OFST (18) +#define A60810_RG_SSUSB_RXDET_STB3_SET_P3_OFST (9) +#define A60810_RG_SSUSB_RXDET_STB2_SET_P3_OFST (0) + +/* U3D_B2_PHYD_MISC0 */ +#define A60810_RG_SSUSB_TX_EIDLE_LP_P0DLYCYC_OFST (26) +#define A60810_RG_SSUSB_TX_SER_EN_OFST (25) +#define A60810_RG_SSUSB_FORCE_TX_SER_EN_OFST (24) +#define A60810_RG_SSUSB_TXPLL_REFCKSEL_OFST (23) +#define A60810_RG_SSUSB_FORCE_PLL_DDS_HF_EN_OFST (22) +#define A60810_RG_SSUSB_PLL_DDS_HF_EN_MAN_OFST (21) +#define A60810_RG_SSUSB_RXLFPS_ENTXDRV_OFST (20) +#define A60810_RG_SSUSB_RX_FL_UNLOCKTH_OFST (16) +#define A60810_RG_SSUSB_LFPS_PSEL_OFST (15) +#define A60810_RG_SSUSB_RX_SIGDET_EN_OFST (14) +#define A60810_RG_SSUSB_RX_SIGDET_EN_SEL_OFST (13) +#define A60810_RG_SSUSB_RX_PI_CAL_EN_OFST (12) +#define A60810_RG_SSUSB_RX_PI_CAL_EN_SEL_OFST (11) +#define A60810_RG_SSUSB_P3_CLS_CK_SEL_OFST (10) +#define A60810_RG_SSUSB_T2RLB_PSEL_OFST (8) +#define A60810_RG_SSUSB_PPCTL_PSEL_OFST (5) +#define A60810_RG_SSUSB_PHYD_TX_DATA_INV_OFST (4) +#define A60810_RG_SSUSB_BERTLB_PSEL_OFST (2) +#define A60810_RG_SSUSB_RETRACK_DIS_OFST (1) +#define A60810_RG_SSUSB_PPERRCNT_CLR_OFST (0) + +/* U3D_B2_PHYD_MISC2 */ +#define A60810_RG_SSUSB_FRC_PLL_DDS_PREDIV2_OFST (31) +#define A60810_RG_SSUSB_FRC_PLL_DDS_IADJ_OFST (27) +#define A60810_RG_SSUSB_P_SIGDET_125FILTER_OFST (26) +#define A60810_RG_SSUSB_P_SIGDET_RST_FILTER_OFST (25) +#define A60810_RG_SSUSB_P_SIGDET_EID_USE_RAW_OFST (24) +#define A60810_RG_SSUSB_P_SIGDET_LTD_USE_RAW_OFST (23) +#define A60810_RG_SSUSB_EIDLE_BF_RXDET_OFST (22) +#define A60810_RG_SSUSB_EIDLE_LP_STBCYC_OFST (13) +#define A60810_RG_SSUSB_TX_EIDLE_LP_POSTDLY_OFST (7) +#define A60810_RG_SSUSB_TX_EIDLE_LP_PREDLY_OFST (1) +#define A60810_RG_SSUSB_TX_EIDLE_LP_EN_ADV_OFST (0) + +/* U3D_B2_PHYD_MISC3 */ +#define A60810_RGS_SSUSB_DDS_CALIB_C_STATE_OFST (16) +#define A60810_RGS_SSUSB_PPERRCNT_OFST (0) + +/* U3D_B2_PHYD_L1SS */ +#define A60810_RG_SSUSB_L1SS_REV1_OFST (24) +#define A60810_RG_SSUSB_L1SS_REV0_OFST (16) +#define A60810_RG_SSUSB_P_LTD1_SLOCK_DIS_OFST (11) +#define A60810_RG_SSUSB_PLL_CNT_CLEAN_DIS_OFST (10) +#define A60810_RG_SSUSB_P_PLL_REK_SEL_OFST (9) +#define A60810_RG_SSUSB_TXDRV_MASKDLY_OFST (8) +#define A60810_RG_SSUSB_RXSTS_VAL_OFST (7) +#define A60810_RG_PCIE_PHY_CLKREQ_N_EN_OFST (6) +#define A60810_RG_PCIE_FORCE_PHY_CLKREQ_N_EN_OFST (5) +#define A60810_RG_PCIE_PHY_CLKREQ_N_OUT_OFST (4) +#define A60810_RG_PCIE_FORCE_PHY_CLKREQ_N_OUT_OFST (3) +#define A60810_RG_SSUSB_RXPLL_STB_PX0_OFST (2) +#define A60810_RG_PCIE_L1SS_EN_OFST (1) +#define A60810_RG_PCIE_FORCE_L1SS_EN_OFST (0) + +/* U3D_B2_ROSC_0 */ +#define A60810_RG_SSUSB_RING_OSC_CNTEND_OFST (23) +#define A60810_RG_SSUSB_XTAL_OSC_CNTEND_OFST (16) +#define A60810_RG_SSUSB_RING_OSC_EN_OFST (3) +#define A60810_RG_SSUSB_RING_OSC_FORCE_EN_OFST (2) +#define A60810_RG_SSUSB_FRC_RING_BYPASS_DET_OFST (1) +#define A60810_RG_SSUSB_RING_BYPASS_DET_OFST (0) + +/* U3D_B2_ROSC_1 */ +#define A60810_RG_SSUSB_RING_OSC_FRC_P3_OFST (20) +#define A60810_RG_SSUSB_RING_OSC_P3_OFST (19) +#define A60810_RG_SSUSB_RING_OSC_FRC_RECAL_OFST (17) +#define A60810_RG_SSUSB_RING_OSC_RECAL_OFST (16) +#define A60810_RG_SSUSB_RING_OSC_SEL_OFST (8) +#define A60810_RG_SSUSB_RING_OSC_FRC_SEL_OFST (0) + +/* U3D_B2_ROSC_2 */ +#define A60810_RG_SSUSB_RING_DET_STRCYC2_OFST (16) +#define A60810_RG_SSUSB_RING_DET_STRCYC1_OFST (0) + +/* U3D_B2_ROSC_3 */ +#define A60810_RG_SSUSB_RING_DET_DETWIN1_OFST (16) +#define A60810_RG_SSUSB_RING_DET_STRCYC3_OFST (0) + +/* U3D_B2_ROSC_4 */ +#define A60810_RG_SSUSB_RING_DET_DETWIN3_OFST (16) +#define A60810_RG_SSUSB_RING_DET_DETWIN2_OFST (0) + +/* U3D_B2_ROSC_5 */ +#define A60810_RG_SSUSB_RING_DET_LBOND1_OFST (16) +#define A60810_RG_SSUSB_RING_DET_UBOND1_OFST (0) + +/* U3D_B2_ROSC_6 */ +#define A60810_RG_SSUSB_RING_DET_LBOND2_OFST (16) +#define A60810_RG_SSUSB_RING_DET_UBOND2_OFST (0) + +/* U3D_B2_ROSC_7 */ +#define A60810_RG_SSUSB_RING_DET_LBOND3_OFST (16) +#define A60810_RG_SSUSB_RING_DET_UBOND3_OFST (0) + +/* U3D_B2_ROSC_8 */ +#define A60810_RG_SSUSB_RING_RESERVE_OFST (16) +#define A60810_RG_SSUSB_ROSC_PROB_SEL_OFST (2) +#define A60810_RG_SSUSB_RING_FREQMETER_EN_OFST (1) +#define A60810_RG_SSUSB_RING_DET_BPS_UBOND_OFST (0) + +/* U3D_B2_ROSC_9 */ +#define A60810_RGS_FM_RING_CNT_OFST (16) +#define A60810_RGS_SSUSB_RING_OSC_STATE_OFST (10) +#define A60810_RGS_SSUSB_RING_OSC_STABLE_OFST (9) +#define A60810_RGS_SSUSB_RING_OSC_CAL_FAIL_OFST (8) +#define A60810_RGS_SSUSB_RING_OSC_CAL_OFST (0) + +/* U3D_B2_ROSC_A */ +#define A60810_RGS_SSUSB_ROSC_PROB_OUT_OFST (0) + +/* U3D_PHYD_VERSION */ +#define A60810_RGS_SSUSB_PHYD_VERSION_OFST (0) + +/* U3D_PHYD_MODEL */ +#define A60810_RGS_SSUSB_PHYD_MODEL_OFST (0) + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct sifslv_chip_reg_a { + /* 0x0 */ + PHY_LE32 gpio_ctla; + PHY_LE32 gpio_ctlb; + PHY_LE32 gpio_ctlc; +}; + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct sifslv_fm_reg_a { + /* 0x0 */ + PHY_LE32 fmcr0; + PHY_LE32 fmcr1; + PHY_LE32 fmcr2; + PHY_LE32 fmmonr0; + /* 0X10 */ + PHY_LE32 fmmonr1; +}; + +/* U3D_FMCR0 */ +#define A60810_RG_LOCKTH (0xf<<28) /* 31:28 */ +#define A60810_RG_MONCLK_SEL (0x3<<26) /* 27:26 */ +#define A60810_RG_FM_MODE (0x1<<25) /* 25:25 */ +#define A60810_RG_FREQDET_EN (0x1<<24) /* 24:24 */ +#define A60810_RG_CYCLECNT (0xffffff<<0) /* 23:0 */ + +/* U3D_FMCR1 */ +#define A60810_RG_TARGET (0xffffffff<<0) /* 31:0 */ + +/* U3D_FMCR2 */ +#define A60810_RG_OFFSET (0xffffffff<<0) /* 31:0 */ + +/* U3D_FMMONR0 */ +#define A60810_USB_FM_OUT (0xffffffff<<0) /* 31:0 */ + +/* U3D_FMMONR1 */ +#define A60810_RG_MONCLK_SEL_2 (0x1<<9) /* 9:9 */ +#define A60810_RG_FRCK_EN (0x1<<8) /* 8:8 */ +#define A60810_USBPLL_LOCK (0x1<<1) /* 1:1 */ +#define A60810_USB_FM_VLD (0x1<<0) /* 0:0 */ + +/* OFFSET */ + +/* U3D_FMCR0 */ +#define A60810_RG_LOCKTH_OFST (28) +#define A60810_RG_MONCLK_SEL_OFST (26) +#define A60810_RG_FM_MODE_OFST (25) +#define A60810_RG_FREQDET_EN_OFST (24) +#define A60810_RG_CYCLECNT_OFST (0) + +/* U3D_FMCR1 */ +#define A60810_RG_TARGET_OFST (0) + +/* U3D_FMCR2 */ +#define A60810_RG_OFFSET_OFST (0) + +/* U3D_FMMONR0 */ +#define A60810_USB_FM_OUT_OFST (0) + +/* U3D_FMMONR1 */ +#define A60810_RG_MONCLK_SEL_2_OFST (9) +#define A60810_RG_FRCK_EN_OFST (8) +#define A60810_USBPLL_LOCK_OFST (1) +#define A60810_USB_FM_VLD_OFST (0) + +/* ///////////////////////////////////////////////////////////////////////////// */ + +struct spllc_reg_a { + /* 0x0 */ + PHY_LE32 u3d_syspll_0; + PHY_LE32 u3d_syspll_1; + PHY_LE32 u3d_syspll_2; + PHY_LE32 u3d_syspll_sdm; + /* 0x10 */ + PHY_LE32 u3d_xtalctl_1; + PHY_LE32 u3d_xtalctl_2; + PHY_LE32 u3d_xtalctl3; +}; + +/* U3D_SYSPLL_0 */ +#define A60810_RG_SSUSB_SPLL_DDSEN_CYC (0x1f<<27) /* 31:27 */ +#define A60810_RG_SSUSB_SPLL_NCPOEN_CYC (0x3<<25) /* 26:25 */ +#define A60810_RG_SSUSB_SPLL_STBCYC (0x1ff<<16) /* 24:16 */ +#define A60810_RG_SSUSB_SPLL_NCPOCHG_CYC (0xf<<12) /* 15:12 */ +#define A60810_RG_SSUSB_SYSPLL_ON (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_FORCE_SYSPLLON (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_SPLL_DDSRSTB_CYC (0x7<<0) /* 2:0 */ + +/* U3D_SYSPLL_1 */ +#define A60810_RG_SSUSB_PLL_BIAS_CYC (0xff<<24) /* 31:24 */ +#define A60810_RG_SSUSB_SYSPLL_STB (0x1<<23) /* 23:23 */ +#define A60810_RG_SSUSB_FORCE_SYSPLL_STB (0x1<<22) /* 22:22 */ +#define A60810_RG_SSUSB_SPLL_DDS_ISO_EN (0x1<<21) /* 21:21 */ +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_ISO_EN (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_SPLL_DDS_PWR_ON (0x1<<19) /* 19:19 */ +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_PWR_ON (0x1<<18) /* 18:18 */ +#define A60810_RG_SSUSB_PLL_BIAS_PWD (0x1<<17) /* 17:17 */ +#define A60810_RG_SSUSB_FORCE_PLL_BIAS_PWD (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_FORCE_SPLL_NCPO_EN (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_FORCE_SPLL_FIFO_START_MAN (0x1<<14) /* 14:14 */ +#define A60810_RG_SSUSB_FORCE_SPLL_NCPO_CHG (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_RSTB (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_PWDB (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_FORCE_SPLL_DDSEN (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_FORCE_SPLL_PWD (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_SPLL_NCPO_EN (0x1<<7) /* 7:7 */ +#define A60810_RG_SSUSB_SPLL_FIFO_START_MAN (0x1<<6) /* 6:6 */ +#define A60810_RG_SSUSB_SPLL_NCPO_CHG (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_SPLL_DDS_RSTB (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_SPLL_DDS_PWDB (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_SPLL_DDSEN (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_SPLL_PWD (0x1<<0) /* 0:0 */ + +/* U3D_SYSPLL_2 */ +#define A60810_RG_SSUSB_SPLL_P_ON_SEL (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_SPLL_FBDIV_CHG (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_SPLL_DDS_ISOEN_CYC (0x3ff<<0) /* 9:0 */ + +/* U3D_SYSPLL_SDM */ +#define A60810_RG_SSUSB_SPLL_SDM_ISO_EN_CYC (0x3ff<<14) /* 23:14 */ +#define A60810_RG_SSUSB_SPLL_FORCE_SDM_ISO_EN (0x1<<13) /* 13:13 */ +#define A60810_RG_SSUSB_SPLL_SDM_ISO_EN (0x1<<12) /* 12:12 */ +#define A60810_RG_SSUSB_SPLL_SDM_PWR_ON_CYC (0x3ff<<2) /* 11:2 */ +#define A60810_RG_SSUSB_SPLL_FORCE_SDM_PWR_ON (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_SPLL_SDM_PWR_ON (0x1<<0) /* 0:0 */ + +/* U3D_XTALCTL_1 */ +#define A60810_RG_SSUSB_BIAS_STBCYC (0x3fff<<17) /* 30:17 */ +#define A60810_RG_SSUSB_XTAL_CLK_REQ_N (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_XTAL_FORCE_CLK_REQ_N (0x1<<15) /* 15:15 */ +#define A60810_RG_SSUSB_XTAL_STBCYC (0x7fff<<0) /* 14:0 */ + +/* U3D_XTALCTL_2 */ +#define A60810_RG_SSUSB_INT_XTAL_SEL (0x1<<29) /* 29:29 */ +#define A60810_RG_SSUSB_BG_LPF_DLY (0x3<<27) /* 28:27 */ +#define A60810_RG_SSUSB_BG_LPF_EN (0x1<<26) /* 26:26 */ +#define A60810_RG_SSUSB_FORCE_BG_LPF_EN (0x1<<25) /* 25:25 */ +#define A60810_RG_SSUSB_P3_BIAS_PWD (0x1<<24) /* 24:24 */ +#define A60810_RG_SSUSB_PCIE_CLKDET_HIT (0x1<<20) /* 20:20 */ +#define A60810_RG_SSUSB_PCIE_CLKDET_EN (0x1<<19) /* 19:19 */ +#define A60810_RG_SSUSB_FRC_PCIE_CLKDET_EN (0x1<<18) /* 18:18 */ +#define A60810_RG_SSUSB_USB20_BIAS_EN (0x1<<17) /* 17:17 */ +#define A60810_RG_SSUSB_USB20_SLEEP (0x1<<16) /* 16:16 */ +#define A60810_RG_SSUSB_OSC_ONLY (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_OSC_EN (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_XTALBIAS_STB (0x1<<5) /* 5:5 */ +#define A60810_RG_SSUSB_FORCE_XTALBIAS_STB (0x1<<4) /* 4:4 */ +#define A60810_RG_SSUSB_BIAS_PWD (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_XTAL_PWD (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_FORCE_BIAS_PWD (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_FORCE_XTAL_PWD (0x1<<0) /* 0:0 */ + +/* U3D_XTALCTL3 */ +#define A60810_RG_SSUSB_XTALCTL_REV (0xf<<12) /* 15:12 */ +#define A60810_RG_SSUSB_BIASIMR_EN (0x1<<11) /* 11:11 */ +#define A60810_RG_SSUSB_FORCE_BIASIMR_EN (0x1<<10) /* 10:10 */ +#define A60810_RG_SSUSB_XTAL_RX_PWD (0x1<<9) /* 9:9 */ +#define A60810_RG_SSUSB_FRC_XTAL_RX_PWD (0x1<<8) /* 8:8 */ +#define A60810_RG_SSUSB_CKBG_PROB_SEL (0x3<<6) /* 7:6 */ +#define A60810_RG_SSUSB_XTAL_PROB_SEL (0x3<<4) /* 5:4 */ +#define A60810_RG_SSUSB_XTAL_VREGBIAS_LPF_ENB (0x1<<3) /* 3:3 */ +#define A60810_RG_SSUSB_XTAL_FRC_VREGBIAS_LPF_ENB (0x1<<2) /* 2:2 */ +#define A60810_RG_SSUSB_XTAL_VREGBIAS_PWD (0x1<<1) /* 1:1 */ +#define A60810_RG_SSUSB_XTAL_FRC_VREGBIAS_PWD (0x1<<0) /* 0:0 */ + + +/* SSUSB_SIFSLV_SPLLC FIELD OFFSET DEFINITION */ + +/* U3D_SYSPLL_0 */ +#define A60810_RG_SSUSB_SPLL_DDSEN_CYC_OFST (27) +#define A60810_RG_SSUSB_SPLL_NCPOEN_CYC_OFST (25) +#define A60810_RG_SSUSB_SPLL_STBCYC_OFST (16) +#define A60810_RG_SSUSB_SPLL_NCPOCHG_CYC_OFST (12) +#define A60810_RG_SSUSB_SYSPLL_ON_OFST (11) +#define A60810_RG_SSUSB_FORCE_SYSPLLON_OFST (10) +#define A60810_RG_SSUSB_SPLL_DDSRSTB_CYC_OFST (0) + +/* U3D_SYA60810_SPLL_1 */ +#define A60810_RG_SSUSB_PLL_BIAS_CYC_OFST (24) +#define A60810_RG_SSUSB_SYSPLL_STB_OFST (23) +#define A60810_RG_SSUSB_FORCE_SYSPLL_STB_OFST (22) +#define A60810_RG_SSUSB_SPLL_DDS_ISO_EN_OFST (21) +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_ISO_EN_OFST (20) +#define A60810_RG_SSUSB_SPLL_DDS_PWR_ON_OFST (19) +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_PWR_ON_OFST (18) +#define A60810_RG_SSUSB_PLL_BIAS_PWD_OFST (17) +#define A60810_RG_SSUSB_FORCE_PLL_BIAS_PWD_OFST (16) +#define A60810_RG_SSUSB_FORCE_SPLL_NCPO_EN_OFST (15) +#define A60810_RG_SSUSB_FORCE_SPLL_FIFO_START_MAN_OFST (14) +#define A60810_RG_SSUSB_FORCE_SPLL_NCPO_CHG_OFST (12) +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_RSTB_OFST (11) +#define A60810_RG_SSUSB_FORCE_SPLL_DDS_PWDB_OFST (10) +#define A60810_RG_SSUSB_FORCE_SPLL_DDSEN_OFST (9) +#define A60810_RG_SSUSB_FORCE_SPLL_PWD_OFST (8) +#define A60810_RG_SSUSB_SPLL_NCPO_EN_OFST (7) +#define A60810_RG_SSUSB_SPLL_FIFO_START_MAN_OFST (6) +#define A60810_RG_SSUSB_SPLL_NCPO_CHG_OFST (4) +#define A60810_RG_SSUSB_SPLL_DDS_RSTB_OFST (3) +#define A60810_RG_SSUSB_SPLL_DDS_PWDB_OFST (2) +#define A60810_RG_SSUSB_SPLL_DDSEN_OFST (1) +#define A60810_RG_SSUSB_SPLL_PWD_OFST (0) + +/* U3D_SYSPLL_2 */ +#define A60810_RG_SSUSB_SPLL_P_ON_SEL_OFST (11) +#define A60810_RG_SSUSB_SPLL_FBDIV_CHG_OFST (10) +#define A60810_RG_SSUSB_SPLL_DDS_ISOEN_CYC_OFST (0) + +/* U3D_SYSPLL_SDM */ +#define A60810_RG_SSUSB_SPLL_SDM_ISO_EN_CYC_OFST (14) +#define A60810_RG_SSUSB_SPLL_FORCE_SDM_ISO_EN_OFST (13) +#define A60810_RG_SSUSB_SPLL_SDM_ISO_EN_OFST (12) +#define A60810_RG_SSUSB_SPLL_SDM_PWR_ON_CYC_OFST (2) +#define A60810_RG_SSUSB_SPLL_FORCE_SDM_PWR_ON_OFST (1) +#define A60810_RG_SSUSB_SPLL_SDM_PWR_ON_OFST (0) + +/* U3D_XTALCTL_1 */ +#define A60810_RG_SSUSB_BIAS_STBCYC_OFST (17) +#define A60810_RG_SSUSB_XTAL_CLK_REQ_N_OFST (16) +#define A60810_RG_SSUSB_XTAL_FORCE_CLK_REQ_N_OFST (15) +#define A60810_RG_SSUSB_XTAL_STBCYC_OFST (0) + +/* U3D_XTALCTL_2 */ +#define A60810_RG_SSUSB_INT_XTAL_SEL_OFST (29) +#define A60810_RG_SSUSB_BG_LPF_DLY_OFST (27) +#define A60810_RG_SSUSB_BG_LPF_EN_OFST (26) +#define A60810_RG_SSUSB_FORCE_BG_LPF_EN_OFST (25) +#define A60810_RG_SSUSB_P3_BIAS_PWD_OFST (24) +#define A60810_RG_SSUSB_PCIE_CLKDET_HIT_OFST (20) +#define A60810_RG_SSUSB_PCIE_CLKDET_EN_OFST (19) +#define A60810_RG_SSUSB_FRC_PCIE_CLKDET_EN_OFST (18) +#define A60810_RG_SSUSB_USB20_BIAS_EN_OFST (17) +#define A60810_RG_SSUSB_USB20_SLEEP_OFST (16) +#define A60810_RG_SSUSB_OSC_ONLY_OFST (9) +#define A60810_RG_SSUSB_OSC_EN_OFST (8) +#define A60810_RG_SSUSB_XTALBIAS_STB_OFST (5) +#define A60810_RG_SSUSB_FORCE_XTALBIAS_STB_OFST (4) +#define A60810_RG_SSUSB_BIAS_PWD_OFST (3) +#define A60810_RG_SSUSB_XTAL_PWD_OFST (2) +#define A60810_RG_SSUSB_FORCE_BIAS_PWD_OFST (1) +#define A60810_RG_SSUSB_FORCE_XTAL_PWD_OFST (0) + +/* U3D_XTALCTL3 */ +#define A60810_RG_SSUSB_XTALCTL_REV_OFST (12) +#define A60810_RG_SSUSB_BIASIMR_EN_OFST (11) +#define A60810_RG_SSUSB_FORCE_BIASIMR_EN_OFST (10) +#define A60810_RG_SSUSB_XTAL_RX_PWD_OFST (9) +#define A60810_RG_SSUSB_FRC_XTAL_RX_PWD_OFST (8) +#define A60810_RG_SSUSB_CKBG_PROB_SEL_OFST (6) +#define A60810_RG_SSUSB_XTAL_PROB_SEL_OFST (4) +#define A60810_RG_SSUSB_XTAL_VREGBIAS_LPF_ENB_OFST (3) +#define A60810_RG_SSUSB_XTAL_FRC_VREGBIAS_LPF_ENB_OFST (2) +#define A60810_RG_SSUSB_XTAL_VREGBIAS_PWD_OFST (1) +#define A60810_RG_SSUSB_XTAL_FRC_VREGBIAS_PWD_OFST (0) + +/* ///////////////////////////////////////////////////////////////////////////// */ +PHY_INT32 phy_init_a60810(struct u3phy_info *info); +PHY_INT32 phy_change_pipe_phase_a60810(struct u3phy_info *info, PHY_INT32 phy_drv, + PHY_INT32 pipe_phase); +PHY_INT32 eyescan_init_a60810(struct u3phy_info *info); +PHY_INT32 phy_eyescan_a60810(struct u3phy_info *info, PHY_INT32 x_t1, PHY_INT32 y_t1, + PHY_INT32 x_br, PHY_INT32 y_br, PHY_INT32 delta_x, PHY_INT32 delta_y, + PHY_INT32 eye_cnt, PHY_INT32 num_cnt, PHY_INT32 PI_cal_en, + PHY_INT32 num_ignore_cnt); +PHY_INT32 u2_connect_a60810(struct u3phy_info *info); +PHY_INT32 u2_disconnect_a60810(struct u3phy_info *info); +PHY_INT32 u2_save_cur_en_a60810(struct u3phy_info *info); +PHY_INT32 u2_save_cur_re_a60810(struct u3phy_info *info); +PHY_INT32 u2_slew_rate_calibration_a60810(struct u3phy_info *info); + +#endif +#endif diff --git a/drivers/misc/mediatek/mu3phy/mtk-phy-ahb.c b/drivers/misc/mediatek/mu3phy/mtk-phy-ahb.c new file mode 100644 index 000000000000..2c03dde249a7 --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/mtk-phy-ahb.c @@ -0,0 +1,35 @@ +#include "mtk-phy.h" +#ifdef CONFIG_U3D_HAL_SUPPORT +#include "mu3d_hal_osal.h" +#endif + +#ifdef CONFIG_U3_PHY_AHB_SUPPORT + +PHY_INT32 U3PhyWriteReg32(u3phy_addr_t addr, PHY_UINT32 data) +{ + if (0) + os_printk(K_DEBUG, "%s addr=%llx, data=%x\n", __func__, (unsigned long long)addr, + data); + writel(data, (void __iomem *)addr); + return 0; +} + +PHY_INT32 U3PhyReadReg32(u3phy_addr_t addr) +{ + return readl((void __iomem *)addr); +} + +PHY_INT32 U3PhyWriteReg8(u3phy_addr_t addr, PHY_UINT8 data) +{ + os_writelmsk((void __iomem *)(addr & ALIGN_MASK), data << ((addr % 4) * 8), + 0xff << ((addr % 4) * 8)); + + return 0; +} + +PHY_INT8 U3PhyReadReg8(u3phy_addr_t addr) +{ + return (readl((void __iomem *)(addr & ALIGN_MASK)) >> ((addr % 4) * 8)) & 0xff; +} + +#endif diff --git a/drivers/misc/mediatek/mu3phy/mtk-phy-gpio.c b/drivers/misc/mediatek/mu3phy/mtk-phy-gpio.c new file mode 100644 index 000000000000..e111662b0f8e --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/mtk-phy-gpio.c @@ -0,0 +1,454 @@ +#include <linux/mu3phy/mtk-phy.h> +#include <linux/mu3phy/mtk-phy.h> + +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + +/* TEST CHIP PHY define, edit this in different platform */ +#define U3_PHY_I2C_DEV 0x60 +#define U3_PHY_PAGE 0xff +#define GPIO_BASE 0xf0044700 /* 0x80080000 */ +#define SSUSB_I2C_OUT (GPIO_BASE+0xd0) +#define SSUSB_I2C_IN (GPIO_BASE+0xd4) + +#ifdef NEVER /* USE_GPIO */ + +/* /////////////////////////////////////////////////////////////// */ + +#define OUTPUT 1 +#define INPUT 0 + +#define SDA 0 /* / GPIO #0: I2C data pin */ +#define SCL 1 /* / GPIO #1: I2C clock pin */ + +/* /////////////////////////////////////////////////////////////// */ + +#define SDA_OUT (1<<0) +#define SDA_OEN (1<<1) +#define SCL_OUT (1<<2) +#define SCL_OEN (1<<3) + +#define SDA_IN_OFFSET 0 +#define SCL_IN_OFFSET 1 + +/* #define GPIO_PULLEN1_SET (GPIO_BASE+0x0030+0x04) */ +/* #define GPIO_DIR1_SET (GPIO_BASE+0x0000+0x04) */ +/* #define GPIO_PULLEN1_CLR (GPIO_BASE+0x0030+0x08) */ +/* #define GPIO_DIR1_CLR (GPIO_BASE+0x0000+0x08) */ +/* #define GPIO_DOUT1_SET (GPIO_BASE+0x00C0+0x04) */ +/* #define GPIO_DOUT1_CLR (GPIO_BASE+0x00C0+0x08) */ +/* #define GPIO_DIN1 (GPIO_BASE+0x00F0) */ + +void gpio_dir_set(PHY_INT32 pin) +{ + PHY_INT32 addr, temp; + + addr = SSUSB_I2C_OUT; + temp = DRV_Reg32(addr); + if (pin == SDA) { + temp |= SDA_OEN; + DRV_WriteReg32(addr, temp); + } else { + temp |= SCL_OEN; + DRV_WriteReg32(addr, temp); + } +} + +void gpio_dir_clr(PHY_INT32 pin) +{ + PHY_INT32 addr, temp; + + addr = SSUSB_I2C_OUT; + temp = DRV_Reg32(addr); + if (pin == SDA) { + temp &= ~SDA_OEN; + DRV_WriteReg32(addr, temp); + } else { + temp &= ~SCL_OEN; + DRV_WriteReg32(addr, temp); + } +} + +void gpio_dout_set(PHY_INT32 pin) +{ + PHY_INT32 addr, temp; + + addr = SSUSB_I2C_OUT; + temp = DRV_Reg32(addr); + if (pin == SDA) { + temp |= SDA_OUT; + DRV_WriteReg32(addr, temp); + } else { + temp |= SCL_OUT; + DRV_WriteReg32(addr, temp); + } +} + +void gpio_dout_clr(PHY_INT32 pin) +{ + PHY_INT32 addr, temp; + + addr = SSUSB_I2C_OUT; + temp = DRV_Reg32(addr); + if (pin == SDA) { + temp &= ~SDA_OUT; + DRV_WriteReg32(addr, temp); + } else { + temp &= ~SCL_OUT; + DRV_WriteReg32(addr, temp); + } +} + +PHY_INT32 gpio_din(PHY_INT32 pin) +{ + PHY_INT32 addr, temp; + + addr = SSUSB_I2C_IN; + temp = DRV_Reg32(addr); + if (pin == SDA) + temp = (temp >> SDA_IN_OFFSET) & 1; + else + temp = (temp >> SCL_IN_OFFSET) & 1; + return temp; +} + +/* #define GPIO_PULLEN_SET(_no) (GPIO_PULLEN1_SET+(0x10*(_no))) */ +#define GPIO_DIR_SET(pin) gpio_dir_set(pin) +#define GPIO_DOUT_SET(pin) gpio_dout_set(pin) +/* #define GPIO_PULLEN_CLR(_no) (GPIO_PULLEN1_CLR+(0x10*(_no))) */ +#define GPIO_DIR_CLR(pin) gpio_dir_clr(pin) +#define GPIO_DOUT_CLR(pin) gpio_dout_clr(pin) +#define GPIO_DIN(pin) gpio_din(pin) + + +PHY_UINT32 i2c_dummy_cnt; + +#define I2C_DELAY 10 +#define I2C_DUMMY_DELAY(_delay) for (i2c_dummy_cnt = ((_delay)); i2c_dummy_cnt != 0; i2c_dummy_cnt--) + +void GPIO_InitIO(PHY_UINT32 dir, PHY_UINT32 pin) +{ + if (dir == OUTPUT) { + /* DRV_WriteReg16(GPIO_PULLEN_SET(no),(1 << remainder)); */ + GPIO_DIR_SET(pin); + } else { + /* DRV_WriteReg16(GPIO_PULLEN_CLR(no),(1 << remainder)); */ + GPIO_DIR_CLR(pin); + } + I2C_DUMMY_DELAY(100); +} + +void GPIO_WriteIO(PHY_UINT32 data, PHY_UINT32 pin) +{ + if (data == 1) + GPIO_DOUT_SET(pin); + else + GPIO_DOUT_CLR(pin); +} + +PHY_UINT32 GPIO_ReadIO(PHY_UINT32 pin) +{ + PHY_UINT16 data; + + data = GPIO_DIN(pin); + return (PHY_UINT32) data; +} + + +void SerialCommStop(void) +{ + GPIO_InitIO(OUTPUT, SDA); + GPIO_WriteIO(0, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(0, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_InitIO(INPUT, SCL); + GPIO_InitIO(INPUT, SDA); +} + +void SerialCommStart(void) +{ /* Prepare the SDA and SCL for sending/receiving */ + GPIO_InitIO(OUTPUT, SCL); + GPIO_InitIO(OUTPUT, SDA); + GPIO_WriteIO(1, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(0, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(0, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); +} + +PHY_UINT32 SerialCommTxByte(PHY_UINT8 data) +{ /* return 0 --> ack */ + PHY_INT32 i, ack; + + GPIO_InitIO(OUTPUT, SDA); + + for (i = 8; --i > 0;) { + GPIO_WriteIO((data >> i) & 0x01, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SCL); /* high */ + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(0, SCL); /* low */ + I2C_DUMMY_DELAY(I2C_DELAY); + } + GPIO_WriteIO((data >> i) & 0x01, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SCL); /* high */ + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(0, SCL); /* low */ + I2C_DUMMY_DELAY(I2C_DELAY); + + GPIO_WriteIO(0, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_InitIO(INPUT, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + ack = GPIO_ReadIO(SDA); /* / ack 1: error , 0:ok */ + GPIO_WriteIO(0, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + + if (ack == 1) + return PHY_FALSE; + else + return PHY_TRUE; +} + +void SerialCommRxByte(PHY_UINT8 *data, PHY_UINT8 ack) +{ + PHY_INT32 i; + PHY_UINT32 dataCache; + + dataCache = 0; + GPIO_InitIO(INPUT, SDA); + for (i = 8; --i >= 0;) { + dataCache <<= 1; + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + dataCache |= GPIO_ReadIO(SDA); + GPIO_WriteIO(0, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + } + GPIO_InitIO(OUTPUT, SDA); + GPIO_WriteIO(ack, SDA); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(1, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + GPIO_WriteIO(0, SCL); + I2C_DUMMY_DELAY(I2C_DELAY); + *data = (unsigned char)dataCache; +} + +PHY_INT32 I2cWriteReg(PHY_UINT8 dev_id, PHY_UINT8 Addr, PHY_UINT8 Data) +{ + PHY_INT32 acknowledge = 0; + + SerialCommStart(); + acknowledge = SerialCommTxByte((dev_id << 1) & 0xff); + if (acknowledge) + acknowledge = SerialCommTxByte(Addr); + else + return PHY_FALSE; + acknowledge = SerialCommTxByte(Data); + if (acknowledge) { + SerialCommStop(); + return PHY_FALSE; + } else { + return PHY_TRUE; + } +} + +PHY_INT32 I2cReadReg(PHY_UINT8 dev_id, PHY_UINT8 Addr, PHY_UINT8 *Data) +{ + PHY_INT32 acknowledge = 0; + + SerialCommStart(); + acknowledge = SerialCommTxByte((dev_id << 1) & 0xff); + if (acknowledge) + acknowledge = SerialCommTxByte(Addr); + else + return PHY_FALSE; + SerialCommStart(); + acknowledge = SerialCommTxByte(((dev_id << 1) & 0xff) | 0x01); + if (acknowledge) + SerialCommRxByte(Data, 1); /* ack 0: ok , 1 error */ + else + return PHY_FALSE; + SerialCommStop(); + return acknowledge; +} + +#else /* Use I2C controller */ + +#define REG_I2C_START_BIT 0x1 +#define I2C_READ_BIT 0x1 + +#define PHY_I2C_BASE (i2c1_base) + +/* "volatile" type class should not be used, see volatile-considered-harmful.txt */ +#define REG_I2C_DATA_PORT (*((volatile unsigned short int *) (PHY_I2C_BASE + 0x00))) +#define REG_I2C_SLAVE_ADDR (*((volatile unsigned short int *) (PHY_I2C_BASE + 0x04))) +#define REG_I2C_TRANSFER_LEN (*((volatile unsigned short int *) (PHY_I2C_BASE + 0x14))) +#define REG_I2C_START (*((volatile unsigned short int *) (PHY_I2C_BASE + 0x24))) +#define REG_I2C_SOFT_RESET (*((volatile unsigned short int *) (PHY_I2C_BASE + 0x50))) +#define REG_I2C_CONTROL (*((volatile unsigned short int *) (PHY_I2C_BASE + 0x10))) + +#define IS_PRINT 0 + +PHY_INT32 I2cWriteReg(PHY_UINT8 dev_id, PHY_UINT8 addr, PHY_UINT8 val) +{ + if (IS_PRINT) + pr_debug("I2C Write@%x [%x]=%x\n", dev_id, addr, val); + + REG_I2C_SLAVE_ADDR = dev_id << 1; + REG_I2C_TRANSFER_LEN = 2; + + REG_I2C_DATA_PORT = addr; + REG_I2C_DATA_PORT = val; + + REG_I2C_START = REG_I2C_START_BIT; + + while ((REG_I2C_START & REG_I2C_START_BIT)) + NULL; + return PHY_TRUE; +} + +PHY_INT32 I2cReadReg(PHY_UINT8 dev_id, PHY_UINT8 addr, PHY_UINT8 *data) +{ + if (IS_PRINT) + pr_debug("I2C Read@%x [%x]\n", dev_id, addr); + + REG_I2C_SLAVE_ADDR = dev_id << 1; + REG_I2C_TRANSFER_LEN = 0x01; + REG_I2C_DATA_PORT = addr; + REG_I2C_START = REG_I2C_START_BIT; + + while ((REG_I2C_START & REG_I2C_START_BIT)) + NULL; + + REG_I2C_SLAVE_ADDR = (dev_id << 1) | I2C_READ_BIT; + REG_I2C_TRANSFER_LEN = 0x01; + REG_I2C_START = REG_I2C_START_BIT; + + while ((REG_I2C_START & REG_I2C_START_BIT)) + NULL; + + *data = REG_I2C_DATA_PORT; + + if (IS_PRINT) + pr_debug("I2C Read [%x]=%x\n", addr, *data); + + return PHY_TRUE; /* !!(PHY_INT32)*data; */ +} +#endif + +void _U3_Write_Bank(PHY_INT32 bankValue) +{ + I2cWriteReg(U3_PHY_I2C_DEV, U3_PHY_PAGE, bankValue); +} + +PHY_INT32 _U3Write_Reg(PHY_INT32 address, PHY_INT32 value) +{ + I2cWriteReg(U3_PHY_I2C_DEV, address, value); + return PHY_TRUE; +} + +PHY_INT32 _U3Read_Reg(PHY_INT32 address) +{ + PHY_INT8 *pu1Buf; + PHY_INT32 ret; + + pu1Buf = kmalloc(1, GFP_NOIO); + ret = I2cReadReg(U3_PHY_I2C_DEV, address, pu1Buf); + if (ret == PHY_FALSE) { + pr_err("Read failed\n"); + return PHY_FALSE; + } + ret = (char)pu1Buf[0]; + kfree(pu1Buf); + return ret; + +} + +PHY_INT32 U3PhyWriteReg32(PHY_UINT32 addr, PHY_UINT32 data) +{ + PHY_INT32 bank; + PHY_INT32 addr8; + PHY_INT32 data_0, data_1, data_2, data_3; + + bank = (addr >> 16) & 0xff; + addr8 = addr & 0xff; + data_0 = data & 0xff; + data_1 = (data >> 8) & 0xff; + data_2 = (data >> 16) & 0xff; + data_3 = (data >> 24) & 0xff; + + pr_debug("addr: %x, data: %x\n", addr8, data); + _U3_Write_Bank(bank); + pr_debug("addr: %x, data: %x\n", addr8, data_0); + _U3Write_Reg(addr8, data_0); + pr_debug("addr: %x, data: %x\n", addr8 + 1, data_1); + _U3Write_Reg(addr8 + 1, data_1); + pr_debug("addr: %x, data: %x\n", addr8 + 2, data_2); + _U3Write_Reg(addr8 + 2, data_2); + pr_debug("addr: %x, data: %x\n", addr8 + 3, data_3); + _U3Write_Reg(addr8 + 3, data_3); + + return 0; +} + +PHY_INT32 U3PhyReadReg32(PHY_UINT32 addr) +{ + PHY_INT32 bank; + PHY_INT32 addr8; + PHY_INT32 data; + + bank = (addr >> 16) & 0xff; + addr8 = addr & 0xff; + + _U3_Write_Bank(bank); + data = _U3Read_Reg(addr8); + data |= (_U3Read_Reg(addr8 + 1) << 8); + data |= (_U3Read_Reg(addr8 + 2) << 16); + data |= (_U3Read_Reg(addr8 + 3) << 24); + + return data; +} + +PHY_INT32 U3PhyWriteReg8(PHY_UINT32 addr, PHY_UINT8 data) +{ + PHY_INT32 bank; + PHY_INT32 addr8; + + bank = (addr >> 16) & 0xff; + addr8 = addr & 0xff; + _U3_Write_Bank(bank); + _U3Write_Reg(addr8, data); + + pr_debug("addr: %x, data: %x\n", addr8, data); + + return PHY_TRUE; +} + +PHY_INT8 U3PhyReadReg8(PHY_UINT32 addr) +{ + PHY_INT32 bank; + PHY_INT32 addr8; + PHY_INT32 data; + + bank = (addr >> 16) & 0xff; + addr8 = addr & 0xff; + _U3_Write_Bank(bank); + data = _U3Read_Reg(addr8); + + return data; +} + +#endif diff --git a/drivers/misc/mediatek/mu3phy/mtk-phy.c b/drivers/misc/mediatek/mu3phy/mtk-phy.c new file mode 100644 index 000000000000..2d02c0b4ff9f --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/mtk-phy.c @@ -0,0 +1,290 @@ +#define U3_PHY_LIB +#include "mtk-phy.h" +#undef U3_PHY_LIB + +#ifdef CONFIG_C60802_SUPPORT +#include "mtk-phy-c60802.h" +#endif +#ifdef CONFIG_D60802_SUPPORT +#include "mtk-phy-d60802.h" +#endif +#ifdef CONFIG_E60802_SUPPORT +#include "mtk-phy-e60802.h" +#endif +#ifdef CONFIG_A60810_SUPPORT +#include "mtk-phy-a60810.h" +#endif +#ifdef CONFIG_PROJECT_PHY +#include "mtk-phy-asic.h" +#endif + +#ifdef CONFIG_C60802_SUPPORT +static const struct u3phy_operator c60802_operators = { + .init = phy_init_c60802, + .change_pipe_phase = phy_change_pipe_phase_c60802, + .eyescan_init = eyescan_init_c60802, + .eyescan = phy_eyescan_c60802, + .u2_connect = u2_connect_c60802, + .u2_disconnect = u2_disconnect_c60802, + .u2_save_current_entry = u2_save_cur_en_c60802, + .u2_save_current_recovery = u2_save_cur_re_c60802, + .u2_slew_rate_calibration = u2_slew_rate_calibration_c60802, +}; +#endif +#ifdef CONFIG_D60802_SUPPORT +static const struct u3phy_operator d60802_operators = { + .init = phy_init_d60802, + .change_pipe_phase = phy_change_pipe_phase_d60802, + .eyescan_init = eyescan_init_d60802, + .eyescan = phy_eyescan_d60802, + .u2_connect = u2_connect_d60802, + .u2_disconnect = u2_disconnect_d60802, + /* .u2_save_current_entry = u2_save_cur_en_d60802, */ + /* .u2_save_current_recovery = u2_save_cur_re_d60802, */ + .u2_slew_rate_calibration = u2_slew_rate_calibration_d60802, +}; +#endif +#ifdef CONFIG_E60802_SUPPORT +static const struct u3phy_operator e60802_operators = { + .init = phy_init_e60802, + .change_pipe_phase = phy_change_pipe_phase_e60802, + .eyescan_init = eyescan_init_e60802, + .eyescan = phy_eyescan_e60802, + .u2_connect = u2_connect_e60802, + .u2_disconnect = u2_disconnect_e60802, + /* .u2_save_current_entry = u2_save_cur_en_e60802, */ + /* .u2_save_current_recovery = u2_save_cur_re_e60802, */ + .u2_slew_rate_calibration = u2_slew_rate_calibration_e60802, +}; +#endif +#ifdef CONFIG_A60810_SUPPORT +static const struct u3phy_operator a60810_operators = { + .init = phy_init_a60810, + .change_pipe_phase = phy_change_pipe_phase_a60810, + .eyescan_init = eyescan_init_a60810, + .eyescan = phy_eyescan_a60810, + .u2_connect = u2_connect_a60810, + .u2_disconnect = u2_disconnect_a60810, + /* .u2_save_current_entry = u2_save_cur_en_a60810, */ + /* .u2_save_current_recovery = u2_save_cur_re_a60810, */ + .u2_slew_rate_calibration = u2_slew_rate_calibration_a60810, +}; +#endif + +#ifdef CONFIG_PROJECT_PHY +static struct u3phy_operator project_operators = { + .init = phy_init_soc, + .u2_slew_rate_calibration = u2_slew_rate_calibration, +}; +#endif + + +PHY_INT32 u3phy_init(void) +{ +#ifndef CONFIG_PROJECT_PHY + PHY_INT32 u3phy_version; +#endif + + if (u3phy != NULL) + return PHY_TRUE; + + u3phy = kmalloc(sizeof(struct u3phy_info), GFP_NOIO); +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + u3phy->phyd_version_addr = 0x2000e4; +#else + u3phy->phyd_version_addr = U3_PHYD_B2_BASE + 0xe4; +#endif + u3phy_ops = NULL; + +#ifdef CONFIG_PROJECT_PHY + u3phy->u2phy_regs_e = (struct u2phy_reg_e *)U2_PHY_BASE; + u3phy->u3phyd_regs_e = (struct u3phyd_reg_e *)U3_PHYD_BASE; + u3phy->u3phyd_bank2_regs_e = (struct u3phyd_bank2_reg_e *)U3_PHYD_B2_BASE; + u3phy->u3phya_regs_e = (struct u3phya_reg_e *)U3_PHYA_BASE; + u3phy->u3phya_da_regs_e = (struct u3phya_da_reg_e *)U3_PHYA_DA_BASE; + u3phy->sifslv_chip_regs_e = (struct sifslv_chip_reg_e *)SIFSLV_CHIP_BASE; + u3phy->spllc_regs_e = (struct spllc_reg_e *)SIFSLV_SPLLC_BASE; + u3phy->sifslv_fm_regs_e = (struct sifslv_fm_feg_e *)SIFSLV_FM_FEG_BASE; + u3phy_ops = (struct u3phy_operator *)&project_operators; +#else + + /* parse phy version */ + u3phy_version = U3PhyReadReg32(u3phy->phyd_version_addr); + pr_debug("phy version: %x\n", u3phy_version); + u3phy->phy_version = u3phy_version; + + if (u3phy_version == 0xc60802a) { +#ifdef CONFIG_C60802_SUPPORT +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + u3phy->u2phy_regs_c = (struct u2phy_reg_c *)0x0; + u3phy->u3phyd_regs_c = (struct u3phyd_reg_c *)0x100000; + u3phy->u3phyd_bank2_regs_c = (struct u3phyd_bank2_reg_c *)0x200000; + u3phy->u3phya_regs_c = (struct u3phya_reg_c *)0x300000; + u3phy->u3phya_da_regs_c = (struct u3phya_da_reg_c *)0x400000; + u3phy->sifslv_chip_regs_c = (struct sifslv_chip_reg_c *)0x500000; + u3phy->sifslv_fm_regs_c = (struct sifslv_fm_feg_c *)0xf00000; +#else + u3phy->u2phy_regs_c = (struct u2phy_reg_c *)U2_PHY_BASE; + u3phy->u3phyd_regs_c = (struct u3phyd_reg_c *)U3_PHYD_BASE; + u3phy->u3phyd_bank2_regs_c = (struct u3phyd_bank2_reg_c *)U3_PHYD_B2_BASE; + u3phy->u3phya_regs_c = (struct u3phya_reg_c *)U3_PHYA_BASE; + u3phy->u3phya_da_regs_c = (struct u3phya_da_reg_c *)U3_PHYA_DA_BASE; + u3phy->sifslv_chip_regs_c = (struct sifslv_chip_reg_c *)SIFSLV_CHIP_BASE; + u3phy->sifslv_fm_regs_c = (struct sifslv_fm_feg_c *)SIFSLV_FM_FEG_BASE; +#endif + u3phy_ops = (struct u3phy_operator *)&c60802_operators; +#endif + } else if (u3phy_version == 0xd60802a) { +#ifdef CONFIG_D60802_SUPPORT +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + u3phy->u2phy_regs_d = (struct u2phy_reg_d *)0x0; + u3phy->u3phyd_regs_d = (struct u3phyd_reg_d *)0x100000; + u3phy->u3phyd_bank2_regs_d = (struct u3phyd_bank2_reg_d *)0x200000; + u3phy->u3phya_regs_d = (struct u3phya_reg_d *)0x300000; + u3phy->u3phya_da_regs_d = (struct u3phya_da_reg_d *)0x400000; + u3phy->sifslv_chip_regs_d = (struct sifslv_chip_reg_d *)0x500000; + u3phy->sifslv_fm_regs_d = (struct sifslv_fm_feg_d *)0xf00000; +#else + u3phy->u2phy_regs_d = (struct u2phy_reg_d *)U2_PHY_BASE; + u3phy->u3phyd_regs_d = (struct u3phyd_reg_d *)U3_PHYD_BASE; + u3phy->u3phyd_bank2_regs_d = (struct u3phyd_bank2_reg_d *)U3_PHYD_B2_BASE; + u3phy->u3phya_regs_d = (struct u3phya_reg_d *)U3_PHYA_BASE; + u3phy->u3phya_da_regs_d = (struct u3phya_da_reg_d *)U3_PHYA_DA_BASE; + u3phy->sifslv_chip_regs_d = (struct sifslv_chip_reg_d *)SIFSLV_CHIP_BASE; + u3phy->sifslv_fm_regs_d = (struct sifslv_fm_feg_d *)SIFSLV_FM_FEG_BASE; +#endif + u3phy_ops = ((struct u3phy_operator *)&d60802_operators); +#endif + } else if (u3phy_version == 0xe60802a) { +#ifdef CONFIG_E60802_SUPPORT +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + u3phy->u2phy_regs_e = (struct u2phy_reg_e *)0x0; + u3phy->u3phyd_regs_e = (struct u3phyd_reg_e *)0x100000; + u3phy->u3phyd_bank2_regs_e = (struct u3phyd_bank2_reg_e *)0x200000; + u3phy->u3phya_regs_e = (struct u3phya_reg_e *)0x300000; + u3phy->u3phya_da_regs_e = (struct u3phya_da_reg_e *)0x400000; + u3phy->sifslv_chip_regs_e = (struct sifslv_chip_reg_e *)0x500000; + u3phy->spllc_regs_e = (struct spllc_reg_e *)0x600000; + u3phy->sifslv_fm_regs_e = (struct sifslv_fm_feg_e *)0xf00000; +#else + u3phy->u2phy_regs_e = (struct u2phy_reg_e *)U2_PHY_BASE; + u3phy->u3phyd_regs_e = (struct u3phyd_reg_e *)U3_PHYD_BASE; + u3phy->u3phyd_bank2_regs_e = (struct u3phyd_bank2_reg_e *)U3_PHYD_B2_BASE; + u3phy->u3phya_regs_e = (struct u3phya_reg_e *)U3_PHYA_BASE; + u3phy->u3phya_da_regs_e = (struct u3phya_da_reg_e *)U3_PHYA_DA_BASE; + u3phy->sifslv_chip_regs_e = (struct sifslv_chip_reg_e *)SIFSLV_CHIP_BASE; + u3phy->sifslv_fm_regs_e = (struct sifslv_fm_feg_e *)SIFSLV_FM_FEG_BASE; +#endif + u3phy_ops = ((struct u3phy_operator *)&e60802_operators); +#endif + } else if (u3phy_version == 0xa60810a) { +#ifdef CONFIG_A60810_SUPPORT +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT + u3phy->u2phy_regs_a = (struct u2phy_reg_a *)0x0; + u3phy->u3phyd_regs_a = (struct u3phyd_reg_a *)0x100000; + u3phy->u3phyd_bank2_regs_a = (struct u3phyd_bank2_reg_a *)0x200000; + u3phy->u3phya_regs_a = (struct u3phya_reg_e *)0x300000; + u3phy->u3phya_da_regs_a = (struct u3phya_da_reg_a *)0x400000; + u3phy->sifslv_chip_regs_a = (struct sifslv_chip_reg_a *)0x500000; + u3phy->spllc_regs_a = (struct spllc_reg_a *)0x600000; + u3phy->sifslv_fm_regs_a = (struct sifslv_fm_feg_a *)0xf00000; +#else + u3phy->u2phy_regs_a = (struct u2phy_reg_a *)U2_PHY_BASE; + u3phy->u3phyd_regs_a = (struct u3phyd_reg_a *)U3_PHYD_BASE; + u3phy->u3phyd_bank2_regs_a = (struct u3phyd_bank2_reg_a *)U3_PHYD_B2_BASE; + u3phy->u3phya_regs_a = (struct u3phya_reg_e *)U3_PHYA_BASE; + u3phy->u3phya_da_regs_a = (struct u3phya_da_reg_a *)U3_PHYA_DA_BASE; + u3phy->sifslv_chip_regs_a = (struct sifslv_chip_reg_a *)SIFSLV_CHIP_BASE; + u3phy->sifslv_fm_regs_a = (struct sifslv_fm_feg_a *)SIFSLV_FM_FEG_BASE; +#endif + u3phy_ops = ((struct u3phy_operator *)&a60810_operators); +#endif + } else { + pr_err("No match phy version\n"); + return PHY_FALSE; + } + +#endif + + if (!u3phy_ops) + return PHY_FALSE; + else + return PHY_TRUE; +} + +PHY_INT32 U3PhyWriteField8(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask, PHY_INT32 value) +{ + PHY_INT8 cur_value; + PHY_INT8 new_value; + + cur_value = U3PhyReadReg8((u3phy_addr_t) addr); + new_value = (cur_value & (~mask)) | ((value << offset) & mask); + + mb(); + /**/ U3PhyWriteReg8((u3phy_addr_t) addr, new_value); + + mb(); + /**/ return PHY_TRUE; +} + +PHY_INT32 U3PhyWriteField32(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask, PHY_INT32 value) +{ + PHY_INT32 cur_value; + PHY_INT32 new_value; + + cur_value = U3PhyReadReg32((u3phy_addr_t) addr); + new_value = (cur_value & (~mask)) | ((value << offset) & mask); + + mb(); + /**/ U3PhyWriteReg32((u3phy_addr_t) addr, new_value); + + mb(); + /**/ return PHY_TRUE; +} + +PHY_INT32 U3PhyReadField8(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask) +{ + return (U3PhyReadReg8((u3phy_addr_t) addr) & mask) >> offset; +} + +PHY_INT32 U3PhyReadField32(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask) +{ + + return (U3PhyReadReg32((u3phy_addr_t) addr) & mask) >> offset; +} + +void phy_hsrx_set(void) +{ + switch (u3phy->phy_version) { +#ifdef CONFIG_D60802_SUPPORT + case 0xd60802a: + U3PhyWriteField32(((phys_addr_t) &u3phy->u2phy_regs_d->usbphyacr6) + , D60802_RG_USB20_HSRX_MMODE_SELE_OFST, + D60802_RG_USB20_HSRX_MMODE_SELE, 0x2); + + pr_debug("%s: WRITE HSRX_MMODE_SELE(%d)\n", __func__, + U3PhyReadField32(((phys_addr_t) &u3phy->u2phy_regs_d->usbphyacr6) + , D60802_RG_USB20_HSRX_MMODE_SELE_OFST, + D60802_RG_USB20_HSRX_MMODE_SELE)); + break; +#endif + } +} + +void phy_hsrx_reset(void) +{ + switch (u3phy->phy_version) { +#ifdef CONFIG_D60802_SUPPORT + case 0xd60802a: + U3PhyWriteField32(((phys_addr_t) &u3phy->u2phy_regs_d->usbphyacr6) + , D60802_RG_USB20_HSRX_MMODE_SELE_OFST, + D60802_RG_USB20_HSRX_MMODE_SELE, 0x0); + + pr_debug("%s: WRITE HSRX_MMODE_SELE(%d)\n", __func__, + U3PhyReadField32(((phys_addr_t) &u3phy->u2phy_regs_d->usbphyacr6) + , D60802_RG_USB20_HSRX_MMODE_SELE_OFST, + D60802_RG_USB20_HSRX_MMODE_SELE)); + break; +#endif + } +} diff --git a/drivers/misc/mediatek/mu3phy/mtk-phy.h b/drivers/misc/mediatek/mu3phy/mtk-phy.h new file mode 100644 index 000000000000..7083a4952cdf --- /dev/null +++ b/drivers/misc/mediatek/mu3phy/mtk-phy.h @@ -0,0 +1,232 @@ +#ifndef __MTK_PHY_NEW_H +#define __MTK_PHY_NEW_H + +#define CONFIG_U3D_HAL_SUPPORT +#ifdef CONFIG_U3D_HAL_SUPPORT +#include "mu3d_hal_hw.h" +#endif +#ifdef CONFIG_U3D_HAL_SUPPORT +#define REF_CK U3D_PHY_REF_CK +#else +#define REF_CK 25 +#endif + +/* include system library */ +#include <linux/slab.h> +#include <linux/delay.h> + +/* BASE ADDRESS DEFINE, should define this on ASIC */ +#define PHY_BASE 0x0 +#define SIFSLV_SPLLC_BASE (PHY_BASE+0x0) +#define SIFSLV_FM_FEG_BASE (PHY_BASE+0x100) +#define SIFSLV_CHIP_BASE (PHY_BASE+0x700) +#define U2_PHY_BASE (PHY_BASE+0x800) +#define U3_PHYD_BASE (PHY_BASE+0x900) +#define U3_PHYD_B2_BASE (PHY_BASE+0xa00) +#define U3_PHYA_BASE (PHY_BASE+0xb00) +#define U3_PHYA_DA_BASE (PHY_BASE+0xc00) + +/* +0x00000100 MODULE ssusb_sifslv_fmreg ssusb_sifslv_fmreg +0x00000700 MODULE ssusb_sifslv_ippc ssusb_sifslv_ippc +0x00000800 MODULE ssusb_sifslv_u2phy_com ssusb_sifslv_u2_phy_com_T28 +0x00000900 MODULE ssusb_sifslv_u3phyd ssusb_sifslv_u3phyd_T28 +0x00000a00 MODULE ssusb_sifslv_u3phyd_bank2 ssusb_sifslv_u3phyd_bank2_T28 +0x00000b00 MODULE ssusb_sifslv_u3phya ssusb_sifslv_u3phya_T28 +0x00000c00 MODULE ssusb_sifslv_u3phya_da ssusb_sifslv_u3phya_da_T28 +*/ + + +/* TYPE DEFINE */ +typedef unsigned int PHY_UINT32; +typedef int PHY_INT32; +typedef unsigned short PHY_UINT16; +typedef short PHY_INT16; +typedef unsigned char PHY_UINT8; +typedef char PHY_INT8; + +typedef PHY_UINT32 __bitwise PHY_LE32; + + +#ifdef CONFIG_U3_PHY_AHB_SUPPORT +#ifdef CONFIG_ARM64 +typedef u64 u3phy_addr_t; +#define ALIGN_MASK 0xFFFFFFFFFFFFFFFC +#else +typedef u32 u3phy_addr_t; +#define ALIGN_MASK 0xFFFFFFFC +#endif +#else +typedef u32 u3phy_addr_t; +#define ALIGN_MASK 0xFFFFFFFC +#endif + + +/* CONSTANT DEFINE */ +#define PHY_FALSE 0 +#define PHY_TRUE 1 + +/* #define DRV_MDELAY mdelay */ +#define DRV_MSLEEP msleep +#define DRV_UDELAY udelay +/* #define DRV_USLEEP usleep */ + +/* PHY FUNCTION DEFINE, implemented in platform files, ex. ahb, gpio */ +PHY_INT32 U3PhyWriteReg32(u3phy_addr_t addr, PHY_UINT32 data); +PHY_INT32 U3PhyReadReg32(u3phy_addr_t addr); +PHY_INT32 U3PhyWriteReg8(u3phy_addr_t addr, PHY_UINT8 data); +PHY_INT8 U3PhyReadReg8(u3phy_addr_t addr); + +/* PHY GENERAL USAGE FUNC, implemented in mtk-phy.c */ +PHY_INT32 U3PhyWriteField8(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask, PHY_INT32 value); +PHY_INT32 U3PhyWriteField32(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask, PHY_INT32 value); +PHY_INT32 U3PhyReadField8(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask); +PHY_INT32 U3PhyReadField32(phys_addr_t addr, PHY_INT32 offset, PHY_INT32 mask); + +struct u3phy_info { + PHY_INT32 phy_version; + PHY_INT32 phyd_version_addr; + +#ifdef CONFIG_PROJECT_PHY + struct u2phy_reg_e *u2phy_regs_e; + struct u3phya_reg_e *u3phya_regs_e; + struct u3phya_da_reg_e *u3phya_da_regs_e; + struct u3phyd_reg_e *u3phyd_regs_e; + struct u3phyd_bank2_reg_e *u3phyd_bank2_regs_e; + struct sifslv_chip_reg_e *sifslv_chip_regs_e; + struct spllc_reg_e *spllc_regs_e; + struct sifslv_fm_feg_e *sifslv_fm_regs_e; +#else +#ifdef CONFIG_C60802_SUPPORT + /* c60802 regs reference */ + struct u2phy_reg_c *u2phy_regs_c; + struct u3phya_reg_c *u3phya_regs_c; + struct u3phya_da_reg_c *u3phya_da_regs_c; + struct u3phyd_reg_c *u3phyd_regs_c; + struct u3phyd_bank2_reg_c *u3phyd_bank2_regs_c; + struct sifslv_chip_reg_c *sifslv_chip_regs_c; + struct sifslv_fm_feg_c *sifslv_fm_regs_c; +#endif +#ifdef CONFIG_D60802_SUPPORT + /* d60802 regs reference */ + struct u2phy_reg_d *u2phy_regs_d; + struct u3phya_reg_d *u3phya_regs_d; + struct u3phya_da_reg_d *u3phya_da_regs_d; + struct u3phyd_reg_d *u3phyd_regs_d; + struct u3phyd_bank2_reg_d *u3phyd_bank2_regs_d; + struct sifslv_chip_reg_d *sifslv_chip_regs_d; + struct sifslv_fm_feg_d *sifslv_fm_regs_d; +#endif +#ifdef CONFIG_E60802_SUPPORT + /* e60802 regs reference */ + struct u2phy_reg_e *u2phy_regs_e; + struct u3phya_reg_e *u3phya_regs_e; + struct u3phya_da_reg_e *u3phya_da_regs_e; + struct u3phyd_reg_e *u3phyd_regs_e; + struct u3phyd_bank2_reg_e *u3phyd_bank2_regs_e; + struct sifslv_chip_reg_e *sifslv_chip_regs_e; + struct spllc_reg_e *spllc_regs_e; + struct sifslv_fm_feg_e *sifslv_fm_regs_e; +#endif +#ifdef CONFIG_A60810_SUPPORT + /* A60810 regs reference */ + struct u2phy_reg_a *u2phy_regs_a; + struct u3phya_reg_a *u3phya_regs_a; + struct u3phya_da_reg_a *u3phya_da_regs_a; + struct u3phyd_reg_a *u3phyd_regs_a; + struct u3phyd_bank2_reg_a *u3phyd_bank2_regs_a; + struct sifslv_chip_reg_a *sifslv_chip_regs_a; + struct spllc_reg_a *spllc_regs_a; + struct sifslv_fm_reg_a *sifslv_fm_regs_a; +#endif +#endif +}; + +struct u3phy_operator { + PHY_INT32(*init)(struct u3phy_info *info); + PHY_INT32(*change_pipe_phase)(struct u3phy_info *info, PHY_INT32 phy_drv, + PHY_INT32 pipe_phase); + PHY_INT32(*eyescan_init)(struct u3phy_info *info); + PHY_INT32(*eyescan)(struct u3phy_info *info, PHY_INT32 x_t1, PHY_INT32 y_t1, + PHY_INT32 x_br, PHY_INT32 y_br, PHY_INT32 delta_x, PHY_INT32 delta_y, + PHY_INT32 eye_cnt, PHY_INT32 num_cnt, PHY_INT32 PI_cal_en, + PHY_INT32 num_ignore_cnt); + PHY_INT32(*u2_connect)(struct u3phy_info *info); + PHY_INT32(*u2_disconnect)(struct u3phy_info *info); + PHY_INT32(*u2_save_current_entry)(struct u3phy_info *info); + PHY_INT32(*u2_save_current_recovery)(struct u3phy_info *info); + PHY_INT32(*u2_slew_rate_calibration)(struct u3phy_info *info); +}; + +#undef EXTERN +#ifdef U3_PHY_LIB +#define EXTERN +#else +#define EXTERN \ +extern +#endif + +EXTERN struct u3phy_info *u3phy; +EXTERN struct u3phy_operator *u3phy_ops; + +/*********eye scan required*********/ + +#define LO_BYTE(x) ((PHY_UINT8)((x) & 0xFF)) +#define HI_BYTE(x) ((PHY_UINT8)(((x) & 0xFF00) >> 8)) + +typedef enum { + SCAN_UP, + SCAN_DN +} enumScanDir; + +struct strucScanRegion { + PHY_INT8 bX_tl; + PHY_INT8 bY_tl; + PHY_INT8 bX_br; + PHY_INT8 bY_br; + PHY_INT8 bDeltaX; + PHY_INT8 bDeltaY; +}; + +struct strucTestCycle { + PHY_UINT16 wEyeCnt; + PHY_INT8 bNumOfEyeCnt; + PHY_INT8 bPICalEn; + PHY_INT8 bNumOfIgnoreCnt; +}; + +#define ERRCNT_MAX 128 +#define CYCLE_COUNT_MAX 15 + +/* / the map resolution is 128 x 128 pts */ +#define MAX_X 127 +#define MAX_Y 127 +#define MIN_X 0 +#define MIN_Y 0 + +PHY_INT32 u3phy_init(void); + +EXTERN struct strucScanRegion _rEye1; +EXTERN struct strucScanRegion _rEye2; +EXTERN struct strucTestCycle _rTestCycle; +EXTERN PHY_UINT8 _bXcurr; +EXTERN PHY_UINT8 _bYcurr; +EXTERN enumScanDir _eScanDir; +EXTERN PHY_INT8 _fgXChged; +EXTERN unsigned int _bPIResult; + +/* Comment for saving the kernel size. This's only used at external PHY*/ +#ifdef CONFIG_U3_PHY_GPIO_SUPPORT +EXTERN PHY_UINT32 pwErrCnt0[CYCLE_COUNT_MAX][ERRCNT_MAX][ERRCNT_MAX]; +EXTERN PHY_UINT32 pwErrCnt1[CYCLE_COUNT_MAX][ERRCNT_MAX][ERRCNT_MAX]; +#endif + +extern void phy_hsrx_set(void); + +/***********************************/ +extern void __iomem *ap_uart0_base; +#ifdef CONFIG_MTK_FPGA +extern void __iomem *i2c1_base; +#endif +/***********************************/ +#endif |