linux/drivers/phy/marvell/phy-pxa-28nm-usb2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2015 Linaro, Ltd.
   4 * Rob Herring <robh@kernel.org>
   5 *
   6 * Based on vendor driver:
   7 * Copyright (C) 2013 Marvell Inc.
   8 * Author: Chao Xie <xiechao.mail@gmail.com>
   9 */
  10
  11#include <linux/delay.h>
  12#include <linux/slab.h>
  13#include <linux/of.h>
  14#include <linux/of_device.h>
  15#include <linux/io.h>
  16#include <linux/err.h>
  17#include <linux/clk.h>
  18#include <linux/module.h>
  19#include <linux/platform_device.h>
  20#include <linux/phy/phy.h>
  21
  22/* USB PXA1928 PHY mapping */
  23#define PHY_28NM_PLL_REG0                       0x0
  24#define PHY_28NM_PLL_REG1                       0x4
  25#define PHY_28NM_CAL_REG                        0x8
  26#define PHY_28NM_TX_REG0                        0x0c
  27#define PHY_28NM_TX_REG1                        0x10
  28#define PHY_28NM_RX_REG0                        0x14
  29#define PHY_28NM_RX_REG1                        0x18
  30#define PHY_28NM_DIG_REG0                       0x1c
  31#define PHY_28NM_DIG_REG1                       0x20
  32#define PHY_28NM_TEST_REG0                      0x24
  33#define PHY_28NM_TEST_REG1                      0x28
  34#define PHY_28NM_MOC_REG                        0x2c
  35#define PHY_28NM_PHY_RESERVE                    0x30
  36#define PHY_28NM_OTG_REG                        0x34
  37#define PHY_28NM_CHRG_DET                       0x38
  38#define PHY_28NM_CTRL_REG0                      0xc4
  39#define PHY_28NM_CTRL_REG1                      0xc8
  40#define PHY_28NM_CTRL_REG2                      0xd4
  41#define PHY_28NM_CTRL_REG3                      0xdc
  42
  43/* PHY_28NM_PLL_REG0 */
  44#define PHY_28NM_PLL_READY                      BIT(31)
  45
  46#define PHY_28NM_PLL_SELLPFR_SHIFT              28
  47#define PHY_28NM_PLL_SELLPFR_MASK               (0x3 << 28)
  48
  49#define PHY_28NM_PLL_FBDIV_SHIFT                16
  50#define PHY_28NM_PLL_FBDIV_MASK                 (0x1ff << 16)
  51
  52#define PHY_28NM_PLL_ICP_SHIFT                  8
  53#define PHY_28NM_PLL_ICP_MASK                   (0x7 << 8)
  54
  55#define PHY_28NM_PLL_REFDIV_SHIFT               0
  56#define PHY_28NM_PLL_REFDIV_MASK                0x7f
  57
  58/* PHY_28NM_PLL_REG1 */
  59#define PHY_28NM_PLL_PU_BY_REG                  BIT(1)
  60
  61#define PHY_28NM_PLL_PU_PLL                     BIT(0)
  62
  63/* PHY_28NM_CAL_REG */
  64#define PHY_28NM_PLL_PLLCAL_DONE                BIT(31)
  65
  66#define PHY_28NM_PLL_IMPCAL_DONE                BIT(23)
  67
  68#define PHY_28NM_PLL_KVCO_SHIFT                 16
  69#define PHY_28NM_PLL_KVCO_MASK                  (0x7 << 16)
  70
  71#define PHY_28NM_PLL_CAL12_SHIFT                20
  72#define PHY_28NM_PLL_CAL12_MASK                 (0x3 << 20)
  73
  74#define PHY_28NM_IMPCAL_VTH_SHIFT               8
  75#define PHY_28NM_IMPCAL_VTH_MASK                (0x7 << 8)
  76
  77#define PHY_28NM_PLLCAL_START_SHIFT             22
  78#define PHY_28NM_IMPCAL_START_SHIFT             13
  79
  80/* PHY_28NM_TX_REG0 */
  81#define PHY_28NM_TX_PU_BY_REG                   BIT(25)
  82
  83#define PHY_28NM_TX_PU_ANA                      BIT(24)
  84
  85#define PHY_28NM_TX_AMP_SHIFT                   20
  86#define PHY_28NM_TX_AMP_MASK                    (0x7 << 20)
  87
  88/* PHY_28NM_RX_REG0 */
  89#define PHY_28NM_RX_SQ_THRESH_SHIFT             0
  90#define PHY_28NM_RX_SQ_THRESH_MASK              (0xf << 0)
  91
  92/* PHY_28NM_RX_REG1 */
  93#define PHY_28NM_RX_SQCAL_DONE                  BIT(31)
  94
  95/* PHY_28NM_DIG_REG0 */
  96#define PHY_28NM_DIG_BITSTAFFING_ERR            BIT(31)
  97#define PHY_28NM_DIG_SYNC_ERR                   BIT(30)
  98
  99#define PHY_28NM_DIG_SQ_FILT_SHIFT              16
 100#define PHY_28NM_DIG_SQ_FILT_MASK               (0x7 << 16)
 101
 102#define PHY_28NM_DIG_SQ_BLK_SHIFT               12
 103#define PHY_28NM_DIG_SQ_BLK_MASK                (0x7 << 12)
 104
 105#define PHY_28NM_DIG_SYNC_NUM_SHIFT             0
 106#define PHY_28NM_DIG_SYNC_NUM_MASK              (0x3 << 0)
 107
 108#define PHY_28NM_PLL_LOCK_BYPASS                BIT(7)
 109
 110/* PHY_28NM_OTG_REG */
 111#define PHY_28NM_OTG_CONTROL_BY_PIN             BIT(5)
 112#define PHY_28NM_OTG_PU_OTG                     BIT(4)
 113
 114#define PHY_28NM_CHGDTC_ENABLE_SWITCH_DM_SHIFT_28 13
 115#define PHY_28NM_CHGDTC_ENABLE_SWITCH_DP_SHIFT_28 12
 116#define PHY_28NM_CHGDTC_VSRC_CHARGE_SHIFT_28    10
 117#define PHY_28NM_CHGDTC_VDAT_CHARGE_SHIFT_28    8
 118#define PHY_28NM_CHGDTC_CDP_DM_AUTO_SWITCH_SHIFT_28 7
 119#define PHY_28NM_CHGDTC_DP_DM_SWAP_SHIFT_28     6
 120#define PHY_28NM_CHGDTC_PU_CHRG_DTC_SHIFT_28    5
 121#define PHY_28NM_CHGDTC_PD_EN_SHIFT_28          4
 122#define PHY_28NM_CHGDTC_DCP_EN_SHIFT_28         3
 123#define PHY_28NM_CHGDTC_CDP_EN_SHIFT_28         2
 124#define PHY_28NM_CHGDTC_TESTMON_CHRGDTC_SHIFT_28 0
 125
 126#define PHY_28NM_CTRL1_CHRG_DTC_OUT_SHIFT_28    4
 127#define PHY_28NM_CTRL1_VBUSDTC_OUT_SHIFT_28     2
 128
 129#define PHY_28NM_CTRL3_OVERWRITE                BIT(0)
 130#define PHY_28NM_CTRL3_VBUS_VALID               BIT(4)
 131#define PHY_28NM_CTRL3_AVALID                   BIT(5)
 132#define PHY_28NM_CTRL3_BVALID                   BIT(6)
 133
 134struct mv_usb2_phy {
 135        struct phy              *phy;
 136        struct platform_device  *pdev;
 137        void __iomem            *base;
 138        struct clk              *clk;
 139};
 140
 141static bool wait_for_reg(void __iomem *reg, u32 mask, unsigned long timeout)
 142{
 143        timeout += jiffies;
 144        while (time_is_after_eq_jiffies(timeout)) {
 145                if ((readl(reg) & mask) == mask)
 146                        return true;
 147                msleep(1);
 148        }
 149        return false;
 150}
 151
 152static int mv_usb2_phy_28nm_init(struct phy *phy)
 153{
 154        struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy);
 155        struct platform_device *pdev = mv_phy->pdev;
 156        void __iomem *base = mv_phy->base;
 157        u32 reg;
 158        int ret;
 159
 160        clk_prepare_enable(mv_phy->clk);
 161
 162        /* PHY_28NM_PLL_REG0 */
 163        reg = readl(base + PHY_28NM_PLL_REG0) &
 164                ~(PHY_28NM_PLL_SELLPFR_MASK | PHY_28NM_PLL_FBDIV_MASK
 165                | PHY_28NM_PLL_ICP_MASK | PHY_28NM_PLL_REFDIV_MASK);
 166        writel(reg | (0x1 << PHY_28NM_PLL_SELLPFR_SHIFT
 167                | 0xf0 << PHY_28NM_PLL_FBDIV_SHIFT
 168                | 0x3 << PHY_28NM_PLL_ICP_SHIFT
 169                | 0xd << PHY_28NM_PLL_REFDIV_SHIFT),
 170                base + PHY_28NM_PLL_REG0);
 171
 172        /* PHY_28NM_PLL_REG1 */
 173        reg = readl(base + PHY_28NM_PLL_REG1);
 174        writel(reg | PHY_28NM_PLL_PU_PLL | PHY_28NM_PLL_PU_BY_REG,
 175                base + PHY_28NM_PLL_REG1);
 176
 177        /* PHY_28NM_TX_REG0 */
 178        reg = readl(base + PHY_28NM_TX_REG0) & ~PHY_28NM_TX_AMP_MASK;
 179        writel(reg | PHY_28NM_TX_PU_BY_REG | 0x3 << PHY_28NM_TX_AMP_SHIFT |
 180                PHY_28NM_TX_PU_ANA,
 181                base + PHY_28NM_TX_REG0);
 182
 183        /* PHY_28NM_RX_REG0 */
 184        reg = readl(base + PHY_28NM_RX_REG0) & ~PHY_28NM_RX_SQ_THRESH_MASK;
 185        writel(reg | 0xa << PHY_28NM_RX_SQ_THRESH_SHIFT,
 186                base + PHY_28NM_RX_REG0);
 187
 188        /* PHY_28NM_DIG_REG0 */
 189        reg = readl(base + PHY_28NM_DIG_REG0) &
 190                ~(PHY_28NM_DIG_BITSTAFFING_ERR | PHY_28NM_DIG_SYNC_ERR |
 191                PHY_28NM_DIG_SQ_FILT_MASK | PHY_28NM_DIG_SQ_BLK_MASK |
 192                PHY_28NM_DIG_SYNC_NUM_MASK);
 193        writel(reg | (0x1 << PHY_28NM_DIG_SYNC_NUM_SHIFT |
 194                PHY_28NM_PLL_LOCK_BYPASS),
 195                base + PHY_28NM_DIG_REG0);
 196
 197        /* PHY_28NM_OTG_REG */
 198        reg = readl(base + PHY_28NM_OTG_REG) | PHY_28NM_OTG_PU_OTG;
 199        writel(reg & ~PHY_28NM_OTG_CONTROL_BY_PIN, base + PHY_28NM_OTG_REG);
 200
 201        /*
 202         *  Calibration Timing
 203         *                 ____________________________
 204         *  CAL START   ___|
 205         *                         ____________________
 206         *  CAL_DONE    ___________|
 207         *                 | 400us |
 208         */
 209
 210        /* Make sure PHY Calibration is ready */
 211        if (!wait_for_reg(base + PHY_28NM_CAL_REG,
 212            PHY_28NM_PLL_PLLCAL_DONE | PHY_28NM_PLL_IMPCAL_DONE,
 213            HZ / 10)) {
 214                dev_warn(&pdev->dev, "USB PHY PLL calibrate not done after 100mS.");
 215                ret = -ETIMEDOUT;
 216                goto err_clk;
 217        }
 218        if (!wait_for_reg(base + PHY_28NM_RX_REG1,
 219            PHY_28NM_RX_SQCAL_DONE, HZ / 10)) {
 220                dev_warn(&pdev->dev, "USB PHY RX SQ calibrate not done after 100mS.");
 221                ret = -ETIMEDOUT;
 222                goto err_clk;
 223        }
 224        /* Make sure PHY PLL is ready */
 225        if (!wait_for_reg(base + PHY_28NM_PLL_REG0,
 226            PHY_28NM_PLL_READY, HZ / 10)) {
 227                dev_warn(&pdev->dev, "PLL_READY not set after 100mS.");
 228                ret = -ETIMEDOUT;
 229                goto err_clk;
 230        }
 231
 232        return 0;
 233err_clk:
 234        clk_disable_unprepare(mv_phy->clk);
 235        return ret;
 236}
 237
 238static int mv_usb2_phy_28nm_power_on(struct phy *phy)
 239{
 240        struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy);
 241        void __iomem *base = mv_phy->base;
 242
 243        writel(readl(base + PHY_28NM_CTRL_REG3) |
 244                (PHY_28NM_CTRL3_OVERWRITE | PHY_28NM_CTRL3_VBUS_VALID |
 245                PHY_28NM_CTRL3_AVALID | PHY_28NM_CTRL3_BVALID),
 246                base + PHY_28NM_CTRL_REG3);
 247
 248        return 0;
 249}
 250
 251static int mv_usb2_phy_28nm_power_off(struct phy *phy)
 252{
 253        struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy);
 254        void __iomem *base = mv_phy->base;
 255
 256        writel(readl(base + PHY_28NM_CTRL_REG3) |
 257                ~(PHY_28NM_CTRL3_OVERWRITE | PHY_28NM_CTRL3_VBUS_VALID
 258                | PHY_28NM_CTRL3_AVALID | PHY_28NM_CTRL3_BVALID),
 259                base + PHY_28NM_CTRL_REG3);
 260
 261        return 0;
 262}
 263
 264static int mv_usb2_phy_28nm_exit(struct phy *phy)
 265{
 266        struct mv_usb2_phy *mv_phy = phy_get_drvdata(phy);
 267        void __iomem *base = mv_phy->base;
 268        unsigned int val;
 269
 270        val = readw(base + PHY_28NM_PLL_REG1);
 271        val &= ~PHY_28NM_PLL_PU_PLL;
 272        writew(val, base + PHY_28NM_PLL_REG1);
 273
 274        /* power down PHY Analog part */
 275        val = readw(base + PHY_28NM_TX_REG0);
 276        val &= ~PHY_28NM_TX_PU_ANA;
 277        writew(val, base + PHY_28NM_TX_REG0);
 278
 279        /* power down PHY OTG part */
 280        val = readw(base + PHY_28NM_OTG_REG);
 281        val &= ~PHY_28NM_OTG_PU_OTG;
 282        writew(val, base + PHY_28NM_OTG_REG);
 283
 284        clk_disable_unprepare(mv_phy->clk);
 285        return 0;
 286}
 287
 288static const struct phy_ops usb_ops = {
 289        .init           = mv_usb2_phy_28nm_init,
 290        .power_on       = mv_usb2_phy_28nm_power_on,
 291        .power_off      = mv_usb2_phy_28nm_power_off,
 292        .exit           = mv_usb2_phy_28nm_exit,
 293        .owner          = THIS_MODULE,
 294};
 295
 296static int mv_usb2_phy_probe(struct platform_device *pdev)
 297{
 298        struct phy_provider *phy_provider;
 299        struct mv_usb2_phy *mv_phy;
 300        struct resource *r;
 301
 302        mv_phy = devm_kzalloc(&pdev->dev, sizeof(*mv_phy), GFP_KERNEL);
 303        if (!mv_phy)
 304                return -ENOMEM;
 305
 306        mv_phy->pdev = pdev;
 307
 308        mv_phy->clk = devm_clk_get(&pdev->dev, NULL);
 309        if (IS_ERR(mv_phy->clk)) {
 310                dev_err(&pdev->dev, "failed to get clock.\n");
 311                return PTR_ERR(mv_phy->clk);
 312        }
 313
 314        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 315        mv_phy->base = devm_ioremap_resource(&pdev->dev, r);
 316        if (IS_ERR(mv_phy->base))
 317                return PTR_ERR(mv_phy->base);
 318
 319        mv_phy->phy = devm_phy_create(&pdev->dev, pdev->dev.of_node, &usb_ops);
 320        if (IS_ERR(mv_phy->phy))
 321                return PTR_ERR(mv_phy->phy);
 322
 323        phy_set_drvdata(mv_phy->phy, mv_phy);
 324
 325        phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
 326        return PTR_ERR_OR_ZERO(phy_provider);
 327}
 328
 329static const struct of_device_id mv_usbphy_dt_match[] = {
 330        { .compatible = "marvell,pxa1928-usb-phy", },
 331        {},
 332};
 333MODULE_DEVICE_TABLE(of, mv_usbphy_dt_match);
 334
 335static struct platform_driver mv_usb2_phy_driver = {
 336        .probe  = mv_usb2_phy_probe,
 337        .driver = {
 338                .name   = "mv-usb2-phy",
 339                .of_match_table = of_match_ptr(mv_usbphy_dt_match),
 340        },
 341};
 342module_platform_driver(mv_usb2_phy_driver);
 343
 344MODULE_AUTHOR("Rob Herring <robh@kernel.org>");
 345MODULE_DESCRIPTION("Marvell USB2 phy driver");
 346MODULE_LICENSE("GPL v2");
 347