linux/drivers/usb/phy/phy-mxs-usb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2012-2014 Freescale Semiconductor, Inc.
   4 * Copyright (C) 2012 Marek Vasut <marex@denx.de>
   5 * on behalf of DENX Software Engineering GmbH
   6 */
   7
   8#include <linux/module.h>
   9#include <linux/kernel.h>
  10#include <linux/platform_device.h>
  11#include <linux/clk.h>
  12#include <linux/usb/otg.h>
  13#include <linux/stmp_device.h>
  14#include <linux/delay.h>
  15#include <linux/err.h>
  16#include <linux/io.h>
  17#include <linux/of_device.h>
  18#include <linux/regmap.h>
  19#include <linux/mfd/syscon.h>
  20#include <linux/iopoll.h>
  21
  22#define DRIVER_NAME "mxs_phy"
  23
  24/* Register Macro */
  25#define HW_USBPHY_PWD                           0x00
  26#define HW_USBPHY_TX                            0x10
  27#define HW_USBPHY_CTRL                          0x30
  28#define HW_USBPHY_CTRL_SET                      0x34
  29#define HW_USBPHY_CTRL_CLR                      0x38
  30
  31#define HW_USBPHY_DEBUG_SET                     0x54
  32#define HW_USBPHY_DEBUG_CLR                     0x58
  33
  34#define HW_USBPHY_IP                            0x90
  35#define HW_USBPHY_IP_SET                        0x94
  36#define HW_USBPHY_IP_CLR                        0x98
  37
  38#define GM_USBPHY_TX_TXCAL45DP(x)            (((x) & 0xf) << 16)
  39#define GM_USBPHY_TX_TXCAL45DN(x)            (((x) & 0xf) << 8)
  40#define GM_USBPHY_TX_D_CAL(x)                (((x) & 0xf) << 0)
  41
  42/* imx7ulp */
  43#define HW_USBPHY_PLL_SIC                       0xa0
  44#define HW_USBPHY_PLL_SIC_SET                   0xa4
  45#define HW_USBPHY_PLL_SIC_CLR                   0xa8
  46
  47#define BM_USBPHY_CTRL_SFTRST                   BIT(31)
  48#define BM_USBPHY_CTRL_CLKGATE                  BIT(30)
  49#define BM_USBPHY_CTRL_OTG_ID_VALUE             BIT(27)
  50#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS        BIT(26)
  51#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE     BIT(25)
  52#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP           BIT(23)
  53#define BM_USBPHY_CTRL_ENIDCHG_WKUP             BIT(22)
  54#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP           BIT(21)
  55#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD        BIT(20)
  56#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE        BIT(19)
  57#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL         BIT(18)
  58#define BM_USBPHY_CTRL_ENUTMILEVEL3             BIT(15)
  59#define BM_USBPHY_CTRL_ENUTMILEVEL2             BIT(14)
  60#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT       BIT(1)
  61
  62#define BM_USBPHY_IP_FIX                       (BIT(17) | BIT(18))
  63
  64#define BM_USBPHY_DEBUG_CLKGATE                 BIT(30)
  65/* imx7ulp */
  66#define BM_USBPHY_PLL_LOCK                      BIT(31)
  67#define BM_USBPHY_PLL_REG_ENABLE                BIT(21)
  68#define BM_USBPHY_PLL_BYPASS                    BIT(16)
  69#define BM_USBPHY_PLL_POWER                     BIT(12)
  70#define BM_USBPHY_PLL_EN_USB_CLKS               BIT(6)
  71
  72/* Anatop Registers */
  73#define ANADIG_ANA_MISC0                        0x150
  74#define ANADIG_ANA_MISC0_SET                    0x154
  75#define ANADIG_ANA_MISC0_CLR                    0x158
  76
  77#define ANADIG_USB1_CHRG_DETECT_SET             0x1b4
  78#define ANADIG_USB1_CHRG_DETECT_CLR             0x1b8
  79#define ANADIG_USB2_CHRG_DETECT_SET             0x214
  80#define ANADIG_USB1_CHRG_DETECT_EN_B            BIT(20)
  81#define ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B      BIT(19)
  82#define ANADIG_USB1_CHRG_DETECT_CHK_CONTACT     BIT(18)
  83
  84#define ANADIG_USB1_VBUS_DET_STAT               0x1c0
  85#define ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID    BIT(3)
  86
  87#define ANADIG_USB1_CHRG_DET_STAT               0x1d0
  88#define ANADIG_USB1_CHRG_DET_STAT_DM_STATE      BIT(2)
  89#define ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED BIT(1)
  90#define ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT  BIT(0)
  91
  92#define ANADIG_USB2_VBUS_DET_STAT               0x220
  93
  94#define ANADIG_USB1_LOOPBACK_SET                0x1e4
  95#define ANADIG_USB1_LOOPBACK_CLR                0x1e8
  96#define ANADIG_USB1_LOOPBACK_UTMI_TESTSTART     BIT(0)
  97
  98#define ANADIG_USB2_LOOPBACK_SET                0x244
  99#define ANADIG_USB2_LOOPBACK_CLR                0x248
 100
 101#define ANADIG_USB1_MISC                        0x1f0
 102#define ANADIG_USB2_MISC                        0x250
 103
 104#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG    BIT(12)
 105#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11)
 106
 107#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
 108#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3)
 109
 110#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1   BIT(2)
 111#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN      BIT(5)
 112#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1   BIT(2)
 113#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN      BIT(5)
 114
 115#define BM_ANADIG_USB1_MISC_RX_VPIN_FS          BIT(29)
 116#define BM_ANADIG_USB1_MISC_RX_VMIN_FS          BIT(28)
 117#define BM_ANADIG_USB2_MISC_RX_VPIN_FS          BIT(29)
 118#define BM_ANADIG_USB2_MISC_RX_VMIN_FS          BIT(28)
 119
 120#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
 121
 122/* Do disconnection between PHY and controller without vbus */
 123#define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS    BIT(0)
 124
 125/*
 126 * The PHY will be in messy if there is a wakeup after putting
 127 * bus to suspend (set portsc.suspendM) but before setting PHY to low
 128 * power mode (set portsc.phcd).
 129 */
 130#define MXS_PHY_ABNORMAL_IN_SUSPEND             BIT(1)
 131
 132/*
 133 * The SOF sends too fast after resuming, it will cause disconnection
 134 * between host and high speed device.
 135 */
 136#define MXS_PHY_SENDING_SOF_TOO_FAST            BIT(2)
 137
 138/*
 139 * IC has bug fixes logic, they include
 140 * MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST
 141 * which are described at above flags, the RTL will handle it
 142 * according to different versions.
 143 */
 144#define MXS_PHY_NEED_IP_FIX                     BIT(3)
 145
 146/* Minimum and maximum values for device tree entries */
 147#define MXS_PHY_TX_CAL45_MIN                    30
 148#define MXS_PHY_TX_CAL45_MAX                    55
 149#define MXS_PHY_TX_D_CAL_MIN                    79
 150#define MXS_PHY_TX_D_CAL_MAX                    119
 151
 152struct mxs_phy_data {
 153        unsigned int flags;
 154};
 155
 156static const struct mxs_phy_data imx23_phy_data = {
 157        .flags = MXS_PHY_ABNORMAL_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
 158};
 159
 160static const struct mxs_phy_data imx6q_phy_data = {
 161        .flags = MXS_PHY_SENDING_SOF_TOO_FAST |
 162                MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
 163                MXS_PHY_NEED_IP_FIX,
 164};
 165
 166static const struct mxs_phy_data imx6sl_phy_data = {
 167        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
 168                MXS_PHY_NEED_IP_FIX,
 169};
 170
 171static const struct mxs_phy_data vf610_phy_data = {
 172        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
 173                MXS_PHY_NEED_IP_FIX,
 174};
 175
 176static const struct mxs_phy_data imx6sx_phy_data = {
 177        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
 178};
 179
 180static const struct mxs_phy_data imx6ul_phy_data = {
 181        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
 182};
 183
 184static const struct mxs_phy_data imx7ulp_phy_data = {
 185};
 186
 187static const struct of_device_id mxs_phy_dt_ids[] = {
 188        { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
 189        { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
 190        { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
 191        { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
 192        { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
 193        { .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
 194        { .compatible = "fsl,imx7ulp-usbphy", .data = &imx7ulp_phy_data, },
 195        { /* sentinel */ }
 196};
 197MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
 198
 199struct mxs_phy {
 200        struct usb_phy phy;
 201        struct clk *clk;
 202        const struct mxs_phy_data *data;
 203        struct regmap *regmap_anatop;
 204        int port_id;
 205        u32 tx_reg_set;
 206        u32 tx_reg_mask;
 207};
 208
 209static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
 210{
 211        return mxs_phy->data == &imx6q_phy_data;
 212}
 213
 214static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
 215{
 216        return mxs_phy->data == &imx6sl_phy_data;
 217}
 218
 219static inline bool is_imx7ulp_phy(struct mxs_phy *mxs_phy)
 220{
 221        return mxs_phy->data == &imx7ulp_phy_data;
 222}
 223
 224/*
 225 * PHY needs some 32K cycles to switch from 32K clock to
 226 * bus (such as AHB/AXI, etc) clock.
 227 */
 228static void mxs_phy_clock_switch_delay(void)
 229{
 230        usleep_range(300, 400);
 231}
 232
 233static void mxs_phy_tx_init(struct mxs_phy *mxs_phy)
 234{
 235        void __iomem *base = mxs_phy->phy.io_priv;
 236        u32 phytx;
 237
 238        /* Update TX register if there is anything to write */
 239        if (mxs_phy->tx_reg_mask) {
 240                phytx = readl(base + HW_USBPHY_TX);
 241                phytx &= ~mxs_phy->tx_reg_mask;
 242                phytx |= mxs_phy->tx_reg_set;
 243                writel(phytx, base + HW_USBPHY_TX);
 244        }
 245}
 246
 247static int mxs_phy_pll_enable(void __iomem *base, bool enable)
 248{
 249        int ret = 0;
 250
 251        if (enable) {
 252                u32 value;
 253
 254                writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_SET);
 255                writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_CLR);
 256                writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_SET);
 257                ret = readl_poll_timeout(base + HW_USBPHY_PLL_SIC,
 258                        value, (value & BM_USBPHY_PLL_LOCK) != 0,
 259                        100, 10000);
 260                if (ret)
 261                        return ret;
 262
 263                writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
 264                                HW_USBPHY_PLL_SIC_SET);
 265        } else {
 266                writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
 267                                HW_USBPHY_PLL_SIC_CLR);
 268                writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_CLR);
 269                writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_SET);
 270                writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_CLR);
 271        }
 272
 273        return ret;
 274}
 275
 276static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
 277{
 278        int ret;
 279        void __iomem *base = mxs_phy->phy.io_priv;
 280
 281        if (is_imx7ulp_phy(mxs_phy)) {
 282                ret = mxs_phy_pll_enable(base, true);
 283                if (ret)
 284                        return ret;
 285        }
 286
 287        ret = stmp_reset_block(base + HW_USBPHY_CTRL);
 288        if (ret)
 289                goto disable_pll;
 290
 291        /* Power up the PHY */
 292        writel(0, base + HW_USBPHY_PWD);
 293
 294        /*
 295         * USB PHY Ctrl Setting
 296         * - Auto clock/power on
 297         * - Enable full/low speed support
 298         */
 299        writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
 300                BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
 301                BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
 302                BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
 303                BM_USBPHY_CTRL_ENAUTO_PWRON_PLL |
 304                BM_USBPHY_CTRL_ENUTMILEVEL2 |
 305                BM_USBPHY_CTRL_ENUTMILEVEL3,
 306               base + HW_USBPHY_CTRL_SET);
 307
 308        if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX)
 309                writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
 310
 311        if (mxs_phy->regmap_anatop) {
 312                unsigned int reg = mxs_phy->port_id ?
 313                        ANADIG_USB1_CHRG_DETECT_SET :
 314                        ANADIG_USB2_CHRG_DETECT_SET;
 315                /*
 316                 * The external charger detector needs to be disabled,
 317                 * or the signal at DP will be poor
 318                 */
 319                regmap_write(mxs_phy->regmap_anatop, reg,
 320                             ANADIG_USB1_CHRG_DETECT_EN_B |
 321                             ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
 322        }
 323
 324        mxs_phy_tx_init(mxs_phy);
 325
 326        return 0;
 327
 328disable_pll:
 329        if (is_imx7ulp_phy(mxs_phy))
 330                mxs_phy_pll_enable(base, false);
 331        return ret;
 332}
 333
 334/* Return true if the vbus is there */
 335static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
 336{
 337        unsigned int vbus_value = 0;
 338
 339        if (!mxs_phy->regmap_anatop)
 340                return false;
 341
 342        if (mxs_phy->port_id == 0)
 343                regmap_read(mxs_phy->regmap_anatop,
 344                        ANADIG_USB1_VBUS_DET_STAT,
 345                        &vbus_value);
 346        else if (mxs_phy->port_id == 1)
 347                regmap_read(mxs_phy->regmap_anatop,
 348                        ANADIG_USB2_VBUS_DET_STAT,
 349                        &vbus_value);
 350
 351        if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)
 352                return true;
 353        else
 354                return false;
 355}
 356
 357static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
 358{
 359        void __iomem *base = mxs_phy->phy.io_priv;
 360        u32 reg;
 361
 362        if (disconnect)
 363                writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
 364                        base + HW_USBPHY_DEBUG_CLR);
 365
 366        if (mxs_phy->port_id == 0) {
 367                reg = disconnect ? ANADIG_USB1_LOOPBACK_SET
 368                        : ANADIG_USB1_LOOPBACK_CLR;
 369                regmap_write(mxs_phy->regmap_anatop, reg,
 370                        BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 |
 371                        BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN);
 372        } else if (mxs_phy->port_id == 1) {
 373                reg = disconnect ? ANADIG_USB2_LOOPBACK_SET
 374                        : ANADIG_USB2_LOOPBACK_CLR;
 375                regmap_write(mxs_phy->regmap_anatop, reg,
 376                        BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 |
 377                        BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN);
 378        }
 379
 380        if (!disconnect)
 381                writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
 382                        base + HW_USBPHY_DEBUG_SET);
 383
 384        /* Delay some time, and let Linestate be SE0 for controller */
 385        if (disconnect)
 386                usleep_range(500, 1000);
 387}
 388
 389static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
 390{
 391        void __iomem *base = mxs_phy->phy.io_priv;
 392        u32 phyctrl = readl(base + HW_USBPHY_CTRL);
 393
 394        if (IS_ENABLED(CONFIG_USB_OTG) &&
 395                        !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
 396                return true;
 397
 398        return false;
 399}
 400
 401static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
 402{
 403        bool vbus_is_on = false;
 404
 405        /* If the SoCs don't need to disconnect line without vbus, quit */
 406        if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
 407                return;
 408
 409        /* If the SoCs don't have anatop, quit */
 410        if (!mxs_phy->regmap_anatop)
 411                return;
 412
 413        vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
 414
 415        if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
 416                __mxs_phy_disconnect_line(mxs_phy, true);
 417        else
 418                __mxs_phy_disconnect_line(mxs_phy, false);
 419
 420}
 421
 422static int mxs_phy_init(struct usb_phy *phy)
 423{
 424        int ret;
 425        struct mxs_phy *mxs_phy = to_mxs_phy(phy);
 426
 427        mxs_phy_clock_switch_delay();
 428        ret = clk_prepare_enable(mxs_phy->clk);
 429        if (ret)
 430                return ret;
 431
 432        return mxs_phy_hw_init(mxs_phy);
 433}
 434
 435static void mxs_phy_shutdown(struct usb_phy *phy)
 436{
 437        struct mxs_phy *mxs_phy = to_mxs_phy(phy);
 438        u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
 439                        BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
 440                        BM_USBPHY_CTRL_ENIDCHG_WKUP |
 441                        BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
 442                        BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
 443                        BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
 444                        BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
 445                        BM_USBPHY_CTRL_ENAUTO_PWRON_PLL;
 446
 447        writel(value, phy->io_priv + HW_USBPHY_CTRL_CLR);
 448        writel(0xffffffff, phy->io_priv + HW_USBPHY_PWD);
 449
 450        writel(BM_USBPHY_CTRL_CLKGATE,
 451               phy->io_priv + HW_USBPHY_CTRL_SET);
 452
 453        if (is_imx7ulp_phy(mxs_phy))
 454                mxs_phy_pll_enable(phy->io_priv, false);
 455
 456        clk_disable_unprepare(mxs_phy->clk);
 457}
 458
 459static bool mxs_phy_is_low_speed_connection(struct mxs_phy *mxs_phy)
 460{
 461        unsigned int line_state;
 462        /* bit definition is the same for all controllers */
 463        unsigned int dp_bit = BM_ANADIG_USB1_MISC_RX_VPIN_FS,
 464                     dm_bit = BM_ANADIG_USB1_MISC_RX_VMIN_FS;
 465        unsigned int reg = ANADIG_USB1_MISC;
 466
 467        /* If the SoCs don't have anatop, quit */
 468        if (!mxs_phy->regmap_anatop)
 469                return false;
 470
 471        if (mxs_phy->port_id == 0)
 472                reg = ANADIG_USB1_MISC;
 473        else if (mxs_phy->port_id == 1)
 474                reg = ANADIG_USB2_MISC;
 475
 476        regmap_read(mxs_phy->regmap_anatop, reg, &line_state);
 477
 478        if ((line_state & (dp_bit | dm_bit)) ==  dm_bit)
 479                return true;
 480        else
 481                return false;
 482}
 483
 484static int mxs_phy_suspend(struct usb_phy *x, int suspend)
 485{
 486        int ret;
 487        struct mxs_phy *mxs_phy = to_mxs_phy(x);
 488        bool low_speed_connection, vbus_is_on;
 489
 490        low_speed_connection = mxs_phy_is_low_speed_connection(mxs_phy);
 491        vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
 492
 493        if (suspend) {
 494                /*
 495                 * FIXME: Do not power down RXPWD1PT1 bit for low speed
 496                 * connect. The low speed connection will have problem at
 497                 * very rare cases during usb suspend and resume process.
 498                 */
 499                if (low_speed_connection & vbus_is_on) {
 500                        /*
 501                         * If value to be set as pwd value is not 0xffffffff,
 502                         * several 32Khz cycles are needed.
 503                         */
 504                        mxs_phy_clock_switch_delay();
 505                        writel(0xffbfffff, x->io_priv + HW_USBPHY_PWD);
 506                } else {
 507                        writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
 508                }
 509                writel(BM_USBPHY_CTRL_CLKGATE,
 510                       x->io_priv + HW_USBPHY_CTRL_SET);
 511                clk_disable_unprepare(mxs_phy->clk);
 512        } else {
 513                mxs_phy_clock_switch_delay();
 514                ret = clk_prepare_enable(mxs_phy->clk);
 515                if (ret)
 516                        return ret;
 517                writel(BM_USBPHY_CTRL_CLKGATE,
 518                       x->io_priv + HW_USBPHY_CTRL_CLR);
 519                writel(0, x->io_priv + HW_USBPHY_PWD);
 520        }
 521
 522        return 0;
 523}
 524
 525static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled)
 526{
 527        struct mxs_phy *mxs_phy = to_mxs_phy(x);
 528        u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
 529                        BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
 530                                BM_USBPHY_CTRL_ENIDCHG_WKUP;
 531        if (enabled) {
 532                mxs_phy_disconnect_line(mxs_phy, true);
 533                writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET);
 534        } else {
 535                writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR);
 536                mxs_phy_disconnect_line(mxs_phy, false);
 537        }
 538
 539        return 0;
 540}
 541
 542static int mxs_phy_on_connect(struct usb_phy *phy,
 543                enum usb_device_speed speed)
 544{
 545        dev_dbg(phy->dev, "%s device has connected\n",
 546                (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
 547
 548        if (speed == USB_SPEED_HIGH)
 549                writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
 550                       phy->io_priv + HW_USBPHY_CTRL_SET);
 551
 552        return 0;
 553}
 554
 555static int mxs_phy_on_disconnect(struct usb_phy *phy,
 556                enum usb_device_speed speed)
 557{
 558        dev_dbg(phy->dev, "%s device has disconnected\n",
 559                (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
 560
 561        /* Sometimes, the speed is not high speed when the error occurs */
 562        if (readl(phy->io_priv + HW_USBPHY_CTRL) &
 563                        BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
 564                writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
 565                       phy->io_priv + HW_USBPHY_CTRL_CLR);
 566
 567        return 0;
 568}
 569
 570#define MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT    100
 571static int mxs_charger_data_contact_detect(struct mxs_phy *x)
 572{
 573        struct regmap *regmap = x->regmap_anatop;
 574        int i, stable_contact_count = 0;
 575        u32 val;
 576
 577        /* Check if vbus is valid */
 578        regmap_read(regmap, ANADIG_USB1_VBUS_DET_STAT, &val);
 579        if (!(val & ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)) {
 580                dev_err(x->phy.dev, "vbus is not valid\n");
 581                return -EINVAL;
 582        }
 583
 584        /* Enable charger detector */
 585        regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_CLR,
 586                                ANADIG_USB1_CHRG_DETECT_EN_B);
 587        /*
 588         * - Do not check whether a charger is connected to the USB port
 589         * - Check whether the USB plug has been in contact with each other
 590         */
 591        regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
 592                        ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
 593                        ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
 594
 595        /* Check if plug is connected */
 596        for (i = 0; i < MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT; i++) {
 597                regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
 598                if (val & ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT) {
 599                        stable_contact_count++;
 600                        if (stable_contact_count > 5)
 601                                /* Data pin makes contact */
 602                                break;
 603                        else
 604                                usleep_range(5000, 10000);
 605                } else {
 606                        stable_contact_count = 0;
 607                        usleep_range(5000, 6000);
 608                }
 609        }
 610
 611        if (i == MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT) {
 612                dev_err(x->phy.dev,
 613                        "Data pin can't make good contact.\n");
 614                /* Disable charger detector */
 615                regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
 616                                ANADIG_USB1_CHRG_DETECT_EN_B |
 617                                ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
 618                return -ENXIO;
 619        }
 620
 621        return 0;
 622}
 623
 624static enum usb_charger_type mxs_charger_primary_detection(struct mxs_phy *x)
 625{
 626        struct regmap *regmap = x->regmap_anatop;
 627        enum usb_charger_type chgr_type = UNKNOWN_TYPE;
 628        u32 val;
 629
 630        /*
 631         * - Do check whether a charger is connected to the USB port
 632         * - Do not Check whether the USB plug has been in contact with
 633         *   each other
 634         */
 635        regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_CLR,
 636                        ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
 637                        ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
 638
 639        msleep(100);
 640
 641        /* Check if it is a charger */
 642        regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
 643        if (!(val & ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED)) {
 644                chgr_type = SDP_TYPE;
 645                dev_dbg(x->phy.dev, "It is a standard downstream port\n");
 646        }
 647
 648        /* Disable charger detector */
 649        regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
 650                        ANADIG_USB1_CHRG_DETECT_EN_B |
 651                        ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
 652
 653        return chgr_type;
 654}
 655
 656/*
 657 * It must be called after DP is pulled up, which is used to
 658 * differentiate DCP and CDP.
 659 */
 660static enum usb_charger_type mxs_charger_secondary_detection(struct mxs_phy *x)
 661{
 662        struct regmap *regmap = x->regmap_anatop;
 663        int val;
 664
 665        msleep(80);
 666
 667        regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
 668        if (val & ANADIG_USB1_CHRG_DET_STAT_DM_STATE) {
 669                dev_dbg(x->phy.dev, "It is a dedicate charging port\n");
 670                return DCP_TYPE;
 671        } else {
 672                dev_dbg(x->phy.dev, "It is a charging downstream port\n");
 673                return CDP_TYPE;
 674        }
 675}
 676
 677static enum usb_charger_type mxs_phy_charger_detect(struct usb_phy *phy)
 678{
 679        struct mxs_phy *mxs_phy = to_mxs_phy(phy);
 680        struct regmap *regmap = mxs_phy->regmap_anatop;
 681        void __iomem *base = phy->io_priv;
 682        enum usb_charger_type chgr_type = UNKNOWN_TYPE;
 683
 684        if (!regmap)
 685                return UNKNOWN_TYPE;
 686
 687        if (mxs_charger_data_contact_detect(mxs_phy))
 688                return chgr_type;
 689
 690        chgr_type = mxs_charger_primary_detection(mxs_phy);
 691
 692        if (chgr_type != SDP_TYPE) {
 693                /* Pull up DP via test */
 694                writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
 695                                base + HW_USBPHY_DEBUG_CLR);
 696                regmap_write(regmap, ANADIG_USB1_LOOPBACK_SET,
 697                                ANADIG_USB1_LOOPBACK_UTMI_TESTSTART);
 698
 699                chgr_type = mxs_charger_secondary_detection(mxs_phy);
 700
 701                /* Stop the test */
 702                regmap_write(regmap, ANADIG_USB1_LOOPBACK_CLR,
 703                                ANADIG_USB1_LOOPBACK_UTMI_TESTSTART);
 704                writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
 705                                base + HW_USBPHY_DEBUG_SET);
 706        }
 707
 708        return chgr_type;
 709}
 710
 711static int mxs_phy_probe(struct platform_device *pdev)
 712{
 713        struct resource *res;
 714        void __iomem *base;
 715        struct clk *clk;
 716        struct mxs_phy *mxs_phy;
 717        int ret;
 718        const struct of_device_id *of_id;
 719        struct device_node *np = pdev->dev.of_node;
 720        u32 val;
 721
 722        of_id = of_match_device(mxs_phy_dt_ids, &pdev->dev);
 723        if (!of_id)
 724                return -ENODEV;
 725
 726        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 727        base = devm_ioremap_resource(&pdev->dev, res);
 728        if (IS_ERR(base))
 729                return PTR_ERR(base);
 730
 731        clk = devm_clk_get(&pdev->dev, NULL);
 732        if (IS_ERR(clk)) {
 733                dev_err(&pdev->dev,
 734                        "can't get the clock, err=%ld", PTR_ERR(clk));
 735                return PTR_ERR(clk);
 736        }
 737
 738        mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL);
 739        if (!mxs_phy)
 740                return -ENOMEM;
 741
 742        /* Some SoCs don't have anatop registers */
 743        if (of_get_property(np, "fsl,anatop", NULL)) {
 744                mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
 745                        (np, "fsl,anatop");
 746                if (IS_ERR(mxs_phy->regmap_anatop)) {
 747                        dev_dbg(&pdev->dev,
 748                                "failed to find regmap for anatop\n");
 749                        return PTR_ERR(mxs_phy->regmap_anatop);
 750                }
 751        }
 752
 753        /* Precompute which bits of the TX register are to be updated, if any */
 754        if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) &&
 755            val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
 756                /* Scale to a 4-bit value */
 757                val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
 758                        / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
 759                mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DN(~0);
 760                mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DN(val);
 761        }
 762
 763        if (!of_property_read_u32(np, "fsl,tx-cal-45-dp-ohms", &val) &&
 764            val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
 765                /* Scale to a 4-bit value. */
 766                val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
 767                        / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
 768                mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DP(~0);
 769                mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DP(val);
 770        }
 771
 772        if (!of_property_read_u32(np, "fsl,tx-d-cal", &val) &&
 773            val >= MXS_PHY_TX_D_CAL_MIN && val <= MXS_PHY_TX_D_CAL_MAX) {
 774                /* Scale to a 4-bit value.  Round up the values and heavily
 775                 * weight the rounding by adding 2/3 of the denominator.
 776                 */
 777                val = ((MXS_PHY_TX_D_CAL_MAX - val) * 0xF
 778                        + (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN) * 2/3)
 779                        / (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN);
 780                mxs_phy->tx_reg_mask |= GM_USBPHY_TX_D_CAL(~0);
 781                mxs_phy->tx_reg_set  |= GM_USBPHY_TX_D_CAL(val);
 782        }
 783
 784        ret = of_alias_get_id(np, "usbphy");
 785        if (ret < 0)
 786                dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret);
 787        mxs_phy->port_id = ret;
 788
 789        mxs_phy->phy.io_priv            = base;
 790        mxs_phy->phy.dev                = &pdev->dev;
 791        mxs_phy->phy.label              = DRIVER_NAME;
 792        mxs_phy->phy.init               = mxs_phy_init;
 793        mxs_phy->phy.shutdown           = mxs_phy_shutdown;
 794        mxs_phy->phy.set_suspend        = mxs_phy_suspend;
 795        mxs_phy->phy.notify_connect     = mxs_phy_on_connect;
 796        mxs_phy->phy.notify_disconnect  = mxs_phy_on_disconnect;
 797        mxs_phy->phy.type               = USB_PHY_TYPE_USB2;
 798        mxs_phy->phy.set_wakeup         = mxs_phy_set_wakeup;
 799        mxs_phy->phy.charger_detect     = mxs_phy_charger_detect;
 800
 801        mxs_phy->clk = clk;
 802        mxs_phy->data = of_id->data;
 803
 804        platform_set_drvdata(pdev, mxs_phy);
 805
 806        device_set_wakeup_capable(&pdev->dev, true);
 807
 808        return usb_add_phy_dev(&mxs_phy->phy);
 809}
 810
 811static int mxs_phy_remove(struct platform_device *pdev)
 812{
 813        struct mxs_phy *mxs_phy = platform_get_drvdata(pdev);
 814
 815        usb_remove_phy(&mxs_phy->phy);
 816
 817        return 0;
 818}
 819
 820#ifdef CONFIG_PM_SLEEP
 821static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
 822{
 823        unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
 824
 825        /* If the SoCs don't have anatop, quit */
 826        if (!mxs_phy->regmap_anatop)
 827                return;
 828
 829        if (is_imx6q_phy(mxs_phy))
 830                regmap_write(mxs_phy->regmap_anatop, reg,
 831                        BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
 832        else if (is_imx6sl_phy(mxs_phy))
 833                regmap_write(mxs_phy->regmap_anatop,
 834                        reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
 835}
 836
 837static int mxs_phy_system_suspend(struct device *dev)
 838{
 839        struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
 840
 841        if (device_may_wakeup(dev))
 842                mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
 843
 844        return 0;
 845}
 846
 847static int mxs_phy_system_resume(struct device *dev)
 848{
 849        struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
 850
 851        if (device_may_wakeup(dev))
 852                mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
 853
 854        return 0;
 855}
 856#endif /* CONFIG_PM_SLEEP */
 857
 858static SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend,
 859                mxs_phy_system_resume);
 860
 861static struct platform_driver mxs_phy_driver = {
 862        .probe = mxs_phy_probe,
 863        .remove = mxs_phy_remove,
 864        .driver = {
 865                .name = DRIVER_NAME,
 866                .of_match_table = mxs_phy_dt_ids,
 867                .pm = &mxs_phy_pm,
 868         },
 869};
 870
 871static int __init mxs_phy_module_init(void)
 872{
 873        return platform_driver_register(&mxs_phy_driver);
 874}
 875postcore_initcall(mxs_phy_module_init);
 876
 877static void __exit mxs_phy_module_exit(void)
 878{
 879        platform_driver_unregister(&mxs_phy_driver);
 880}
 881module_exit(mxs_phy_module_exit);
 882
 883MODULE_ALIAS("platform:mxs-usb-phy");
 884MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
 885MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
 886MODULE_DESCRIPTION("Freescale MXS USB PHY driver");
 887MODULE_LICENSE("GPL");
 888