linux/drivers/phy/rockchip/phy-rockchip-pcie.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Rockchip PCIe PHY driver
   4 *
   5 * Copyright (C) 2016 Shawn Lin <shawn.lin@rock-chips.com>
   6 * Copyright (C) 2016 ROCKCHIP, Inc.
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/delay.h>
  11#include <linux/io.h>
  12#include <linux/mfd/syscon.h>
  13#include <linux/module.h>
  14#include <linux/of.h>
  15#include <linux/of_address.h>
  16#include <linux/of_platform.h>
  17#include <linux/phy/phy.h>
  18#include <linux/platform_device.h>
  19#include <linux/regmap.h>
  20#include <linux/reset.h>
  21
  22/*
  23 * The higher 16-bit of this register is used for write protection
  24 * only if BIT(x + 16) set to 1 the BIT(x) can be written.
  25 */
  26#define HIWORD_UPDATE(val, mask, shift) \
  27                ((val) << (shift) | (mask) << ((shift) + 16))
  28
  29#define PHY_MAX_LANE_NUM      4
  30#define PHY_CFG_DATA_SHIFT    7
  31#define PHY_CFG_ADDR_SHIFT    1
  32#define PHY_CFG_DATA_MASK     0xf
  33#define PHY_CFG_ADDR_MASK     0x3f
  34#define PHY_CFG_RD_MASK       0x3ff
  35#define PHY_CFG_WR_ENABLE     1
  36#define PHY_CFG_WR_DISABLE    1
  37#define PHY_CFG_WR_SHIFT      0
  38#define PHY_CFG_WR_MASK       1
  39#define PHY_CFG_PLL_LOCK      0x10
  40#define PHY_CFG_CLK_TEST      0x10
  41#define PHY_CFG_CLK_SCC       0x12
  42#define PHY_CFG_SEPE_RATE     BIT(3)
  43#define PHY_CFG_PLL_100M      BIT(3)
  44#define PHY_PLL_LOCKED        BIT(9)
  45#define PHY_PLL_OUTPUT        BIT(10)
  46#define PHY_LANE_A_STATUS     0x30
  47#define PHY_LANE_B_STATUS     0x31
  48#define PHY_LANE_C_STATUS     0x32
  49#define PHY_LANE_D_STATUS     0x33
  50#define PHY_LANE_RX_DET_SHIFT 11
  51#define PHY_LANE_RX_DET_TH    0x1
  52#define PHY_LANE_IDLE_OFF     0x1
  53#define PHY_LANE_IDLE_MASK    0x1
  54#define PHY_LANE_IDLE_A_SHIFT 3
  55#define PHY_LANE_IDLE_B_SHIFT 4
  56#define PHY_LANE_IDLE_C_SHIFT 5
  57#define PHY_LANE_IDLE_D_SHIFT 6
  58
  59struct rockchip_pcie_data {
  60        unsigned int pcie_conf;
  61        unsigned int pcie_status;
  62        unsigned int pcie_laneoff;
  63};
  64
  65struct rockchip_pcie_phy {
  66        struct rockchip_pcie_data *phy_data;
  67        struct regmap *reg_base;
  68        struct phy_pcie_instance {
  69                struct phy *phy;
  70                u32 index;
  71        } phys[PHY_MAX_LANE_NUM];
  72        struct mutex pcie_mutex;
  73        struct reset_control *phy_rst;
  74        struct clk *clk_pciephy_ref;
  75        int pwr_cnt;
  76        int init_cnt;
  77};
  78
  79static struct rockchip_pcie_phy *to_pcie_phy(struct phy_pcie_instance *inst)
  80{
  81        return container_of(inst, struct rockchip_pcie_phy,
  82                                        phys[inst->index]);
  83}
  84
  85static struct phy *rockchip_pcie_phy_of_xlate(struct device *dev,
  86                                              struct of_phandle_args *args)
  87{
  88        struct rockchip_pcie_phy *rk_phy = dev_get_drvdata(dev);
  89
  90        if (args->args_count == 0)
  91                return rk_phy->phys[0].phy;
  92
  93        if (WARN_ON(args->args[0] >= PHY_MAX_LANE_NUM))
  94                return ERR_PTR(-ENODEV);
  95
  96        return rk_phy->phys[args->args[0]].phy;
  97}
  98
  99
 100static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy,
 101                              u32 addr, u32 data)
 102{
 103        regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
 104                     HIWORD_UPDATE(data,
 105                                   PHY_CFG_DATA_MASK,
 106                                   PHY_CFG_DATA_SHIFT) |
 107                     HIWORD_UPDATE(addr,
 108                                   PHY_CFG_ADDR_MASK,
 109                                   PHY_CFG_ADDR_SHIFT));
 110        udelay(1);
 111        regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
 112                     HIWORD_UPDATE(PHY_CFG_WR_ENABLE,
 113                                   PHY_CFG_WR_MASK,
 114                                   PHY_CFG_WR_SHIFT));
 115        udelay(1);
 116        regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
 117                     HIWORD_UPDATE(PHY_CFG_WR_DISABLE,
 118                                   PHY_CFG_WR_MASK,
 119                                   PHY_CFG_WR_SHIFT));
 120}
 121
 122static inline u32 phy_rd_cfg(struct rockchip_pcie_phy *rk_phy,
 123                             u32 addr)
 124{
 125        u32 val;
 126
 127        regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
 128                     HIWORD_UPDATE(addr,
 129                                   PHY_CFG_RD_MASK,
 130                                   PHY_CFG_ADDR_SHIFT));
 131        regmap_read(rk_phy->reg_base,
 132                    rk_phy->phy_data->pcie_status,
 133                    &val);
 134        return val;
 135}
 136
 137static int rockchip_pcie_phy_power_off(struct phy *phy)
 138{
 139        struct phy_pcie_instance *inst = phy_get_drvdata(phy);
 140        struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
 141        int err = 0;
 142
 143        mutex_lock(&rk_phy->pcie_mutex);
 144
 145        regmap_write(rk_phy->reg_base,
 146                     rk_phy->phy_data->pcie_laneoff,
 147                     HIWORD_UPDATE(PHY_LANE_IDLE_OFF,
 148                                   PHY_LANE_IDLE_MASK,
 149                                   PHY_LANE_IDLE_A_SHIFT + inst->index));
 150
 151        if (--rk_phy->pwr_cnt)
 152                goto err_out;
 153
 154        err = reset_control_assert(rk_phy->phy_rst);
 155        if (err) {
 156                dev_err(&phy->dev, "assert phy_rst err %d\n", err);
 157                goto err_restore;
 158        }
 159
 160err_out:
 161        mutex_unlock(&rk_phy->pcie_mutex);
 162        return 0;
 163
 164err_restore:
 165        rk_phy->pwr_cnt++;
 166        regmap_write(rk_phy->reg_base,
 167                     rk_phy->phy_data->pcie_laneoff,
 168                     HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
 169                                   PHY_LANE_IDLE_MASK,
 170                                   PHY_LANE_IDLE_A_SHIFT + inst->index));
 171        mutex_unlock(&rk_phy->pcie_mutex);
 172        return err;
 173}
 174
 175static int rockchip_pcie_phy_power_on(struct phy *phy)
 176{
 177        struct phy_pcie_instance *inst = phy_get_drvdata(phy);
 178        struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
 179        int err = 0;
 180        u32 status;
 181        unsigned long timeout;
 182
 183        mutex_lock(&rk_phy->pcie_mutex);
 184
 185        if (rk_phy->pwr_cnt++)
 186                goto err_out;
 187
 188        err = reset_control_deassert(rk_phy->phy_rst);
 189        if (err) {
 190                dev_err(&phy->dev, "deassert phy_rst err %d\n", err);
 191                goto err_pwr_cnt;
 192        }
 193
 194        regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
 195                     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
 196                                   PHY_CFG_ADDR_MASK,
 197                                   PHY_CFG_ADDR_SHIFT));
 198
 199        regmap_write(rk_phy->reg_base,
 200                     rk_phy->phy_data->pcie_laneoff,
 201                     HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
 202                                   PHY_LANE_IDLE_MASK,
 203                                   PHY_LANE_IDLE_A_SHIFT + inst->index));
 204
 205        /*
 206         * No documented timeout value for phy operation below,
 207         * so we make it large enough here. And we use loop-break
 208         * method which should not be harmful.
 209         */
 210        timeout = jiffies + msecs_to_jiffies(1000);
 211
 212        err = -EINVAL;
 213        while (time_before(jiffies, timeout)) {
 214                regmap_read(rk_phy->reg_base,
 215                            rk_phy->phy_data->pcie_status,
 216                            &status);
 217                if (status & PHY_PLL_LOCKED) {
 218                        dev_dbg(&phy->dev, "pll locked!\n");
 219                        err = 0;
 220                        break;
 221                }
 222                msleep(20);
 223        }
 224
 225        if (err) {
 226                dev_err(&phy->dev, "pll lock timeout!\n");
 227                goto err_pll_lock;
 228        }
 229
 230        phy_wr_cfg(rk_phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE);
 231        phy_wr_cfg(rk_phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M);
 232
 233        err = -ETIMEDOUT;
 234        while (time_before(jiffies, timeout)) {
 235                regmap_read(rk_phy->reg_base,
 236                            rk_phy->phy_data->pcie_status,
 237                            &status);
 238                if (!(status & PHY_PLL_OUTPUT)) {
 239                        dev_dbg(&phy->dev, "pll output enable done!\n");
 240                        err = 0;
 241                        break;
 242                }
 243                msleep(20);
 244        }
 245
 246        if (err) {
 247                dev_err(&phy->dev, "pll output enable timeout!\n");
 248                goto err_pll_lock;
 249        }
 250
 251        regmap_write(rk_phy->reg_base, rk_phy->phy_data->pcie_conf,
 252                     HIWORD_UPDATE(PHY_CFG_PLL_LOCK,
 253                                   PHY_CFG_ADDR_MASK,
 254                                   PHY_CFG_ADDR_SHIFT));
 255        err = -EINVAL;
 256        while (time_before(jiffies, timeout)) {
 257                regmap_read(rk_phy->reg_base,
 258                            rk_phy->phy_data->pcie_status,
 259                            &status);
 260                if (status & PHY_PLL_LOCKED) {
 261                        dev_dbg(&phy->dev, "pll relocked!\n");
 262                        err = 0;
 263                        break;
 264                }
 265                msleep(20);
 266        }
 267
 268        if (err) {
 269                dev_err(&phy->dev, "pll relock timeout!\n");
 270                goto err_pll_lock;
 271        }
 272
 273err_out:
 274        mutex_unlock(&rk_phy->pcie_mutex);
 275        return 0;
 276
 277err_pll_lock:
 278        reset_control_assert(rk_phy->phy_rst);
 279err_pwr_cnt:
 280        rk_phy->pwr_cnt--;
 281        mutex_unlock(&rk_phy->pcie_mutex);
 282        return err;
 283}
 284
 285static int rockchip_pcie_phy_init(struct phy *phy)
 286{
 287        struct phy_pcie_instance *inst = phy_get_drvdata(phy);
 288        struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
 289        int err = 0;
 290
 291        mutex_lock(&rk_phy->pcie_mutex);
 292
 293        if (rk_phy->init_cnt++)
 294                goto err_out;
 295
 296        err = clk_prepare_enable(rk_phy->clk_pciephy_ref);
 297        if (err) {
 298                dev_err(&phy->dev, "Fail to enable pcie ref clock.\n");
 299                goto err_refclk;
 300        }
 301
 302        err = reset_control_assert(rk_phy->phy_rst);
 303        if (err) {
 304                dev_err(&phy->dev, "assert phy_rst err %d\n", err);
 305                goto err_reset;
 306        }
 307
 308err_out:
 309        mutex_unlock(&rk_phy->pcie_mutex);
 310        return 0;
 311
 312err_reset:
 313
 314        clk_disable_unprepare(rk_phy->clk_pciephy_ref);
 315err_refclk:
 316        rk_phy->init_cnt--;
 317        mutex_unlock(&rk_phy->pcie_mutex);
 318        return err;
 319}
 320
 321static int rockchip_pcie_phy_exit(struct phy *phy)
 322{
 323        struct phy_pcie_instance *inst = phy_get_drvdata(phy);
 324        struct rockchip_pcie_phy *rk_phy = to_pcie_phy(inst);
 325
 326        mutex_lock(&rk_phy->pcie_mutex);
 327
 328        if (--rk_phy->init_cnt)
 329                goto err_init_cnt;
 330
 331        clk_disable_unprepare(rk_phy->clk_pciephy_ref);
 332
 333err_init_cnt:
 334        mutex_unlock(&rk_phy->pcie_mutex);
 335        return 0;
 336}
 337
 338static const struct phy_ops ops = {
 339        .init           = rockchip_pcie_phy_init,
 340        .exit           = rockchip_pcie_phy_exit,
 341        .power_on       = rockchip_pcie_phy_power_on,
 342        .power_off      = rockchip_pcie_phy_power_off,
 343        .owner          = THIS_MODULE,
 344};
 345
 346static const struct rockchip_pcie_data rk3399_pcie_data = {
 347        .pcie_conf = 0xe220,
 348        .pcie_status = 0xe2a4,
 349        .pcie_laneoff = 0xe214,
 350};
 351
 352static const struct of_device_id rockchip_pcie_phy_dt_ids[] = {
 353        {
 354                .compatible = "rockchip,rk3399-pcie-phy",
 355                .data = &rk3399_pcie_data,
 356        },
 357        {}
 358};
 359
 360MODULE_DEVICE_TABLE(of, rockchip_pcie_phy_dt_ids);
 361
 362static int rockchip_pcie_phy_probe(struct platform_device *pdev)
 363{
 364        struct device *dev = &pdev->dev;
 365        struct rockchip_pcie_phy *rk_phy;
 366        struct phy_provider *phy_provider;
 367        struct regmap *grf;
 368        const struct of_device_id *of_id;
 369        int i;
 370        u32 phy_num;
 371
 372        grf = syscon_node_to_regmap(dev->parent->of_node);
 373        if (IS_ERR(grf)) {
 374                dev_err(dev, "Cannot find GRF syscon\n");
 375                return PTR_ERR(grf);
 376        }
 377
 378        rk_phy = devm_kzalloc(dev, sizeof(*rk_phy), GFP_KERNEL);
 379        if (!rk_phy)
 380                return -ENOMEM;
 381
 382        of_id = of_match_device(rockchip_pcie_phy_dt_ids, &pdev->dev);
 383        if (!of_id)
 384                return -EINVAL;
 385
 386        rk_phy->phy_data = (struct rockchip_pcie_data *)of_id->data;
 387        rk_phy->reg_base = grf;
 388
 389        mutex_init(&rk_phy->pcie_mutex);
 390
 391        rk_phy->phy_rst = devm_reset_control_get(dev, "phy");
 392        if (IS_ERR(rk_phy->phy_rst)) {
 393                if (PTR_ERR(rk_phy->phy_rst) != -EPROBE_DEFER)
 394                        dev_err(dev,
 395                                "missing phy property for reset controller\n");
 396                return PTR_ERR(rk_phy->phy_rst);
 397        }
 398
 399        rk_phy->clk_pciephy_ref = devm_clk_get(dev, "refclk");
 400        if (IS_ERR(rk_phy->clk_pciephy_ref)) {
 401                dev_err(dev, "refclk not found.\n");
 402                return PTR_ERR(rk_phy->clk_pciephy_ref);
 403        }
 404
 405        /* parse #phy-cells to see if it's legacy PHY model */
 406        if (of_property_read_u32(dev->of_node, "#phy-cells", &phy_num))
 407                return -ENOENT;
 408
 409        phy_num = (phy_num == 0) ? 1 : PHY_MAX_LANE_NUM;
 410        dev_dbg(dev, "phy number is %d\n", phy_num);
 411
 412        for (i = 0; i < phy_num; i++) {
 413                rk_phy->phys[i].phy = devm_phy_create(dev, dev->of_node, &ops);
 414                if (IS_ERR(rk_phy->phys[i].phy)) {
 415                        dev_err(dev, "failed to create PHY%d\n", i);
 416                        return PTR_ERR(rk_phy->phys[i].phy);
 417                }
 418                rk_phy->phys[i].index = i;
 419                phy_set_drvdata(rk_phy->phys[i].phy, &rk_phy->phys[i]);
 420        }
 421
 422        platform_set_drvdata(pdev, rk_phy);
 423        phy_provider = devm_of_phy_provider_register(dev,
 424                                        rockchip_pcie_phy_of_xlate);
 425
 426        return PTR_ERR_OR_ZERO(phy_provider);
 427}
 428
 429static struct platform_driver rockchip_pcie_driver = {
 430        .probe          = rockchip_pcie_phy_probe,
 431        .driver         = {
 432                .name   = "rockchip-pcie-phy",
 433                .of_match_table = rockchip_pcie_phy_dt_ids,
 434        },
 435};
 436
 437module_platform_driver(rockchip_pcie_driver);
 438
 439MODULE_AUTHOR("Shawn Lin <shawn.lin@rock-chips.com>");
 440MODULE_DESCRIPTION("Rockchip PCIe PHY driver");
 441MODULE_LICENSE("GPL v2");
 442