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