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