linux/drivers/phy/phy-mt65xx-usb3.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2015 MediaTek Inc.
   3 * Author: Chunfeng Yun <chunfeng.yun@mediatek.com>
   4 *
   5 * This software is licensed under the terms of the GNU General Public
   6 * License version 2, as published by the Free Software Foundation, and
   7 * may be copied, distributed, and modified under those terms.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 */
  15
  16#include <dt-bindings/phy/phy.h>
  17#include <linux/clk.h>
  18#include <linux/delay.h>
  19#include <linux/io.h>
  20#include <linux/iopoll.h>
  21#include <linux/module.h>
  22#include <linux/of_address.h>
  23#include <linux/phy/phy.h>
  24#include <linux/platform_device.h>
  25
  26/* version V1 sub-banks offset base address */
  27/* banks shared by multiple phys */
  28#define SSUSB_SIFSLV_V1_SPLLC           0x000   /* shared by u3 phys */
  29#define SSUSB_SIFSLV_V1_U2FREQ          0x100   /* shared by u2 phys */
  30/* u2 phy bank */
  31#define SSUSB_SIFSLV_V1_U2PHY_COM       0x000
  32/* u3 phy banks */
  33#define SSUSB_SIFSLV_V1_U3PHYD          0x000
  34#define SSUSB_SIFSLV_V1_U3PHYA          0x200
  35
  36/* version V2 sub-banks offset base address */
  37/* u2 phy banks */
  38#define SSUSB_SIFSLV_V2_MISC            0x000
  39#define SSUSB_SIFSLV_V2_U2FREQ          0x100
  40#define SSUSB_SIFSLV_V2_U2PHY_COM       0x300
  41/* u3 phy banks */
  42#define SSUSB_SIFSLV_V2_SPLLC           0x000
  43#define SSUSB_SIFSLV_V2_CHIP            0x100
  44#define SSUSB_SIFSLV_V2_U3PHYD          0x200
  45#define SSUSB_SIFSLV_V2_U3PHYA          0x400
  46
  47#define U3P_USBPHYACR0          0x000
  48#define PA0_RG_U2PLL_FORCE_ON           BIT(15)
  49#define PA0_RG_USB20_INTR_EN            BIT(5)
  50
  51#define U3P_USBPHYACR2          0x008
  52#define PA2_RG_SIF_U2PLL_FORCE_EN       BIT(18)
  53
  54#define U3P_USBPHYACR5          0x014
  55#define PA5_RG_U2_HSTX_SRCAL_EN BIT(15)
  56#define PA5_RG_U2_HSTX_SRCTRL           GENMASK(14, 12)
  57#define PA5_RG_U2_HSTX_SRCTRL_VAL(x)    ((0x7 & (x)) << 12)
  58#define PA5_RG_U2_HS_100U_U3_EN BIT(11)
  59
  60#define U3P_USBPHYACR6          0x018
  61#define PA6_RG_U2_BC11_SW_EN            BIT(23)
  62#define PA6_RG_U2_OTG_VBUSCMP_EN        BIT(20)
  63#define PA6_RG_U2_SQTH          GENMASK(3, 0)
  64#define PA6_RG_U2_SQTH_VAL(x)   (0xf & (x))
  65
  66#define U3P_U2PHYACR4           0x020
  67#define P2C_RG_USB20_GPIO_CTL           BIT(9)
  68#define P2C_USB20_GPIO_MODE             BIT(8)
  69#define P2C_U2_GPIO_CTR_MSK     (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE)
  70
  71#define U3D_U2PHYDCR0           0x060
  72#define P2C_RG_SIF_U2PLL_FORCE_ON       BIT(24)
  73
  74#define U3P_U2PHYDTM0           0x068
  75#define P2C_FORCE_UART_EN               BIT(26)
  76#define P2C_FORCE_DATAIN                BIT(23)
  77#define P2C_FORCE_DM_PULLDOWN           BIT(21)
  78#define P2C_FORCE_DP_PULLDOWN           BIT(20)
  79#define P2C_FORCE_XCVRSEL               BIT(19)
  80#define P2C_FORCE_SUSPENDM              BIT(18)
  81#define P2C_FORCE_TERMSEL               BIT(17)
  82#define P2C_RG_DATAIN                   GENMASK(13, 10)
  83#define P2C_RG_DATAIN_VAL(x)            ((0xf & (x)) << 10)
  84#define P2C_RG_DMPULLDOWN               BIT(7)
  85#define P2C_RG_DPPULLDOWN               BIT(6)
  86#define P2C_RG_XCVRSEL                  GENMASK(5, 4)
  87#define P2C_RG_XCVRSEL_VAL(x)           ((0x3 & (x)) << 4)
  88#define P2C_RG_SUSPENDM                 BIT(3)
  89#define P2C_RG_TERMSEL                  BIT(2)
  90#define P2C_DTM0_PART_MASK \
  91                (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \
  92                P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \
  93                P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \
  94                P2C_RG_DPPULLDOWN | P2C_RG_TERMSEL)
  95
  96#define U3P_U2PHYDTM1           0x06C
  97#define P2C_RG_UART_EN                  BIT(16)
  98#define P2C_RG_VBUSVALID                BIT(5)
  99#define P2C_RG_SESSEND                  BIT(4)
 100#define P2C_RG_AVALID                   BIT(2)
 101
 102#define U3P_U3_PHYA_REG6        0x018
 103#define P3A_RG_TX_EIDLE_CM              GENMASK(31, 28)
 104#define P3A_RG_TX_EIDLE_CM_VAL(x)       ((0xf & (x)) << 28)
 105
 106#define U3P_U3_PHYA_REG9        0x024
 107#define P3A_RG_RX_DAC_MUX               GENMASK(5, 1)
 108#define P3A_RG_RX_DAC_MUX_VAL(x)        ((0x1f & (x)) << 1)
 109
 110#define U3P_U3_PHYA_DA_REG0     0x100
 111#define P3A_RG_XTAL_EXT_EN_U3           GENMASK(11, 10)
 112#define P3A_RG_XTAL_EXT_EN_U3_VAL(x)    ((0x3 & (x)) << 10)
 113
 114#define U3P_U3_PHYD_LFPS1               0x00c
 115#define P3D_RG_FWAKE_TH         GENMASK(21, 16)
 116#define P3D_RG_FWAKE_TH_VAL(x)  ((0x3f & (x)) << 16)
 117
 118#define U3P_U3_PHYD_CDR1                0x05c
 119#define P3D_RG_CDR_BIR_LTD1             GENMASK(28, 24)
 120#define P3D_RG_CDR_BIR_LTD1_VAL(x)      ((0x1f & (x)) << 24)
 121#define P3D_RG_CDR_BIR_LTD0             GENMASK(12, 8)
 122#define P3D_RG_CDR_BIR_LTD0_VAL(x)      ((0x1f & (x)) << 8)
 123
 124#define U3P_U3_PHYD_RXDET1              0x128
 125#define P3D_RG_RXDET_STB2_SET           GENMASK(17, 9)
 126#define P3D_RG_RXDET_STB2_SET_VAL(x)    ((0x1ff & (x)) << 9)
 127
 128#define U3P_U3_PHYD_RXDET2              0x12c
 129#define P3D_RG_RXDET_STB2_SET_P3        GENMASK(8, 0)
 130#define P3D_RG_RXDET_STB2_SET_P3_VAL(x) (0x1ff & (x))
 131
 132#define U3P_SPLLC_XTALCTL3              0x018
 133#define XC3_RG_U3_XTAL_RX_PWD           BIT(9)
 134#define XC3_RG_U3_FRC_XTAL_RX_PWD       BIT(8)
 135
 136#define U3P_U2FREQ_FMCR0        0x00
 137#define P2F_RG_MONCLK_SEL       GENMASK(27, 26)
 138#define P2F_RG_MONCLK_SEL_VAL(x)        ((0x3 & (x)) << 26)
 139#define P2F_RG_FREQDET_EN       BIT(24)
 140#define P2F_RG_CYCLECNT         GENMASK(23, 0)
 141#define P2F_RG_CYCLECNT_VAL(x)  ((P2F_RG_CYCLECNT) & (x))
 142
 143#define U3P_U2FREQ_VALUE        0x0c
 144
 145#define U3P_U2FREQ_FMMONR1      0x10
 146#define P2F_USB_FM_VALID        BIT(0)
 147#define P2F_RG_FRCK_EN          BIT(8)
 148
 149#define U3P_REF_CLK             26      /* MHZ */
 150#define U3P_SLEW_RATE_COEF      28
 151#define U3P_SR_COEF_DIVISOR     1000
 152#define U3P_FM_DET_CYCLE_CNT    1024
 153
 154enum mt_phy_version {
 155        MT_PHY_V1 = 1,
 156        MT_PHY_V2,
 157};
 158
 159struct mt65xx_phy_pdata {
 160        /* avoid RX sensitivity level degradation only for mt8173 */
 161        bool avoid_rx_sen_degradation;
 162        enum mt_phy_version version;
 163};
 164
 165struct u2phy_banks {
 166        void __iomem *misc;
 167        void __iomem *fmreg;
 168        void __iomem *com;
 169};
 170
 171struct u3phy_banks {
 172        void __iomem *spllc;
 173        void __iomem *chip;
 174        void __iomem *phyd; /* include u3phyd_bank2 */
 175        void __iomem *phya; /* include u3phya_da */
 176};
 177
 178struct mt65xx_phy_instance {
 179        struct phy *phy;
 180        void __iomem *port_base;
 181        union {
 182                struct u2phy_banks u2_banks;
 183                struct u3phy_banks u3_banks;
 184        };
 185        struct clk *ref_clk;    /* reference clock of anolog phy */
 186        u32 index;
 187        u8 type;
 188};
 189
 190struct mt65xx_u3phy {
 191        struct device *dev;
 192        void __iomem *sif_base; /* only shared sif */
 193        /* deprecated, use @ref_clk instead in phy instance */
 194        struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */
 195        const struct mt65xx_phy_pdata *pdata;
 196        struct mt65xx_phy_instance **phys;
 197        int nphys;
 198};
 199
 200static void hs_slew_rate_calibrate(struct mt65xx_u3phy *u3phy,
 201        struct mt65xx_phy_instance *instance)
 202{
 203        struct u2phy_banks *u2_banks = &instance->u2_banks;
 204        void __iomem *fmreg = u2_banks->fmreg;
 205        void __iomem *com = u2_banks->com;
 206        int calibration_val;
 207        int fm_out;
 208        u32 tmp;
 209
 210        /* enable USB ring oscillator */
 211        tmp = readl(com + U3P_USBPHYACR5);
 212        tmp |= PA5_RG_U2_HSTX_SRCAL_EN;
 213        writel(tmp, com + U3P_USBPHYACR5);
 214        udelay(1);
 215
 216        /*enable free run clock */
 217        tmp = readl(fmreg + U3P_U2FREQ_FMMONR1);
 218        tmp |= P2F_RG_FRCK_EN;
 219        writel(tmp, fmreg + U3P_U2FREQ_FMMONR1);
 220
 221        /* set cycle count as 1024, and select u2 channel */
 222        tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
 223        tmp &= ~(P2F_RG_CYCLECNT | P2F_RG_MONCLK_SEL);
 224        tmp |= P2F_RG_CYCLECNT_VAL(U3P_FM_DET_CYCLE_CNT);
 225        if (u3phy->pdata->version == MT_PHY_V1)
 226                tmp |= P2F_RG_MONCLK_SEL_VAL(instance->index >> 1);
 227
 228        writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
 229
 230        /* enable frequency meter */
 231        tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
 232        tmp |= P2F_RG_FREQDET_EN;
 233        writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
 234
 235        /* ignore return value */
 236        readl_poll_timeout(fmreg + U3P_U2FREQ_FMMONR1, tmp,
 237                           (tmp & P2F_USB_FM_VALID), 10, 200);
 238
 239        fm_out = readl(fmreg + U3P_U2FREQ_VALUE);
 240
 241        /* disable frequency meter */
 242        tmp = readl(fmreg + U3P_U2FREQ_FMCR0);
 243        tmp &= ~P2F_RG_FREQDET_EN;
 244        writel(tmp, fmreg + U3P_U2FREQ_FMCR0);
 245
 246        /*disable free run clock */
 247        tmp = readl(fmreg + U3P_U2FREQ_FMMONR1);
 248        tmp &= ~P2F_RG_FRCK_EN;
 249        writel(tmp, fmreg + U3P_U2FREQ_FMMONR1);
 250
 251        if (fm_out) {
 252                /* ( 1024 / FM_OUT ) x reference clock frequency x 0.028 */
 253                tmp = U3P_FM_DET_CYCLE_CNT * U3P_REF_CLK * U3P_SLEW_RATE_COEF;
 254                tmp /= fm_out;
 255                calibration_val = DIV_ROUND_CLOSEST(tmp, U3P_SR_COEF_DIVISOR);
 256        } else {
 257                /* if FM detection fail, set default value */
 258                calibration_val = 4;
 259        }
 260        dev_dbg(u3phy->dev, "phy:%d, fm_out:%d, calib:%d\n",
 261                instance->index, fm_out, calibration_val);
 262
 263        /* set HS slew rate */
 264        tmp = readl(com + U3P_USBPHYACR5);
 265        tmp &= ~PA5_RG_U2_HSTX_SRCTRL;
 266        tmp |= PA5_RG_U2_HSTX_SRCTRL_VAL(calibration_val);
 267        writel(tmp, com + U3P_USBPHYACR5);
 268
 269        /* disable USB ring oscillator */
 270        tmp = readl(com + U3P_USBPHYACR5);
 271        tmp &= ~PA5_RG_U2_HSTX_SRCAL_EN;
 272        writel(tmp, com + U3P_USBPHYACR5);
 273}
 274
 275static void u3_phy_instance_init(struct mt65xx_u3phy *u3phy,
 276        struct mt65xx_phy_instance *instance)
 277{
 278        struct u3phy_banks *u3_banks = &instance->u3_banks;
 279        u32 tmp;
 280
 281        /* gating PCIe Analog XTAL clock */
 282        tmp = readl(u3_banks->spllc + U3P_SPLLC_XTALCTL3);
 283        tmp |= XC3_RG_U3_XTAL_RX_PWD | XC3_RG_U3_FRC_XTAL_RX_PWD;
 284        writel(tmp, u3_banks->spllc + U3P_SPLLC_XTALCTL3);
 285
 286        /* gating XSQ */
 287        tmp = readl(u3_banks->phya + U3P_U3_PHYA_DA_REG0);
 288        tmp &= ~P3A_RG_XTAL_EXT_EN_U3;
 289        tmp |= P3A_RG_XTAL_EXT_EN_U3_VAL(2);
 290        writel(tmp, u3_banks->phya + U3P_U3_PHYA_DA_REG0);
 291
 292        tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG9);
 293        tmp &= ~P3A_RG_RX_DAC_MUX;
 294        tmp |= P3A_RG_RX_DAC_MUX_VAL(4);
 295        writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG9);
 296
 297        tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG6);
 298        tmp &= ~P3A_RG_TX_EIDLE_CM;
 299        tmp |= P3A_RG_TX_EIDLE_CM_VAL(0xe);
 300        writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG6);
 301
 302        tmp = readl(u3_banks->phyd + U3P_U3_PHYD_CDR1);
 303        tmp &= ~(P3D_RG_CDR_BIR_LTD0 | P3D_RG_CDR_BIR_LTD1);
 304        tmp |= P3D_RG_CDR_BIR_LTD0_VAL(0xc) | P3D_RG_CDR_BIR_LTD1_VAL(0x3);
 305        writel(tmp, u3_banks->phyd + U3P_U3_PHYD_CDR1);
 306
 307        tmp = readl(u3_banks->phyd + U3P_U3_PHYD_LFPS1);
 308        tmp &= ~P3D_RG_FWAKE_TH;
 309        tmp |= P3D_RG_FWAKE_TH_VAL(0x34);
 310        writel(tmp, u3_banks->phyd + U3P_U3_PHYD_LFPS1);
 311
 312        tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET1);
 313        tmp &= ~P3D_RG_RXDET_STB2_SET;
 314        tmp |= P3D_RG_RXDET_STB2_SET_VAL(0x10);
 315        writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET1);
 316
 317        tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RXDET2);
 318        tmp &= ~P3D_RG_RXDET_STB2_SET_P3;
 319        tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
 320        writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
 321
 322        dev_dbg(u3phy->dev, "%s(%d)\n", __func__, instance->index);
 323}
 324
 325static void phy_instance_init(struct mt65xx_u3phy *u3phy,
 326        struct mt65xx_phy_instance *instance)
 327{
 328        struct u2phy_banks *u2_banks = &instance->u2_banks;
 329        void __iomem *com = u2_banks->com;
 330        u32 index = instance->index;
 331        u32 tmp;
 332
 333        /* switch to USB function. (system register, force ip into usb mode) */
 334        tmp = readl(com + U3P_U2PHYDTM0);
 335        tmp &= ~P2C_FORCE_UART_EN;
 336        tmp |= P2C_RG_XCVRSEL_VAL(1) | P2C_RG_DATAIN_VAL(0);
 337        writel(tmp, com + U3P_U2PHYDTM0);
 338
 339        tmp = readl(com + U3P_U2PHYDTM1);
 340        tmp &= ~P2C_RG_UART_EN;
 341        writel(tmp, com + U3P_U2PHYDTM1);
 342
 343        tmp = readl(com + U3P_USBPHYACR0);
 344        tmp |= PA0_RG_USB20_INTR_EN;
 345        writel(tmp, com + U3P_USBPHYACR0);
 346
 347        /* disable switch 100uA current to SSUSB */
 348        tmp = readl(com + U3P_USBPHYACR5);
 349        tmp &= ~PA5_RG_U2_HS_100U_U3_EN;
 350        writel(tmp, com + U3P_USBPHYACR5);
 351
 352        if (!index) {
 353                tmp = readl(com + U3P_U2PHYACR4);
 354                tmp &= ~P2C_U2_GPIO_CTR_MSK;
 355                writel(tmp, com + U3P_U2PHYACR4);
 356        }
 357
 358        if (u3phy->pdata->avoid_rx_sen_degradation) {
 359                if (!index) {
 360                        tmp = readl(com + U3P_USBPHYACR2);
 361                        tmp |= PA2_RG_SIF_U2PLL_FORCE_EN;
 362                        writel(tmp, com + U3P_USBPHYACR2);
 363
 364                        tmp = readl(com + U3D_U2PHYDCR0);
 365                        tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
 366                        writel(tmp, com + U3D_U2PHYDCR0);
 367                } else {
 368                        tmp = readl(com + U3D_U2PHYDCR0);
 369                        tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
 370                        writel(tmp, com + U3D_U2PHYDCR0);
 371
 372                        tmp = readl(com + U3P_U2PHYDTM0);
 373                        tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
 374                        writel(tmp, com + U3P_U2PHYDTM0);
 375                }
 376        }
 377
 378        tmp = readl(com + U3P_USBPHYACR6);
 379        tmp &= ~PA6_RG_U2_BC11_SW_EN;   /* DP/DM BC1.1 path Disable */
 380        tmp &= ~PA6_RG_U2_SQTH;
 381        tmp |= PA6_RG_U2_SQTH_VAL(2);
 382        writel(tmp, com + U3P_USBPHYACR6);
 383
 384        dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
 385}
 386
 387static void phy_instance_power_on(struct mt65xx_u3phy *u3phy,
 388        struct mt65xx_phy_instance *instance)
 389{
 390        struct u2phy_banks *u2_banks = &instance->u2_banks;
 391        void __iomem *com = u2_banks->com;
 392        u32 index = instance->index;
 393        u32 tmp;
 394
 395        /* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */
 396        tmp = readl(com + U3P_U2PHYDTM0);
 397        tmp &= ~(P2C_FORCE_SUSPENDM | P2C_RG_XCVRSEL);
 398        tmp &= ~(P2C_RG_DATAIN | P2C_DTM0_PART_MASK);
 399        writel(tmp, com + U3P_U2PHYDTM0);
 400
 401        /* OTG Enable */
 402        tmp = readl(com + U3P_USBPHYACR6);
 403        tmp |= PA6_RG_U2_OTG_VBUSCMP_EN;
 404        writel(tmp, com + U3P_USBPHYACR6);
 405
 406        tmp = readl(com + U3P_U2PHYDTM1);
 407        tmp |= P2C_RG_VBUSVALID | P2C_RG_AVALID;
 408        tmp &= ~P2C_RG_SESSEND;
 409        writel(tmp, com + U3P_U2PHYDTM1);
 410
 411        if (u3phy->pdata->avoid_rx_sen_degradation && index) {
 412                tmp = readl(com + U3D_U2PHYDCR0);
 413                tmp |= P2C_RG_SIF_U2PLL_FORCE_ON;
 414                writel(tmp, com + U3D_U2PHYDCR0);
 415
 416                tmp = readl(com + U3P_U2PHYDTM0);
 417                tmp |= P2C_RG_SUSPENDM | P2C_FORCE_SUSPENDM;
 418                writel(tmp, com + U3P_U2PHYDTM0);
 419        }
 420        dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
 421}
 422
 423static void phy_instance_power_off(struct mt65xx_u3phy *u3phy,
 424        struct mt65xx_phy_instance *instance)
 425{
 426        struct u2phy_banks *u2_banks = &instance->u2_banks;
 427        void __iomem *com = u2_banks->com;
 428        u32 index = instance->index;
 429        u32 tmp;
 430
 431        tmp = readl(com + U3P_U2PHYDTM0);
 432        tmp &= ~(P2C_RG_XCVRSEL | P2C_RG_DATAIN);
 433        tmp |= P2C_FORCE_SUSPENDM;
 434        writel(tmp, com + U3P_U2PHYDTM0);
 435
 436        /* OTG Disable */
 437        tmp = readl(com + U3P_USBPHYACR6);
 438        tmp &= ~PA6_RG_U2_OTG_VBUSCMP_EN;
 439        writel(tmp, com + U3P_USBPHYACR6);
 440
 441        /* let suspendm=0, set utmi into analog power down */
 442        tmp = readl(com + U3P_U2PHYDTM0);
 443        tmp &= ~P2C_RG_SUSPENDM;
 444        writel(tmp, com + U3P_U2PHYDTM0);
 445        udelay(1);
 446
 447        tmp = readl(com + U3P_U2PHYDTM1);
 448        tmp &= ~(P2C_RG_VBUSVALID | P2C_RG_AVALID);
 449        tmp |= P2C_RG_SESSEND;
 450        writel(tmp, com + U3P_U2PHYDTM1);
 451
 452        if (u3phy->pdata->avoid_rx_sen_degradation && index) {
 453                tmp = readl(com + U3D_U2PHYDCR0);
 454                tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
 455                writel(tmp, com + U3D_U2PHYDCR0);
 456        }
 457
 458        dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index);
 459}
 460
 461static void phy_instance_exit(struct mt65xx_u3phy *u3phy,
 462        struct mt65xx_phy_instance *instance)
 463{
 464        struct u2phy_banks *u2_banks = &instance->u2_banks;
 465        void __iomem *com = u2_banks->com;
 466        u32 index = instance->index;
 467        u32 tmp;
 468
 469        if (u3phy->pdata->avoid_rx_sen_degradation && index) {
 470                tmp = readl(com + U3D_U2PHYDCR0);
 471                tmp &= ~P2C_RG_SIF_U2PLL_FORCE_ON;
 472                writel(tmp, com + U3D_U2PHYDCR0);
 473
 474                tmp = readl(com + U3P_U2PHYDTM0);
 475                tmp &= ~P2C_FORCE_SUSPENDM;
 476                writel(tmp, com + U3P_U2PHYDTM0);
 477        }
 478}
 479
 480static void phy_v1_banks_init(struct mt65xx_u3phy *u3phy,
 481                              struct mt65xx_phy_instance *instance)
 482{
 483        struct u2phy_banks *u2_banks = &instance->u2_banks;
 484        struct u3phy_banks *u3_banks = &instance->u3_banks;
 485
 486        if (instance->type == PHY_TYPE_USB2) {
 487                u2_banks->misc = NULL;
 488                u2_banks->fmreg = u3phy->sif_base + SSUSB_SIFSLV_V1_U2FREQ;
 489                u2_banks->com = instance->port_base + SSUSB_SIFSLV_V1_U2PHY_COM;
 490        } else if (instance->type == PHY_TYPE_USB3) {
 491                u3_banks->spllc = u3phy->sif_base + SSUSB_SIFSLV_V1_SPLLC;
 492                u3_banks->chip = NULL;
 493                u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V1_U3PHYD;
 494                u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V1_U3PHYA;
 495        }
 496}
 497
 498static void phy_v2_banks_init(struct mt65xx_u3phy *u3phy,
 499                              struct mt65xx_phy_instance *instance)
 500{
 501        struct u2phy_banks *u2_banks = &instance->u2_banks;
 502        struct u3phy_banks *u3_banks = &instance->u3_banks;
 503
 504        if (instance->type == PHY_TYPE_USB2) {
 505                u2_banks->misc = instance->port_base + SSUSB_SIFSLV_V2_MISC;
 506                u2_banks->fmreg = instance->port_base + SSUSB_SIFSLV_V2_U2FREQ;
 507                u2_banks->com = instance->port_base + SSUSB_SIFSLV_V2_U2PHY_COM;
 508        } else if (instance->type == PHY_TYPE_USB3) {
 509                u3_banks->spllc = instance->port_base + SSUSB_SIFSLV_V2_SPLLC;
 510                u3_banks->chip = instance->port_base + SSUSB_SIFSLV_V2_CHIP;
 511                u3_banks->phyd = instance->port_base + SSUSB_SIFSLV_V2_U3PHYD;
 512                u3_banks->phya = instance->port_base + SSUSB_SIFSLV_V2_U3PHYA;
 513        }
 514}
 515
 516static int mt65xx_phy_init(struct phy *phy)
 517{
 518        struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
 519        struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
 520        int ret;
 521
 522        ret = clk_prepare_enable(u3phy->u3phya_ref);
 523        if (ret) {
 524                dev_err(u3phy->dev, "failed to enable u3phya_ref\n");
 525                return ret;
 526        }
 527
 528        ret = clk_prepare_enable(instance->ref_clk);
 529        if (ret) {
 530                dev_err(u3phy->dev, "failed to enable ref_clk\n");
 531                return ret;
 532        }
 533
 534        if (instance->type == PHY_TYPE_USB2)
 535                phy_instance_init(u3phy, instance);
 536        else
 537                u3_phy_instance_init(u3phy, instance);
 538
 539        return 0;
 540}
 541
 542static int mt65xx_phy_power_on(struct phy *phy)
 543{
 544        struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
 545        struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
 546
 547        if (instance->type == PHY_TYPE_USB2) {
 548                phy_instance_power_on(u3phy, instance);
 549                hs_slew_rate_calibrate(u3phy, instance);
 550        }
 551        return 0;
 552}
 553
 554static int mt65xx_phy_power_off(struct phy *phy)
 555{
 556        struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
 557        struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
 558
 559        if (instance->type == PHY_TYPE_USB2)
 560                phy_instance_power_off(u3phy, instance);
 561
 562        return 0;
 563}
 564
 565static int mt65xx_phy_exit(struct phy *phy)
 566{
 567        struct mt65xx_phy_instance *instance = phy_get_drvdata(phy);
 568        struct mt65xx_u3phy *u3phy = dev_get_drvdata(phy->dev.parent);
 569
 570        if (instance->type == PHY_TYPE_USB2)
 571                phy_instance_exit(u3phy, instance);
 572
 573        clk_disable_unprepare(instance->ref_clk);
 574        clk_disable_unprepare(u3phy->u3phya_ref);
 575        return 0;
 576}
 577
 578static struct phy *mt65xx_phy_xlate(struct device *dev,
 579                                        struct of_phandle_args *args)
 580{
 581        struct mt65xx_u3phy *u3phy = dev_get_drvdata(dev);
 582        struct mt65xx_phy_instance *instance = NULL;
 583        struct device_node *phy_np = args->np;
 584        int index;
 585
 586        if (args->args_count != 1) {
 587                dev_err(dev, "invalid number of cells in 'phy' property\n");
 588                return ERR_PTR(-EINVAL);
 589        }
 590
 591        for (index = 0; index < u3phy->nphys; index++)
 592                if (phy_np == u3phy->phys[index]->phy->dev.of_node) {
 593                        instance = u3phy->phys[index];
 594                        break;
 595                }
 596
 597        if (!instance) {
 598                dev_err(dev, "failed to find appropriate phy\n");
 599                return ERR_PTR(-EINVAL);
 600        }
 601
 602        instance->type = args->args[0];
 603        if (!(instance->type == PHY_TYPE_USB2 ||
 604              instance->type == PHY_TYPE_USB3)) {
 605                dev_err(dev, "unsupported device type: %d\n", instance->type);
 606                return ERR_PTR(-EINVAL);
 607        }
 608
 609        if (u3phy->pdata->version == MT_PHY_V1) {
 610                phy_v1_banks_init(u3phy, instance);
 611        } else if (u3phy->pdata->version == MT_PHY_V2) {
 612                phy_v2_banks_init(u3phy, instance);
 613        } else {
 614                dev_err(dev, "phy version is not supported\n");
 615                return ERR_PTR(-EINVAL);
 616        }
 617
 618        return instance->phy;
 619}
 620
 621static const struct phy_ops mt65xx_u3phy_ops = {
 622        .init           = mt65xx_phy_init,
 623        .exit           = mt65xx_phy_exit,
 624        .power_on       = mt65xx_phy_power_on,
 625        .power_off      = mt65xx_phy_power_off,
 626        .owner          = THIS_MODULE,
 627};
 628
 629static const struct mt65xx_phy_pdata mt2701_pdata = {
 630        .avoid_rx_sen_degradation = false,
 631        .version = MT_PHY_V1,
 632};
 633
 634static const struct mt65xx_phy_pdata mt2712_pdata = {
 635        .avoid_rx_sen_degradation = false,
 636        .version = MT_PHY_V2,
 637};
 638
 639static const struct mt65xx_phy_pdata mt8173_pdata = {
 640        .avoid_rx_sen_degradation = true,
 641        .version = MT_PHY_V1,
 642};
 643
 644static const struct of_device_id mt65xx_u3phy_id_table[] = {
 645        { .compatible = "mediatek,mt2701-u3phy", .data = &mt2701_pdata },
 646        { .compatible = "mediatek,mt2712-u3phy", .data = &mt2712_pdata },
 647        { .compatible = "mediatek,mt8173-u3phy", .data = &mt8173_pdata },
 648        { },
 649};
 650MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table);
 651
 652static int mt65xx_u3phy_probe(struct platform_device *pdev)
 653{
 654        const struct of_device_id *match;
 655        struct device *dev = &pdev->dev;
 656        struct device_node *np = dev->of_node;
 657        struct device_node *child_np;
 658        struct phy_provider *provider;
 659        struct resource *sif_res;
 660        struct mt65xx_u3phy *u3phy;
 661        struct resource res;
 662        int port, retval;
 663
 664        match = of_match_node(mt65xx_u3phy_id_table, pdev->dev.of_node);
 665        if (!match)
 666                return -EINVAL;
 667
 668        u3phy = devm_kzalloc(dev, sizeof(*u3phy), GFP_KERNEL);
 669        if (!u3phy)
 670                return -ENOMEM;
 671
 672        u3phy->pdata = match->data;
 673        u3phy->nphys = of_get_child_count(np);
 674        u3phy->phys = devm_kcalloc(dev, u3phy->nphys,
 675                                       sizeof(*u3phy->phys), GFP_KERNEL);
 676        if (!u3phy->phys)
 677                return -ENOMEM;
 678
 679        u3phy->dev = dev;
 680        platform_set_drvdata(pdev, u3phy);
 681
 682        if (u3phy->pdata->version == MT_PHY_V1) {
 683                /* get banks shared by multiple phys */
 684                sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 685                u3phy->sif_base = devm_ioremap_resource(dev, sif_res);
 686                if (IS_ERR(u3phy->sif_base)) {
 687                        dev_err(dev, "failed to remap sif regs\n");
 688                        return PTR_ERR(u3phy->sif_base);
 689                }
 690        }
 691
 692        /* it's deprecated, make it optional for backward compatibility */
 693        u3phy->u3phya_ref = devm_clk_get(dev, "u3phya_ref");
 694        if (IS_ERR(u3phy->u3phya_ref)) {
 695                if (PTR_ERR(u3phy->u3phya_ref) == -EPROBE_DEFER)
 696                        return -EPROBE_DEFER;
 697
 698                u3phy->u3phya_ref = NULL;
 699        }
 700
 701        port = 0;
 702        for_each_child_of_node(np, child_np) {
 703                struct mt65xx_phy_instance *instance;
 704                struct phy *phy;
 705
 706                instance = devm_kzalloc(dev, sizeof(*instance), GFP_KERNEL);
 707                if (!instance) {
 708                        retval = -ENOMEM;
 709                        goto put_child;
 710                }
 711
 712                u3phy->phys[port] = instance;
 713
 714                phy = devm_phy_create(dev, child_np, &mt65xx_u3phy_ops);
 715                if (IS_ERR(phy)) {
 716                        dev_err(dev, "failed to create phy\n");
 717                        retval = PTR_ERR(phy);
 718                        goto put_child;
 719                }
 720
 721                retval = of_address_to_resource(child_np, 0, &res);
 722                if (retval) {
 723                        dev_err(dev, "failed to get address resource(id-%d)\n",
 724                                port);
 725                        goto put_child;
 726                }
 727
 728                instance->port_base = devm_ioremap_resource(&phy->dev, &res);
 729                if (IS_ERR(instance->port_base)) {
 730                        dev_err(dev, "failed to remap phy regs\n");
 731                        retval = PTR_ERR(instance->port_base);
 732                        goto put_child;
 733                }
 734
 735                instance->phy = phy;
 736                instance->index = port;
 737                phy_set_drvdata(phy, instance);
 738                port++;
 739
 740                /* if deprecated clock is provided, ignore instance's one */
 741                if (u3phy->u3phya_ref)
 742                        continue;
 743
 744                instance->ref_clk = devm_clk_get(&phy->dev, "ref");
 745                if (IS_ERR(instance->ref_clk)) {
 746                        dev_err(dev, "failed to get ref_clk(id-%d)\n", port);
 747                        retval = PTR_ERR(instance->ref_clk);
 748                        goto put_child;
 749                }
 750        }
 751
 752        provider = devm_of_phy_provider_register(dev, mt65xx_phy_xlate);
 753
 754        return PTR_ERR_OR_ZERO(provider);
 755put_child:
 756        of_node_put(child_np);
 757        return retval;
 758}
 759
 760static struct platform_driver mt65xx_u3phy_driver = {
 761        .probe          = mt65xx_u3phy_probe,
 762        .driver         = {
 763                .name   = "mt65xx-u3phy",
 764                .of_match_table = mt65xx_u3phy_id_table,
 765        },
 766};
 767
 768module_platform_driver(mt65xx_u3phy_driver);
 769
 770MODULE_AUTHOR("Chunfeng Yun <chunfeng.yun@mediatek.com>");
 771MODULE_DESCRIPTION("mt65xx USB PHY driver");
 772MODULE_LICENSE("GPL v2");
 773