linux/drivers/usb/phy/phy-mxs-usb.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012-2014 Freescale Semiconductor, Inc.
   3 * Copyright (C) 2012 Marek Vasut <marex@denx.de>
   4 * on behalf of DENX Software Engineering GmbH
   5 *
   6 * The code contained herein is licensed under the GNU General Public
   7 * License. You may obtain a copy of the GNU General Public License
   8 * Version 2 or later at the following locations:
   9 *
  10 * http://www.opensource.org/licenses/gpl-license.html
  11 * http://www.gnu.org/copyleft/gpl.html
  12 */
  13
  14#include <linux/module.h>
  15#include <linux/kernel.h>
  16#include <linux/platform_device.h>
  17#include <linux/clk.h>
  18#include <linux/usb/otg.h>
  19#include <linux/stmp_device.h>
  20#include <linux/delay.h>
  21#include <linux/err.h>
  22#include <linux/io.h>
  23#include <linux/of_device.h>
  24#include <linux/regmap.h>
  25#include <linux/mfd/syscon.h>
  26
  27#define DRIVER_NAME "mxs_phy"
  28
  29#define HW_USBPHY_PWD                           0x00
  30#define HW_USBPHY_TX                            0x10
  31#define HW_USBPHY_CTRL                          0x30
  32#define HW_USBPHY_CTRL_SET                      0x34
  33#define HW_USBPHY_CTRL_CLR                      0x38
  34
  35#define HW_USBPHY_DEBUG_SET                     0x54
  36#define HW_USBPHY_DEBUG_CLR                     0x58
  37
  38#define HW_USBPHY_IP                            0x90
  39#define HW_USBPHY_IP_SET                        0x94
  40#define HW_USBPHY_IP_CLR                        0x98
  41
  42#define GM_USBPHY_TX_TXCAL45DP(x)            (((x) & 0xf) << 16)
  43#define GM_USBPHY_TX_TXCAL45DN(x)            (((x) & 0xf) << 8)
  44#define GM_USBPHY_TX_D_CAL(x)                (((x) & 0xf) << 0)
  45
  46#define BM_USBPHY_CTRL_SFTRST                   BIT(31)
  47#define BM_USBPHY_CTRL_CLKGATE                  BIT(30)
  48#define BM_USBPHY_CTRL_OTG_ID_VALUE             BIT(27)
  49#define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS        BIT(26)
  50#define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE     BIT(25)
  51#define BM_USBPHY_CTRL_ENVBUSCHG_WKUP           BIT(23)
  52#define BM_USBPHY_CTRL_ENIDCHG_WKUP             BIT(22)
  53#define BM_USBPHY_CTRL_ENDPDMCHG_WKUP           BIT(21)
  54#define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD        BIT(20)
  55#define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE        BIT(19)
  56#define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL         BIT(18)
  57#define BM_USBPHY_CTRL_ENUTMILEVEL3             BIT(15)
  58#define BM_USBPHY_CTRL_ENUTMILEVEL2             BIT(14)
  59#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT       BIT(1)
  60
  61#define BM_USBPHY_IP_FIX                       (BIT(17) | BIT(18))
  62
  63#define BM_USBPHY_DEBUG_CLKGATE                 BIT(30)
  64
  65/* Anatop Registers */
  66#define ANADIG_ANA_MISC0                        0x150
  67#define ANADIG_ANA_MISC0_SET                    0x154
  68#define ANADIG_ANA_MISC0_CLR                    0x158
  69
  70#define ANADIG_USB1_VBUS_DET_STAT               0x1c0
  71#define ANADIG_USB2_VBUS_DET_STAT               0x220
  72
  73#define ANADIG_USB1_LOOPBACK_SET                0x1e4
  74#define ANADIG_USB1_LOOPBACK_CLR                0x1e8
  75#define ANADIG_USB2_LOOPBACK_SET                0x244
  76#define ANADIG_USB2_LOOPBACK_CLR                0x248
  77
  78#define ANADIG_USB1_MISC                        0x1f0
  79#define ANADIG_USB2_MISC                        0x250
  80
  81#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG    BIT(12)
  82#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11)
  83
  84#define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
  85#define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3)
  86
  87#define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1   BIT(2)
  88#define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN      BIT(5)
  89#define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1   BIT(2)
  90#define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN      BIT(5)
  91
  92#define BM_ANADIG_USB1_MISC_RX_VPIN_FS          BIT(29)
  93#define BM_ANADIG_USB1_MISC_RX_VMIN_FS          BIT(28)
  94#define BM_ANADIG_USB2_MISC_RX_VPIN_FS          BIT(29)
  95#define BM_ANADIG_USB2_MISC_RX_VMIN_FS          BIT(28)
  96
  97#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
  98
  99/* Do disconnection between PHY and controller without vbus */
 100#define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS    BIT(0)
 101
 102/*
 103 * The PHY will be in messy if there is a wakeup after putting
 104 * bus to suspend (set portsc.suspendM) but before setting PHY to low
 105 * power mode (set portsc.phcd).
 106 */
 107#define MXS_PHY_ABNORMAL_IN_SUSPEND             BIT(1)
 108
 109/*
 110 * The SOF sends too fast after resuming, it will cause disconnection
 111 * between host and high speed device.
 112 */
 113#define MXS_PHY_SENDING_SOF_TOO_FAST            BIT(2)
 114
 115/*
 116 * IC has bug fixes logic, they include
 117 * MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST
 118 * which are described at above flags, the RTL will handle it
 119 * according to different versions.
 120 */
 121#define MXS_PHY_NEED_IP_FIX                     BIT(3)
 122
 123/* Minimum and maximum values for device tree entries */
 124#define MXS_PHY_TX_CAL45_MIN                    30
 125#define MXS_PHY_TX_CAL45_MAX                    55
 126#define MXS_PHY_TX_D_CAL_MIN                    79
 127#define MXS_PHY_TX_D_CAL_MAX                    119
 128
 129struct mxs_phy_data {
 130        unsigned int flags;
 131};
 132
 133static const struct mxs_phy_data imx23_phy_data = {
 134        .flags = MXS_PHY_ABNORMAL_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
 135};
 136
 137static const struct mxs_phy_data imx6q_phy_data = {
 138        .flags = MXS_PHY_SENDING_SOF_TOO_FAST |
 139                MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
 140                MXS_PHY_NEED_IP_FIX,
 141};
 142
 143static const struct mxs_phy_data imx6sl_phy_data = {
 144        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
 145                MXS_PHY_NEED_IP_FIX,
 146};
 147
 148static const struct mxs_phy_data vf610_phy_data = {
 149        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
 150                MXS_PHY_NEED_IP_FIX,
 151};
 152
 153static const struct mxs_phy_data imx6sx_phy_data = {
 154        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
 155};
 156
 157static const struct mxs_phy_data imx6ul_phy_data = {
 158        .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
 159};
 160
 161static const struct of_device_id mxs_phy_dt_ids[] = {
 162        { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
 163        { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
 164        { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
 165        { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
 166        { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
 167        { .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
 168        { /* sentinel */ }
 169};
 170MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
 171
 172struct mxs_phy {
 173        struct usb_phy phy;
 174        struct clk *clk;
 175        const struct mxs_phy_data *data;
 176        struct regmap *regmap_anatop;
 177        int port_id;
 178        u32 tx_reg_set;
 179        u32 tx_reg_mask;
 180};
 181
 182static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
 183{
 184        return mxs_phy->data == &imx6q_phy_data;
 185}
 186
 187static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
 188{
 189        return mxs_phy->data == &imx6sl_phy_data;
 190}
 191
 192/*
 193 * PHY needs some 32K cycles to switch from 32K clock to
 194 * bus (such as AHB/AXI, etc) clock.
 195 */
 196static void mxs_phy_clock_switch_delay(void)
 197{
 198        usleep_range(300, 400);
 199}
 200
 201static void mxs_phy_tx_init(struct mxs_phy *mxs_phy)
 202{
 203        void __iomem *base = mxs_phy->phy.io_priv;
 204        u32 phytx;
 205
 206        /* Update TX register if there is anything to write */
 207        if (mxs_phy->tx_reg_mask) {
 208                phytx = readl(base + HW_USBPHY_TX);
 209                phytx &= ~mxs_phy->tx_reg_mask;
 210                phytx |= mxs_phy->tx_reg_set;
 211                writel(phytx, base + HW_USBPHY_TX);
 212        }
 213}
 214
 215static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
 216{
 217        int ret;
 218        void __iomem *base = mxs_phy->phy.io_priv;
 219
 220        ret = stmp_reset_block(base + HW_USBPHY_CTRL);
 221        if (ret)
 222                return ret;
 223
 224        /* Power up the PHY */
 225        writel(0, base + HW_USBPHY_PWD);
 226
 227        /*
 228         * USB PHY Ctrl Setting
 229         * - Auto clock/power on
 230         * - Enable full/low speed support
 231         */
 232        writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
 233                BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
 234                BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
 235                BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
 236                BM_USBPHY_CTRL_ENAUTO_PWRON_PLL |
 237                BM_USBPHY_CTRL_ENUTMILEVEL2 |
 238                BM_USBPHY_CTRL_ENUTMILEVEL3,
 239               base + HW_USBPHY_CTRL_SET);
 240
 241        if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX)
 242                writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
 243
 244        mxs_phy_tx_init(mxs_phy);
 245
 246        return 0;
 247}
 248
 249/* Return true if the vbus is there */
 250static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
 251{
 252        unsigned int vbus_value = 0;
 253
 254        if (!mxs_phy->regmap_anatop)
 255                return false;
 256
 257        if (mxs_phy->port_id == 0)
 258                regmap_read(mxs_phy->regmap_anatop,
 259                        ANADIG_USB1_VBUS_DET_STAT,
 260                        &vbus_value);
 261        else if (mxs_phy->port_id == 1)
 262                regmap_read(mxs_phy->regmap_anatop,
 263                        ANADIG_USB2_VBUS_DET_STAT,
 264                        &vbus_value);
 265
 266        if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)
 267                return true;
 268        else
 269                return false;
 270}
 271
 272static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
 273{
 274        void __iomem *base = mxs_phy->phy.io_priv;
 275        u32 reg;
 276
 277        if (disconnect)
 278                writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
 279                        base + HW_USBPHY_DEBUG_CLR);
 280
 281        if (mxs_phy->port_id == 0) {
 282                reg = disconnect ? ANADIG_USB1_LOOPBACK_SET
 283                        : ANADIG_USB1_LOOPBACK_CLR;
 284                regmap_write(mxs_phy->regmap_anatop, reg,
 285                        BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 |
 286                        BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN);
 287        } else if (mxs_phy->port_id == 1) {
 288                reg = disconnect ? ANADIG_USB2_LOOPBACK_SET
 289                        : ANADIG_USB2_LOOPBACK_CLR;
 290                regmap_write(mxs_phy->regmap_anatop, reg,
 291                        BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 |
 292                        BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN);
 293        }
 294
 295        if (!disconnect)
 296                writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
 297                        base + HW_USBPHY_DEBUG_SET);
 298
 299        /* Delay some time, and let Linestate be SE0 for controller */
 300        if (disconnect)
 301                usleep_range(500, 1000);
 302}
 303
 304static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
 305{
 306        void __iomem *base = mxs_phy->phy.io_priv;
 307        u32 phyctrl = readl(base + HW_USBPHY_CTRL);
 308
 309        if (IS_ENABLED(CONFIG_USB_OTG) &&
 310                        !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
 311                return true;
 312
 313        return false;
 314}
 315
 316static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
 317{
 318        bool vbus_is_on = false;
 319
 320        /* If the SoCs don't need to disconnect line without vbus, quit */
 321        if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
 322                return;
 323
 324        /* If the SoCs don't have anatop, quit */
 325        if (!mxs_phy->regmap_anatop)
 326                return;
 327
 328        vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
 329
 330        if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
 331                __mxs_phy_disconnect_line(mxs_phy, true);
 332        else
 333                __mxs_phy_disconnect_line(mxs_phy, false);
 334
 335}
 336
 337static int mxs_phy_init(struct usb_phy *phy)
 338{
 339        int ret;
 340        struct mxs_phy *mxs_phy = to_mxs_phy(phy);
 341
 342        mxs_phy_clock_switch_delay();
 343        ret = clk_prepare_enable(mxs_phy->clk);
 344        if (ret)
 345                return ret;
 346
 347        return mxs_phy_hw_init(mxs_phy);
 348}
 349
 350static void mxs_phy_shutdown(struct usb_phy *phy)
 351{
 352        struct mxs_phy *mxs_phy = to_mxs_phy(phy);
 353        u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
 354                        BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
 355                        BM_USBPHY_CTRL_ENIDCHG_WKUP |
 356                        BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
 357                        BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
 358                        BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
 359                        BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
 360                        BM_USBPHY_CTRL_ENAUTO_PWRON_PLL;
 361
 362        writel(value, phy->io_priv + HW_USBPHY_CTRL_CLR);
 363        writel(0xffffffff, phy->io_priv + HW_USBPHY_PWD);
 364
 365        writel(BM_USBPHY_CTRL_CLKGATE,
 366               phy->io_priv + HW_USBPHY_CTRL_SET);
 367
 368        clk_disable_unprepare(mxs_phy->clk);
 369}
 370
 371static bool mxs_phy_is_low_speed_connection(struct mxs_phy *mxs_phy)
 372{
 373        unsigned int line_state;
 374        /* bit definition is the same for all controllers */
 375        unsigned int dp_bit = BM_ANADIG_USB1_MISC_RX_VPIN_FS,
 376                     dm_bit = BM_ANADIG_USB1_MISC_RX_VMIN_FS;
 377        unsigned int reg = ANADIG_USB1_MISC;
 378
 379        /* If the SoCs don't have anatop, quit */
 380        if (!mxs_phy->regmap_anatop)
 381                return false;
 382
 383        if (mxs_phy->port_id == 0)
 384                reg = ANADIG_USB1_MISC;
 385        else if (mxs_phy->port_id == 1)
 386                reg = ANADIG_USB2_MISC;
 387
 388        regmap_read(mxs_phy->regmap_anatop, reg, &line_state);
 389
 390        if ((line_state & (dp_bit | dm_bit)) ==  dm_bit)
 391                return true;
 392        else
 393                return false;
 394}
 395
 396static int mxs_phy_suspend(struct usb_phy *x, int suspend)
 397{
 398        int ret;
 399        struct mxs_phy *mxs_phy = to_mxs_phy(x);
 400        bool low_speed_connection, vbus_is_on;
 401
 402        low_speed_connection = mxs_phy_is_low_speed_connection(mxs_phy);
 403        vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
 404
 405        if (suspend) {
 406                /*
 407                 * FIXME: Do not power down RXPWD1PT1 bit for low speed
 408                 * connect. The low speed connection will have problem at
 409                 * very rare cases during usb suspend and resume process.
 410                 */
 411                if (low_speed_connection & vbus_is_on) {
 412                        /*
 413                         * If value to be set as pwd value is not 0xffffffff,
 414                         * several 32Khz cycles are needed.
 415                         */
 416                        mxs_phy_clock_switch_delay();
 417                        writel(0xffbfffff, x->io_priv + HW_USBPHY_PWD);
 418                } else {
 419                        writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
 420                }
 421                writel(BM_USBPHY_CTRL_CLKGATE,
 422                       x->io_priv + HW_USBPHY_CTRL_SET);
 423                clk_disable_unprepare(mxs_phy->clk);
 424        } else {
 425                mxs_phy_clock_switch_delay();
 426                ret = clk_prepare_enable(mxs_phy->clk);
 427                if (ret)
 428                        return ret;
 429                writel(BM_USBPHY_CTRL_CLKGATE,
 430                       x->io_priv + HW_USBPHY_CTRL_CLR);
 431                writel(0, x->io_priv + HW_USBPHY_PWD);
 432        }
 433
 434        return 0;
 435}
 436
 437static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled)
 438{
 439        struct mxs_phy *mxs_phy = to_mxs_phy(x);
 440        u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
 441                        BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
 442                                BM_USBPHY_CTRL_ENIDCHG_WKUP;
 443        if (enabled) {
 444                mxs_phy_disconnect_line(mxs_phy, true);
 445                writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET);
 446        } else {
 447                writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR);
 448                mxs_phy_disconnect_line(mxs_phy, false);
 449        }
 450
 451        return 0;
 452}
 453
 454static int mxs_phy_on_connect(struct usb_phy *phy,
 455                enum usb_device_speed speed)
 456{
 457        dev_dbg(phy->dev, "%s device has connected\n",
 458                (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
 459
 460        if (speed == USB_SPEED_HIGH)
 461                writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
 462                       phy->io_priv + HW_USBPHY_CTRL_SET);
 463
 464        return 0;
 465}
 466
 467static int mxs_phy_on_disconnect(struct usb_phy *phy,
 468                enum usb_device_speed speed)
 469{
 470        dev_dbg(phy->dev, "%s device has disconnected\n",
 471                (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
 472
 473        /* Sometimes, the speed is not high speed when the error occurs */
 474        if (readl(phy->io_priv + HW_USBPHY_CTRL) &
 475                        BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
 476                writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
 477                       phy->io_priv + HW_USBPHY_CTRL_CLR);
 478
 479        return 0;
 480}
 481
 482static int mxs_phy_probe(struct platform_device *pdev)
 483{
 484        struct resource *res;
 485        void __iomem *base;
 486        struct clk *clk;
 487        struct mxs_phy *mxs_phy;
 488        int ret;
 489        const struct of_device_id *of_id;
 490        struct device_node *np = pdev->dev.of_node;
 491        u32 val;
 492
 493        of_id = of_match_device(mxs_phy_dt_ids, &pdev->dev);
 494        if (!of_id)
 495                return -ENODEV;
 496
 497        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 498        base = devm_ioremap_resource(&pdev->dev, res);
 499        if (IS_ERR(base))
 500                return PTR_ERR(base);
 501
 502        clk = devm_clk_get(&pdev->dev, NULL);
 503        if (IS_ERR(clk)) {
 504                dev_err(&pdev->dev,
 505                        "can't get the clock, err=%ld", PTR_ERR(clk));
 506                return PTR_ERR(clk);
 507        }
 508
 509        mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL);
 510        if (!mxs_phy)
 511                return -ENOMEM;
 512
 513        /* Some SoCs don't have anatop registers */
 514        if (of_get_property(np, "fsl,anatop", NULL)) {
 515                mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
 516                        (np, "fsl,anatop");
 517                if (IS_ERR(mxs_phy->regmap_anatop)) {
 518                        dev_dbg(&pdev->dev,
 519                                "failed to find regmap for anatop\n");
 520                        return PTR_ERR(mxs_phy->regmap_anatop);
 521                }
 522        }
 523
 524        /* Precompute which bits of the TX register are to be updated, if any */
 525        if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) &&
 526            val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
 527                /* Scale to a 4-bit value */
 528                val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
 529                        / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
 530                mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DN(~0);
 531                mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DN(val);
 532        }
 533
 534        if (!of_property_read_u32(np, "fsl,tx-cal-45-dp-ohms", &val) &&
 535            val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
 536                /* Scale to a 4-bit value. */
 537                val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
 538                        / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
 539                mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DP(~0);
 540                mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DP(val);
 541        }
 542
 543        if (!of_property_read_u32(np, "fsl,tx-d-cal", &val) &&
 544            val >= MXS_PHY_TX_D_CAL_MIN && val <= MXS_PHY_TX_D_CAL_MAX) {
 545                /* Scale to a 4-bit value.  Round up the values and heavily
 546                 * weight the rounding by adding 2/3 of the denominator.
 547                 */
 548                val = ((MXS_PHY_TX_D_CAL_MAX - val) * 0xF
 549                        + (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN) * 2/3)
 550                        / (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN);
 551                mxs_phy->tx_reg_mask |= GM_USBPHY_TX_D_CAL(~0);
 552                mxs_phy->tx_reg_set  |= GM_USBPHY_TX_D_CAL(val);
 553        }
 554
 555        ret = of_alias_get_id(np, "usbphy");
 556        if (ret < 0)
 557                dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret);
 558        mxs_phy->port_id = ret;
 559
 560        mxs_phy->phy.io_priv            = base;
 561        mxs_phy->phy.dev                = &pdev->dev;
 562        mxs_phy->phy.label              = DRIVER_NAME;
 563        mxs_phy->phy.init               = mxs_phy_init;
 564        mxs_phy->phy.shutdown           = mxs_phy_shutdown;
 565        mxs_phy->phy.set_suspend        = mxs_phy_suspend;
 566        mxs_phy->phy.notify_connect     = mxs_phy_on_connect;
 567        mxs_phy->phy.notify_disconnect  = mxs_phy_on_disconnect;
 568        mxs_phy->phy.type               = USB_PHY_TYPE_USB2;
 569        mxs_phy->phy.set_wakeup         = mxs_phy_set_wakeup;
 570
 571        mxs_phy->clk = clk;
 572        mxs_phy->data = of_id->data;
 573
 574        platform_set_drvdata(pdev, mxs_phy);
 575
 576        device_set_wakeup_capable(&pdev->dev, true);
 577
 578        return usb_add_phy_dev(&mxs_phy->phy);
 579}
 580
 581static int mxs_phy_remove(struct platform_device *pdev)
 582{
 583        struct mxs_phy *mxs_phy = platform_get_drvdata(pdev);
 584
 585        usb_remove_phy(&mxs_phy->phy);
 586
 587        return 0;
 588}
 589
 590#ifdef CONFIG_PM_SLEEP
 591static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
 592{
 593        unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
 594
 595        /* If the SoCs don't have anatop, quit */
 596        if (!mxs_phy->regmap_anatop)
 597                return;
 598
 599        if (is_imx6q_phy(mxs_phy))
 600                regmap_write(mxs_phy->regmap_anatop, reg,
 601                        BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
 602        else if (is_imx6sl_phy(mxs_phy))
 603                regmap_write(mxs_phy->regmap_anatop,
 604                        reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
 605}
 606
 607static int mxs_phy_system_suspend(struct device *dev)
 608{
 609        struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
 610
 611        if (device_may_wakeup(dev))
 612                mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
 613
 614        return 0;
 615}
 616
 617static int mxs_phy_system_resume(struct device *dev)
 618{
 619        struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
 620
 621        if (device_may_wakeup(dev))
 622                mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
 623
 624        return 0;
 625}
 626#endif /* CONFIG_PM_SLEEP */
 627
 628static SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend,
 629                mxs_phy_system_resume);
 630
 631static struct platform_driver mxs_phy_driver = {
 632        .probe = mxs_phy_probe,
 633        .remove = mxs_phy_remove,
 634        .driver = {
 635                .name = DRIVER_NAME,
 636                .of_match_table = mxs_phy_dt_ids,
 637                .pm = &mxs_phy_pm,
 638         },
 639};
 640
 641static int __init mxs_phy_module_init(void)
 642{
 643        return platform_driver_register(&mxs_phy_driver);
 644}
 645postcore_initcall(mxs_phy_module_init);
 646
 647static void __exit mxs_phy_module_exit(void)
 648{
 649        platform_driver_unregister(&mxs_phy_driver);
 650}
 651module_exit(mxs_phy_module_exit);
 652
 653MODULE_ALIAS("platform:mxs-usb-phy");
 654MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
 655MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
 656MODULE_DESCRIPTION("Freescale MXS USB PHY driver");
 657MODULE_LICENSE("GPL");
 658