From patchwork Tue May 26 03:33:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Wang X-Patchwork-Id: 1234 Return-Path: X-Original-To: linux-amarula@patchwork.amarulasolutions.com Delivered-To: linux-amarula@patchwork.amarulasolutions.com Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by ganimede.amarulasolutions.com (Postfix) with ESMTPS id CCC7D3F08B for ; Tue, 26 May 2020 05:34:32 +0200 (CEST) Received: by mail-pg1-f197.google.com with SMTP id b131sf15574558pga.9 for ; Mon, 25 May 2020 20:34:32 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1590464071; cv=pass; d=google.com; s=arc-20160816; b=HGstTO0PNcAi4rQZeBeOqVS0YGsz0kPgch2FkdhNNr4HTCTX6QIRiJH7CyhuErYdpd dkrnTa71cYTXB5oEIx9fep0nXJ9Z/VEwjdEkqhtW8ML2LB728t9NZSwe+/vnbvJIxkXd 37rlgFLF7TdY0LdEucg3bhfyJHb+HZBxjulR15DfCI5cdEnb3LDfcSTdE2GHpST+lqzr 9TpDowap4WKYPE1o5s2iTCcCSA9NXX7g8HhMzYoNAW0EiiV1Br0IsLfw2+AMLaW4NATS Ov+DVPDdnt+K95p+g3hZuo8stuiyCbucZs/aY/oKS17hsb5yyXBYbjwvYemPd4cumj3l lqqg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-archive:list-help:list-post:list-id :mailing-list:precedence:references:in-reply-to:message-id:date :subject:cc:to:from:mime-version:sender:dkim-signature; bh=5TUqAJgeha8/v5lRC2L+bKWQtKEc3HHXPdef5JBPsvc=; b=H3CrS7s1fJaAo8iHqN/ugi4TCGOpLmmWNDwvklhS2dDtHBFrFZgMIMtNsLonBy2w3i 3H/behapBVp82tFzLnhjoQPFGrcsL+tihj9xzKc95YtkhaqduwPwHLY8/xxihBgFWb/u AC/1F0oK8CBXJwPkuasufx4g5AHjLWUty40A4xTDm9joebwbuKnd4aUuf6M57E4PXOCM YMV311jZCqNNKZIXJPPUqe+e1Tmo/w/xpVGEMeP8bVPmUc/OjGCNEApGcyQDsihewjs/ M8K88/3a3ifyrybWEwMFbTkJXx9VMxW8OlTnqo1b1ZdclxepRNIXpvesQg/77hgPVxEA 7dUg== ARC-Authentication-Results: i=2; mx.google.com; spf=pass (google.com: domain of frank.wang@rock-chips.com designates 211.157.147.131 as permitted sender) smtp.mailfrom=frank.wang@rock-chips.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=sender:mime-version:from:to:cc:subject:date:message-id:in-reply-to :references:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:list-post:list-help:list-archive :list-unsubscribe; bh=5TUqAJgeha8/v5lRC2L+bKWQtKEc3HHXPdef5JBPsvc=; b=o6fjWPOx1h60XpnYFN5mdIa9mGxwtyEouSi/vTcalHq/dpndylufh1VyoygSBbWdBh +g+irq47Okaut6jnSPx7KwsxID9FkudRSxNJfmof/tYJvSorK5iD17Zczx6z/sT3jtPy Xt7IfgGXxX6HV27Tec9BCN85yHexewZDh3SBU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:mime-version:from:to:cc:subject:date :message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :x-spam-checked-in-group:list-post:list-help:list-archive :list-unsubscribe; bh=5TUqAJgeha8/v5lRC2L+bKWQtKEc3HHXPdef5JBPsvc=; b=YiNE4YNKRbkijV+mlaPexJFd39Hah7hg7IVLhYwMJYyhqTiz3u4ndWZeNkmYbsd9Ep CtoxgWpDJQH3NL3pAV25UzouQj3Y/c6buWtIfvLp+OROzGReIIOzL4h1DSVsf1JrWbBq 5ZKoN9iBH3mpJ56Z9lW5m0dztoKlvKnpExbl6br3BFy+5lq8vogRjfFdtJEKgQS/ijPP 1BeGalRwhxnoCQk0A1phIh4UpXvcHRoW47YNuzuq4MukoA+1izuiqwgAbbjon6L9vCG/ 2SgweL420u7BgTrIq6DaZUyBAyL6UOjHxW868BLt8zwqtPyen150F3FOHUkRUcyR9c4S r+zw== Sender: linux-amarula@amarulasolutions.com X-Gm-Message-State: AOAM532NWhTnBUttGqn/opW1X+JCoMaECm/TXjL8Q+cgxqHLT3W2yYci +QGbT2SsEXE4kdjGrAEveo+o7nM1 X-Google-Smtp-Source: ABdhPJwLGK3T2B/dT97UFGBVXkKiHeiE6A8esDMBQbrmkx+d3T2H40aW862IUpy4/MtLAy9yxyJDXg== X-Received: by 2002:a17:90a:f0d8:: with SMTP id fa24mr23372073pjb.93.1590464071647; Mon, 25 May 2020 20:34:31 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: linux-amarula@amarulasolutions.com Received: by 2002:a17:902:a717:: with SMTP id w23ls4410071plq.7.gmail; Mon, 25 May 2020 20:34:31 -0700 (PDT) X-Received: by 2002:a17:90a:344c:: with SMTP id o70mr24991004pjb.23.1590464070962; Mon, 25 May 2020 20:34:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590464070; cv=none; d=google.com; s=arc-20160816; b=dTxk83TpqmEbFlFEBH055ahFz/pfaOvGstdWML65i0pe3xy9GtNi0WrUn8o8YR2P4H gwWOS0XvevuG+UFEGBgRJKZ35mTiRnCoGYYVAnPx0Nlmt4Vr/CO5XjC6+T9KmnkVa2Q5 PvOu0xT4InlA9jR1pdJIyihemMSNFIeDahqk5jC1W8LsVxw5WhkTxOF6KrSMNWSgUYvx 99ukh4/TaMk8/BgKDhZKbrPKnGyA/kypb1pTNApaHgsD502UyJpoVkDfSTYwX2qLMnGg /RC+X74YGT263AgF5t4vyi/ZTGx3mpvAcJe9cekkE7mR4KlJxs9ph/uOtIgPyrjWaFeD edUg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from; bh=Wh8zwjfFC0HsvpBCJSTi6ZUn/PRhD7KwgM3+Ww0etng=; b=uHEzC4c6Wr9mYuMfxIDjTeEEtbrgNUuh66FV0dYLlwNgGA0+RqHvr1cVpMmkPBGG9F 0J9xPZFnHUk/3DkUHrxJqG343xpbY2CxrQrqnfLw08ZRvItuA0awwXWN2IZ7LZQa1/rl Q1K+ZYjyXfva8NVA8YZq0ZaZ8c3lza7x8OuXPvmGVMufLlcVseChfRxPA7z5UJaHbgIU 4s4YKOouJGKQzECnGjWCqt+ML37ohqPoxeFFnzzubzoBnHtTGY/k0niRw9uq1FOdtUTi 616Ui70ZXKthdyjTMjnx+0qiFesf80MACCWLeBptuPxkdqqBcTE2qsjAjxVGO9EOf22d Fk5A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of frank.wang@rock-chips.com designates 211.157.147.131 as permitted sender) smtp.mailfrom=frank.wang@rock-chips.com Received: from lucky1.263xmail.com (lucky1.263xmail.com. [211.157.147.131]) by mx.google.com with ESMTPS id d8si15969608pll.43.2020.05.25.20.34.30 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 May 2020 20:34:30 -0700 (PDT) Received-SPF: pass (google.com: domain of frank.wang@rock-chips.com designates 211.157.147.131 as permitted sender) client-ip=211.157.147.131; Received: from localhost (unknown [192.168.167.8]) by lucky1.263xmail.com (Postfix) with ESMTP id 26C9AA7556; Tue, 26 May 2020 11:33:59 +0800 (CST) X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-ADDR-CHECKED4: 1 X-ANTISPAM-LEVEL: 2 X-ABS-CHECKED: 0 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (postfix) whith ESMTP id P21206T140696195421952S1590464037437993_; Tue, 26 May 2020 11:33:59 +0800 (CST) X-IP-DOMAINF: 1 X-UNIQUE-TAG: <727fcfa8ca40f3f2fd2d8a63cec33c78> X-RL-SENDER: frank.wang@rock-chips.com X-SENDER: wmc@rock-chips.com X-LOGIN-NAME: frank.wang@rock-chips.com X-FST-TO: heiko@sntech.de X-SENDER-IP: 58.22.7.114 X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 X-System-Flag: 0 From: Frank Wang To: heiko@sntech.de, marex@denx.de, bmeng.cn@gmail.com, philipp.tomsich@theobroma-systems.com, klaus.goger@theobroma-systems.com, jagan@amarulasolutions.com, sjg@chromium.org, kever.yang@rock-chips.com Cc: u-boot@lists.denx.de, linux-rockchip@lists.infradead.org, linux-amarula@amarulasolutions.com, marek.belisko@gmail.com, william.wu@rock-chips.com, jianing.ren@rock-chips.com, chenjh@rock-chips.com, wmc@rock-chips.com, Frank Wang Subject: [PATCH v6 05/16] phy: rockchip: Add Rockchip USB2PHY driver Date: Tue, 26 May 2020 11:33:44 +0800 Message-Id: <20200526033355.20147-1-frank.wang@rock-chips.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200526033220.20047-1-frank.wang@rock-chips.com> References: <20200526033220.20047-1-frank.wang@rock-chips.com> X-Original-Sender: frank.wang@rock-chips.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of frank.wang@rock-chips.com designates 211.157.147.131 as permitted sender) smtp.mailfrom=frank.wang@rock-chips.com Content-Type: text/plain; charset="UTF-8" Precedence: list Mailing-list: list linux-amarula@amarulasolutions.com; contact linux-amarula+owners@amarulasolutions.com List-ID: X-Spam-Checked-In-Group: linux-amarula@amarulasolutions.com X-Google-Group-Id: 476853432473 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Jagan Teki Add Rockchip USB2PHY driver with initial support. This will help to use it for EHCI controller in host mode, and USB 3.0 controller in otg mode. More functionality like charge, vbus detection will add it in future changes. Signed-off-by: Jagan Teki Signed-off-by: Frank Wang Reviewed-by: Kever Yang --- drivers/Makefile | 1 + drivers/phy/Kconfig | 1 + drivers/phy/rockchip/Kconfig | 14 + drivers/phy/rockchip/Makefile | 6 + drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 312 ++++++++++++++++++ 5 files changed, 334 insertions(+) create mode 100644 drivers/phy/rockchip/Kconfig create mode 100644 drivers/phy/rockchip/Makefile create mode 100644 drivers/phy/rockchip/phy-rockchip-inno-usb2.c diff --git a/drivers/Makefile b/drivers/Makefile index 4208750428..94e8c5da17 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -91,6 +91,7 @@ obj-y += dfu/ obj-$(CONFIG_PCH) += pch/ obj-y += phy/allwinner/ obj-y += phy/marvell/ +obj-y += phy/rockchip/ obj-y += rtc/ obj-y += scsi/ obj-y += sound/ diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 1e38c8741f..9c775107e9 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -225,4 +225,5 @@ config PHY_MTK_TPHY multi-ports is first version, otherwise is second veriosn, so you can easily distinguish them by banks layout. +source "drivers/phy/rockchip/Kconfig" endmenu diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig new file mode 100644 index 0000000000..d73ac695e1 --- /dev/null +++ b/drivers/phy/rockchip/Kconfig @@ -0,0 +1,14 @@ +# +# Phy drivers for Rockchip platforms +# + +menu "Rockchip PHY driver" + +config PHY_ROCKCHIP_INNO_USB2 + bool "Rockchip INNO USB2PHY Driver" + depends on ARCH_ROCKCHIP + select PHY + help + Support for Rockchip USB2.0 PHY with Innosilicon IP block. + +endmenu diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile new file mode 100644 index 0000000000..9b0cbc6acf --- /dev/null +++ b/drivers/phy/rockchip/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2020 Amarula Solutions(India) +# + +obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c new file mode 100644 index 0000000000..c5ea6ca31f --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Rockchip USB2.0 PHY with Innosilicon IP block driver + * + * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd + * Copyright (C) 2020 Amarula Solutions(India) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define usleep_range(a, b) udelay((b)) +#define BIT_WRITEABLE_SHIFT 16 + +enum rockchip_usb2phy_port_id { + USB2PHY_PORT_OTG, + USB2PHY_PORT_HOST, + USB2PHY_NUM_PORTS, +}; + +struct usb2phy_reg { + unsigned int offset; + unsigned int bitend; + unsigned int bitstart; + unsigned int disable; + unsigned int enable; +}; + +struct rockchip_usb2phy_port_cfg { + struct usb2phy_reg phy_sus; + struct usb2phy_reg bvalid_det_en; + struct usb2phy_reg bvalid_det_st; + struct usb2phy_reg bvalid_det_clr; + struct usb2phy_reg ls_det_en; + struct usb2phy_reg ls_det_st; + struct usb2phy_reg ls_det_clr; + struct usb2phy_reg utmi_avalid; + struct usb2phy_reg utmi_bvalid; + struct usb2phy_reg utmi_ls; + struct usb2phy_reg utmi_hstdet; +}; + +struct rockchip_usb2phy_cfg { + unsigned int reg; + const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; +}; + +struct rockchip_usb2phy { + void *reg_base; + struct clk phyclk; + const struct rockchip_usb2phy_cfg *phy_cfg; +}; + +static inline int property_enable(void *reg_base, + const struct usb2phy_reg *reg, bool en) +{ + unsigned int val, mask, tmp; + + tmp = en ? reg->enable : reg->disable; + mask = GENMASK(reg->bitend, reg->bitstart); + val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); + + return writel(val, reg_base + reg->offset); +} + +static const +struct rockchip_usb2phy_port_cfg *us2phy_get_port(struct phy *phy) +{ + struct udevice *parent = dev_get_parent(phy->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg; + + return &phy_cfg->port_cfgs[phy->id]; +} + +static int rockchip_usb2phy_power_on(struct phy *phy) +{ + struct udevice *parent = dev_get_parent(phy->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy); + + property_enable(priv->reg_base, &port_cfg->phy_sus, false); + + /* waiting for the utmi_clk to become stable */ + usleep_range(1500, 2000); + + return 0; +} + +static int rockchip_usb2phy_power_off(struct phy *phy) +{ + struct udevice *parent = dev_get_parent(phy->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy); + + property_enable(priv->reg_base, &port_cfg->phy_sus, true); + + return 0; +} + +static int rockchip_usb2phy_init(struct phy *phy) +{ + struct udevice *parent = dev_get_parent(phy->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy); + int ret; + + ret = clk_enable(&priv->phyclk); + if (ret) { + dev_err(phy->dev, "failed to enable phyclk (ret=%d)\n", ret); + return ret; + } + + if (phy->id == USB2PHY_PORT_OTG) { + property_enable(priv->reg_base, &port_cfg->bvalid_det_clr, true); + property_enable(priv->reg_base, &port_cfg->bvalid_det_en, true); + } else if (phy->id == USB2PHY_PORT_HOST) { + property_enable(priv->reg_base, &port_cfg->bvalid_det_clr, true); + property_enable(priv->reg_base, &port_cfg->bvalid_det_en, true); + } + + return 0; +} + +static int rockchip_usb2phy_exit(struct phy *phy) +{ + struct udevice *parent = dev_get_parent(phy->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + + clk_disable(&priv->phyclk); + + return 0; +} + +static int rockchip_usb2phy_of_xlate(struct phy *phy, + struct ofnode_phandle_args *args) +{ + const char *name = phy->dev->name; + + if (!strcasecmp(name, "host-port")) + phy->id = USB2PHY_PORT_HOST; + else if (!strcasecmp(name, "otg-port")) + phy->id = USB2PHY_PORT_OTG; + else + dev_err(phy->dev, "improper %s device\n", name); + + return 0; +} + +static struct phy_ops rockchip_usb2phy_ops = { + .init = rockchip_usb2phy_init, + .exit = rockchip_usb2phy_exit, + .power_on = rockchip_usb2phy_power_on, + .power_off = rockchip_usb2phy_power_off, + .of_xlate = rockchip_usb2phy_of_xlate, +}; + +static int rockchip_usb2phy_probe(struct udevice *dev) +{ + struct rockchip_usb2phy *priv = dev_get_priv(dev); + const struct rockchip_usb2phy_cfg *phy_cfgs; + unsigned int reg; + int index, ret; + + priv->reg_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + if (IS_ERR(priv->reg_base)) + return PTR_ERR(priv->reg_base); + + ret = ofnode_read_u32(dev_ofnode(dev), "reg", ®); + if (ret) { + dev_err(dev, "failed to read reg property (ret = %d)\n", ret); + return ret; + } + + phy_cfgs = (const struct rockchip_usb2phy_cfg *) + dev_get_driver_data(dev); + if (!phy_cfgs) + return -EINVAL; + + /* find out a proper config which can be matched with dt. */ + index = 0; + while (phy_cfgs[index].reg) { + if (phy_cfgs[index].reg == reg) { + priv->phy_cfg = &phy_cfgs[index]; + break; + } + + ++index; + } + + if (!priv->phy_cfg) { + dev_err(dev, "failed find proper phy-cfg\n"); + return -EINVAL; + } + + ret = clk_get_by_name(dev, "phyclk", &priv->phyclk); + if (ret) { + dev_err(dev, "failed to get the phyclk (ret=%d)\n", ret); + return ret; + } + + return 0; +} + +static int rockchip_usb2phy_bind(struct udevice *dev) +{ + struct udevice *usb2phy_dev; + ofnode node; + const char *name; + int ret = 0; + + dev_for_each_subnode(node, dev) { + if (!ofnode_valid(node)) { + dev_info(dev, "subnode %s not found\n", dev->name); + return -ENXIO; + } + + name = ofnode_get_name(node); + dev_dbg(dev, "subnode %s\n", name); + + ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_port", + name, node, &usb2phy_dev); + if (ret) { + dev_err(dev, + "'%s' cannot bind 'rockchip_usb2phy_port'\n", name); + return ret; + } + } + + return ret; +} + +static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = { + { + .reg = 0xe450, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0xe454, 1, 0, 2, 1 }, + .bvalid_det_en = { 0xe3c0, 3, 3, 0, 1 }, + .bvalid_det_st = { 0xe3e0, 3, 3, 0, 1 }, + .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 }, + .utmi_avalid = { 0xe2ac, 7, 7, 0, 1 }, + .utmi_bvalid = { 0xe2ac, 12, 12, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0xe458, 1, 0, 0x2, 0x1 }, + .ls_det_en = { 0xe3c0, 6, 6, 0, 1 }, + .ls_det_st = { 0xe3e0, 6, 6, 0, 1 }, + .ls_det_clr = { 0xe3d0, 6, 6, 0, 1 }, + .utmi_ls = { 0xe2ac, 22, 21, 0, 1 }, + .utmi_hstdet = { 0xe2ac, 23, 23, 0, 1 } + } + }, + }, + { + .reg = 0xe460, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0xe464, 1, 0, 2, 1 }, + .bvalid_det_en = { 0xe3c0, 8, 8, 0, 1 }, + .bvalid_det_st = { 0xe3e0, 8, 8, 0, 1 }, + .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 }, + .utmi_avalid = { 0xe2ac, 10, 10, 0, 1 }, + .utmi_bvalid = { 0xe2ac, 16, 16, 0, 1 }, + }, + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0xe468, 1, 0, 0x2, 0x1 }, + .ls_det_en = { 0xe3c0, 11, 11, 0, 1 }, + .ls_det_st = { 0xe3e0, 11, 11, 0, 1 }, + .ls_det_clr = { 0xe3d0, 11, 11, 0, 1 }, + .utmi_ls = { 0xe2ac, 26, 25, 0, 1 }, + .utmi_hstdet = { 0xe2ac, 27, 27, 0, 1 } + } + }, + }, + { /* sentinel */ } +}; + +static const struct udevice_id rockchip_usb2phy_ids[] = { + { + .compatible = "rockchip,rk3399-usb2phy", + .data = (ulong)&rk3399_usb2phy_cfgs, + }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(rockchip_usb2phy_port) = { + .name = "rockchip_usb2phy_port", + .id = UCLASS_PHY, + .ops = &rockchip_usb2phy_ops, +}; + +U_BOOT_DRIVER(rockchip_usb2phy) = { + .name = "rockchip_usb2phy", + .id = UCLASS_PHY, + .of_match = rockchip_usb2phy_ids, + .probe = rockchip_usb2phy_probe, + .bind = rockchip_usb2phy_bind, + .priv_auto_alloc_size = sizeof(struct rockchip_usb2phy), +};