diff --git a/drivers/phy/mediatek/phy-mtk-mt6873.c b/drivers/phy/mediatek/phy-mtk-mt6873.c deleted file mode 100644 index d02996c8dfbf..000000000000 --- a/drivers/phy/mediatek/phy-mtk-mt6873.c +++ /dev/null @@ -1,1128 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (c) 2019 MediaTek Inc. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "phy-mtk.h" - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT -#include -#endif - -#define MTK_USB_PHY_BASE (phy_drv->phy_base) -#define MTK_USB_PHY_PORT_BASE (instance->port_base) -#define MTK_USB_PHY_MISC_BASE (instance->sif_misc) -#define MTK_USB_PHY_FMREG_BASE (instance->sif_fmreg) -#define MTK_USB_PHY_SPLLC_BASE (instance->sif_spllc) -#define MTK_USB_PHY_U2_BASE (instance->sif_u2phy_com) -#define MTK_USB_PHY_CHIP_BASE (instance->sif_chip) -#define MTK_USB_PHY_U3PHYD_BASE (instance->sif_u3phyd) -#define MTK_USB_PHY_B2_BASE (instance->sif_u3phyd_bank2) -#define MTK_USB_PHY_PHYA_BASE (instance->sif_u3phya) -#define MTK_USB_PHY_PHYA_DA_BASE (instance->sif_u3phya_da) - -#include "phy-mtk-ssusb-reg.h" - -static DEFINE_MUTEX(prepare_lock); - -enum mt_phy_version { - MT_PHY_V1 = 1, - MT_PHY_V2, -}; - -static bool usb_enable_clock(struct mtk_phy_drv *u3phy, bool enable) -{ - static int count; - - if (!u3phy->clk) - return false; - - mutex_lock(&prepare_lock); - phy_printk(K_INFO, "CG, enable<%d>, count<%d>\n", enable, count); - - if (enable && count == 0) { - if (clk_prepare_enable(u3phy->clk) != 0) - phy_printk(K_ERR, "clk enable fail\n"); - } else if (!enable && count == 1) { - clk_disable_unprepare(u3phy->clk); - } - - if (enable) - count++; - else - count = (count == 0) ? 0 : (count - 1); - - mutex_unlock(&prepare_lock); - return true; -} - -static void u3phywrite32(void __iomem *addr, int offset, int mask, int value) -{ - int cur_value; - int new_value; - - cur_value = readl(addr); - new_value = (cur_value & (~mask)) | ((value << offset) & mask); - writel(new_value, addr); -} - -static int u3phyread32(void __iomem *addr) -{ - return readl(addr); -} - -static void phy_advance_settings(struct mtk_phy_instance *instance) -{ - /* special request from DE */ - u32 val, offset; - - /* RG_SSUSB_TX_EIDLE_CM, 0x11F40B20[31:28] */ - /* 4'b1000, ssusb_USB30_PHYA_regmap_T12FF_TPHY */ - val = 0x8; - offset = 0x20; - u3phywrite32( - (MTK_USB_PHY_PHYA_BASE + offset), 28, - (0xf<<28), val); - - /* rg_ssusb_cdr_bir_ltr, 0x11F4095C[20:16] 5'b01101 */ - /* ssusb_USB30_PHYD_regmap_T12FF_TPHY */ - val = 0xd; - offset = 0x5c; - u3phywrite32( - (MTK_USB_PHY_U3PHYD_BASE + offset), 16, - (0x1f<<16), val); -} - -static void phy_efuse_settings(struct mtk_phy_instance *instance) -{ - u32 evalue; - - evalue = (get_devinfo_with_index(108) & (0x1f<<0)) >> 0; - if (evalue) { - phy_printk(K_INFO, "RG_USB20_INTR_CAL=0x%x\n", - evalue); - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_INTR_CAL_OFST, - RG_USB20_INTR_CAL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x3f << 16)) >> 16; - if (evalue) { - phy_printk(K_INFO, "RG_SSUSB_IEXT_INTR_CTRL=0x%x\n", - evalue); - u3phywrite32(U3D_USB30_PHYA_REG0, - RG_SSUSB_IEXT_INTR_CTRL_OFST, - RG_SSUSB_IEXT_INTR_CTRL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x1f << 8)) >> 8; - if (evalue) { - phy_printk(K_INFO, "rg_ssusb_rx_impsel=0x%x\n", - evalue); - u3phywrite32(U3D_PHYD_IMPCAL1, - RG_SSUSB_RX_IMPSEL_OFST, - RG_SSUSB_RX_IMPSEL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x1f << 0)) >> 0; - if (evalue) { - phy_printk(K_INFO, "g_ssusb_tx_impsel=0x%x (R50)\n", - evalue); - - if (evalue < 6) - evalue += 2; - else if (evalue >= 6 && evalue < 15) - evalue += 3; - else - evalue = 15; - phy_printk(K_INFO, "g_ssusb_tx_impsel=0x%x (R45)\n", - evalue); - u3phywrite32(U3D_PHYD_IMPCAL0, - RG_SSUSB_TX_IMPSEL_OFST, - RG_SSUSB_TX_IMPSEL, evalue); - } -} - -static int phy_slew_rate_calibration(struct mtk_phy_instance *instance) -{ - int i = 0; - int fgRet = 0; - int u4FmOut = 0; - int u4Tmp = 0; - - phy_printk(K_DEBUG, "%s\n", __func__); - - /* enable USB ring oscillator */ - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCAL_EN_OFST, - RG_USB20_HSTX_SRCAL_EN, 1); - - /* wait 1us */ - udelay(1); - - /* Enable free run clock */ - u3phywrite32(RG_SSUSB_SIFSLV_FMMONR1, RG_FRCK_EN_OFST, - RG_FRCK_EN, 0x1); - /* Setting cyclecnt */ - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_CYCLECNT_OFST, - RG_CYCLECNT, 0x400); - /* Enable frequency meter */ - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_FREQDET_EN_OFST, - RG_FREQDET_EN, 0x1); - phy_printk(K_DEBUG, "Freq_Valid=(0x%08X)\n", - u3phyread32(RG_SSUSB_SIFSLV_FMMONR1)); - - mdelay(1); - - /* wait for FM detection done, set 10ms timeout */ - for (i = 0; i < 10; i++) { - u4FmOut = u3phyread32(RG_SSUSB_SIFSLV_FMMONR0); - phy_printk(K_DEBUG, "FM_OUT u4FmOut = %d(0x%08X)\n", - u4FmOut, u4FmOut); - if (u4FmOut != 0) { - fgRet = 0; - phy_printk(K_DEBUG, "FM detect loop = %d\n", i); - break; - } - fgRet = 1; - mdelay(1); - } - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_FREQDET_EN_OFST, - RG_FREQDET_EN, 0); - u3phywrite32(RG_SSUSB_SIFSLV_FMMONR1, RG_FRCK_EN_OFST, - RG_FRCK_EN, 0); - - if (u4FmOut == 0) { - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCTRL_OFST, - RG_USB20_HSTX_SRCTRL, 0x4); - fgRet = 1; - } else { - u4Tmp = (1024 * U3D_PHY_REF_CK * U2_SR_COEF); - u4Tmp = u4Tmp / (u4FmOut * 1000); - phy_printk(K_DEBUG, "SR cali u1SrCalVal = %d\n", u4Tmp); - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCTRL_OFST, - RG_USB20_HSTX_SRCTRL, u4Tmp); - } - - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCAL_EN_OFST, - RG_USB20_HSTX_SRCAL_EN, 0); - - return fgRet; -} - -#ifdef CONFIG_MTK_UART_USB_SWITCH -static bool bFirstUartCheck = true; -static bool phy_check_in_uart_mode(struct mtk_phy_instance *instance); -#endif - -static int phy_init_soc(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_DEBUG, "%s\n", __func__); - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if ((bFirstUartCheck && phy_check_in_uart_mode(instance)) || - instance->uart_mode) { - phy_printk(K_ALET, "%s+ already in UART_MODE\n", __func__); - bFirstUartCheck = false; - instance->uart_mode = 1; - goto reg_done; - } else - bFirstUartCheck = false; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return 0; - } -#endif - - /*switch to USB function. (system register, force ip into usb mode) */ - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_UART_MODE_OFST, - RG_UART_MODE, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DP_100K_MODE_OFST, - RG_USB20_DP_100K_MODE, 1); - u3phywrite32(U3D_U2PHYACR4, USB20_DP_100K_EN_OFST, - USB20_DP_100K_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DM_100K_EN_OFST, - RG_USB20_DM_100K_EN, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_OTG_VBUSCMP_EN_OFST, - RG_USB20_OTG_VBUSCMP_EN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 0); - - udelay(800); - - u3phywrite32(U3D_U2PHYDTM1, FORCE_VBUSVALID_OFST, - FORCE_VBUSVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, FORCE_AVALID_OFST, - FORCE_AVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, FORCE_SESSEND_OFST, - FORCE_SESSEND, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH -reg_done: -#endif - usb_enable_clock(phy_drv, false); - - return 0; -} - - -static void phy_savecurrent(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_ALET, "%s\n", __func__); - if (instance->sib_mode) { - phy_printk(K_INFO, "%s sib_mode can't savecurrent\n", __func__); - return; - } - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if (instance->uart_mode) - goto reg_done; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return; - } -#endif - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - /*u3phywrite32(U3D_USBPHYACR6, - *RG_USB20_OTG_VBUSCMP_EN_OFST, - *RG_USB20_OTG_VBUSCMP_EN, 0); - */ - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 1); - udelay(2000); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_XCVRSEL_OFST, - RG_XCVRSEL, 0x1); - u3phywrite32(U3D_U2PHYDTM0, RG_TERMSEL_OFST, - RG_TERMSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DATAIN_OFST, - RG_DATAIN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DP_PULLDOWN_OFST, - FORCE_DP_PULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DM_PULLDOWN_OFST, - FORCE_DM_PULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_XCVRSEL_OFST, - FORCE_XCVRSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_TERMSEL_OFST, - FORCE_TERMSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DATAIN_OFST, - FORCE_DATAIN, 1); - udelay(800); - - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 0); - - udelay(1); - - u3phywrite32(U3D_U2PHYDTM1, RG_VBUSVALID_OFST, - RG_VBUSVALID, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_AVALID_OFST, - RG_AVALID, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_SESSEND_OFST, - RG_SESSEND, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH -reg_done: -#endif - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - udelay(10); - usb_enable_clock(phy_drv, false); -} - -#define VAL_MAX_WIDTH_2 0x3 -#define VAL_MAX_WIDTH_3 0x7 -static void usb_phy_tuning(struct mtk_phy_instance *instance) -{ - s32 u2_vrt_ref, u2_term_ref, u2_enhance; - struct device_node *of_node; - - if (!instance->phy_tuning.inited) { - instance->phy_tuning.u2_vrt_ref = 6; - instance->phy_tuning.u2_term_ref = 6; - instance->phy_tuning.u2_enhance = 1; - of_node = of_find_compatible_node(NULL, NULL, - instance->phycfg->tuning_node_name); - if (of_node) { - /* value won't be updated if property not being found */ - of_property_read_u32(of_node, "u2_vrt_ref", - (u32 *) &instance->phy_tuning.u2_vrt_ref); - of_property_read_u32(of_node, "u2_term_ref", - (u32 *) &instance->phy_tuning.u2_term_ref); - of_property_read_u32(of_node, "u2_enhance", - (u32 *) &instance->phy_tuning.u2_enhance); - } - instance->phy_tuning.inited = true; - } - u2_vrt_ref = instance->phy_tuning.u2_vrt_ref; - u2_term_ref = instance->phy_tuning.u2_term_ref; - u2_enhance = instance->phy_tuning.u2_enhance; - - if (u2_vrt_ref != -1) { - if (u2_vrt_ref <= VAL_MAX_WIDTH_3) { - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_VRT_VREF_SEL_OFST, - RG_USB20_VRT_VREF_SEL, u2_vrt_ref); - } - } - if (u2_term_ref != -1) { - if (u2_term_ref <= VAL_MAX_WIDTH_3) { - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_TERM_VREF_SEL_OFST, - RG_USB20_TERM_VREF_SEL, u2_term_ref); - } - } - if (u2_enhance != -1) { - if (u2_enhance <= VAL_MAX_WIDTH_2) { - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_6_OFST, - RG_USB20_PHY_REV_6, u2_enhance); - } - } - - phy_printk(K_INFO, "%s - SSUSB TX EYE Tuning\n", __func__); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_IDRVSEL_OFST, - RG_SSUSB_IDRVSEL, 0x19); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_FORCE_IDRVSEL_OFST, - RG_SSUSB_FORCE_IDRVSEL, 1); - - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_IDEMSEL_OFST, - RG_SSUSB_IDEMSEL, 0x1a); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_FORCE_IDEMSEL_OFST, - RG_SSUSB_FORCE_IDEMSEL, 1); -} - - -static void phy_recover(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if (instance->uart_mode) - return; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return; - } -#endif - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_XCVRSEL_OFST, - RG_XCVRSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_TERMSEL_OFST, - RG_TERMSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DATAIN_OFST, - RG_DATAIN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DP_PULLDOWN_OFST, - FORCE_DP_PULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DM_PULLDOWN_OFST, - FORCE_DM_PULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_XCVRSEL_OFST, - FORCE_XCVRSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_TERMSEL_OFST, - FORCE_TERMSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DATAIN_OFST, - FORCE_DATAIN, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - /*u3phywrite32(U3D_USBPHYACR6, RG_USB20_OTG_VBUSCMP_EN_OFST, - * RG_USB20_OTG_VBUSCMP_EN, 1); - */ - /* Wait 800 usec */ - udelay(800); - - u3phywrite32(U3D_U2PHYDTM1, RG_VBUSVALID_OFST, - RG_VBUSVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_AVALID_OFST, - RG_AVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_SESSEND_OFST, - RG_SESSEND, 0); - - phy_efuse_settings(instance); - - u3phywrite32(U3D_USBPHYACR6, RG_USB20_DISCTH_OFST, - RG_USB20_DISCTH, 0x7); - - usb_phy_tuning(instance); - phy_advance_settings(instance); - - phy_slew_rate_calibration(instance); - - phy_printk(K_INFO, "%s-\n", __func__); -} - - -static int charger_detect_init(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 1); - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); - return 0; -} - -static int charger_detect_release(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); - return 0; -} - -static void phy_charger_switch_bc11(struct mtk_phy_instance *instance, - bool on) -{ - if (on) - charger_detect_init(instance); - else - charger_detect_release(instance); -} - -static void phy_dpdm_pulldown(struct mtk_phy_instance *instance, - bool enable) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - if (enable) { - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 1); - - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_OFST, (0x2<<24), 0x0); - } else { - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - - /*For water detection function, - *need to set DPPULLDOWN and DMPULLDOWN 0 - *Also adjust RG_USB20_PHY_REV to prevent power leakage - */ - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_OFST, (0x2<<24), 0x2); - } - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); -} - -static int phy_lpm_enable(struct mtk_phy_instance *instance, bool on) -{ - phy_printk(K_DEBUG, "%s+ = %d\n", __func__, on); - - if (on) - u3phywrite32(U3D_U2PHYDCR1, RG_USB20_SW_PLLMODE_OFST, - RG_USB20_SW_PLLMODE, 0x1); - else - u3phywrite32(U3D_U2PHYDCR1, RG_USB20_SW_PLLMODE_OFST, - RG_USB20_SW_PLLMODE, 0x0); - - return 0; -} - -static int phy_host_mode(struct mtk_phy_instance *instance, bool on) -{ - phy_printk(K_DEBUG, "%s+ = %d\n", __func__, on); - - return 0; -} - -static int phy_ioread(struct mtk_phy_instance *instance, u32 reg) -{ - if (reg < instance->port_rgsz) - return readl(instance->sif_u2phy_com + reg); - else - return 0; -} - -static int phy_iowrite(struct mtk_phy_instance *instance, - u32 val, u32 reg) -{ - if (reg < instance->port_rgsz) - writel(val, instance->sif_u2phy_com + reg); - - return 0; -} - - -static bool phy_u3_loop_back_test(struct mtk_phy_instance *instance) -{ - int reg; - bool loop_back_ret = false; - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int r_pipe0, r_rx0, rx_mix0, r_t2rlb; - - /* VA10 is shared by U3/UFS */ - /* default on and set voltage by PMIC */ - /* off/on in SPM suspend/resume */ - - usb_enable_clock(phy_drv, true); - - r_pipe0 = readl(U3D_PHYD_PIPE0); - r_rx0 = readl(U3D_PHYD_RX0); - rx_mix0 = readl(U3D_PHYD_MIX0); - r_t2rlb = readl(U3D_PHYD_T2RLB); - - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<30)) | 0x01<<30, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<28)) | 0x00<<28, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x03<<26)) | 0x01<<26, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x03<<24)) | 0x00<<24, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<22)) | 0x00<<22, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<21)) | 0x00<<21, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<20)) | 0x01<<20, - U3D_PHYD_PIPE0); - mdelay(10); - - /*T2R loop back disable*/ - writel((readl(U3D_PHYD_RX0)&~(0x01<<15)) | 0x00<<15, - U3D_PHYD_RX0); - mdelay(10); - - /* TSEQ lock detect threshold */ - writel((readl(U3D_PHYD_MIX0) & ~(0x07<<24)) | 0x07<<24, - U3D_PHYD_MIX0); - /* set default TSEQ polarity check value = 1 */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<28)) | 0x01<<28, - U3D_PHYD_MIX0); - /* TSEQ polarity check enable */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<29)) | 0x01<<29, - U3D_PHYD_MIX0); - /* TSEQ decoder enable */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<30)) | 0x01<<30, - U3D_PHYD_MIX0); - mdelay(10); - - /* set T2R loop back TSEQ length (x 16us) */ - writel((readl(U3D_PHYD_T2RLB) & ~(0xff<<0)) | 0xF0<<0, - U3D_PHYD_T2RLB); - /* set T2R loop back BDAT reset period (x 16us) */ - writel((readl(U3D_PHYD_T2RLB) & ~(0x0f<<12)) | 0x0F<<12, - U3D_PHYD_T2RLB); - /* T2R loop back pattern select */ - writel((readl(U3D_PHYD_T2RLB) & ~(0x03<<8)) | 0x00<<8, - U3D_PHYD_T2RLB); - mdelay(10); - - /* T2R loop back serial mode */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<13)) | 0x01<<13, - U3D_PHYD_RX0); - /* T2R loop back parallel mode = 0 */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<12)) | 0x00<<12, - U3D_PHYD_RX0); - /* T2R loop back mode enable */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<11)) | 0x01<<11, - U3D_PHYD_RX0); - /* T2R loop back enable */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<15)) | 0x01<<15, - U3D_PHYD_RX0); - mdelay(100); - - reg = u3phyread32(SSUSB_SIFSLV_U3PHYD_BASE + 0xb4); - phy_printk(K_INFO, "rb back : 0x%x\n", reg); - phy_printk(K_INFO, "rb t2rlb_lock : %d\n", (reg >> 2) & 0x01); - phy_printk(K_INFO, "rb t2rlb_pass : %d\n", (reg >> 3) & 0x01); - phy_printk(K_INFO, "rb t2rlb_passth: %d\n", (reg >> 4) & 0x01); - - if ((reg & 0x0E) == 0x0E) - loop_back_ret = true; - else - loop_back_ret = false; - - writel(r_rx0, U3D_PHYD_RX0); - writel(r_pipe0, U3D_PHYD_PIPE0); - writel(rx_mix0, U3D_PHYD_MIX0); - writel(r_t2rlb, U3D_PHYD_T2RLB); - - usb_enable_clock(phy_drv, false); - return loop_back_ret; -} - - -#ifdef CONFIG_MTK_SIB_USB_SWITCH -static void phy_sib_enable(struct mtk_phy_instance *instance, bool enable) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_DEBUG, "usb_phy_sib_enable_switch =%d\n", enable); - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - /* SSUSB_SIFSLV_IPPC_BASE SSUSB_IP_SW_RST = 0 */ - writel(0x00031000, (void __iomem *)phy_drv->ippc_base + 0x0); - /* SSUSB_IP_HOST_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0x4); - /* SSUSB_IP_DEV_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0x8); - /* SSUSB_IP_PCIE_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0xC); - /* SSUSB_U3_PORT_DIS/SSUSB_U3_PORT_PDN = 0*/ - writel(0x0000000C, (void __iomem *)phy_drv->ippc_base + 0x30); - - /* - * USBMAC mode is 0x62910002 (bit 1) - * MDSIB mode is 0x62910008 (bit 3) - * 0x0629 just likes a signature. Can't be removed. - */ - if (enable) { - writel(0x62910008, MTK_USB_PHY_CHIP_BASE); - instance->sib_mode = true; - } else { - writel(0x62910002, MTK_USB_PHY_CHIP_BASE); - instance->sib_mode = false; - } -} - -static bool phy_sib_switch_status(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int reg; - bool ret; - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - reg = u3phyread32(MTK_USB_PHY_CHIP_BASE); - phy_printk(K_DEBUG, "%s reg=%d\n", __func__, reg); - - if (reg == 0x62910008) - ret = true; - else - ret = false; - - return ret; -} - -#endif - -#ifdef CONFIG_MTK_UART_USB_SWITCH -#include - -static void phy_dump_usb2uart_reg(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - usb_enable_clock(phy_drv, true); - udelay(250); - - phy_printk(K_ALET, "addr: 0x18, value: 0x%x\n", - u3phyread32(U3D_USBPHYACR6)); - phy_printk(K_ALET, "addr: 0x20, value: 0x%x\n", - u3phyread32(U3D_U2PHYACR4)); - phy_printk(K_ALET, "addr: 0x68, value: 0x%x\n", - u3phyread32(U3D_U2PHYDTM0)); - phy_printk(K_ALET, "addr: 0x6C, value: 0x%x\n", - u3phyread32(U3D_U2PHYDTM1)); - - usb_enable_clock(phy_drv, false); -} - -bool phy_check_in_uart_mode(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int usb_port_mode; - - usb_enable_clock(phy_drv, true); - udelay(250); - - usb_port_mode = u3phyread32(U3D_U2PHYDTM0) >> RG_UART_MODE_OFST; - - usb_enable_clock(phy_drv, false); - phy_printk(K_ALET, "%s - usb_port_mode = %d, ", - __func__, usb_port_mode); - phy_printk(K_ALET, "%s - instance->uart_mode = %d\n", - __func__, instance->uart_mode); - - if (usb_port_mode == 0x1) - return true; - else - return false; -} - -static int phy_switch_usb2uart_gpio(enum PORT_MODE portmode) -{ - struct device_node *node; - void __iomem *gpio_base; - - /* SET USB to UART GPIO to UART0 */ - node = of_find_compatible_node(NULL, NULL, "mediatek,gpio"); - if (!node) { - pr_info("error: can't find GPIO node\n"); - return -EINVAL; - } - - gpio_base = of_iomap(node, 0); - if (!gpio_base) { - pr_info("error: iomap fail for GPIO\n"); - return -EINVAL; - } - - if (portmode == PORT_MODE_UART) - writel((readl(gpio_base + RG_GPIO_SELECT) | - (GPIO_SEL_UART0<phy_drv; - - if (phy_check_in_uart_mode(instance)) { - phy_printk(K_DEBUG, "%s+ UART_MODE\n", __func__); - return; - } - - phy_printk(K_DEBUG, "%s+ USB_MODE\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_UART_MODE_OFST, - RG_UART_MODE, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_TX_OE_OFST, - FORCE_UART_TX_OE, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_BIAS_EN_OFST, - FORCE_UART_BIAS_EN, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_TX_OE_OFST, - RG_UART_TX_OE, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_BIAS_EN_OFST, - RG_UART_BIAS_EN, 1); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DM_100K_EN_OFST, - RG_USB20_DM_100K_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - - usb_enable_clock(phy_drv, false); - - phy_switch_usb2uart_gpio(PORT_MODE_UART); - - instance->uart_mode = true; -} - - -static void phy_switch_to_usb(struct mtk_phy_instance *instance) -{ - instance->uart_mode = false; - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - - phy_switch_usb2uart_gpio(PORT_MODE_USB); - - phy_init_soc(instance); -} -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT -int usb2jtag_usb_init(void) -{ - struct device_node *node = NULL; - void __iomem *usb3_sif2_base; - u32 temp; - - pr_notice("[USB2JTAG] %s ++\n", __func__); - - node = of_find_compatible_node(NULL, NULL, "mediatek,usb3"); - if (!node) { - pr_notice("[USB2JTAG] map node @ mediatek,usb3 failed\n"); - return -1; - } - - usb3_sif2_base = of_iomap(node, 2); - if (!usb3_sif2_base) { - pr_notice("[USB2JTAG] iomap usb3_sif2_base failed\n"); - return -1; - } - - /* rg_usb20_gpio_ctl: bit[9] = 1 */ - temp = readl(usb3_sif2_base + 0x320); - writel(temp | (1 << 9), usb3_sif2_base + 0x320); - - /* RG_USB20_BC11_SW_EN: bit[23] = 0 */ - temp = readl(usb3_sif2_base + 0x318); - writel(temp & ~(1 << 23), usb3_sif2_base + 0x318); - - /* RG_USB20_BGR_EN: bit[0] = 1 */ - temp = readl(usb3_sif2_base + 0x300); - writel(temp | (1 << 0), usb3_sif2_base + 0x300); - - /* rg_sifslv_mac_bandgap_en: bit[17] = 0 */ - temp = readl(usb3_sif2_base + 0x308); - writel(temp & ~(1 << 17), usb3_sif2_base + 0x308); - - /* wait stable */ - mdelay(1); - - iounmap(usb3_sif2_base); - - return 0; -} -#endif - -static int mtk_phy_drv_init(struct platform_device *pdev, - struct mtk_phy_drv *mtkphy) -{ - int ret = 0; - struct device *dev = &pdev->dev; - struct resource *res; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sif_base"); - if (!res) - return -EINVAL; - - mtkphy->phy_base = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(mtkphy->phy_base)) { - dev_info(dev, "failed to remap phy regs\n"); - return PTR_ERR(mtkphy->phy_base); - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ippc"); - if (!res) - return -EINVAL; - - mtkphy->ippc_base = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(mtkphy->ippc_base)) { - dev_info(dev, "failed to remap ippc_base regs\n"); - return PTR_ERR(mtkphy->ippc_base); - } - - mtkphy->clk = devm_clk_get(dev, "ref_clk"); - if (IS_ERR(mtkphy->clk)) { - if (PTR_ERR(mtkphy->clk) == -EPROBE_DEFER) { - dev_info(dev, "mtkphy->clk EPROBE_DEFER\n"); - return -EPROBE_DEFER; - } - mtkphy->clk = NULL; - } - - return ret; -} - -static int mtk_phy_drv_exit(struct platform_device *pdev, - struct mtk_phy_drv *mtkphy) -{ - if (!IS_ERR_OR_NULL(mtkphy->clk)) - clk_disable_unprepare(mtkphy->clk); - return 0; -} - -static int phy_inst_init(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - void __iomem *port_base; - - phy_printk(K_DEBUG, "%s+\n", __func__); - - port_base = instance->port_base; - - if (phy_drv->phycfg->version == MT_PHY_V1) { - instance->sif_misc = NULL; - instance->sif_fmreg = phy_drv->phy_base + 0x100; - instance->sif_u2phy_com = port_base; - if (instance->phycfg->port_type == PHY_TYPE_USB3) { - instance->sif_spllc = phy_drv->phy_base; - instance->sif_chip = NULL; - instance->sif_u3phyd = port_base + 0x100; - instance->sif_u3phyd_bank2 = port_base + 0x200; - instance->sif_u3phya = port_base + 0x300; - instance->sif_u3phya_da = port_base + 0x400; - } - instance->port_rgsz = 0x800; - } else if (phy_drv->phycfg->version == MT_PHY_V2) { - instance->sif_misc = port_base; - instance->sif_fmreg = port_base + 0x100; - instance->sif_u2phy_com = port_base + 0x300; - instance->port_rgsz = 0x500; - if (instance->phycfg->port_type == PHY_TYPE_USB3) { - instance->sif_spllc = port_base + 0x700; - instance->sif_chip = port_base + 0x800; - instance->sif_u3phyd = port_base + 0x900; - instance->sif_u3phyd_bank2 = port_base + 0xa00; - instance->sif_u3phya = port_base + 0xb00; - instance->sif_u3phya_da = port_base + 0xc00; - instance->port_rgsz = 0x1000; - } - } - return 0; -} - - -static const struct mtk_phy_interface ssusb_phys[] = { -{ - .name = "port0", - .tuning_node_name = "mediatek,phy_tuning", - .port_num = 0, - .reg_offset = 0, - .port_type = PHY_TYPE_USB3, - .usb_phy_inst_init = phy_inst_init, - .usb_phy_init = phy_init_soc, - .usb_phy_savecurrent = phy_savecurrent, - .usb_phy_recover = phy_recover, - .usb_phy_switch_to_bc11 = phy_charger_switch_bc11, - .usb_phy_dpdm_pulldown = phy_dpdm_pulldown, - .usb_phy_lpm_enable = phy_lpm_enable, - .usb_phy_host_mode = phy_host_mode, - .usb_phy_io_read = phy_ioread, - .usb_phy_io_write = phy_iowrite, -#ifdef CONFIG_MTK_UART_USB_SWITCH - .usb_phy_switch_to_usb = phy_switch_to_usb, - .usb_phy_switch_to_uart = phy_switch_to_uart, - .usb_phy_check_in_uart_mode = phy_check_in_uart_mode, - .usb_phy_dump_usb2uart_reg = phy_dump_usb2uart_reg, -#endif -#ifdef CONFIG_MTK_SIB_USB_SWITCH - .usb_phy_sib_enable_switch = phy_sib_enable, - .usb_phy_sib_switch_status = phy_sib_switch_status, -#endif - .usb_phy_u3_loop_back_test = phy_u3_loop_back_test, - }, -}; - -static const struct mtk_usbphy_config ssusb_phy_config = { - .phys = ssusb_phys, - .num_phys = 1, - .version = MT_PHY_V2, - .usb_drv_init = mtk_phy_drv_init, - .usb_drv_exit = mtk_phy_drv_exit, -}; - -const struct of_device_id mtk_phy_of_match[] = { - { - .compatible = "mediatek,mt6873-phy", - .data = &ssusb_phy_config, - }, - { }, -}; diff --git a/drivers/phy/mediatek/phy-mtk-mt6877.c b/drivers/phy/mediatek/phy-mtk-mt6877.c deleted file mode 100644 index ee834916d4d9..000000000000 --- a/drivers/phy/mediatek/phy-mtk-mt6877.c +++ /dev/null @@ -1,1211 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) 2020 MediaTek Inc. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "phy-mtk.h" - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT -#include -#endif - -#define MTK_USB_PHY_BASE (phy_drv->phy_base) -#define MTK_USB_PHY_PORT_BASE (instance->port_base) -#define MTK_USB_PHY_MISC_BASE (instance->sif_misc) -#define MTK_USB_PHY_FMREG_BASE (instance->sif_fmreg) -#define MTK_USB_PHY_SPLLC_BASE (instance->sif_spllc) -#define MTK_USB_PHY_U2_BASE (instance->sif_u2phy_com) -#define MTK_USB_PHY_CHIP_BASE (instance->sif_chip) -#define MTK_USB_PHY_U3PHYD_BASE (instance->sif_u3phyd) -#define MTK_USB_PHY_B2_BASE (instance->sif_u3phyd_bank2) -#define MTK_USB_PHY_PHYA_BASE (instance->sif_u3phya) -#define MTK_USB_PHY_PHYA_DA_BASE (instance->sif_u3phya_da) - -#include "phy-mtk-ssusb-reg.h" - -static DEFINE_MUTEX(prepare_lock); - -enum mt_phy_version { - MT_PHY_V1 = 1, - MT_PHY_V2, -}; - -#ifdef CONFIG_FPGA_EARLY_PORTING - -static int phy_inst_init(struct mtk_phy_instance *instance) -{ - return 0; -} - -static int phy_init_soc(struct mtk_phy_instance *instance) -{ - return 0; -} - -static void phy_savecurrent(struct mtk_phy_instance *instance) -{ -} - -static void phy_recover(struct mtk_phy_instance *instance) -{ -} - -static void phy_charger_switch_bc11(struct mtk_phy_instance *instance, - bool on) -{ -} - -static void phy_dpdm_pulldown(struct mtk_phy_instance *instance, - bool enable) -{ -} - -static int phy_lpm_enable(struct mtk_phy_instance *instance, bool on) -{ - return 0; -} - -static int phy_host_mode(struct mtk_phy_instance *instance, bool on) -{ - return 0; -} - -static int phy_ioread(struct mtk_phy_instance *instance, u32 reg) -{ - return 0; -} - -static int phy_iowrite(struct mtk_phy_instance *instance, - u32 val, u32 reg) -{ - return 0; -} - -static bool phy_u3_loop_back_test(struct mtk_phy_instance *instance) -{ - return true; -} - -static void phy_switch_to_usb(struct mtk_phy_instance *instance) -{ -} - -static void phy_switch_to_uart(struct mtk_phy_instance *instance) -{ -} - -bool phy_check_in_uart_mode(struct mtk_phy_instance *instance) -{ - return true; -} - -static void phy_dump_usb2uart_reg(struct mtk_phy_instance *instance) -{ -} - -#else - -static bool usb_enable_clock(struct mtk_phy_drv *u3phy, bool enable) -{ - static int count; - - if (!u3phy->clk) - return false; - - mutex_lock(&prepare_lock); - phy_printk(K_INFO, "CG, enable<%d>, count<%d>\n", enable, count); - - if (enable && count == 0) { - if (clk_prepare_enable(u3phy->clk) != 0) - phy_printk(K_ERR, "clk enable fail\n"); - } else if (!enable && count == 1) { - clk_disable_unprepare(u3phy->clk); - } - - if (enable) - count++; - else - count = (count == 0) ? 0 : (count - 1); - - mutex_unlock(&prepare_lock); - return true; -} - -static void u3phywrite32(void __iomem *addr, int offset, int mask, int value) -{ - int cur_value; - int new_value; - - cur_value = readl(addr); - new_value = (cur_value & (~mask)) | ((value << offset) & mask); - writel(new_value, addr); -} - -static int u3phyread32(void __iomem *addr) -{ - return readl(addr); -} - -static void phy_advance_settings(struct mtk_phy_instance *instance) -{ - /* special request from DE */ - u32 val, offset; - - /* RG_SSUSB_TX_EIDLE_CM, 0x11F40B20[31:28] */ - /* 4'b1000, ssusb_USB30_PHYA_regmap_T12FF_TPHY */ - val = 0x8; - offset = 0x20; - u3phywrite32( - (MTK_USB_PHY_PHYA_BASE + offset), 28, - (0xf<<28), val); - - /* rg_ssusb_cdr_bir_ltr, 0x11F4095C[20:16] 5'b01101 */ - /* ssusb_USB30_PHYD_regmap_T12FF_TPHY */ - val = 0xd; - offset = 0x5c; - u3phywrite32( - (MTK_USB_PHY_U3PHYD_BASE + offset), 16, - (0x1f<<16), val); - - /* HQA request */ - u3phywrite32(U3D_USBPHYACR6, RG_USB20_SQTH_OFST, - RG_USB20_SQTH, 0x5); - - u3phywrite32(U3D_USBPHYACR6, (28), - (0x1<<28), 0x1); -} - -static void phy_efuse_settings(struct mtk_phy_instance *instance) -{ - u32 evalue; - - evalue = (get_devinfo_with_index(108) & (0x1f<<0)) >> 0; - if (evalue) { - phy_printk(K_INFO, "RG_USB20_INTR_CAL=0x%x\n", - evalue); - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_INTR_CAL_OFST, - RG_USB20_INTR_CAL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x3f << 16)) >> 16; - if (evalue) { - phy_printk(K_INFO, "RG_SSUSB_IEXT_INTR_CTRL=0x%x\n", - evalue); - u3phywrite32(U3D_USB30_PHYA_REG0, - RG_SSUSB_IEXT_INTR_CTRL_OFST, - RG_SSUSB_IEXT_INTR_CTRL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x1f << 8)) >> 8; - if (evalue) { - phy_printk(K_INFO, "rg_ssusb_rx_impsel=0x%x\n", - evalue); - u3phywrite32(U3D_PHYD_IMPCAL1, - RG_SSUSB_RX_IMPSEL_OFST, - RG_SSUSB_RX_IMPSEL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x1f << 0)) >> 0; - if (evalue) { - phy_printk(K_INFO, "g_ssusb_tx_impsel=0x%x (R50)\n", - evalue); - - if (evalue < 6) - evalue += 2; - else if (evalue >= 6 && evalue < 15) - evalue += 3; - else - evalue = 15; - phy_printk(K_INFO, "g_ssusb_tx_impsel=0x%x (R45)\n", - evalue); - u3phywrite32(U3D_PHYD_IMPCAL0, - RG_SSUSB_TX_IMPSEL_OFST, - RG_SSUSB_TX_IMPSEL, evalue); - } -} - -static int phy_slew_rate_calibration(struct mtk_phy_instance *instance) -{ - int i = 0; - int fgRet = 0; - int u4FmOut = 0; - int u4Tmp = 0; - - phy_printk(K_DEBUG, "%s\n", __func__); - - /* enable USB ring oscillator */ - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCAL_EN_OFST, - RG_USB20_HSTX_SRCAL_EN, 1); - - /* wait 1us */ - udelay(1); - - /* Enable free run clock */ - u3phywrite32(RG_SSUSB_SIFSLV_FMMONR1, RG_FRCK_EN_OFST, - RG_FRCK_EN, 0x1); - /* Setting cyclecnt */ - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_CYCLECNT_OFST, - RG_CYCLECNT, 0x400); - /* Enable frequency meter */ - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_FREQDET_EN_OFST, - RG_FREQDET_EN, 0x1); - phy_printk(K_DEBUG, "Freq_Valid=(0x%08X)\n", - u3phyread32(RG_SSUSB_SIFSLV_FMMONR1)); - - mdelay(1); - - /* wait for FM detection done, set 10ms timeout */ - for (i = 0; i < 10; i++) { - u4FmOut = u3phyread32(RG_SSUSB_SIFSLV_FMMONR0); - phy_printk(K_DEBUG, "FM_OUT u4FmOut = %d(0x%08X)\n", - u4FmOut, u4FmOut); - if (u4FmOut != 0) { - fgRet = 0; - phy_printk(K_DEBUG, "FM detect loop = %d\n", i); - break; - } - fgRet = 1; - mdelay(1); - } - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_FREQDET_EN_OFST, - RG_FREQDET_EN, 0); - u3phywrite32(RG_SSUSB_SIFSLV_FMMONR1, RG_FRCK_EN_OFST, - RG_FRCK_EN, 0); - - if (u4FmOut == 0) { - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCTRL_OFST, - RG_USB20_HSTX_SRCTRL, 0x4); - fgRet = 1; - } else { - u4Tmp = (1024 * U3D_PHY_REF_CK * U2_SR_COEF); - u4Tmp = u4Tmp / (u4FmOut * 1000); - phy_printk(K_DEBUG, "SR cali u1SrCalVal = %d\n", u4Tmp); - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCTRL_OFST, - RG_USB20_HSTX_SRCTRL, u4Tmp); - } - - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCAL_EN_OFST, - RG_USB20_HSTX_SRCAL_EN, 0); - - return fgRet; -} - -#ifdef CONFIG_MTK_UART_USB_SWITCH -static bool bFirstUartCheck = true; -static bool phy_check_in_uart_mode(struct mtk_phy_instance *instance); -#endif - -static int phy_init_soc(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_DEBUG, "%s\n", __func__); - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if ((bFirstUartCheck && phy_check_in_uart_mode(instance)) || - instance->uart_mode) { - phy_printk(K_ALET, "%s+ already in UART_MODE\n", __func__); - bFirstUartCheck = false; - instance->uart_mode = 1; - goto reg_done; - } else - bFirstUartCheck = false; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return 0; - } -#endif - - /*switch to USB function. (system register, force ip into usb mode) */ - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_UART_MODE_OFST, - RG_UART_MODE, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DP_100K_MODE_OFST, - RG_USB20_DP_100K_MODE, 1); - u3phywrite32(U3D_U2PHYACR4, USB20_DP_100K_EN_OFST, - USB20_DP_100K_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DM_100K_EN_OFST, - RG_USB20_DM_100K_EN, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_OTG_VBUSCMP_EN_OFST, - RG_USB20_OTG_VBUSCMP_EN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 0); - - udelay(800); - - u3phywrite32(U3D_U2PHYDTM1, FORCE_VBUSVALID_OFST, - FORCE_VBUSVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, FORCE_AVALID_OFST, - FORCE_AVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, FORCE_SESSEND_OFST, - FORCE_SESSEND, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH -reg_done: -#endif - usb_enable_clock(phy_drv, false); - - return 0; -} - - -static void phy_savecurrent(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_ALET, "%s\n", __func__); - if (instance->sib_mode) { - phy_printk(K_INFO, "%s sib_mode can't savecurrent\n", __func__); - return; - } - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if (instance->uart_mode) - goto reg_done; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return; - } -#endif - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - /*u3phywrite32(U3D_USBPHYACR6, - *RG_USB20_OTG_VBUSCMP_EN_OFST, - *RG_USB20_OTG_VBUSCMP_EN, 0); - */ - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 1); - udelay(2000); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_XCVRSEL_OFST, - RG_XCVRSEL, 0x1); - u3phywrite32(U3D_U2PHYDTM0, RG_TERMSEL_OFST, - RG_TERMSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DATAIN_OFST, - RG_DATAIN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DP_PULLDOWN_OFST, - FORCE_DP_PULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DM_PULLDOWN_OFST, - FORCE_DM_PULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_XCVRSEL_OFST, - FORCE_XCVRSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_TERMSEL_OFST, - FORCE_TERMSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DATAIN_OFST, - FORCE_DATAIN, 1); - udelay(800); - - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 0); - - udelay(1); - - u3phywrite32(U3D_U2PHYDTM1, RG_VBUSVALID_OFST, - RG_VBUSVALID, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_AVALID_OFST, - RG_AVALID, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_SESSEND_OFST, - RG_SESSEND, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH -reg_done: -#endif - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - udelay(10); - usb_enable_clock(phy_drv, false); -} - -#define VAL_MAX_WIDTH_2 0x3 -#define VAL_MAX_WIDTH_3 0x7 -static void usb_phy_tuning(struct mtk_phy_instance *instance) -{ - s32 u2_vrt_ref, u2_term_ref, u2_enhance; - struct device_node *of_node; - - if (!instance->phy_tuning.inited) { - instance->phy_tuning.u2_vrt_ref = 6; - instance->phy_tuning.u2_term_ref = 6; - instance->phy_tuning.u2_enhance = 1; - of_node = of_find_compatible_node(NULL, NULL, - instance->phycfg->tuning_node_name); - if (of_node) { - /* value won't be updated if property not being found */ - of_property_read_u32(of_node, "u2_vrt_ref", - (u32 *) &instance->phy_tuning.u2_vrt_ref); - of_property_read_u32(of_node, "u2_term_ref", - (u32 *) &instance->phy_tuning.u2_term_ref); - of_property_read_u32(of_node, "u2_enhance", - (u32 *) &instance->phy_tuning.u2_enhance); - } - instance->phy_tuning.inited = true; - } - u2_vrt_ref = instance->phy_tuning.u2_vrt_ref; - u2_term_ref = instance->phy_tuning.u2_term_ref; - u2_enhance = instance->phy_tuning.u2_enhance; - - if (u2_vrt_ref != -1) { - if (u2_vrt_ref <= VAL_MAX_WIDTH_3) { - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_VRT_VREF_SEL_OFST, - RG_USB20_VRT_VREF_SEL, u2_vrt_ref); - } - } - if (u2_term_ref != -1) { - if (u2_term_ref <= VAL_MAX_WIDTH_3) { - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_TERM_VREF_SEL_OFST, - RG_USB20_TERM_VREF_SEL, u2_term_ref); - } - } - if (u2_enhance != -1) { - if (u2_enhance <= VAL_MAX_WIDTH_2) { - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_6_OFST, - RG_USB20_PHY_REV_6, u2_enhance); - } - } - - phy_printk(K_INFO, "%s - SSUSB TX EYE Tuning\n", __func__); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_IDRVSEL_OFST, - RG_SSUSB_IDRVSEL, 0x19); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_FORCE_IDRVSEL_OFST, - RG_SSUSB_FORCE_IDRVSEL, 1); - - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_IDEMSEL_OFST, - RG_SSUSB_IDEMSEL, 0x1a); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_FORCE_IDEMSEL_OFST, - RG_SSUSB_FORCE_IDEMSEL, 1); -} - - -static void phy_recover(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if (instance->uart_mode) - return; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return; - } -#endif - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_XCVRSEL_OFST, - RG_XCVRSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_TERMSEL_OFST, - RG_TERMSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DATAIN_OFST, - RG_DATAIN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DP_PULLDOWN_OFST, - FORCE_DP_PULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DM_PULLDOWN_OFST, - FORCE_DM_PULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_XCVRSEL_OFST, - FORCE_XCVRSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_TERMSEL_OFST, - FORCE_TERMSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DATAIN_OFST, - FORCE_DATAIN, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - /*u3phywrite32(U3D_USBPHYACR6, RG_USB20_OTG_VBUSCMP_EN_OFST, - * RG_USB20_OTG_VBUSCMP_EN, 1); - */ - /* Wait 800 usec */ - udelay(800); - - u3phywrite32(U3D_U2PHYDTM1, RG_VBUSVALID_OFST, - RG_VBUSVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_AVALID_OFST, - RG_AVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_SESSEND_OFST, - RG_SESSEND, 0); - - phy_efuse_settings(instance); - - u3phywrite32(U3D_USBPHYACR6, RG_USB20_DISCTH_OFST, - RG_USB20_DISCTH, 0x7); - - usb_phy_tuning(instance); - phy_advance_settings(instance); - - phy_slew_rate_calibration(instance); - - phy_printk(K_INFO, "%s-\n", __func__); -} - - -static int charger_detect_init(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 1); - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); - return 0; -} - -static int charger_detect_release(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); - return 0; -} - -static void phy_charger_switch_bc11(struct mtk_phy_instance *instance, - bool on) -{ - if (on) - charger_detect_init(instance); - else - charger_detect_release(instance); -} - -static void phy_dpdm_pulldown(struct mtk_phy_instance *instance, - bool enable) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - if (enable) { - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 1); - - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_OFST, (0x2<<24), 0x0); - } else { - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - - /*For water detection function, - *need to set DPPULLDOWN and DMPULLDOWN 0 - *Also adjust RG_USB20_PHY_REV to prevent power leakage - */ - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_OFST, (0x2<<24), 0x2); - } - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); -} - -static int phy_lpm_enable(struct mtk_phy_instance *instance, bool on) -{ - phy_printk(K_DEBUG, "%s+ = %d\n", __func__, on); - - if (on) - u3phywrite32(U3D_U2PHYDCR1, RG_USB20_SW_PLLMODE_OFST, - RG_USB20_SW_PLLMODE, 0x1); - else - u3phywrite32(U3D_U2PHYDCR1, RG_USB20_SW_PLLMODE_OFST, - RG_USB20_SW_PLLMODE, 0x0); - - return 0; -} - -static int phy_host_mode(struct mtk_phy_instance *instance, bool on) -{ - phy_printk(K_DEBUG, "%s+ = %d\n", __func__, on); - - return 0; -} - -static int phy_ioread(struct mtk_phy_instance *instance, u32 reg) -{ - if (reg < instance->port_rgsz) - return readl(instance->sif_u2phy_com + reg); - else - return 0; -} - -static int phy_iowrite(struct mtk_phy_instance *instance, - u32 val, u32 reg) -{ - if (reg < instance->port_rgsz) - writel(val, instance->sif_u2phy_com + reg); - - return 0; -} - - -static bool phy_u3_loop_back_test(struct mtk_phy_instance *instance) -{ - int reg; - bool loop_back_ret = false; - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int r_pipe0, r_rx0, rx_mix0, r_t2rlb; - - /* VA10 is shared by U3/UFS */ - /* default on and set voltage by PMIC */ - /* off/on in SPM suspend/resume */ - - usb_enable_clock(phy_drv, true); - - r_pipe0 = readl(U3D_PHYD_PIPE0); - r_rx0 = readl(U3D_PHYD_RX0); - rx_mix0 = readl(U3D_PHYD_MIX0); - r_t2rlb = readl(U3D_PHYD_T2RLB); - - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<30)) | 0x01<<30, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<28)) | 0x00<<28, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x03<<26)) | 0x01<<26, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x03<<24)) | 0x00<<24, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<22)) | 0x00<<22, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<21)) | 0x00<<21, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<20)) | 0x01<<20, - U3D_PHYD_PIPE0); - mdelay(10); - - /*T2R loop back disable*/ - writel((readl(U3D_PHYD_RX0)&~(0x01<<15)) | 0x00<<15, - U3D_PHYD_RX0); - mdelay(10); - - /* TSEQ lock detect threshold */ - writel((readl(U3D_PHYD_MIX0) & ~(0x07<<24)) | 0x07<<24, - U3D_PHYD_MIX0); - /* set default TSEQ polarity check value = 1 */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<28)) | 0x01<<28, - U3D_PHYD_MIX0); - /* TSEQ polarity check enable */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<29)) | 0x01<<29, - U3D_PHYD_MIX0); - /* TSEQ decoder enable */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<30)) | 0x01<<30, - U3D_PHYD_MIX0); - mdelay(10); - - /* set T2R loop back TSEQ length (x 16us) */ - writel((readl(U3D_PHYD_T2RLB) & ~(0xff<<0)) | 0xF0<<0, - U3D_PHYD_T2RLB); - /* set T2R loop back BDAT reset period (x 16us) */ - writel((readl(U3D_PHYD_T2RLB) & ~(0x0f<<12)) | 0x0F<<12, - U3D_PHYD_T2RLB); - /* T2R loop back pattern select */ - writel((readl(U3D_PHYD_T2RLB) & ~(0x03<<8)) | 0x00<<8, - U3D_PHYD_T2RLB); - mdelay(10); - - /* T2R loop back serial mode */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<13)) | 0x01<<13, - U3D_PHYD_RX0); - /* T2R loop back parallel mode = 0 */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<12)) | 0x00<<12, - U3D_PHYD_RX0); - /* T2R loop back mode enable */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<11)) | 0x01<<11, - U3D_PHYD_RX0); - /* T2R loop back enable */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<15)) | 0x01<<15, - U3D_PHYD_RX0); - mdelay(100); - - reg = u3phyread32(SSUSB_SIFSLV_U3PHYD_BASE + 0xb4); - phy_printk(K_INFO, "rb back : 0x%x\n", reg); - phy_printk(K_INFO, "rb t2rlb_lock : %d\n", (reg >> 2) & 0x01); - phy_printk(K_INFO, "rb t2rlb_pass : %d\n", (reg >> 3) & 0x01); - phy_printk(K_INFO, "rb t2rlb_passth: %d\n", (reg >> 4) & 0x01); - - if ((reg & 0x0E) == 0x0E) - loop_back_ret = true; - else - loop_back_ret = false; - - writel(r_rx0, U3D_PHYD_RX0); - writel(r_pipe0, U3D_PHYD_PIPE0); - writel(rx_mix0, U3D_PHYD_MIX0); - writel(r_t2rlb, U3D_PHYD_T2RLB); - - usb_enable_clock(phy_drv, false); - return loop_back_ret; -} - - -#ifdef CONFIG_MTK_SIB_USB_SWITCH -static void phy_sib_enable(struct mtk_phy_instance *instance, bool enable) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_DEBUG, "usb_phy_sib_enable_switch =%d\n", enable); - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - /* SSUSB_SIFSLV_IPPC_BASE SSUSB_IP_SW_RST = 0 */ - writel(0x00031000, (void __iomem *)phy_drv->ippc_base + 0x0); - /* SSUSB_IP_HOST_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0x4); - /* SSUSB_IP_DEV_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0x8); - /* SSUSB_IP_PCIE_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0xC); - /* SSUSB_U3_PORT_DIS/SSUSB_U3_PORT_PDN = 0*/ - writel(0x0000000C, (void __iomem *)phy_drv->ippc_base + 0x30); - - /* - * USBMAC mode is 0x62910002 (bit 1) - * MDSIB mode is 0x62910008 (bit 3) - * 0x0629 just likes a signature. Can't be removed. - */ - if (enable) { - writel(0x62910008, MTK_USB_PHY_CHIP_BASE); - instance->sib_mode = true; - } else { - writel(0x62910002, MTK_USB_PHY_CHIP_BASE); - instance->sib_mode = false; - } -} - -static bool phy_sib_switch_status(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int reg; - bool ret; - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - reg = u3phyread32(MTK_USB_PHY_CHIP_BASE); - phy_printk(K_DEBUG, "%s reg=%d\n", __func__, reg); - - if (reg == 0x62910008) - ret = true; - else - ret = false; - - return ret; -} - -#endif - -#ifdef CONFIG_MTK_UART_USB_SWITCH -#include - -static void phy_dump_usb2uart_reg(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - usb_enable_clock(phy_drv, true); - udelay(250); - - phy_printk(K_ALET, "addr: 0x18, value: 0x%x\n", - u3phyread32(U3D_USBPHYACR6)); - phy_printk(K_ALET, "addr: 0x20, value: 0x%x\n", - u3phyread32(U3D_U2PHYACR4)); - phy_printk(K_ALET, "addr: 0x68, value: 0x%x\n", - u3phyread32(U3D_U2PHYDTM0)); - phy_printk(K_ALET, "addr: 0x6C, value: 0x%x\n", - u3phyread32(U3D_U2PHYDTM1)); - - usb_enable_clock(phy_drv, false); -} - -bool phy_check_in_uart_mode(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int usb_port_mode; - - usb_enable_clock(phy_drv, true); - udelay(250); - - usb_port_mode = u3phyread32(U3D_U2PHYDTM0) >> RG_UART_MODE_OFST; - - usb_enable_clock(phy_drv, false); - phy_printk(K_ALET, "%s - usb_port_mode = %d, ", - __func__, usb_port_mode); - phy_printk(K_ALET, "%s - instance->uart_mode = %d\n", - __func__, instance->uart_mode); - - if (usb_port_mode == 0x1) - return true; - else - return false; -} - -static int phy_switch_usb2uart_gpio(enum PORT_MODE portmode) -{ - struct device_node *node; - void __iomem *gpio_base; - - /* SET USB to UART GPIO to UART0 */ - node = of_find_compatible_node(NULL, NULL, "mediatek,gpio"); - if (!node) { - pr_info("error: can't find GPIO node\n"); - return -EINVAL; - } - - gpio_base = of_iomap(node, 0); - if (!gpio_base) { - pr_info("error: iomap fail for GPIO\n"); - return -EINVAL; - } - - if (portmode == PORT_MODE_UART) - writel((readl(gpio_base + RG_GPIO_SELECT) | - (GPIO_SEL_UART0<phy_drv; - - if (phy_check_in_uart_mode(instance)) { - phy_printk(K_DEBUG, "%s+ UART_MODE\n", __func__); - return; - } - - phy_printk(K_DEBUG, "%s+ USB_MODE\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_UART_MODE_OFST, - RG_UART_MODE, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_TX_OE_OFST, - FORCE_UART_TX_OE, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_BIAS_EN_OFST, - FORCE_UART_BIAS_EN, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_TX_OE_OFST, - RG_UART_TX_OE, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_BIAS_EN_OFST, - RG_UART_BIAS_EN, 1); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DM_100K_EN_OFST, - RG_USB20_DM_100K_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - - usb_enable_clock(phy_drv, false); - - phy_switch_usb2uart_gpio(PORT_MODE_UART); - - instance->uart_mode = true; -} - - -static void phy_switch_to_usb(struct mtk_phy_instance *instance) -{ - instance->uart_mode = false; - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - - phy_switch_usb2uart_gpio(PORT_MODE_USB); - - phy_init_soc(instance); -} -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT -int usb2jtag_usb_init(void) -{ - struct device_node *node = NULL; - void __iomem *usb3_sif2_base; - u32 temp; - - pr_notice("[USB2JTAG] %s ++\n", __func__); - - node = of_find_compatible_node(NULL, NULL, "mediatek,usb3"); - if (!node) { - pr_notice("[USB2JTAG] map node @ mediatek,usb3 failed\n"); - return -1; - } - - usb3_sif2_base = of_iomap(node, 2); - if (!usb3_sif2_base) { - pr_notice("[USB2JTAG] iomap usb3_sif2_base failed\n"); - return -1; - } - - /* rg_usb20_gpio_ctl: bit[9] = 1 */ - temp = readl(usb3_sif2_base + 0x320); - writel(temp | (1 << 9), usb3_sif2_base + 0x320); - - /* RG_USB20_BC11_SW_EN: bit[23] = 0 */ - temp = readl(usb3_sif2_base + 0x318); - writel(temp & ~(1 << 23), usb3_sif2_base + 0x318); - - /* RG_USB20_BGR_EN: bit[0] = 1 */ - temp = readl(usb3_sif2_base + 0x300); - writel(temp | (1 << 0), usb3_sif2_base + 0x300); - - /* rg_sifslv_mac_bandgap_en: bit[17] = 0 */ - temp = readl(usb3_sif2_base + 0x308); - writel(temp & ~(1 << 17), usb3_sif2_base + 0x308); - - /* wait stable */ - mdelay(1); - - iounmap(usb3_sif2_base); - - return 0; -} -#endif - -static int phy_inst_init(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - void __iomem *port_base; - - phy_printk(K_DEBUG, "%s+\n", __func__); - - port_base = instance->port_base; - - if (phy_drv->phycfg->version == MT_PHY_V1) { - instance->sif_misc = NULL; - instance->sif_fmreg = phy_drv->phy_base + 0x100; - instance->sif_u2phy_com = port_base; - if (instance->phycfg->port_type == PHY_TYPE_USB3) { - instance->sif_spllc = phy_drv->phy_base; - instance->sif_chip = NULL; - instance->sif_u3phyd = port_base + 0x100; - instance->sif_u3phyd_bank2 = port_base + 0x200; - instance->sif_u3phya = port_base + 0x300; - instance->sif_u3phya_da = port_base + 0x400; - } - instance->port_rgsz = 0x800; - } else if (phy_drv->phycfg->version == MT_PHY_V2) { - instance->sif_misc = port_base; - instance->sif_fmreg = port_base + 0x100; - instance->sif_u2phy_com = port_base + 0x300; - instance->port_rgsz = 0x500; - if (instance->phycfg->port_type == PHY_TYPE_USB3) { - instance->sif_spllc = port_base + 0x700; - instance->sif_chip = port_base + 0x800; - instance->sif_u3phyd = port_base + 0x900; - instance->sif_u3phyd_bank2 = port_base + 0xa00; - instance->sif_u3phya = port_base + 0xb00; - instance->sif_u3phya_da = port_base + 0xc00; - instance->port_rgsz = 0x1000; - } - } - return 0; -} - -#endif - -static int mtk_phy_drv_init(struct platform_device *pdev, - struct mtk_phy_drv *mtkphy) -{ - int ret = 0; - struct device *dev = &pdev->dev; - struct resource *res; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sif_base"); - if (!res) - return -EINVAL; - - mtkphy->phy_base = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(mtkphy->phy_base)) { - dev_info(dev, "failed to remap phy regs\n"); - return PTR_ERR(mtkphy->phy_base); - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ippc"); - if (!res) - return -EINVAL; - - mtkphy->ippc_base = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(mtkphy->ippc_base)) { - dev_info(dev, "failed to remap ippc_base regs\n"); - return PTR_ERR(mtkphy->ippc_base); - } - - mtkphy->clk = devm_clk_get(dev, "ref_clk"); - if (IS_ERR(mtkphy->clk)) { - if (PTR_ERR(mtkphy->clk) == -EPROBE_DEFER) { - dev_info(dev, "mtkphy->clk EPROBE_DEFER\n"); - return -EPROBE_DEFER; - } - mtkphy->clk = NULL; - } - - return ret; -} - -static int mtk_phy_drv_exit(struct platform_device *pdev, - struct mtk_phy_drv *mtkphy) -{ - if (!IS_ERR_OR_NULL(mtkphy->clk)) - clk_disable_unprepare(mtkphy->clk); - return 0; -} - -static const struct mtk_phy_interface ssusb_phys[] = { -{ - .name = "port0", - .tuning_node_name = "mediatek,phy_tuning", - .port_num = 0, - .reg_offset = 0, - .port_type = PHY_TYPE_USB3, - .usb_phy_inst_init = phy_inst_init, - .usb_phy_init = phy_init_soc, - .usb_phy_savecurrent = phy_savecurrent, - .usb_phy_recover = phy_recover, - .usb_phy_switch_to_bc11 = phy_charger_switch_bc11, - .usb_phy_dpdm_pulldown = phy_dpdm_pulldown, - .usb_phy_lpm_enable = phy_lpm_enable, - .usb_phy_host_mode = phy_host_mode, - .usb_phy_io_read = phy_ioread, - .usb_phy_io_write = phy_iowrite, -#ifdef CONFIG_MTK_UART_USB_SWITCH - .usb_phy_switch_to_usb = phy_switch_to_usb, - .usb_phy_switch_to_uart = phy_switch_to_uart, - .usb_phy_check_in_uart_mode = phy_check_in_uart_mode, - .usb_phy_dump_usb2uart_reg = phy_dump_usb2uart_reg, -#endif -#ifdef CONFIG_MTK_SIB_USB_SWITCH - .usb_phy_sib_enable_switch = phy_sib_enable, - .usb_phy_sib_switch_status = phy_sib_switch_status, -#endif - .usb_phy_u3_loop_back_test = phy_u3_loop_back_test, - }, -}; - -static const struct mtk_usbphy_config ssusb_phy_config = { - .phys = ssusb_phys, - .num_phys = 1, - .version = MT_PHY_V2, - .usb_drv_init = mtk_phy_drv_init, - .usb_drv_exit = mtk_phy_drv_exit, -}; - -const struct of_device_id mtk_phy_of_match[] = { - { - .compatible = "mediatek,mt6877-phy", - .data = &ssusb_phy_config, - }, - { }, -}; diff --git a/drivers/phy/mediatek/phy-mtk-mt6885.c b/drivers/phy/mediatek/phy-mtk-mt6885.c deleted file mode 100644 index e6ccf26ba2fe..000000000000 --- a/drivers/phy/mediatek/phy-mtk-mt6885.c +++ /dev/null @@ -1,1128 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2019 MediaTek Inc. -*/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "phy-mtk.h" - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT -#include -#endif - -#define MTK_USB_PHY_BASE (phy_drv->phy_base) -#define MTK_USB_PHY_PORT_BASE (instance->port_base) -#define MTK_USB_PHY_MISC_BASE (instance->sif_misc) -#define MTK_USB_PHY_FMREG_BASE (instance->sif_fmreg) -#define MTK_USB_PHY_SPLLC_BASE (instance->sif_spllc) -#define MTK_USB_PHY_U2_BASE (instance->sif_u2phy_com) -#define MTK_USB_PHY_CHIP_BASE (instance->sif_chip) -#define MTK_USB_PHY_U3PHYD_BASE (instance->sif_u3phyd) -#define MTK_USB_PHY_B2_BASE (instance->sif_u3phyd_bank2) -#define MTK_USB_PHY_PHYA_BASE (instance->sif_u3phya) -#define MTK_USB_PHY_PHYA_DA_BASE (instance->sif_u3phya_da) - -#include "phy-mtk-ssusb-reg.h" - -static DEFINE_MUTEX(prepare_lock); - -enum mt_phy_version { - MT_PHY_V1 = 1, - MT_PHY_V2, -}; - -static bool usb_enable_clock(struct mtk_phy_drv *u3phy, bool enable) -{ - static int count; - - if (!u3phy->clk) - return false; - - mutex_lock(&prepare_lock); - phy_printk(K_INFO, "CG, enable<%d>, count<%d>\n", enable, count); - - if (enable && count == 0) { - if (clk_prepare_enable(u3phy->clk) != 0) - phy_printk(K_ERR, "clk enable fail\n"); - } else if (!enable && count == 1) { - clk_disable_unprepare(u3phy->clk); - } - - if (enable) - count++; - else - count = (count == 0) ? 0 : (count - 1); - - mutex_unlock(&prepare_lock); - return true; -} - -static void u3phywrite32(void __iomem *addr, int offset, int mask, int value) -{ - int cur_value; - int new_value; - - cur_value = readl(addr); - new_value = (cur_value & (~mask)) | ((value << offset) & mask); - writel(new_value, addr); -} - -static int u3phyread32(void __iomem *addr) -{ - return readl(addr); -} - -static void phy_advance_settings(struct mtk_phy_instance *instance) -{ - /* special request from DE */ - u32 val, offset; - - /* RG_SSUSB_TX_EIDLE_CM, 0x11F40B20[31:28] */ - /* 4'b1000, ssusb_USB30_PHYA_regmap_T12FF_TPHY */ - val = 0x8; - offset = 0x20; - u3phywrite32( - (MTK_USB_PHY_PHYA_BASE + offset), 28, - (0xf<<28), val); - - /* rg_ssusb_cdr_bir_ltr, 0x11F4095C[20:16] 5'b01101 */ - /* ssusb_USB30_PHYD_regmap_T12FF_TPHY */ - val = 0xd; - offset = 0x5c; - u3phywrite32( - (MTK_USB_PHY_U3PHYD_BASE + offset), 16, - (0x1f<<16), val); -} - -static void phy_efuse_settings(struct mtk_phy_instance *instance) -{ - u32 evalue; - - evalue = (get_devinfo_with_index(108) & (0x1f<<0)) >> 0; - if (evalue) { - phy_printk(K_INFO, "RG_USB20_INTR_CAL=0x%x\n", - evalue); - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_INTR_CAL_OFST, - RG_USB20_INTR_CAL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x3f << 16)) >> 16; - if (evalue) { - phy_printk(K_INFO, "RG_SSUSB_IEXT_INTR_CTRL=0x%x\n", - evalue); - u3phywrite32(U3D_USB30_PHYA_REG0, - RG_SSUSB_IEXT_INTR_CTRL_OFST, - RG_SSUSB_IEXT_INTR_CTRL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x1f << 8)) >> 8; - if (evalue) { - phy_printk(K_INFO, "rg_ssusb_rx_impsel=0x%x\n", - evalue); - u3phywrite32(U3D_PHYD_IMPCAL1, - RG_SSUSB_RX_IMPSEL_OFST, - RG_SSUSB_RX_IMPSEL, evalue); - } - evalue = (get_devinfo_with_index(107) & (0x1f << 0)) >> 0; - if (evalue) { - phy_printk(K_INFO, "g_ssusb_tx_impsel=0x%x (R50)\n", - evalue); - - if (evalue < 6) - evalue += 2; - else if (evalue >= 6 && evalue < 15) - evalue += 3; - else - evalue = 15; - phy_printk(K_INFO, "g_ssusb_tx_impsel=0x%x (R45)\n", - evalue); - u3phywrite32(U3D_PHYD_IMPCAL0, - RG_SSUSB_TX_IMPSEL_OFST, - RG_SSUSB_TX_IMPSEL, evalue); - } -} - -static int phy_slew_rate_calibration(struct mtk_phy_instance *instance) -{ - int i = 0; - int fgRet = 0; - int u4FmOut = 0; - int u4Tmp = 0; - - phy_printk(K_DEBUG, "%s\n", __func__); - - /* enable USB ring oscillator */ - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCAL_EN_OFST, - RG_USB20_HSTX_SRCAL_EN, 1); - - /* wait 1us */ - udelay(1); - - /* Enable free run clock */ - u3phywrite32(RG_SSUSB_SIFSLV_FMMONR1, RG_FRCK_EN_OFST, - RG_FRCK_EN, 0x1); - /* Setting cyclecnt */ - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_CYCLECNT_OFST, - RG_CYCLECNT, 0x400); - /* Enable frequency meter */ - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_FREQDET_EN_OFST, - RG_FREQDET_EN, 0x1); - phy_printk(K_DEBUG, "Freq_Valid=(0x%08X)\n", - u3phyread32(RG_SSUSB_SIFSLV_FMMONR1)); - - mdelay(1); - - /* wait for FM detection done, set 10ms timeout */ - for (i = 0; i < 10; i++) { - u4FmOut = u3phyread32(RG_SSUSB_SIFSLV_FMMONR0); - phy_printk(K_DEBUG, "FM_OUT u4FmOut = %d(0x%08X)\n", - u4FmOut, u4FmOut); - if (u4FmOut != 0) { - fgRet = 0; - phy_printk(K_DEBUG, "FM detect loop = %d\n", i); - break; - } - fgRet = 1; - mdelay(1); - } - u3phywrite32(RG_SSUSB_SIFSLV_FMCR0, RG_FREQDET_EN_OFST, - RG_FREQDET_EN, 0); - u3phywrite32(RG_SSUSB_SIFSLV_FMMONR1, RG_FRCK_EN_OFST, - RG_FRCK_EN, 0); - - if (u4FmOut == 0) { - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCTRL_OFST, - RG_USB20_HSTX_SRCTRL, 0x4); - fgRet = 1; - } else { - u4Tmp = (1024 * U3D_PHY_REF_CK * U2_SR_COEF); - u4Tmp = u4Tmp / (u4FmOut * 1000); - phy_printk(K_DEBUG, "SR cali u1SrCalVal = %d\n", u4Tmp); - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCTRL_OFST, - RG_USB20_HSTX_SRCTRL, u4Tmp); - } - - u3phywrite32(U3D_USBPHYACR5, RG_USB20_HSTX_SRCAL_EN_OFST, - RG_USB20_HSTX_SRCAL_EN, 0); - - return fgRet; -} - -#ifdef CONFIG_MTK_UART_USB_SWITCH -static bool bFirstUartCheck = true; -static bool phy_check_in_uart_mode(struct mtk_phy_instance *instance); -#endif - -static int phy_init_soc(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_DEBUG, "%s\n", __func__); - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if ((bFirstUartCheck && phy_check_in_uart_mode(instance)) || - instance->uart_mode) { - phy_printk(K_ALET, "%s+ already in UART_MODE\n", __func__); - bFirstUartCheck = false; - instance->uart_mode = 1; - goto reg_done; - } else - bFirstUartCheck = false; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return 0; - } -#endif - - /*switch to USB function. (system register, force ip into usb mode) */ - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_UART_MODE_OFST, - RG_UART_MODE, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DP_100K_MODE_OFST, - RG_USB20_DP_100K_MODE, 1); - u3phywrite32(U3D_U2PHYACR4, USB20_DP_100K_EN_OFST, - USB20_DP_100K_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DM_100K_EN_OFST, - RG_USB20_DM_100K_EN, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_OTG_VBUSCMP_EN_OFST, - RG_USB20_OTG_VBUSCMP_EN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 0); - - udelay(800); - - u3phywrite32(U3D_U2PHYDTM1, FORCE_VBUSVALID_OFST, - FORCE_VBUSVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, FORCE_AVALID_OFST, - FORCE_AVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, FORCE_SESSEND_OFST, - FORCE_SESSEND, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH -reg_done: -#endif - usb_enable_clock(phy_drv, false); - - return 0; -} - - -static void phy_savecurrent(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_ALET, "%s\n", __func__); - if (instance->sib_mode) { - phy_printk(K_INFO, "%s sib_mode can't savecurrent\n", __func__); - return; - } - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if (instance->uart_mode) - goto reg_done; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return; - } -#endif - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - /*u3phywrite32(U3D_USBPHYACR6, - *RG_USB20_OTG_VBUSCMP_EN_OFST, - *RG_USB20_OTG_VBUSCMP_EN, 0); - */ - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 1); - udelay(2000); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_XCVRSEL_OFST, - RG_XCVRSEL, 0x1); - u3phywrite32(U3D_U2PHYDTM0, RG_TERMSEL_OFST, - RG_TERMSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DATAIN_OFST, - RG_DATAIN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DP_PULLDOWN_OFST, - FORCE_DP_PULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DM_PULLDOWN_OFST, - FORCE_DM_PULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_XCVRSEL_OFST, - FORCE_XCVRSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_TERMSEL_OFST, - FORCE_TERMSEL, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DATAIN_OFST, - FORCE_DATAIN, 1); - udelay(800); - - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 0); - - udelay(1); - - u3phywrite32(U3D_U2PHYDTM1, RG_VBUSVALID_OFST, - RG_VBUSVALID, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_AVALID_OFST, - RG_AVALID, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_SESSEND_OFST, - RG_SESSEND, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH -reg_done: -#endif - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - udelay(10); - usb_enable_clock(phy_drv, false); -} - -#define VAL_MAX_WIDTH_2 0x3 -#define VAL_MAX_WIDTH_3 0x7 -static void usb_phy_tuning(struct mtk_phy_instance *instance) -{ - s32 u2_vrt_ref, u2_term_ref, u2_enhance; - struct device_node *of_node; - - if (!instance->phy_tuning.inited) { - instance->phy_tuning.u2_vrt_ref = 6; - instance->phy_tuning.u2_term_ref = 6; - instance->phy_tuning.u2_enhance = 1; - of_node = of_find_compatible_node(NULL, NULL, - instance->phycfg->tuning_node_name); - if (of_node) { - /* value won't be updated if property not being found */ - of_property_read_u32(of_node, "u2_vrt_ref", - (u32 *) &instance->phy_tuning.u2_vrt_ref); - of_property_read_u32(of_node, "u2_term_ref", - (u32 *) &instance->phy_tuning.u2_term_ref); - of_property_read_u32(of_node, "u2_enhance", - (u32 *) &instance->phy_tuning.u2_enhance); - } - instance->phy_tuning.inited = true; - } - u2_vrt_ref = instance->phy_tuning.u2_vrt_ref; - u2_term_ref = instance->phy_tuning.u2_term_ref; - u2_enhance = instance->phy_tuning.u2_enhance; - - if (u2_vrt_ref != -1) { - if (u2_vrt_ref <= VAL_MAX_WIDTH_3) { - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_VRT_VREF_SEL_OFST, - RG_USB20_VRT_VREF_SEL, u2_vrt_ref); - } - } - if (u2_term_ref != -1) { - if (u2_term_ref <= VAL_MAX_WIDTH_3) { - u3phywrite32(U3D_USBPHYACR1, - RG_USB20_TERM_VREF_SEL_OFST, - RG_USB20_TERM_VREF_SEL, u2_term_ref); - } - } - if (u2_enhance != -1) { - if (u2_enhance <= VAL_MAX_WIDTH_2) { - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_6_OFST, - RG_USB20_PHY_REV_6, u2_enhance); - } - } - - phy_printk(K_INFO, "%s - SSUSB TX EYE Tuning\n", __func__); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_IDRVSEL_OFST, - RG_SSUSB_IDRVSEL, 0x19); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_FORCE_IDRVSEL_OFST, - RG_SSUSB_FORCE_IDRVSEL, 1); - - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_IDEMSEL_OFST, - RG_SSUSB_IDEMSEL, 0x1a); - u3phywrite32(U3D_PHYD_MIX6, RG_SSUSB_FORCE_IDEMSEL_OFST, - RG_SSUSB_FORCE_IDEMSEL, 1); -} - - -static void phy_recover(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - -#ifdef CONFIG_MTK_UART_USB_SWITCH - if (instance->uart_mode) - return; -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT - if (usb2jtag_mode()) { - phy_printk(K_INFO, "%s, bypass in usb2jtag mode\n", __func__); - return; - } -#endif - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 0); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_GPIO_CTL_OFST, - RG_USB20_GPIO_CTL, 0); - u3phywrite32(U3D_U2PHYACR4, USB20_GPIO_MODE_OFST, - USB20_GPIO_MODE, 0); - - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_XCVRSEL_OFST, - RG_XCVRSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_TERMSEL_OFST, - RG_TERMSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DATAIN_OFST, - RG_DATAIN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DP_PULLDOWN_OFST, - FORCE_DP_PULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DM_PULLDOWN_OFST, - FORCE_DM_PULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_XCVRSEL_OFST, - FORCE_XCVRSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_TERMSEL_OFST, - FORCE_TERMSEL, 0); - u3phywrite32(U3D_U2PHYDTM0, FORCE_DATAIN_OFST, - FORCE_DATAIN, 0); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - /*u3phywrite32(U3D_USBPHYACR6, RG_USB20_OTG_VBUSCMP_EN_OFST, - * RG_USB20_OTG_VBUSCMP_EN, 1); - */ - /* Wait 800 usec */ - udelay(800); - - u3phywrite32(U3D_U2PHYDTM1, RG_VBUSVALID_OFST, - RG_VBUSVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_AVALID_OFST, - RG_AVALID, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_SESSEND_OFST, - RG_SESSEND, 0); - - phy_efuse_settings(instance); - - u3phywrite32(U3D_USBPHYACR6, RG_USB20_DISCTH_OFST, - RG_USB20_DISCTH, 0x7); - - usb_phy_tuning(instance); - phy_advance_settings(instance); - - phy_slew_rate_calibration(instance); - - phy_printk(K_INFO, "%s-\n", __func__); -} - - -static int charger_detect_init(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 1); - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); - return 0; -} - -static int charger_detect_release(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); - return 0; -} - -static void phy_charger_switch_bc11(struct mtk_phy_instance *instance, - bool on) -{ - if (on) - charger_detect_init(instance); - else - charger_detect_release(instance); -} - -static void phy_dpdm_pulldown(struct mtk_phy_instance *instance, - bool enable) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_INFO, "%s+\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - if (enable) { - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 1); - - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_OFST, (0x2<<24), 0x0); - } else { - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - - /*For water detection function, - *need to set DPPULLDOWN and DMPULLDOWN 0 - *Also adjust RG_USB20_PHY_REV to prevent power leakage - */ - u3phywrite32(U3D_USBPHYACR6, - RG_USB20_PHY_REV_OFST, (0x2<<24), 0x2); - } - udelay(1); - usb_enable_clock(phy_drv, false); - - phy_printk(K_INFO, "%s-\n", __func__); -} - -static int phy_lpm_enable(struct mtk_phy_instance *instance, bool on) -{ - phy_printk(K_DEBUG, "%s+ = %d\n", __func__, on); - - if (on) - u3phywrite32(U3D_U2PHYDCR1, RG_USB20_SW_PLLMODE_OFST, - RG_USB20_SW_PLLMODE, 0x1); - else - u3phywrite32(U3D_U2PHYDCR1, RG_USB20_SW_PLLMODE_OFST, - RG_USB20_SW_PLLMODE, 0x0); - - return 0; -} - -static int phy_host_mode(struct mtk_phy_instance *instance, bool on) -{ - phy_printk(K_DEBUG, "%s+ = %d\n", __func__, on); - - return 0; -} - -static int phy_ioread(struct mtk_phy_instance *instance, u32 reg) -{ - if (reg < instance->port_rgsz) - return readl(instance->sif_u2phy_com + reg); - else - return 0; -} - -static int phy_iowrite(struct mtk_phy_instance *instance, - u32 val, u32 reg) -{ - if (reg < instance->port_rgsz) - writel(val, instance->sif_u2phy_com + reg); - - return 0; -} - - -static bool phy_u3_loop_back_test(struct mtk_phy_instance *instance) -{ - int reg; - bool loop_back_ret = false; - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int r_pipe0, r_rx0, rx_mix0, r_t2rlb; - - /* VA10 is shared by U3/UFS */ - /* default on and set voltage by PMIC */ - /* off/on in SPM suspend/resume */ - - usb_enable_clock(phy_drv, true); - - r_pipe0 = readl(U3D_PHYD_PIPE0); - r_rx0 = readl(U3D_PHYD_RX0); - rx_mix0 = readl(U3D_PHYD_MIX0); - r_t2rlb = readl(U3D_PHYD_T2RLB); - - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<30)) | 0x01<<30, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<28)) | 0x00<<28, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x03<<26)) | 0x01<<26, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x03<<24)) | 0x00<<24, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<22)) | 0x00<<22, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<21)) | 0x00<<21, - U3D_PHYD_PIPE0); - writel((readl(U3D_PHYD_PIPE0) & ~(0x01<<20)) | 0x01<<20, - U3D_PHYD_PIPE0); - mdelay(10); - - /*T2R loop back disable*/ - writel((readl(U3D_PHYD_RX0)&~(0x01<<15)) | 0x00<<15, - U3D_PHYD_RX0); - mdelay(10); - - /* TSEQ lock detect threshold */ - writel((readl(U3D_PHYD_MIX0) & ~(0x07<<24)) | 0x07<<24, - U3D_PHYD_MIX0); - /* set default TSEQ polarity check value = 1 */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<28)) | 0x01<<28, - U3D_PHYD_MIX0); - /* TSEQ polarity check enable */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<29)) | 0x01<<29, - U3D_PHYD_MIX0); - /* TSEQ decoder enable */ - writel((readl(U3D_PHYD_MIX0) & ~(0x01<<30)) | 0x01<<30, - U3D_PHYD_MIX0); - mdelay(10); - - /* set T2R loop back TSEQ length (x 16us) */ - writel((readl(U3D_PHYD_T2RLB) & ~(0xff<<0)) | 0xF0<<0, - U3D_PHYD_T2RLB); - /* set T2R loop back BDAT reset period (x 16us) */ - writel((readl(U3D_PHYD_T2RLB) & ~(0x0f<<12)) | 0x0F<<12, - U3D_PHYD_T2RLB); - /* T2R loop back pattern select */ - writel((readl(U3D_PHYD_T2RLB) & ~(0x03<<8)) | 0x00<<8, - U3D_PHYD_T2RLB); - mdelay(10); - - /* T2R loop back serial mode */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<13)) | 0x01<<13, - U3D_PHYD_RX0); - /* T2R loop back parallel mode = 0 */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<12)) | 0x00<<12, - U3D_PHYD_RX0); - /* T2R loop back mode enable */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<11)) | 0x01<<11, - U3D_PHYD_RX0); - /* T2R loop back enable */ - writel((readl(U3D_PHYD_RX0) & ~(0x01<<15)) | 0x01<<15, - U3D_PHYD_RX0); - mdelay(100); - - reg = u3phyread32(SSUSB_SIFSLV_U3PHYD_BASE + 0xb4); - phy_printk(K_INFO, "rb back : 0x%x\n", reg); - phy_printk(K_INFO, "rb t2rlb_lock : %d\n", (reg >> 2) & 0x01); - phy_printk(K_INFO, "rb t2rlb_pass : %d\n", (reg >> 3) & 0x01); - phy_printk(K_INFO, "rb t2rlb_passth: %d\n", (reg >> 4) & 0x01); - - if ((reg & 0x0E) == 0x0E) - loop_back_ret = true; - else - loop_back_ret = false; - - writel(r_rx0, U3D_PHYD_RX0); - writel(r_pipe0, U3D_PHYD_PIPE0); - writel(rx_mix0, U3D_PHYD_MIX0); - writel(r_t2rlb, U3D_PHYD_T2RLB); - - usb_enable_clock(phy_drv, false); - return loop_back_ret; -} - - -#ifdef CONFIG_MTK_SIB_USB_SWITCH -static void phy_sib_enable(struct mtk_phy_instance *instance, bool enable) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - phy_printk(K_DEBUG, "usb_phy_sib_enable_switch =%d\n", enable); - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - /* SSUSB_SIFSLV_IPPC_BASE SSUSB_IP_SW_RST = 0 */ - writel(0x00031000, (void __iomem *)phy_drv->ippc_base + 0x0); - /* SSUSB_IP_HOST_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0x4); - /* SSUSB_IP_DEV_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0x8); - /* SSUSB_IP_PCIE_PDN = 0 */ - writel(0x00000000, (void __iomem *)phy_drv->ippc_base + 0xC); - /* SSUSB_U3_PORT_DIS/SSUSB_U3_PORT_PDN = 0*/ - writel(0x0000000C, (void __iomem *)phy_drv->ippc_base + 0x30); - - /* - * USBMAC mode is 0x62910002 (bit 1) - * MDSIB mode is 0x62910008 (bit 3) - * 0x0629 just likes a signature. Can't be removed. - */ - if (enable) { - writel(0x62910008, MTK_USB_PHY_CHIP_BASE); - instance->sib_mode = true; - } else { - writel(0x62910002, MTK_USB_PHY_CHIP_BASE); - instance->sib_mode = false; - } -} - -static bool phy_sib_switch_status(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int reg; - bool ret; - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USB30_PHYA_REG1, RG_SSUSB_VUSB10_ON_OFST, - RG_SSUSB_VUSB10_ON, 1); - - reg = u3phyread32(MTK_USB_PHY_CHIP_BASE); - phy_printk(K_DEBUG, "%s reg=%d\n", __func__, reg); - - if (reg == 0x62910008) - ret = true; - else - ret = false; - - return ret; -} - -#endif - -#ifdef CONFIG_MTK_UART_USB_SWITCH -#include - -static void phy_dump_usb2uart_reg(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - - usb_enable_clock(phy_drv, true); - udelay(250); - - phy_printk(K_ALET, "addr: 0x18, value: 0x%x\n", - u3phyread32(U3D_USBPHYACR6)); - phy_printk(K_ALET, "addr: 0x20, value: 0x%x\n", - u3phyread32(U3D_U2PHYACR4)); - phy_printk(K_ALET, "addr: 0x68, value: 0x%x\n", - u3phyread32(U3D_U2PHYDTM0)); - phy_printk(K_ALET, "addr: 0x6C, value: 0x%x\n", - u3phyread32(U3D_U2PHYDTM1)); - - usb_enable_clock(phy_drv, false); -} - -bool phy_check_in_uart_mode(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - int usb_port_mode; - - usb_enable_clock(phy_drv, true); - udelay(250); - - usb_port_mode = u3phyread32(U3D_U2PHYDTM0) >> RG_UART_MODE_OFST; - - usb_enable_clock(phy_drv, false); - phy_printk(K_ALET, "%s - usb_port_mode = %d, ", - __func__, usb_port_mode); - phy_printk(K_ALET, "%s - instance->uart_mode = %d\n", - __func__, instance->uart_mode); - - if (usb_port_mode == 0x1) - return true; - else - return false; -} - -static int phy_switch_usb2uart_gpio(enum PORT_MODE portmode) -{ - struct device_node *node; - void __iomem *gpio_base; - - /* SET USB to UART GPIO to UART0 */ - node = of_find_compatible_node(NULL, NULL, "mediatek,gpio"); - if (!node) { - pr_info("error: can't find GPIO node\n"); - return -EINVAL; - } - - gpio_base = of_iomap(node, 0); - if (!gpio_base) { - pr_info("error: iomap fail for GPIO\n"); - return -EINVAL; - } - - if (portmode == PORT_MODE_UART) - writel((readl(gpio_base + RG_GPIO_SELECT) | - (GPIO_SEL_UART0<phy_drv; - - if (phy_check_in_uart_mode(instance)) { - phy_printk(K_DEBUG, "%s+ UART_MODE\n", __func__); - return; - } - - phy_printk(K_DEBUG, "%s+ USB_MODE\n", __func__); - - usb_enable_clock(phy_drv, true); - udelay(250); - - u3phywrite32(U3D_USBPHYACR6, RG_USB20_BC11_SW_EN_OFST, - RG_USB20_BC11_SW_EN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_SUSPENDM_OFST, - RG_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_SUSPENDM_OFST, - FORCE_SUSPENDM, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_UART_MODE_OFST, - RG_UART_MODE, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_TX_OE_OFST, - FORCE_UART_TX_OE, 1); - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_BIAS_EN_OFST, - FORCE_UART_BIAS_EN, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_EN_OFST, - RG_UART_EN, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_TX_OE_OFST, - RG_UART_TX_OE, 1); - u3phywrite32(U3D_U2PHYDTM1, RG_UART_BIAS_EN_OFST, - RG_UART_BIAS_EN, 1); - u3phywrite32(U3D_U2PHYACR4, RG_USB20_DM_100K_EN_OFST, - RG_USB20_DM_100K_EN, 1); - u3phywrite32(U3D_U2PHYDTM0, RG_DPPULLDOWN_OFST, - RG_DPPULLDOWN, 0); - u3phywrite32(U3D_U2PHYDTM0, RG_DMPULLDOWN_OFST, - RG_DMPULLDOWN, 0); - - usb_enable_clock(phy_drv, false); - - phy_switch_usb2uart_gpio(PORT_MODE_UART); - - instance->uart_mode = true; -} - - -static void phy_switch_to_usb(struct mtk_phy_instance *instance) -{ - instance->uart_mode = false; - - u3phywrite32(U3D_U2PHYDTM0, FORCE_UART_EN_OFST, - FORCE_UART_EN, 0); - - phy_switch_usb2uart_gpio(PORT_MODE_USB); - - phy_init_soc(instance); -} -#endif - -#ifdef CONFIG_MTK_USB2JTAG_SUPPORT -int usb2jtag_usb_init(void) -{ - struct device_node *node = NULL; - void __iomem *usb3_sif2_base; - u32 temp; - - pr_notice("[USB2JTAG] %s ++\n", __func__); - - node = of_find_compatible_node(NULL, NULL, "mediatek,usb3"); - if (!node) { - pr_notice("[USB2JTAG] map node @ mediatek,usb3 failed\n"); - return -1; - } - - usb3_sif2_base = of_iomap(node, 2); - if (!usb3_sif2_base) { - pr_notice("[USB2JTAG] iomap usb3_sif2_base failed\n"); - return -1; - } - - /* rg_usb20_gpio_ctl: bit[9] = 1 */ - temp = readl(usb3_sif2_base + 0x320); - writel(temp | (1 << 9), usb3_sif2_base + 0x320); - - /* RG_USB20_BC11_SW_EN: bit[23] = 0 */ - temp = readl(usb3_sif2_base + 0x318); - writel(temp & ~(1 << 23), usb3_sif2_base + 0x318); - - /* RG_USB20_BGR_EN: bit[0] = 1 */ - temp = readl(usb3_sif2_base + 0x300); - writel(temp | (1 << 0), usb3_sif2_base + 0x300); - - /* rg_sifslv_mac_bandgap_en: bit[17] = 0 */ - temp = readl(usb3_sif2_base + 0x308); - writel(temp & ~(1 << 17), usb3_sif2_base + 0x308); - - /* wait stable */ - mdelay(1); - - iounmap(usb3_sif2_base); - - return 0; -} -#endif - -static int mtk_phy_drv_init(struct platform_device *pdev, - struct mtk_phy_drv *mtkphy) -{ - int ret = 0; - struct device *dev = &pdev->dev; - struct resource *res; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sif_base"); - if (!res) - return -EINVAL; - - mtkphy->phy_base = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(mtkphy->phy_base)) { - dev_info(dev, "failed to remap phy regs\n"); - return PTR_ERR(mtkphy->phy_base); - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ippc"); - if (!res) - return -EINVAL; - - mtkphy->ippc_base = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(mtkphy->ippc_base)) { - dev_info(dev, "failed to remap ippc_base regs\n"); - return PTR_ERR(mtkphy->ippc_base); - } - - mtkphy->clk = devm_clk_get(dev, "ref_clk"); - if (IS_ERR(mtkphy->clk)) { - if (PTR_ERR(mtkphy->clk) == -EPROBE_DEFER) { - dev_info(dev, "mtkphy->clk EPROBE_DEFER\n"); - return -EPROBE_DEFER; - } - mtkphy->clk = NULL; - } - - return ret; -} - -static int mtk_phy_drv_exit(struct platform_device *pdev, - struct mtk_phy_drv *mtkphy) -{ - if (!IS_ERR_OR_NULL(mtkphy->clk)) - clk_disable_unprepare(mtkphy->clk); - return 0; -} - -static int phy_inst_init(struct mtk_phy_instance *instance) -{ - struct mtk_phy_drv *phy_drv = instance->phy_drv; - void __iomem *port_base; - - phy_printk(K_DEBUG, "%s+\n", __func__); - - port_base = instance->port_base; - - if (phy_drv->phycfg->version == MT_PHY_V1) { - instance->sif_misc = NULL; - instance->sif_fmreg = phy_drv->phy_base + 0x100; - instance->sif_u2phy_com = port_base; - if (instance->phycfg->port_type == PHY_TYPE_USB3) { - instance->sif_spllc = phy_drv->phy_base; - instance->sif_chip = NULL; - instance->sif_u3phyd = port_base + 0x100; - instance->sif_u3phyd_bank2 = port_base + 0x200; - instance->sif_u3phya = port_base + 0x300; - instance->sif_u3phya_da = port_base + 0x400; - } - instance->port_rgsz = 0x800; - } else if (phy_drv->phycfg->version == MT_PHY_V2) { - instance->sif_misc = port_base; - instance->sif_fmreg = port_base + 0x100; - instance->sif_u2phy_com = port_base + 0x300; - instance->port_rgsz = 0x500; - if (instance->phycfg->port_type == PHY_TYPE_USB3) { - instance->sif_spllc = port_base + 0x700; - instance->sif_chip = port_base + 0x800; - instance->sif_u3phyd = port_base + 0x900; - instance->sif_u3phyd_bank2 = port_base + 0xa00; - instance->sif_u3phya = port_base + 0xb00; - instance->sif_u3phya_da = port_base + 0xc00; - instance->port_rgsz = 0x1000; - } - } - return 0; -} - - -static const struct mtk_phy_interface ssusb_phys[] = { -{ - .name = "port0", - .tuning_node_name = "mediatek,phy_tuning", - .port_num = 0, - .reg_offset = 0, - .port_type = PHY_TYPE_USB3, - .usb_phy_inst_init = phy_inst_init, - .usb_phy_init = phy_init_soc, - .usb_phy_savecurrent = phy_savecurrent, - .usb_phy_recover = phy_recover, - .usb_phy_switch_to_bc11 = phy_charger_switch_bc11, - .usb_phy_dpdm_pulldown = phy_dpdm_pulldown, - .usb_phy_lpm_enable = phy_lpm_enable, - .usb_phy_host_mode = phy_host_mode, - .usb_phy_io_read = phy_ioread, - .usb_phy_io_write = phy_iowrite, -#ifdef CONFIG_MTK_UART_USB_SWITCH - .usb_phy_switch_to_usb = phy_switch_to_usb, - .usb_phy_switch_to_uart = phy_switch_to_uart, - .usb_phy_check_in_uart_mode = phy_check_in_uart_mode, - .usb_phy_dump_usb2uart_reg = phy_dump_usb2uart_reg, -#endif -#ifdef CONFIG_MTK_SIB_USB_SWITCH - .usb_phy_sib_enable_switch = phy_sib_enable, - .usb_phy_sib_switch_status = phy_sib_switch_status, -#endif - .usb_phy_u3_loop_back_test = phy_u3_loop_back_test, - }, -}; - -static const struct mtk_usbphy_config ssusb_phy_config = { - .phys = ssusb_phys, - .num_phys = 1, - .version = MT_PHY_V2, - .usb_drv_init = mtk_phy_drv_init, - .usb_drv_exit = mtk_phy_drv_exit, -}; - -const struct of_device_id mtk_phy_of_match[] = { - { - .compatible = "mediatek,mt6885-phy", - .data = &ssusb_phy_config, - }, - { }, -}; diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index 0a604a35f3e1..0bf20a2fc10b 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -1336,11 +1336,15 @@ static void u2_phy_instance_power_on(struct mtk_tphy *tphy, /* HQA Setting */ tmp = readl(com + U3P_USBPHYACR6); tmp &= ~PA6_RG_U2_DISCTH; - tmp |= PA6_RG_U2_DISCTH_VAL(0xf); + tmp |= PA6_RG_U2_DISCTH_VAL(0xa); writel(tmp, com + U3P_USBPHYACR6); #endif dev_info(tphy->dev, "%s(%d)\n", __func__, index); + tmp = readl(com + 0x08); + tmp |= 0x1<<3; + writel(tmp, u2_banks->com + 0x08); + dev_info(tphy->dev, "%s, 0x08 = (0x%0x)\n", __func__, readl(com + 0x08)); } static void u2_phy_instance_power_off(struct mtk_tphy *tphy, @@ -1562,6 +1566,7 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy, return; case PHY_MODE_USB_DEVICE: tmp |= P2C_FORCE_IDDIG | P2C_RG_IDDIG; +#if 0 device_property_read_u32(dev, "mediatek,eye-src", &instance->eye_src); device_property_read_u32(dev, "mediatek,eye-vrt", @@ -1572,6 +1577,10 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy, &instance->eye_rev6); device_property_read_u32(dev, "mediatek,eye-disc", &instance->eye_disc); +#endif + instance->eye_vrt = 7; + instance->eye_term = 6; + instance->eye_rev6 = 3; u2_phy_props_set(tphy, instance); break; case PHY_MODE_USB_HOST: @@ -1582,6 +1591,7 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy, tmp |= P2C_RG_VBUSVALID | P2C_RG_BVALID | P2C_RG_AVALID; tmp &= ~P2C_RG_SESSEND; #endif +#if 0 device_property_read_u32(dev, "mediatek,host-eye-src", &instance->eye_src); device_property_read_u32(dev, "mediatek,host-eye-vrt", @@ -1592,6 +1602,10 @@ static void u2_phy_instance_set_mode(struct mtk_tphy *tphy, &instance->eye_rev6); device_property_read_u32(dev, "mediatek,host-eye-disc", &instance->eye_disc); +#endif + instance->eye_vrt = 4; + instance->eye_term = 4; + instance->eye_rev6 = 1; u2_phy_props_set(tphy, instance); break; case PHY_MODE_USB_OTG: