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