uboot/drivers/phy/phy-qcom-ipq4019-usb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2019 Sartura Ltd.
   4 *
   5 * Author: Robert Marko <robert.marko@sartura.hr>
   6 *
   7 * Based on Linux driver
   8 */
   9
  10#include <clk.h>
  11#include <common.h>
  12#include <dm.h>
  13#include <generic-phy.h>
  14#include <log.h>
  15#include <reset.h>
  16#include <asm/io.h>
  17#include <linux/delay.h>
  18
  19struct ipq4019_usb_phy {
  20        phys_addr_t                     base;
  21        struct reset_ctl        por_rst;
  22        struct reset_ctl        srif_rst;
  23};
  24
  25static int ipq4019_ss_phy_power_off(struct phy *_phy)
  26{
  27        struct ipq4019_usb_phy *phy = dev_get_priv(_phy->dev);
  28
  29        reset_assert(&phy->por_rst);
  30        mdelay(10);
  31
  32        return 0;
  33}
  34
  35static int ipq4019_ss_phy_power_on(struct phy *_phy)
  36{
  37        struct ipq4019_usb_phy *phy = dev_get_priv(_phy->dev);
  38
  39        ipq4019_ss_phy_power_off(_phy);
  40
  41        reset_deassert(&phy->por_rst);
  42
  43        return 0;
  44}
  45
  46static struct phy_ops ipq4019_usb_ss_phy_ops = {
  47        .power_on = ipq4019_ss_phy_power_on,
  48        .power_off = ipq4019_ss_phy_power_off,
  49};
  50
  51static int ipq4019_usb_ss_phy_probe(struct udevice *dev)
  52{
  53        struct ipq4019_usb_phy *phy = dev_get_priv(dev);
  54        int ret;
  55
  56        phy->base = dev_read_addr(dev);
  57        if (phy->base == FDT_ADDR_T_NONE)
  58                return -EINVAL;
  59
  60        ret = reset_get_by_name(dev, "por_rst", &phy->por_rst);
  61        if (ret)
  62                return ret;
  63
  64        return 0;
  65}
  66
  67static const struct udevice_id ipq4019_usb_ss_phy_ids[] = {
  68        { .compatible = "qcom,usb-ss-ipq4019-phy" },
  69        { }
  70};
  71
  72U_BOOT_DRIVER(ipq4019_usb_ss_phy) = {
  73        .name           = "ipq4019-usb-ss-phy",
  74        .id             = UCLASS_PHY,
  75        .of_match       = ipq4019_usb_ss_phy_ids,
  76        .ops            = &ipq4019_usb_ss_phy_ops,
  77        .probe          = ipq4019_usb_ss_phy_probe,
  78        .priv_auto      = sizeof(struct ipq4019_usb_phy),
  79};
  80
  81static int ipq4019_hs_phy_power_off(struct phy *_phy)
  82{
  83        struct ipq4019_usb_phy *phy = dev_get_priv(_phy->dev);
  84
  85        reset_assert(&phy->por_rst);
  86        mdelay(10);
  87
  88        reset_assert(&phy->srif_rst);
  89        mdelay(10);
  90
  91        return 0;
  92}
  93
  94static int ipq4019_hs_phy_power_on(struct phy *_phy)
  95{
  96        struct ipq4019_usb_phy *phy = dev_get_priv(_phy->dev);
  97
  98        ipq4019_hs_phy_power_off(_phy);
  99
 100        reset_deassert(&phy->srif_rst);
 101        mdelay(10);
 102
 103        reset_deassert(&phy->por_rst);
 104
 105        return 0;
 106}
 107
 108static struct phy_ops ipq4019_usb_hs_phy_ops = {
 109        .power_on = ipq4019_hs_phy_power_on,
 110        .power_off = ipq4019_hs_phy_power_off,
 111};
 112
 113static int ipq4019_usb_hs_phy_probe(struct udevice *dev)
 114{
 115        struct ipq4019_usb_phy *phy = dev_get_priv(dev);
 116        int ret;
 117
 118        phy->base = dev_read_addr(dev);
 119        if (phy->base == FDT_ADDR_T_NONE)
 120                return -EINVAL;
 121
 122        ret = reset_get_by_name(dev, "por_rst", &phy->por_rst);
 123        if (ret)
 124                return ret;
 125
 126        ret = reset_get_by_name(dev, "srif_rst", &phy->srif_rst);
 127        if (ret)
 128                return ret;
 129
 130        return 0;
 131}
 132
 133static const struct udevice_id ipq4019_usb_hs_phy_ids[] = {
 134        { .compatible = "qcom,usb-hs-ipq4019-phy" },
 135        { }
 136};
 137
 138U_BOOT_DRIVER(ipq4019_usb_hs_phy) = {
 139        .name           = "ipq4019-usb-hs-phy",
 140        .id             = UCLASS_PHY,
 141        .of_match       = ipq4019_usb_hs_phy_ids,
 142        .ops            = &ipq4019_usb_hs_phy_ops,
 143        .probe          = ipq4019_usb_hs_phy_probe,
 144        .priv_auto      = sizeof(struct ipq4019_usb_phy),
 145};
 146