aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShangbing Hu <shangbing.hu@mediatek.com>2016-07-12 10:18:28 +0800
committerShangbing Hu <shangbing.hu@mediatek.com>2016-07-12 10:18:28 +0800
commit2ceb2f927bf03ae52d2addcbcc751306cc9944ea (patch)
treef9ab6873b64ebdfddf2fdb0cac8663cac97faa76
parent971af533fb2cd63fcad0762398b94614e875b5ec (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
-rw-r--r--drivers/misc/mediatek/Kconfig2
-rw-r--r--drivers/misc/mediatek/Makefile2
-rw-r--r--drivers/misc/mediatek/mu3d/Kconfig38
-rw-r--r--drivers/misc/mediatek/mu3d/Makefile3
-rw-r--r--drivers/misc/mediatek/mu3d/drv/Makefile12
-rw-r--r--drivers/misc/mediatek/mu3d/drv/mt_usb.c621
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_core.c2956
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_core.h804
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_debug.h56
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_debugfs.c621
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_dma.h180
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_gadget.c2030
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_gadget.h135
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_gadget_ep0.c1573
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_init.c860
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_io.h183
-rw-r--r--drivers/misc/mediatek/mu3d/drv/musb_regs.h503
-rw-r--r--drivers/misc/mediatek/mu3d/drv/ssusb_qmu.c526
-rw-r--r--drivers/misc/mediatek/mu3d/drv/ssusb_qmu.h17
-rw-r--r--drivers/misc/mediatek/mu3d/hal/Makefile12
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_comm.h189
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_hw.h285
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.c176
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_osal.h80
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.c92
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_phy.h29
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.c1441
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_qmu_drv.h293
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.c1751
-rw-r--r--drivers/misc/mediatek/mu3d/hal/mu3d_hal_usb_drv.h193
-rw-r--r--drivers/misc/mediatek/mu3d/hal/ssusb_dev_c_header.h3727
-rw-r--r--drivers/misc/mediatek/mu3d/hal/ssusb_epctl_csr_c_header.h187
-rw-r--r--drivers/misc/mediatek/mu3d/hal/ssusb_sifslv_ippc_c_header.h728
-rw-r--r--drivers/misc/mediatek/mu3d/hal/ssusb_usb2_csr_c_header.h294
-rw-r--r--drivers/misc/mediatek/mu3d/hal/ssusb_usb3_mac_csr_c_header.h423
-rw-r--r--drivers/misc/mediatek/mu3d/hal/ssusb_usb3_sys_csr_c_header.h318
-rw-r--r--drivers/misc/mediatek/mu3phy/Kconfig89
-rw-r--r--drivers/misc/mediatek/mu3phy/Makefile18
-rw-r--r--drivers/misc/mediatek/mu3phy/mtk-phy-a60810.c596
-rw-r--r--drivers/misc/mediatek/mu3phy/mtk-phy-a60810.h3124
-rw-r--r--drivers/misc/mediatek/mu3phy/mtk-phy-ahb.c35
-rw-r--r--drivers/misc/mediatek/mu3phy/mtk-phy-gpio.c454
-rw-r--r--drivers/misc/mediatek/mu3phy/mtk-phy.c290
-rw-r--r--drivers/misc/mediatek/mu3phy/mtk-phy.h232
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