linux/drivers/phy/renesas/phy-rcar-gen3-usb2.c
<<
>>
Prefs
   1/*
   2 * Renesas R-Car Gen3 for USB2.0 PHY driver
   3 *
   4 * Copyright (C) 2015-2017 Renesas Electronics Corporation
   5 *
   6 * This is based on the phy-rcar-gen2 driver:
   7 * Copyright (C) 2014 Renesas Solutions Corp.
   8 * Copyright (C) 2014 Cogent Embedded, Inc.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14
  15#include <linux/extcon-provider.h>
  16#include <linux/interrupt.h>
  17#include <linux/io.h>
  18#include <linux/module.h>
  19#include <linux/of.h>
  20#include <linux/of_address.h>
  21#include <linux/of_device.h>
  22#include <linux/phy/phy.h>
  23#include <linux/platform_device.h>
  24#include <linux/pm_runtime.h>
  25#include <linux/regulator/consumer.h>
  26#include <linux/usb/of.h>
  27#include <linux/workqueue.h>
  28
  29/******* USB2.0 Host registers (original offset is +0x200) *******/
  30#define USB2_INT_ENABLE         0x000
  31#define USB2_USBCTR             0x00c
  32#define USB2_SPD_RSM_TIMSET     0x10c
  33#define USB2_OC_TIMSET          0x110
  34#define USB2_COMMCTRL           0x600
  35#define USB2_OBINTSTA           0x604
  36#define USB2_OBINTEN            0x608
  37#define USB2_VBCTRL             0x60c
  38#define USB2_LINECTRL1          0x610
  39#define USB2_ADPCTRL            0x630
  40
  41/* INT_ENABLE */
  42#define USB2_INT_ENABLE_UCOM_INTEN      BIT(3)
  43#define USB2_INT_ENABLE_USBH_INTB_EN    BIT(2)
  44#define USB2_INT_ENABLE_USBH_INTA_EN    BIT(1)
  45#define USB2_INT_ENABLE_INIT            (USB2_INT_ENABLE_UCOM_INTEN | \
  46                                         USB2_INT_ENABLE_USBH_INTB_EN | \
  47                                         USB2_INT_ENABLE_USBH_INTA_EN)
  48
  49/* USBCTR */
  50#define USB2_USBCTR_DIRPD       BIT(2)
  51#define USB2_USBCTR_PLL_RST     BIT(1)
  52
  53/* SPD_RSM_TIMSET */
  54#define USB2_SPD_RSM_TIMSET_INIT        0x014e029b
  55
  56/* OC_TIMSET */
  57#define USB2_OC_TIMSET_INIT             0x000209ab
  58
  59/* COMMCTRL */
  60#define USB2_COMMCTRL_OTG_PERI          BIT(31) /* 1 = Peripheral mode */
  61
  62/* OBINTSTA and OBINTEN */
  63#define USB2_OBINT_SESSVLDCHG           BIT(12)
  64#define USB2_OBINT_IDDIGCHG             BIT(11)
  65#define USB2_OBINT_BITS                 (USB2_OBINT_SESSVLDCHG | \
  66                                         USB2_OBINT_IDDIGCHG)
  67
  68/* VBCTRL */
  69#define USB2_VBCTRL_DRVVBUSSEL          BIT(8)
  70
  71/* LINECTRL1 */
  72#define USB2_LINECTRL1_DPRPD_EN         BIT(19)
  73#define USB2_LINECTRL1_DP_RPD           BIT(18)
  74#define USB2_LINECTRL1_DMRPD_EN         BIT(17)
  75#define USB2_LINECTRL1_DM_RPD           BIT(16)
  76#define USB2_LINECTRL1_OPMODE_NODRV     BIT(6)
  77
  78/* ADPCTRL */
  79#define USB2_ADPCTRL_OTGSESSVLD         BIT(20)
  80#define USB2_ADPCTRL_IDDIG              BIT(19)
  81#define USB2_ADPCTRL_IDPULLUP           BIT(5)  /* 1 = ID sampling is enabled */
  82#define USB2_ADPCTRL_DRVVBUS            BIT(4)
  83
  84#define RCAR_GEN3_PHY_HAS_DEDICATED_PINS        1
  85
  86struct rcar_gen3_chan {
  87        void __iomem *base;
  88        struct extcon_dev *extcon;
  89        struct phy *phy;
  90        struct regulator *vbus;
  91        struct work_struct work;
  92        bool extcon_host;
  93        bool has_otg_pins;
  94};
  95
  96static void rcar_gen3_phy_usb2_work(struct work_struct *work)
  97{
  98        struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan,
  99                                                 work);
 100
 101        if (ch->extcon_host) {
 102                extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, true);
 103                extcon_set_state_sync(ch->extcon, EXTCON_USB, false);
 104        } else {
 105                extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, false);
 106                extcon_set_state_sync(ch->extcon, EXTCON_USB, true);
 107        }
 108}
 109
 110static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
 111{
 112        void __iomem *usb2_base = ch->base;
 113        u32 val = readl(usb2_base + USB2_COMMCTRL);
 114
 115        dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, host);
 116        if (host)
 117                val &= ~USB2_COMMCTRL_OTG_PERI;
 118        else
 119                val |= USB2_COMMCTRL_OTG_PERI;
 120        writel(val, usb2_base + USB2_COMMCTRL);
 121}
 122
 123static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
 124{
 125        void __iomem *usb2_base = ch->base;
 126        u32 val = readl(usb2_base + USB2_LINECTRL1);
 127
 128        dev_vdbg(&ch->phy->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm);
 129        val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
 130        if (dp)
 131                val |= USB2_LINECTRL1_DP_RPD;
 132        if (dm)
 133                val |= USB2_LINECTRL1_DM_RPD;
 134        writel(val, usb2_base + USB2_LINECTRL1);
 135}
 136
 137static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus)
 138{
 139        void __iomem *usb2_base = ch->base;
 140        u32 val = readl(usb2_base + USB2_ADPCTRL);
 141
 142        dev_vdbg(&ch->phy->dev, "%s: %08x, %d\n", __func__, val, vbus);
 143        if (vbus)
 144                val |= USB2_ADPCTRL_DRVVBUS;
 145        else
 146                val &= ~USB2_ADPCTRL_DRVVBUS;
 147        writel(val, usb2_base + USB2_ADPCTRL);
 148}
 149
 150static void rcar_gen3_init_for_host(struct rcar_gen3_chan *ch)
 151{
 152        rcar_gen3_set_linectrl(ch, 1, 1);
 153        rcar_gen3_set_host_mode(ch, 1);
 154        rcar_gen3_enable_vbus_ctrl(ch, 1);
 155
 156        ch->extcon_host = true;
 157        schedule_work(&ch->work);
 158}
 159
 160static void rcar_gen3_init_for_peri(struct rcar_gen3_chan *ch)
 161{
 162        rcar_gen3_set_linectrl(ch, 0, 1);
 163        rcar_gen3_set_host_mode(ch, 0);
 164        rcar_gen3_enable_vbus_ctrl(ch, 0);
 165
 166        ch->extcon_host = false;
 167        schedule_work(&ch->work);
 168}
 169
 170static void rcar_gen3_init_for_b_host(struct rcar_gen3_chan *ch)
 171{
 172        void __iomem *usb2_base = ch->base;
 173        u32 val;
 174
 175        val = readl(usb2_base + USB2_LINECTRL1);
 176        writel(val | USB2_LINECTRL1_OPMODE_NODRV, usb2_base + USB2_LINECTRL1);
 177
 178        rcar_gen3_set_linectrl(ch, 1, 1);
 179        rcar_gen3_set_host_mode(ch, 1);
 180        rcar_gen3_enable_vbus_ctrl(ch, 0);
 181
 182        val = readl(usb2_base + USB2_LINECTRL1);
 183        writel(val & ~USB2_LINECTRL1_OPMODE_NODRV, usb2_base + USB2_LINECTRL1);
 184}
 185
 186static void rcar_gen3_init_for_a_peri(struct rcar_gen3_chan *ch)
 187{
 188        rcar_gen3_set_linectrl(ch, 0, 1);
 189        rcar_gen3_set_host_mode(ch, 0);
 190        rcar_gen3_enable_vbus_ctrl(ch, 1);
 191}
 192
 193static void rcar_gen3_init_from_a_peri_to_a_host(struct rcar_gen3_chan *ch)
 194{
 195        void __iomem *usb2_base = ch->base;
 196        u32 val;
 197
 198        val = readl(usb2_base + USB2_OBINTEN);
 199        writel(val & ~USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
 200
 201        rcar_gen3_enable_vbus_ctrl(ch, 0);
 202        rcar_gen3_init_for_host(ch);
 203
 204        writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
 205}
 206
 207static bool rcar_gen3_check_id(struct rcar_gen3_chan *ch)
 208{
 209        return !!(readl(ch->base + USB2_ADPCTRL) & USB2_ADPCTRL_IDDIG);
 210}
 211
 212static void rcar_gen3_device_recognition(struct rcar_gen3_chan *ch)
 213{
 214        if (!rcar_gen3_check_id(ch))
 215                rcar_gen3_init_for_host(ch);
 216        else
 217                rcar_gen3_init_for_peri(ch);
 218}
 219
 220static bool rcar_gen3_is_host(struct rcar_gen3_chan *ch)
 221{
 222        return !(readl(ch->base + USB2_COMMCTRL) & USB2_COMMCTRL_OTG_PERI);
 223}
 224
 225static enum phy_mode rcar_gen3_get_phy_mode(struct rcar_gen3_chan *ch)
 226{
 227        if (rcar_gen3_is_host(ch))
 228                return PHY_MODE_USB_HOST;
 229
 230        return PHY_MODE_USB_DEVICE;
 231}
 232
 233static ssize_t role_store(struct device *dev, struct device_attribute *attr,
 234                          const char *buf, size_t count)
 235{
 236        struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
 237        bool is_b_device;
 238        enum phy_mode cur_mode, new_mode;
 239
 240        if (!ch->has_otg_pins || !ch->phy->init_count)
 241                return -EIO;
 242
 243        if (!strncmp(buf, "host", strlen("host")))
 244                new_mode = PHY_MODE_USB_HOST;
 245        else if (!strncmp(buf, "peripheral", strlen("peripheral")))
 246                new_mode = PHY_MODE_USB_DEVICE;
 247        else
 248                return -EINVAL;
 249
 250        /* is_b_device: true is B-Device. false is A-Device. */
 251        is_b_device = rcar_gen3_check_id(ch);
 252        cur_mode = rcar_gen3_get_phy_mode(ch);
 253
 254        /* If current and new mode is the same, this returns the error */
 255        if (cur_mode == new_mode)
 256                return -EINVAL;
 257
 258        if (new_mode == PHY_MODE_USB_HOST) { /* And is_host must be false */
 259                if (!is_b_device)       /* A-Peripheral */
 260                        rcar_gen3_init_from_a_peri_to_a_host(ch);
 261                else                    /* B-Peripheral */
 262                        rcar_gen3_init_for_b_host(ch);
 263        } else {                        /* And is_host must be true */
 264                if (!is_b_device)       /* A-Host */
 265                        rcar_gen3_init_for_a_peri(ch);
 266                else                    /* B-Host */
 267                        rcar_gen3_init_for_peri(ch);
 268        }
 269
 270        return count;
 271}
 272
 273static ssize_t role_show(struct device *dev, struct device_attribute *attr,
 274                         char *buf)
 275{
 276        struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
 277
 278        if (!ch->has_otg_pins || !ch->phy->init_count)
 279                return -EIO;
 280
 281        return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" :
 282                                                            "peripheral");
 283}
 284static DEVICE_ATTR_RW(role);
 285
 286static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
 287{
 288        void __iomem *usb2_base = ch->base;
 289        u32 val;
 290
 291        val = readl(usb2_base + USB2_VBCTRL);
 292        writel(val | USB2_VBCTRL_DRVVBUSSEL, usb2_base + USB2_VBCTRL);
 293        writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
 294        val = readl(usb2_base + USB2_OBINTEN);
 295        writel(val | USB2_OBINT_BITS, usb2_base + USB2_OBINTEN);
 296        val = readl(usb2_base + USB2_ADPCTRL);
 297        writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
 298        val = readl(usb2_base + USB2_LINECTRL1);
 299        rcar_gen3_set_linectrl(ch, 0, 0);
 300        writel(val | USB2_LINECTRL1_DPRPD_EN | USB2_LINECTRL1_DMRPD_EN,
 301               usb2_base + USB2_LINECTRL1);
 302
 303        rcar_gen3_device_recognition(ch);
 304}
 305
 306static int rcar_gen3_phy_usb2_init(struct phy *p)
 307{
 308        struct rcar_gen3_chan *channel = phy_get_drvdata(p);
 309        void __iomem *usb2_base = channel->base;
 310
 311        /* Initialize USB2 part */
 312        writel(USB2_INT_ENABLE_INIT, usb2_base + USB2_INT_ENABLE);
 313        writel(USB2_SPD_RSM_TIMSET_INIT, usb2_base + USB2_SPD_RSM_TIMSET);
 314        writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
 315
 316        /* Initialize otg part */
 317        if (channel->has_otg_pins)
 318                rcar_gen3_init_otg(channel);
 319
 320        return 0;
 321}
 322
 323static int rcar_gen3_phy_usb2_exit(struct phy *p)
 324{
 325        struct rcar_gen3_chan *channel = phy_get_drvdata(p);
 326
 327        writel(0, channel->base + USB2_INT_ENABLE);
 328
 329        return 0;
 330}
 331
 332static int rcar_gen3_phy_usb2_power_on(struct phy *p)
 333{
 334        struct rcar_gen3_chan *channel = phy_get_drvdata(p);
 335        void __iomem *usb2_base = channel->base;
 336        u32 val;
 337        int ret;
 338
 339        if (channel->vbus) {
 340                ret = regulator_enable(channel->vbus);
 341                if (ret)
 342                        return ret;
 343        }
 344
 345        val = readl(usb2_base + USB2_USBCTR);
 346        val |= USB2_USBCTR_PLL_RST;
 347        writel(val, usb2_base + USB2_USBCTR);
 348        val &= ~USB2_USBCTR_PLL_RST;
 349        writel(val, usb2_base + USB2_USBCTR);
 350
 351        return 0;
 352}
 353
 354static int rcar_gen3_phy_usb2_power_off(struct phy *p)
 355{
 356        struct rcar_gen3_chan *channel = phy_get_drvdata(p);
 357        int ret = 0;
 358
 359        if (channel->vbus)
 360                ret = regulator_disable(channel->vbus);
 361
 362        return ret;
 363}
 364
 365static const struct phy_ops rcar_gen3_phy_usb2_ops = {
 366        .init           = rcar_gen3_phy_usb2_init,
 367        .exit           = rcar_gen3_phy_usb2_exit,
 368        .power_on       = rcar_gen3_phy_usb2_power_on,
 369        .power_off      = rcar_gen3_phy_usb2_power_off,
 370        .owner          = THIS_MODULE,
 371};
 372
 373static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
 374{
 375        struct rcar_gen3_chan *ch = _ch;
 376        void __iomem *usb2_base = ch->base;
 377        u32 status = readl(usb2_base + USB2_OBINTSTA);
 378        irqreturn_t ret = IRQ_NONE;
 379
 380        if (status & USB2_OBINT_BITS) {
 381                dev_vdbg(&ch->phy->dev, "%s: %08x\n", __func__, status);
 382                writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
 383                rcar_gen3_device_recognition(ch);
 384                ret = IRQ_HANDLED;
 385        }
 386
 387        return ret;
 388}
 389
 390static const struct of_device_id rcar_gen3_phy_usb2_match_table[] = {
 391        {
 392                .compatible = "renesas,usb2-phy-r8a7795",
 393                .data = (void *)RCAR_GEN3_PHY_HAS_DEDICATED_PINS,
 394        },
 395        {
 396                .compatible = "renesas,usb2-phy-r8a7796",
 397                .data = (void *)RCAR_GEN3_PHY_HAS_DEDICATED_PINS,
 398        },
 399        {
 400                .compatible = "renesas,usb2-phy-r8a77965",
 401                .data = (void *)RCAR_GEN3_PHY_HAS_DEDICATED_PINS,
 402        },
 403        {
 404                .compatible = "renesas,rcar-gen3-usb2-phy",
 405        },
 406        { }
 407};
 408MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb2_match_table);
 409
 410static const unsigned int rcar_gen3_phy_cable[] = {
 411        EXTCON_USB,
 412        EXTCON_USB_HOST,
 413        EXTCON_NONE,
 414};
 415
 416static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
 417{
 418        struct device *dev = &pdev->dev;
 419        struct rcar_gen3_chan *channel;
 420        struct phy_provider *provider;
 421        struct resource *res;
 422        int irq, ret = 0;
 423
 424        if (!dev->of_node) {
 425                dev_err(dev, "This driver needs device tree\n");
 426                return -EINVAL;
 427        }
 428
 429        channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL);
 430        if (!channel)
 431                return -ENOMEM;
 432
 433        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 434        channel->base = devm_ioremap_resource(dev, res);
 435        if (IS_ERR(channel->base))
 436                return PTR_ERR(channel->base);
 437
 438        /* call request_irq for OTG */
 439        irq = platform_get_irq(pdev, 0);
 440        if (irq >= 0) {
 441                INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
 442                irq = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
 443                                       IRQF_SHARED, dev_name(dev), channel);
 444                if (irq < 0)
 445                        dev_err(dev, "No irq handler (%d)\n", irq);
 446        }
 447
 448        if (of_usb_get_dr_mode_by_phy(dev->of_node, 0) == USB_DR_MODE_OTG) {
 449                int ret;
 450
 451                channel->has_otg_pins = (uintptr_t)of_device_get_match_data(dev);
 452                channel->extcon = devm_extcon_dev_allocate(dev,
 453                                                        rcar_gen3_phy_cable);
 454                if (IS_ERR(channel->extcon))
 455                        return PTR_ERR(channel->extcon);
 456
 457                ret = devm_extcon_dev_register(dev, channel->extcon);
 458                if (ret < 0) {
 459                        dev_err(dev, "Failed to register extcon\n");
 460                        return ret;
 461                }
 462        }
 463
 464        /*
 465         * devm_phy_create() will call pm_runtime_enable(&phy->dev);
 466         * And then, phy-core will manage runtime pm for this device.
 467         */
 468        pm_runtime_enable(dev);
 469        channel->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb2_ops);
 470        if (IS_ERR(channel->phy)) {
 471                dev_err(dev, "Failed to create USB2 PHY\n");
 472                ret = PTR_ERR(channel->phy);
 473                goto error;
 474        }
 475
 476        channel->vbus = devm_regulator_get_optional(dev, "vbus");
 477        if (IS_ERR(channel->vbus)) {
 478                if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) {
 479                        ret = PTR_ERR(channel->vbus);
 480                        goto error;
 481                }
 482                channel->vbus = NULL;
 483        }
 484
 485        platform_set_drvdata(pdev, channel);
 486        phy_set_drvdata(channel->phy, channel);
 487
 488        provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
 489        if (IS_ERR(provider)) {
 490                dev_err(dev, "Failed to register PHY provider\n");
 491                ret = PTR_ERR(provider);
 492                goto error;
 493        } else if (channel->has_otg_pins) {
 494                int ret;
 495
 496                ret = device_create_file(dev, &dev_attr_role);
 497                if (ret < 0)
 498                        goto error;
 499        }
 500
 501        return 0;
 502
 503error:
 504        pm_runtime_disable(dev);
 505
 506        return ret;
 507}
 508
 509static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev)
 510{
 511        struct rcar_gen3_chan *channel = platform_get_drvdata(pdev);
 512
 513        if (channel->has_otg_pins)
 514                device_remove_file(&pdev->dev, &dev_attr_role);
 515
 516        pm_runtime_disable(&pdev->dev);
 517
 518        return 0;
 519};
 520
 521static struct platform_driver rcar_gen3_phy_usb2_driver = {
 522        .driver = {
 523                .name           = "phy_rcar_gen3_usb2",
 524                .of_match_table = rcar_gen3_phy_usb2_match_table,
 525        },
 526        .probe  = rcar_gen3_phy_usb2_probe,
 527        .remove = rcar_gen3_phy_usb2_remove,
 528};
 529module_platform_driver(rcar_gen3_phy_usb2_driver);
 530
 531MODULE_LICENSE("GPL v2");
 532MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 2.0 PHY");
 533MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
 534