linux/drivers/phy/intel/phy-intel-thunderbay-emmc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Intel ThunderBay eMMC PHY driver
   4 *
   5 * Copyright (C) 2021 Intel Corporation
   6 *
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/delay.h>
  11#include <linux/io.h>
  12#include <linux/iopoll.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/phy/phy.h>
  16#include <linux/platform_device.h>
  17
  18/* eMMC/SD/SDIO core/phy configuration registers */
  19#define CTRL_CFG_0      0x00
  20#define CTRL_CFG_1      0x04
  21#define CTRL_PRESET_0   0x08
  22#define CTRL_PRESET_1   0x0c
  23#define CTRL_PRESET_2   0x10
  24#define CTRL_PRESET_3   0x14
  25#define CTRL_PRESET_4   0x18
  26#define CTRL_CFG_2      0x1c
  27#define CTRL_CFG_3      0x20
  28#define PHY_CFG_0       0x24
  29#define PHY_CFG_1       0x28
  30#define PHY_CFG_2       0x2c
  31#define PHYBIST_CTRL    0x30
  32#define SDHC_STAT3      0x34
  33#define PHY_STAT        0x38
  34#define PHYBIST_STAT_0  0x3c
  35#define PHYBIST_STAT_1  0x40
  36#define EMMC_AXI        0x44
  37
  38/* CTRL_PRESET_3 */
  39#define CTRL_PRESET3_MASK       GENMASK(31, 0)
  40#define CTRL_PRESET3_SHIFT      0
  41
  42/* CTRL_CFG_0 bit fields */
  43#define SUPPORT_HS_MASK         BIT(26)
  44#define SUPPORT_HS_SHIFT        26
  45
  46#define SUPPORT_8B_MASK         BIT(24)
  47#define SUPPORT_8B_SHIFT        24
  48
  49/* CTRL_CFG_1 bit fields */
  50#define SUPPORT_SDR50_MASK      BIT(28)
  51#define SUPPORT_SDR50_SHIFT     28
  52#define SLOT_TYPE_MASK          GENMASK(27, 26)
  53#define SLOT_TYPE_OFFSET        26
  54#define SUPPORT_64B_MASK        BIT(24)
  55#define SUPPORT_64B_SHIFT       24
  56#define SUPPORT_HS400_MASK      BIT(2)
  57#define SUPPORT_HS400_SHIFT     2
  58#define SUPPORT_DDR50_MASK      BIT(1)
  59#define SUPPORT_DDR50_SHIFT     1
  60#define SUPPORT_SDR104_MASK     BIT(0)
  61#define SUPPORT_SDR104_SHIFT    0
  62
  63/* PHY_CFG_0 bit fields */
  64#define SEL_DLY_TXCLK_MASK      BIT(29)
  65#define SEL_DLY_TXCLK_SHIFT     29
  66#define SEL_DLY_RXCLK_MASK      BIT(28)
  67#define SEL_DLY_RXCLK_SHIFT     28
  68
  69#define OTAP_DLY_ENA_MASK       BIT(27)
  70#define OTAP_DLY_ENA_SHIFT      27
  71#define OTAP_DLY_SEL_MASK       GENMASK(26, 23)
  72#define OTAP_DLY_SEL_SHIFT      23
  73#define ITAP_CHG_WIN_MASK       BIT(22)
  74#define ITAP_CHG_WIN_SHIFT      22
  75#define ITAP_DLY_ENA_MASK       BIT(21)
  76#define ITAP_DLY_ENA_SHIFT      21
  77#define ITAP_DLY_SEL_MASK       GENMASK(20, 16)
  78#define ITAP_DLY_SEL_SHIFT      16
  79#define RET_ENB_MASK            BIT(15)
  80#define RET_ENB_SHIFT           15
  81#define RET_EN_MASK             BIT(14)
  82#define RET_EN_SHIFT            14
  83#define DLL_IFF_MASK            GENMASK(13, 11)
  84#define DLL_IFF_SHIFT           11
  85#define DLL_EN_MASK             BIT(10)
  86#define DLL_EN_SHIFT            10
  87#define DLL_TRIM_ICP_MASK       GENMASK(9, 6)
  88#define DLL_TRIM_ICP_SHIFT      6
  89#define RETRIM_EN_MASK          BIT(5)
  90#define RETRIM_EN_SHIFT         5
  91#define RETRIM_MASK             BIT(4)
  92#define RETRIM_SHIFT            4
  93#define DR_TY_MASK              GENMASK(3, 1)
  94#define DR_TY_SHIFT             1
  95#define PWR_DOWN_MASK           BIT(0)
  96#define PWR_DOWN_SHIFT          0
  97
  98/* PHY_CFG_1 bit fields */
  99#define REN_DAT_MASK            GENMASK(19, 12)
 100#define REN_DAT_SHIFT           12
 101#define REN_CMD_MASK            BIT(11)
 102#define REN_CMD_SHIFT           11
 103#define REN_STRB_MASK           BIT(10)
 104#define REN_STRB_SHIFT          10
 105#define PU_STRB_MASK            BIT(20)
 106#define PU_STRB_SHIFT           20
 107
 108/* PHY_CFG_2 bit fields */
 109#define CLKBUF_MASK             GENMASK(24, 21)
 110#define CLKBUF_SHIFT            21
 111#define SEL_STRB_MASK           GENMASK(20, 13)
 112#define SEL_STRB_SHIFT          13
 113#define SEL_FREQ_MASK           GENMASK(12, 10)
 114#define SEL_FREQ_SHIFT          10
 115
 116/* PHY_STAT bit fields */
 117#define CAL_DONE                BIT(6)
 118#define DLL_RDY                 BIT(5)
 119
 120#define OTAP_DLY                0x0
 121#define ITAP_DLY                0x0
 122#define STRB                    0x33
 123
 124/* From ACS_eMMC51_16nFFC_RO1100_Userguide_v1p0.pdf p17 */
 125#define FREQSEL_200M_170M       0x0
 126#define FREQSEL_170M_140M       0x1
 127#define FREQSEL_140M_110M       0x2
 128#define FREQSEL_110M_80M        0x3
 129#define FREQSEL_80M_50M         0x4
 130#define FREQSEL_275M_250M       0x5
 131#define FREQSEL_250M_225M       0x6
 132#define FREQSEL_225M_200M       0x7
 133
 134/* Phy power status */
 135#define PHY_UNINITIALIZED       0
 136#define PHY_INITIALIZED         1
 137
 138/*
 139 * During init(400KHz) phy_settings will be called with 200MHZ clock
 140 * To avoid incorrectly setting the phy for init(400KHZ) "phy_power_sts" is used.
 141 * When actual clock is set always phy is powered off once and then powered on.
 142 * (sdhci_arasan_set_clock). That feature will be used to identify whether the
 143 * settings are for init phy_power_on or actual clock phy_power_on
 144 * 0 --> init settings
 145 * 1 --> actual settings
 146 */
 147
 148struct thunderbay_emmc_phy {
 149        void __iomem    *reg_base;
 150        struct clk      *emmcclk;
 151        int phy_power_sts;
 152};
 153
 154static inline void update_reg(struct thunderbay_emmc_phy *tbh_phy, u32 offset,
 155                              u32 mask, u32 shift, u32 val)
 156{
 157        u32 tmp;
 158
 159        tmp = readl(tbh_phy->reg_base + offset);
 160        tmp &= ~mask;
 161        tmp |= val << shift;
 162        writel(tmp, tbh_phy->reg_base + offset);
 163}
 164
 165static int thunderbay_emmc_phy_power(struct phy *phy, bool power_on)
 166{
 167        struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
 168        unsigned int freqsel = FREQSEL_200M_170M;
 169        unsigned long rate;
 170        static int lock;
 171        u32 val;
 172        int ret;
 173
 174        /* Disable DLL */
 175        rate = clk_get_rate(tbh_phy->emmcclk);
 176        switch (rate) {
 177        case 200000000:
 178                /* lock dll only when it is used, i.e only if SEL_DLY_TXCLK/RXCLK are 0 */
 179                update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x0);
 180                break;
 181
 182        /* dll lock not required for other frequencies */
 183        case 50000000 ... 52000000:
 184        case 400000:
 185        default:
 186                break;
 187        }
 188
 189        if (!power_on)
 190                return 0;
 191
 192        rate = clk_get_rate(tbh_phy->emmcclk);
 193        switch (rate) {
 194        case 170000001 ... 200000000:
 195                freqsel = FREQSEL_200M_170M;
 196                break;
 197
 198        case 140000001 ... 170000000:
 199                freqsel = FREQSEL_170M_140M;
 200                break;
 201
 202        case 110000001 ... 140000000:
 203                freqsel = FREQSEL_140M_110M;
 204                break;
 205
 206        case 80000001 ... 110000000:
 207                freqsel = FREQSEL_110M_80M;
 208                break;
 209
 210        case 50000000 ... 80000000:
 211                freqsel = FREQSEL_80M_50M;
 212                break;
 213
 214        case 250000001 ... 275000000:
 215                freqsel = FREQSEL_275M_250M;
 216                break;
 217
 218        case 225000001 ... 250000000:
 219                freqsel = FREQSEL_250M_225M;
 220                break;
 221
 222        case 200000001 ... 225000000:
 223                freqsel = FREQSEL_225M_200M;
 224                break;
 225        default:
 226                break;
 227        }
 228        /* Clock rate is checked against upper limit. It may fall low during init */
 229        if (rate > 200000000)
 230                dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
 231
 232        udelay(5);
 233
 234        if (lock == 0) {
 235                /* PDB will be done only once per boot */
 236                update_reg(tbh_phy, PHY_CFG_0, PWR_DOWN_MASK,
 237                           PWR_DOWN_SHIFT, 0x1);
 238                lock = 1;
 239                /*
 240                 * According to the user manual, it asks driver to wait 5us for
 241                 * calpad busy trimming. However it is documented that this value is
 242                 * PVT(A.K.A. process, voltage and temperature) relevant, so some
 243                 * failure cases are found which indicates we should be more tolerant
 244                 * to calpad busy trimming.
 245                 */
 246                ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT,
 247                                         val, (val & CAL_DONE), 10, 50);
 248                if (ret) {
 249                        dev_err(&phy->dev, "caldone failed, ret=%d\n", ret);
 250                        return ret;
 251                }
 252        }
 253        rate = clk_get_rate(tbh_phy->emmcclk);
 254        switch (rate) {
 255        case 200000000:
 256                /* Set frequency of the DLL operation */
 257                update_reg(tbh_phy, PHY_CFG_2, SEL_FREQ_MASK, SEL_FREQ_SHIFT, freqsel);
 258
 259                /* Enable DLL */
 260                update_reg(tbh_phy, PHY_CFG_0, DLL_EN_MASK, DLL_EN_SHIFT, 0x1);
 261
 262                /*
 263                 * After enabling analog DLL circuits docs say that we need 10.2 us if
 264                 * our source clock is at 50 MHz and that lock time scales linearly
 265                 * with clock speed. If we are powering on the PHY and the card clock
 266                 * is super slow (like 100kHz) this could take as long as 5.1 ms as
 267                 * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms
 268                 * hopefully we won't be running at 100 kHz, but we should still make
 269                 * sure we wait long enough.
 270                 *
 271                 * NOTE: There appear to be corner cases where the DLL seems to take
 272                 * extra long to lock for reasons that aren't understood. In some
 273                 * extreme cases we've seen it take up to over 10ms (!). We'll be
 274                 * generous and give it 50ms.
 275                 */
 276                ret = readl_poll_timeout(tbh_phy->reg_base + PHY_STAT,
 277                                         val, (val & DLL_RDY), 10, 50 * USEC_PER_MSEC);
 278                if (ret) {
 279                        dev_err(&phy->dev, "dllrdy failed, ret=%d\n", ret);
 280                        return ret;
 281                }
 282                break;
 283
 284        default:
 285                break;
 286        }
 287        return 0;
 288}
 289
 290static int thunderbay_emmc_phy_init(struct phy *phy)
 291{
 292        struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
 293
 294        tbh_phy->emmcclk = clk_get(&phy->dev, "emmcclk");
 295
 296        return PTR_ERR_OR_ZERO(tbh_phy->emmcclk);
 297}
 298
 299static int thunderbay_emmc_phy_exit(struct phy *phy)
 300{
 301        struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
 302
 303        clk_put(tbh_phy->emmcclk);
 304
 305        return 0;
 306}
 307
 308static int thunderbay_emmc_phy_power_on(struct phy *phy)
 309{
 310        struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
 311        unsigned long rate;
 312
 313        /* Overwrite capability bits configurable in bootloader */
 314        update_reg(tbh_phy, CTRL_CFG_0,
 315                   SUPPORT_HS_MASK, SUPPORT_HS_SHIFT, 0x1);
 316        update_reg(tbh_phy, CTRL_CFG_0,
 317                   SUPPORT_8B_MASK, SUPPORT_8B_SHIFT, 0x1);
 318        update_reg(tbh_phy, CTRL_CFG_1,
 319                   SUPPORT_SDR50_MASK, SUPPORT_SDR50_SHIFT, 0x1);
 320        update_reg(tbh_phy, CTRL_CFG_1,
 321                   SUPPORT_DDR50_MASK, SUPPORT_DDR50_SHIFT, 0x1);
 322        update_reg(tbh_phy, CTRL_CFG_1,
 323                   SUPPORT_SDR104_MASK, SUPPORT_SDR104_SHIFT, 0x1);
 324        update_reg(tbh_phy, CTRL_CFG_1,
 325                   SUPPORT_HS400_MASK, SUPPORT_HS400_SHIFT, 0x1);
 326        update_reg(tbh_phy, CTRL_CFG_1,
 327                   SUPPORT_64B_MASK, SUPPORT_64B_SHIFT, 0x1);
 328
 329        if (tbh_phy->phy_power_sts == PHY_UNINITIALIZED) {
 330                /* Indicates initialization, settings for init, same as 400KHZ setting */
 331                update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK, SEL_DLY_TXCLK_SHIFT, 0x1);
 332                update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK, SEL_DLY_RXCLK_SHIFT, 0x1);
 333                update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK, ITAP_DLY_ENA_SHIFT, 0x0);
 334                update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK, ITAP_DLY_SEL_SHIFT, 0x0);
 335                update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK, OTAP_DLY_ENA_SHIFT, 0x0);
 336                update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK, OTAP_DLY_SEL_SHIFT, 0);
 337                update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK, DLL_TRIM_ICP_SHIFT, 0);
 338                update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
 339
 340        } else if (tbh_phy->phy_power_sts == PHY_INITIALIZED) {
 341                /* Indicates actual clock setting */
 342                rate = clk_get_rate(tbh_phy->emmcclk);
 343                switch (rate) {
 344                case 200000000:
 345                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
 346                                   SEL_DLY_TXCLK_SHIFT, 0x0);
 347                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
 348                                   SEL_DLY_RXCLK_SHIFT, 0x0);
 349                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
 350                                   ITAP_DLY_ENA_SHIFT, 0x0);
 351                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
 352                                   ITAP_DLY_SEL_SHIFT, 0x0);
 353                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
 354                                   OTAP_DLY_ENA_SHIFT, 0x1);
 355                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
 356                                   OTAP_DLY_SEL_SHIFT, 2);
 357                        update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
 358                                   DLL_TRIM_ICP_SHIFT, 0x8);
 359                        update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
 360                                   DR_TY_SHIFT, 0x1);
 361                        /* For HS400 only */
 362                        update_reg(tbh_phy, PHY_CFG_2, SEL_STRB_MASK,
 363                                   SEL_STRB_SHIFT, STRB);
 364                        break;
 365
 366                case 50000000 ... 52000000:
 367                        /* For both HS and DDR52 this setting works */
 368                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
 369                                   SEL_DLY_TXCLK_SHIFT, 0x1);
 370                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
 371                                   SEL_DLY_RXCLK_SHIFT, 0x1);
 372                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
 373                                   ITAP_DLY_ENA_SHIFT, 0x0);
 374                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
 375                                   ITAP_DLY_SEL_SHIFT, 0x0);
 376                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
 377                                   OTAP_DLY_ENA_SHIFT, 0x1);
 378                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
 379                                   OTAP_DLY_SEL_SHIFT, 4);
 380                        update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
 381                                   DLL_TRIM_ICP_SHIFT, 0x8);
 382                        update_reg(tbh_phy, PHY_CFG_0,
 383                                   DR_TY_MASK, DR_TY_SHIFT, 0x1);
 384                        break;
 385
 386                case 400000:
 387                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
 388                                   SEL_DLY_TXCLK_SHIFT, 0x1);
 389                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
 390                                   SEL_DLY_RXCLK_SHIFT, 0x1);
 391                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
 392                                   ITAP_DLY_ENA_SHIFT, 0x0);
 393                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
 394                                   ITAP_DLY_SEL_SHIFT, 0x0);
 395                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
 396                                   OTAP_DLY_ENA_SHIFT, 0x0);
 397                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
 398                                   OTAP_DLY_SEL_SHIFT, 0);
 399                        update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
 400                                   DLL_TRIM_ICP_SHIFT, 0);
 401                        update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK, DR_TY_SHIFT, 0x1);
 402                        break;
 403
 404                default:
 405                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_TXCLK_MASK,
 406                                   SEL_DLY_TXCLK_SHIFT, 0x1);
 407                        update_reg(tbh_phy, PHY_CFG_0, SEL_DLY_RXCLK_MASK,
 408                                   SEL_DLY_RXCLK_SHIFT, 0x1);
 409                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_ENA_MASK,
 410                                   ITAP_DLY_ENA_SHIFT, 0x0);
 411                        update_reg(tbh_phy, PHY_CFG_0, ITAP_DLY_SEL_MASK,
 412                                   ITAP_DLY_SEL_SHIFT, 0x0);
 413                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_ENA_MASK,
 414                                   OTAP_DLY_ENA_SHIFT, 0x1);
 415                        update_reg(tbh_phy, PHY_CFG_0, OTAP_DLY_SEL_MASK,
 416                                   OTAP_DLY_SEL_SHIFT, 2);
 417                        update_reg(tbh_phy, PHY_CFG_0, DLL_TRIM_ICP_MASK,
 418                                   DLL_TRIM_ICP_SHIFT, 0x8);
 419                        update_reg(tbh_phy, PHY_CFG_0, DR_TY_MASK,
 420                                   DR_TY_SHIFT, 0x1);
 421                        break;
 422                }
 423                /* Reset, init seq called without phy_power_off, this indicates init seq */
 424                tbh_phy->phy_power_sts = PHY_UNINITIALIZED;
 425        }
 426
 427        update_reg(tbh_phy, PHY_CFG_0, RETRIM_EN_MASK, RETRIM_EN_SHIFT, 0x1);
 428        update_reg(tbh_phy, PHY_CFG_0, RETRIM_MASK, RETRIM_SHIFT, 0x0);
 429
 430        return thunderbay_emmc_phy_power(phy, 1);
 431}
 432
 433static int thunderbay_emmc_phy_power_off(struct phy *phy)
 434{
 435        struct thunderbay_emmc_phy *tbh_phy = phy_get_drvdata(phy);
 436
 437        tbh_phy->phy_power_sts = PHY_INITIALIZED;
 438
 439        return thunderbay_emmc_phy_power(phy, 0);
 440}
 441
 442static const struct phy_ops thunderbay_emmc_phy_ops = {
 443        .init           = thunderbay_emmc_phy_init,
 444        .exit           = thunderbay_emmc_phy_exit,
 445        .power_on       = thunderbay_emmc_phy_power_on,
 446        .power_off      = thunderbay_emmc_phy_power_off,
 447        .owner          = THIS_MODULE,
 448};
 449
 450static const struct of_device_id thunderbay_emmc_phy_of_match[] = {
 451        { .compatible = "intel,thunderbay-emmc-phy",
 452                (void *)&thunderbay_emmc_phy_ops },
 453        {}
 454};
 455MODULE_DEVICE_TABLE(of, thunderbay_emmc_phy_of_match);
 456
 457static int thunderbay_emmc_phy_probe(struct platform_device *pdev)
 458{
 459        struct thunderbay_emmc_phy *tbh_phy;
 460        struct phy_provider *phy_provider;
 461        struct device *dev = &pdev->dev;
 462        const struct of_device_id *id;
 463        struct phy *generic_phy;
 464        struct resource *res;
 465
 466        if (!dev->of_node)
 467                return -ENODEV;
 468
 469        tbh_phy = devm_kzalloc(dev, sizeof(*tbh_phy), GFP_KERNEL);
 470        if (!tbh_phy)
 471                return -ENOMEM;
 472
 473        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 474        tbh_phy->reg_base = devm_ioremap_resource(&pdev->dev, res);
 475        if (IS_ERR(tbh_phy->reg_base))
 476                return PTR_ERR(tbh_phy->reg_base);
 477
 478        tbh_phy->phy_power_sts = PHY_UNINITIALIZED;
 479        id = of_match_node(thunderbay_emmc_phy_of_match, pdev->dev.of_node);
 480        if (!id) {
 481                dev_err(dev, "failed to get match_node\n");
 482                return -EINVAL;
 483        }
 484
 485        generic_phy = devm_phy_create(dev, dev->of_node, id->data);
 486        if (IS_ERR(generic_phy)) {
 487                dev_err(dev, "failed to create PHY\n");
 488                return PTR_ERR(generic_phy);
 489        }
 490
 491        phy_set_drvdata(generic_phy, tbh_phy);
 492        phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 493
 494        return PTR_ERR_OR_ZERO(phy_provider);
 495}
 496
 497static struct platform_driver thunderbay_emmc_phy_driver = {
 498        .probe           = thunderbay_emmc_phy_probe,
 499        .driver          = {
 500                .name    = "thunderbay-emmc-phy",
 501                .of_match_table = thunderbay_emmc_phy_of_match,
 502        },
 503};
 504module_platform_driver(thunderbay_emmc_phy_driver);
 505
 506MODULE_AUTHOR("Nandhini S <nandhini.srikandan@intel.com>");
 507MODULE_AUTHOR("Rashmi A <rashmi.a@intel.com>");
 508MODULE_DESCRIPTION("Intel Thunder Bay eMMC PHY driver");
 509MODULE_LICENSE("GPL v2");
 510