linux/drivers/usb/host/ehci-exynos.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Samsung Exynos USB HOST EHCI Controller
   4 *
   5 * Copyright (C) 2011 Samsung Electronics Co.Ltd
   6 * Author: Jingoo Han <jg1.han@samsung.com>
   7 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
   8 */
   9
  10#include <linux/clk.h>
  11#include <linux/dma-mapping.h>
  12#include <linux/io.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/of.h>
  16#include <linux/of_gpio.h>
  17#include <linux/phy/phy.h>
  18#include <linux/platform_device.h>
  19#include <linux/usb.h>
  20#include <linux/usb/hcd.h>
  21
  22#include "ehci.h"
  23
  24#define DRIVER_DESC "EHCI Exynos driver"
  25
  26#define EHCI_INSNREG00(base)                    (base + 0x90)
  27#define EHCI_INSNREG00_ENA_INCR16               (0x1 << 25)
  28#define EHCI_INSNREG00_ENA_INCR8                (0x1 << 24)
  29#define EHCI_INSNREG00_ENA_INCR4                (0x1 << 23)
  30#define EHCI_INSNREG00_ENA_INCRX_ALIGN          (0x1 << 22)
  31#define EHCI_INSNREG00_ENABLE_DMA_BURST \
  32        (EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 | \
  33         EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN)
  34
  35static const char hcd_name[] = "ehci-exynos";
  36static struct hc_driver __read_mostly exynos_ehci_hc_driver;
  37
  38#define PHY_NUMBER 3
  39
  40struct exynos_ehci_hcd {
  41        struct clk *clk;
  42        struct device_node *of_node;
  43        struct phy *phy[PHY_NUMBER];
  44        bool legacy_phy;
  45};
  46
  47#define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv)
  48
  49static int exynos_ehci_get_phy(struct device *dev,
  50                                struct exynos_ehci_hcd *exynos_ehci)
  51{
  52        struct device_node *child;
  53        struct phy *phy;
  54        int phy_number, num_phys;
  55        int ret;
  56
  57        /* Get PHYs for the controller */
  58        num_phys = of_count_phandle_with_args(dev->of_node, "phys",
  59                                              "#phy-cells");
  60        for (phy_number = 0; phy_number < num_phys; phy_number++) {
  61                phy = devm_of_phy_get_by_index(dev, dev->of_node, phy_number);
  62                if (IS_ERR(phy))
  63                        return PTR_ERR(phy);
  64                exynos_ehci->phy[phy_number] = phy;
  65        }
  66        if (num_phys > 0)
  67                return 0;
  68
  69        /* Get PHYs using legacy bindings */
  70        for_each_available_child_of_node(dev->of_node, child) {
  71                ret = of_property_read_u32(child, "reg", &phy_number);
  72                if (ret) {
  73                        dev_err(dev, "Failed to parse device tree\n");
  74                        of_node_put(child);
  75                        return ret;
  76                }
  77
  78                if (phy_number >= PHY_NUMBER) {
  79                        dev_err(dev, "Invalid number of PHYs\n");
  80                        of_node_put(child);
  81                        return -EINVAL;
  82                }
  83
  84                phy = devm_of_phy_get(dev, child, NULL);
  85                exynos_ehci->phy[phy_number] = phy;
  86                if (IS_ERR(phy)) {
  87                        ret = PTR_ERR(phy);
  88                        if (ret == -EPROBE_DEFER) {
  89                                of_node_put(child);
  90                                return ret;
  91                        } else if (ret != -ENOSYS && ret != -ENODEV) {
  92                                dev_err(dev,
  93                                        "Error retrieving usb2 phy: %d\n", ret);
  94                                of_node_put(child);
  95                                return ret;
  96                        }
  97                }
  98        }
  99
 100        exynos_ehci->legacy_phy = true;
 101        return 0;
 102}
 103
 104static int exynos_ehci_phy_enable(struct device *dev)
 105{
 106        struct usb_hcd *hcd = dev_get_drvdata(dev);
 107        struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
 108        int i;
 109        int ret = 0;
 110
 111        for (i = 0; ret == 0 && i < PHY_NUMBER; i++)
 112                if (!IS_ERR(exynos_ehci->phy[i]))
 113                        ret = phy_power_on(exynos_ehci->phy[i]);
 114        if (ret)
 115                for (i--; i >= 0; i--)
 116                        if (!IS_ERR(exynos_ehci->phy[i]))
 117                                phy_power_off(exynos_ehci->phy[i]);
 118
 119        return ret;
 120}
 121
 122static void exynos_ehci_phy_disable(struct device *dev)
 123{
 124        struct usb_hcd *hcd = dev_get_drvdata(dev);
 125        struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
 126        int i;
 127
 128        for (i = 0; i < PHY_NUMBER; i++)
 129                if (!IS_ERR(exynos_ehci->phy[i]))
 130                        phy_power_off(exynos_ehci->phy[i]);
 131}
 132
 133static void exynos_setup_vbus_gpio(struct device *dev)
 134{
 135        int err;
 136        int gpio;
 137
 138        if (!dev->of_node)
 139                return;
 140
 141        gpio = of_get_named_gpio(dev->of_node, "samsung,vbus-gpio", 0);
 142        if (!gpio_is_valid(gpio))
 143                return;
 144
 145        err = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_HIGH,
 146                                    "ehci_vbus_gpio");
 147        if (err)
 148                dev_err(dev, "can't request ehci vbus gpio %d", gpio);
 149}
 150
 151static int exynos_ehci_probe(struct platform_device *pdev)
 152{
 153        struct exynos_ehci_hcd *exynos_ehci;
 154        struct usb_hcd *hcd;
 155        struct ehci_hcd *ehci;
 156        struct resource *res;
 157        int irq;
 158        int err;
 159
 160        /*
 161         * Right now device-tree probed devices don't get dma_mask set.
 162         * Since shared usb code relies on it, set it here for now.
 163         * Once we move to full device tree support this will vanish off.
 164         */
 165        err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
 166        if (err)
 167                return err;
 168
 169        exynos_setup_vbus_gpio(&pdev->dev);
 170
 171        hcd = usb_create_hcd(&exynos_ehci_hc_driver,
 172                             &pdev->dev, dev_name(&pdev->dev));
 173        if (!hcd) {
 174                dev_err(&pdev->dev, "Unable to create HCD\n");
 175                return -ENOMEM;
 176        }
 177        exynos_ehci = to_exynos_ehci(hcd);
 178
 179        err = exynos_ehci_get_phy(&pdev->dev, exynos_ehci);
 180        if (err)
 181                goto fail_clk;
 182
 183        exynos_ehci->clk = devm_clk_get(&pdev->dev, "usbhost");
 184
 185        if (IS_ERR(exynos_ehci->clk)) {
 186                dev_err(&pdev->dev, "Failed to get usbhost clock\n");
 187                err = PTR_ERR(exynos_ehci->clk);
 188                goto fail_clk;
 189        }
 190
 191        err = clk_prepare_enable(exynos_ehci->clk);
 192        if (err)
 193                goto fail_clk;
 194
 195        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 196        hcd->regs = devm_ioremap_resource(&pdev->dev, res);
 197        if (IS_ERR(hcd->regs)) {
 198                err = PTR_ERR(hcd->regs);
 199                goto fail_io;
 200        }
 201
 202        hcd->rsrc_start = res->start;
 203        hcd->rsrc_len = resource_size(res);
 204
 205        irq = platform_get_irq(pdev, 0);
 206        if (irq < 0) {
 207                err = irq;
 208                goto fail_io;
 209        }
 210
 211        err = exynos_ehci_phy_enable(&pdev->dev);
 212        if (err) {
 213                dev_err(&pdev->dev, "Failed to enable USB phy\n");
 214                goto fail_io;
 215        }
 216
 217        ehci = hcd_to_ehci(hcd);
 218        ehci->caps = hcd->regs;
 219
 220        /*
 221         * Workaround: reset of_node pointer to avoid conflict between legacy
 222         * Exynos EHCI port subnodes and generic USB device bindings
 223         */
 224        exynos_ehci->of_node = pdev->dev.of_node;
 225        if (exynos_ehci->legacy_phy)
 226                pdev->dev.of_node = NULL;
 227
 228        /* DMA burst Enable */
 229        writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
 230
 231        err = usb_add_hcd(hcd, irq, IRQF_SHARED);
 232        if (err) {
 233                dev_err(&pdev->dev, "Failed to add USB HCD\n");
 234                goto fail_add_hcd;
 235        }
 236        device_wakeup_enable(hcd->self.controller);
 237
 238        platform_set_drvdata(pdev, hcd);
 239
 240        return 0;
 241
 242fail_add_hcd:
 243        exynos_ehci_phy_disable(&pdev->dev);
 244        pdev->dev.of_node = exynos_ehci->of_node;
 245fail_io:
 246        clk_disable_unprepare(exynos_ehci->clk);
 247fail_clk:
 248        usb_put_hcd(hcd);
 249        return err;
 250}
 251
 252static int exynos_ehci_remove(struct platform_device *pdev)
 253{
 254        struct usb_hcd *hcd = platform_get_drvdata(pdev);
 255        struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
 256
 257        pdev->dev.of_node = exynos_ehci->of_node;
 258
 259        usb_remove_hcd(hcd);
 260
 261        exynos_ehci_phy_disable(&pdev->dev);
 262
 263        clk_disable_unprepare(exynos_ehci->clk);
 264
 265        usb_put_hcd(hcd);
 266
 267        return 0;
 268}
 269
 270#ifdef CONFIG_PM
 271static int exynos_ehci_suspend(struct device *dev)
 272{
 273        struct usb_hcd *hcd = dev_get_drvdata(dev);
 274        struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
 275
 276        bool do_wakeup = device_may_wakeup(dev);
 277        int rc;
 278
 279        rc = ehci_suspend(hcd, do_wakeup);
 280        if (rc)
 281                return rc;
 282
 283        exynos_ehci_phy_disable(dev);
 284
 285        clk_disable_unprepare(exynos_ehci->clk);
 286
 287        return rc;
 288}
 289
 290static int exynos_ehci_resume(struct device *dev)
 291{
 292        struct usb_hcd *hcd = dev_get_drvdata(dev);
 293        struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd);
 294        int ret;
 295
 296        ret = clk_prepare_enable(exynos_ehci->clk);
 297        if (ret)
 298                return ret;
 299
 300        ret = exynos_ehci_phy_enable(dev);
 301        if (ret) {
 302                dev_err(dev, "Failed to enable USB phy\n");
 303                clk_disable_unprepare(exynos_ehci->clk);
 304                return ret;
 305        }
 306
 307        /* DMA burst Enable */
 308        writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs));
 309
 310        ehci_resume(hcd, false);
 311        return 0;
 312}
 313#else
 314#define exynos_ehci_suspend     NULL
 315#define exynos_ehci_resume      NULL
 316#endif
 317
 318static const struct dev_pm_ops exynos_ehci_pm_ops = {
 319        .suspend        = exynos_ehci_suspend,
 320        .resume         = exynos_ehci_resume,
 321};
 322
 323#ifdef CONFIG_OF
 324static const struct of_device_id exynos_ehci_match[] = {
 325        { .compatible = "samsung,exynos4210-ehci" },
 326        {},
 327};
 328MODULE_DEVICE_TABLE(of, exynos_ehci_match);
 329#endif
 330
 331static struct platform_driver exynos_ehci_driver = {
 332        .probe          = exynos_ehci_probe,
 333        .remove         = exynos_ehci_remove,
 334        .shutdown       = usb_hcd_platform_shutdown,
 335        .driver = {
 336                .name   = "exynos-ehci",
 337                .pm     = &exynos_ehci_pm_ops,
 338                .of_match_table = of_match_ptr(exynos_ehci_match),
 339        }
 340};
 341static const struct ehci_driver_overrides exynos_overrides __initconst = {
 342        .extra_priv_size = sizeof(struct exynos_ehci_hcd),
 343};
 344
 345static int __init ehci_exynos_init(void)
 346{
 347        if (usb_disabled())
 348                return -ENODEV;
 349
 350        pr_info("%s: " DRIVER_DESC "\n", hcd_name);
 351        ehci_init_driver(&exynos_ehci_hc_driver, &exynos_overrides);
 352        return platform_driver_register(&exynos_ehci_driver);
 353}
 354module_init(ehci_exynos_init);
 355
 356static void __exit ehci_exynos_cleanup(void)
 357{
 358        platform_driver_unregister(&exynos_ehci_driver);
 359}
 360module_exit(ehci_exynos_cleanup);
 361
 362MODULE_DESCRIPTION(DRIVER_DESC);
 363MODULE_ALIAS("platform:exynos-ehci");
 364MODULE_AUTHOR("Jingoo Han");
 365MODULE_AUTHOR("Joonyoung Shim");
 366MODULE_LICENSE("GPL v2");
 367