Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2218891/?format=api
{ "id": 2218891, "url": "http://patchwork.ozlabs.org/api/patches/2218891/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/0e0acf7c-69d6-4f98-80b8-1fcb3dc859f4@gmail.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<0e0acf7c-69d6-4f98-80b8-1fcb3dc859f4@gmail.com>", "list_archive_url": null, "date": "2026-04-02T01:32:26", "name": "[RFC,v1,1/2] phy: rockchip: add phy-rockchip-usb2.c", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "4294b643cf522c2b84814f2300525f3d0dbe947a", "submitter": { "id": 75645, "url": "http://patchwork.ozlabs.org/api/people/75645/?format=api", "name": "Johan Jonker", "email": "jbx6244@gmail.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/0e0acf7c-69d6-4f98-80b8-1fcb3dc859f4@gmail.com/mbox/", "series": [ { "id": 498416, "url": "http://patchwork.ozlabs.org/api/series/498416/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=498416", "date": "2026-04-02T01:31:14", "name": "Add Rockchip USBPHY DM driver", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/498416/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2218891/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2218891/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=CbtOQGzf;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.b=\"CbtOQGzf\";\n\tdkim-atps=neutral", "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=jbx6244@gmail.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fmPVZ4YhKz1yGH\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 02 Apr 2026 12:32:38 +1100 (AEDT)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id BFCED83D8A;\n\tThu, 2 Apr 2026 03:32:35 +0200 (CEST)", "by phobos.denx.de (Postfix, from userid 109)\n id 80E7F83F7D; Thu, 2 Apr 2026 03:32:33 +0200 (CEST)", "from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com\n [IPv6:2a00:1450:4864:20::52c])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 3CD5680517\n for <u-boot@lists.denx.de>; Thu, 2 Apr 2026 03:32:31 +0200 (CEST)", "by mail-ed1-x52c.google.com with SMTP id\n 4fb4d7f45d1cf-66a87f29614so68761a12.2\n for <u-boot@lists.denx.de>; Wed, 01 Apr 2026 18:32:31 -0700 (PDT)", "from ?IPV6:2a02:a449:4071:0:32d0:42ff:fe10:6983?\n ([2a02:a449:4071:0:32d0:42ff:fe10:6983])\n by smtp.gmail.com with ESMTPSA id\n a640c23a62f3a-b9c3c97218esm39367666b.9.2026.04.01.18.32.26\n (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);\n Wed, 01 Apr 2026 18:32:27 -0700 (PDT)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-0.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_GMAIL_RCVD,\n FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_BLOCKED,\n SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1775093551; x=1775698351; darn=lists.denx.de;\n h=content-transfer-encoding:in-reply-to:content-language:references\n :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to\n :cc:subject:date:message-id:reply-to;\n bh=lLkAFOgsZZx2THCGIorQ5aZlMSxba6nPnHjhixmmauI=;\n b=CbtOQGzf4LcfChjum6mtRjj690AG2yYOpfK5k72x2rpUBNOnEkFlnU6E/uhOLuY0Qd\n fuv1RbTMV3T/iKVfIqTvfYU2cGcAlDtD6q22Z/TI+fiJVZ928YsET/5jc61ws0UE68lH\n UzKliOEO2hR8KTYp3m3oD3ljsFT3Pskw9V03cd4s3pHaYwTVbCxUEouNRN8q/EM7Ekfq\n g7FWapsPllNpf4H2jcr+8DFURfV/28CvbXq9ps9Fe6/1+1ff6r7KTw6HQJrqk2yit3SR\n XsFVwxXGSpAhVpp4jzjqV3x0PY1OJlTOuA2CJ5UTzUZg/wsizgSqqAiY8jvjuPxnhbNB\n 0+OQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775093551; x=1775698351;\n h=content-transfer-encoding:in-reply-to:content-language:references\n :cc:to:subject:from:user-agent:mime-version:date:message-id:x-gm-gg\n :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;\n bh=lLkAFOgsZZx2THCGIorQ5aZlMSxba6nPnHjhixmmauI=;\n b=Qk37Wci0p4dRHvekiULa/bZaw/vurlv9HNj/FPWRxRZ29WSfug19w+wOMpTKfXawyi\n nh+922sLiWsSxvHIoI6pxbDFYlE1JJteko+UDfdPe8gabGBJYN+72Dq0UxWYZntvpQT2\n FLZWf5KagYdp/MsaIVjggUAdXxwmw2ywWwCVTkVqqlPW/nzFdRC4HcDH8zdVnTULcsbd\n djdR6h5V+TsJy+L8gFjdsD2FHZ5u9pG1G1pSIMAQfpoKHzPrZUQV5VMwTYJhivXBexPI\n O5dZzbqchXRYsWknN5k3dGF1oVpED7hoTKwV+2GtbU5YuExfGsb3tiG/LR0GxP1AMvo8\n jF9g==", "X-Forwarded-Encrypted": "i=1;\n AJvYcCVm7oexAS86VgB78EMQ8CcnS9LNEQOhraYrIsPTXhzKrmf1+daUU5zTBQJqxJH50iShICGanRU=@lists.denx.de", "X-Gm-Message-State": "AOJu0Yw7ufprzL6aLLxdLbVIQOvOaJrTkZv860Axw57u1eLqkj5clUIb\n UDhADFxXTpBVbpibtBh+x7Rsdw1nE5XcRrXHdxl6RPad5biYcfSEr8eq", "X-Gm-Gg": "ATEYQzxukWmPDvW0pE2WYO3oyonpJWOEhjWy9LpNIiO/N3by/U3oVZu19EBvzo2g1Ec\n vH5f3Ce15TQEIOpRpgqH0ymnb6TVrbcPxlTB+XRfngqS9b0iuHG8L/cnTw+v/gF1RQ9M/y8wkse\n wHPP8mUkKlag4W2/46mTN5HpC2BbATw6XfMBY/0e/lRdwsu5L7Iq/R9RGKHZSJZdArX5cwm4Fhi\n XbQVgB5wElfMlzwxoCYBQqQcuVKKk6GWTyAL6i5Wo9X1b79VgdJS6MQDUvJb1f8IpoGs04F9SB5\n EicGOXOnHNfDsR7n+gVKYZ6NJ9Xthqf/TVqvySNC8E/n+jO6XiAxFCthrFh7P103JcZBcdFHeSx\n tAs5kEtUr51cbDrRA/1MBv0uTpu724MDK4V5Vnn8n+Ko3lhsZYAEXH3suRekc/17WgTqlha6OKi\n g2jPdQPuC1pam+wKVq4StTiy5FWxQa2bAry018Ib7Dp7Hu2f5QgrucUpZAZ42SiiZCVl1Ezpc0", "X-Received": "by 2002:a17:907:6d05:b0:b9b:52d4:40fb with SMTP id\n a640c23a62f3a-b9c13cc2521mr142418566b.5.1775093550181;\n Wed, 01 Apr 2026 18:32:30 -0700 (PDT)", "Message-ID": "<0e0acf7c-69d6-4f98-80b8-1fcb3dc859f4@gmail.com>", "Date": "Thu, 2 Apr 2026 03:32:26 +0200", "MIME-Version": "1.0", "User-Agent": "Mozilla Thunderbird", "From": "Johan Jonker <jbx6244@gmail.com>", "Subject": "[RFC PATCH v1 1/2] phy: rockchip: add phy-rockchip-usb2.c", "To": "kever.yang@rock-chips.com", "Cc": "sjg@chromium.org, philipp.tomsich@vrull.eu, trini@konsulko.com,\n hl@rock-chips.com, jernej.skrabec@gmail.com, w.egorov@phytec.de,\n jagan@amarulasolutions.com, heiko@sntech.de, jonas@kwiboo.se,\n michael@amarulasolutions.com, marex@denx.de, u-boot@lists.denx.de,\n upstream@lists.phytec.de", "References": "<1e443ab0-129b-42db-b224-253ba8a2f80f@gmail.com>", "Content-Language": "en-US, ar-EG", "In-Reply-To": "<1e443ab0-129b-42db-b224-253ba8a2f80f@gmail.com>", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "7bit", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "Add phy-rockchip-usb2.c driver with support\nfor RK3066, RK3188 and RK3288 pdata.\n\nSigned-off-by: Johan Jonker <jbx6244@gmail.com>\n---\n drivers/phy/rockchip/Kconfig | 28 +-\n drivers/phy/rockchip/Makefile | 5 +-\n drivers/phy/rockchip/phy-rockchip-usb2.c | 379 +++++++++++++++++++++++\n 3 files changed, 400 insertions(+), 12 deletions(-)\n create mode 100644 drivers/phy/rockchip/phy-rockchip-usb2.c\n\n--\n2.39.5", "diff": "diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig\nindex 80128335d52f..745e0ea67b8d 100644\n--- a/drivers/phy/rockchip/Kconfig\n+++ b/drivers/phy/rockchip/Kconfig\n@@ -27,7 +27,7 @@ config PHY_ROCKCHIP_INNO_USB2\n \t Support for Rockchip USB2.0 PHY with Innosilicon IP block.\n\n config PHY_ROCKCHIP_NANENG_COMBOPHY\n-\tbool \"Support Rockchip NANENG combo PHY Driver\"\n+\tbool \"Rockchip NANENG combo PHY Driver\"\n \tdepends on ARCH_ROCKCHIP\n \tselect PHY\n \thelp\n@@ -41,26 +41,34 @@ config PHY_ROCKCHIP_PCIE\n \t Enable this to support the Rockchip PCIe PHY.\n\n config PHY_ROCKCHIP_SNPS_PCIE3\n-\tbool \"Rockchip Snps PCIe3 PHY Driver\"\n-\tdepends on PHY && ARCH_ROCKCHIP\n+\tbool \"Rockchip SNPS PCIe3 PHY Driver\"\n+\tdepends on ARCH_ROCKCHIP\n+\tselect PHY\n \thelp\n \t Support for Rockchip PCIe3 PHY with Synopsys IP block.\n \t It could support PCIe Gen3 single root complex, and could\n \t also be able splited into multiple combinations of lanes.\n\n-config PHY_ROCKCHIP_USBDP\n-\ttristate \"Rockchip USBDP COMBO PHY Driver\"\n+config PHY_ROCKCHIP_TYPEC\n+\tbool \"Rockchip TYPEC PHY Driver\"\n \tdepends on ARCH_ROCKCHIP\n \tselect PHY\n \thelp\n-\t Enable this to support the Rockchip USB3.0/DP\n-\t combo PHY with Samsung IP block.\n+\t Enable this to support the Rockchip USB TYPEC PHY.\n\n-config PHY_ROCKCHIP_TYPEC\n-\tbool \"Rockchip TYPEC PHY Driver\"\n+config PHY_ROCKCHIP_USB2\n+\tbool \"Rockchip USB2 PHY\"\n \tdepends on ARCH_ROCKCHIP\n \tselect PHY\n \thelp\n-\t Enable this to support the Rockchip USB TYPEC PHY.\n+\t Support for Rockchip USB 2.0 PHY.\n+\n+config PHY_ROCKCHIP_USBDP\n+\ttristate \"Rockchip USBDP COMBO PHY Driver\"\n+\tdepends on ARCH_ROCKCHIP\n+\tselect PHY\n+\thelp\n+\t Enable this to support the Rockchip USB3.0/DP\n+\t combo PHY with Samsung IP block.\n\n endmenu\ndiff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile\nindex 04200174254e..f296dc8f3d2a 100644\n--- a/drivers/phy/rockchip/Makefile\n+++ b/drivers/phy/rockchip/Makefile\n@@ -3,11 +3,12 @@\n # Copyright (C) 2020 Amarula Solutions(India)\n #\n\n+obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY)\t+= phy-rockchip-inno-dsidphy.o\n obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI)\t+= phy-rockchip-inno-hdmi.o\n obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)\t+= phy-rockchip-inno-usb2.o\n obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY) += phy-rockchip-naneng-combphy.o\n obj-$(CONFIG_PHY_ROCKCHIP_PCIE)\t\t+= phy-rockchip-pcie.o\n obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3)\t+= phy-rockchip-snps-pcie3.o\n obj-$(CONFIG_PHY_ROCKCHIP_TYPEC)\t+= phy-rockchip-typec.o\n-obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY)\t+= phy-rockchip-inno-dsidphy.o\n-obj-$(CONFIG_PHY_ROCKCHIP_USBDP) += phy-rockchip-usbdp.o\n+obj-$(CONFIG_PHY_ROCKCHIP_USB2)\t\t+= phy-rockchip-usb2.o\n+obj-$(CONFIG_PHY_ROCKCHIP_USBDP)\t+= phy-rockchip-usbdp.o\ndiff --git a/drivers/phy/rockchip/phy-rockchip-usb2.c b/drivers/phy/rockchip/phy-rockchip-usb2.c\nnew file mode 100644\nindex 000000000000..4f02cd18b302\n--- /dev/null\n+++ b/drivers/phy/rockchip/phy-rockchip-usb2.c\n@@ -0,0 +1,379 @@\n+// SPDX-License-Identifier: GPL-2.0+\n+\n+#include <clk.h>\n+#include <dm.h>\n+#include <dm/device.h>\n+#include <dm/lists.h>\n+#include <generic-phy.h>\n+#include <power/regulator.h>\n+#include <regmap.h>\n+#include <reset.h>\n+#include <syscon.h>\n+\n+DECLARE_GLOBAL_DATA_PTR;\n+\n+#define BIT_WRITEABLE_SHIFT\t16\n+#define usleep_range(a, b) udelay((b))\n+\n+struct usbphy_reg {\n+\tunsigned int offset;\n+\tunsigned int bitend;\n+\tunsigned int bitstart;\n+\tunsigned int disable;\n+\tunsigned int enable;\n+};\n+\n+struct rockchip_usbphy_port_cfg {\n+\tint num_phys;\n+\tstruct usbphy_reg port_reset;\n+\tstruct usbphy_reg soft_con;\n+\tstruct usbphy_reg suspend;\n+};\n+\n+struct rockchip_usb_phy {\n+\tofnode node;\n+\tunsigned int reg;\n+\tstruct clk clock;\n+\tstruct reset_ctl reset;\n+\tstruct udevice *vbus_supply;\n+};\n+\n+struct rockchip_usbphy_priv {\n+\tstruct device *dev;\n+\tstruct regmap *grf_regmap;\n+\tconst struct rockchip_usbphy_port_cfg *port_cfg;\n+\tstruct rockchip_usb_phy *usb_phy;\n+};\n+\n+static void rockchip_usbphy_property_enable(struct phy *phy, const struct usbphy_reg *reg, bool en)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\tunsigned int val, mask, tmp;\n+\n+\ttmp = en ? reg->enable : reg->disable;\n+\tmask = GENMASK(reg->bitend, reg->bitstart);\n+\tval = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);\n+\n+\tregmap_write(priv->grf_regmap,\n+\t\t priv->usb_phy[phy->id].reg + reg->offset, val);\n+}\n+\n+static const struct rockchip_usbphy_port_cfg *rockchip_usbphy_get_port_cfg(struct phy *phy)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\n+\treturn priv->port_cfg;\n+}\n+\n+static int rockchip_usbphy_power_on(struct phy *phy)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\tconst struct rockchip_usbphy_port_cfg *port_cfg = rockchip_usbphy_get_port_cfg(phy);\n+\tint ret;\n+\n+\tif (priv->usb_phy[phy->id].vbus_supply) {\n+\t\tret = regulator_set_enable(priv->usb_phy[phy->id].vbus_supply, true);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\t/* Exit suspend. */\n+\trockchip_usbphy_property_enable(phy, &port_cfg->suspend, false);\n+\tusleep_range(1500, 2000);\n+\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_power_off(struct phy *phy)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\tconst struct rockchip_usbphy_port_cfg *port_cfg = rockchip_usbphy_get_port_cfg(phy);\n+\n+\t/* Enter suspend. */\n+\trockchip_usbphy_property_enable(phy, &port_cfg->suspend, true);\n+\n+\tif (!priv->usb_phy[phy->id].vbus_supply)\n+\t\treturn 0;\n+\n+\treturn regulator_set_enable(priv->usb_phy[phy->id].vbus_supply, false);\n+}\n+\n+static inline int rockchip_usbphy_reset_assert(struct reset_ctl *rst)\n+{\n+\tif (rst)\n+\t\treturn reset_assert(rst);\n+\telse\n+\t\treturn 0;\n+}\n+\n+static inline int rockchip_usbphy_reset_deassert(struct reset_ctl *rst)\n+{\n+\tif (rst)\n+\t\treturn reset_deassert(rst);\n+\telse\n+\t\treturn 0;\n+}\n+\n+#define reset_control_assert(rst) rockchip_usbphy_reset_assert(rst)\n+#define reset_control_deassert(rst) rockchip_usbphy_reset_deassert(rst)\n+\n+static int rockchip_usbphy_reset(struct phy *phy)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\n+\tif (reset_valid(&priv->usb_phy[phy->id].reset)) {\n+\t\treset_control_assert(&priv->usb_phy[phy->id].reset);\n+\t\tudelay(10);\n+\t\treset_control_deassert(&priv->usb_phy[phy->id].reset);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_init(struct phy *phy)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\tconst struct rockchip_usbphy_port_cfg *port_cfg = rockchip_usbphy_get_port_cfg(phy);\n+\tint ret;\n+\n+\tret = clk_enable(&priv->usb_phy[phy->id].clock);\n+\tif (ret) {\n+\t\tdebug(\"failed to enable phyclk\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\t/* Disable software control. */\n+\trockchip_usbphy_property_enable(phy, &port_cfg->soft_con, false);\n+\n+\t/* Reset OTG port. */\n+\trockchip_usbphy_property_enable(phy, &port_cfg->port_reset, true);\n+\tmdelay(1);\n+\trockchip_usbphy_property_enable(phy, &port_cfg->port_reset, false);\n+\tudelay(1);\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_exit(struct phy *phy)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\tconst struct rockchip_usbphy_port_cfg *port_cfg = rockchip_usbphy_get_port_cfg(phy);\n+\n+\t/* Enable software control. */\n+\trockchip_usbphy_property_enable(phy, &port_cfg->soft_con, true);\n+\n+\tclk_disable(&priv->usb_phy[phy->id].clock);\n+\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_of_xlate(struct phy *phy, struct ofnode_phandle_args *args)\n+{\n+\tstruct udevice *parent = phy->dev->parent;\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(parent);\n+\tint id;\n+\n+\tif (args->args_count != 0) {\n+\t\tdebug(\"invalid number of arguments\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor (id = 0; id < priv->port_cfg->num_phys; id++) {\n+\t\tif (of_live_active()) {\n+\t\t\tif (args->node.np == priv->usb_phy[id].node.np) {\n+\t\t\t\tphy->id = id;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t} else {\n+\t\t\tif (args->node.of_offset == priv->usb_phy[id].node.of_offset) {\n+\t\t\t\tphy->id = id;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tif (id >= priv->port_cfg->num_phys) {\n+\t\tdebug(\"failed to get phy id\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_get_regulator(ofnode node, char *supply_name,\n+\t\t\t\t\t struct udevice **regulator)\n+{\n+\tstruct ofnode_phandle_args regulator_phandle;\n+\tint ret;\n+\n+\tret = ofnode_parse_phandle_with_args(node, supply_name,\n+\t\t\t\t\t NULL, 0, 0,\n+\t\t\t\t\t ®ulator_phandle);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = uclass_get_device_by_ofnode(UCLASS_REGULATOR,\n+\t\t\t\t\t regulator_phandle.node,\n+\t\t\t\t\t regulator);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_init_port(struct rockchip_usbphy_priv *priv,\n+\t\t\t\t ofnode node, unsigned int id)\n+{\n+\tunsigned int reg;\n+\tint ret;\n+\n+\tif (ofnode_read_u32(node, \"reg\", ®)) {\n+\t\tdebug(\"missing reg property\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tpriv->usb_phy[id].node = node;\n+\tpriv->usb_phy[id].reg = reg;\n+\n+\tret = reset_get_by_index_nodev(node, 0, &priv->usb_phy[id].reset);\n+\tif (ret)\n+\t\tdebug(\"failed to get phy-reset\\n\");\n+\n+\tret = clk_get_by_index_nodev(node, 0, &priv->usb_phy[id].clock);\n+\tif (ret) {\n+\t\tdebug(\"failed to get phyclk clock\\n\");\n+\t\treturn ret;\n+\t}\n+\n+\tret = rockchip_usbphy_get_regulator(node, \"vbus-supply\", &priv->usb_phy[id].vbus_supply);\n+\tif (ret)\n+\t\tdebug(\"failed to get vbus-supply\\n\");\n+\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_probe(struct udevice *dev)\n+{\n+\tstruct rockchip_usbphy_priv *priv = dev_get_priv(dev);\n+\tconst struct rockchip_usbphy_port_cfg *port_cfg;\n+\tint ret, i = 0;\n+\tofnode node;\n+\n+\tport_cfg = (const struct rockchip_usbphy_port_cfg *)dev_get_driver_data(dev);\n+\tif (!port_cfg)\n+\t\treturn -EINVAL;\n+\n+\tpriv->usb_phy = kcalloc(port_cfg->num_phys, sizeof(struct rockchip_usb_phy), GFP_KERNEL);\n+\n+\tpriv->port_cfg = port_cfg;\n+\n+\tif (dev_read_bool(dev, \"rockchip,grf\"))\n+\t\tpriv->grf_regmap = syscon_regmap_lookup_by_phandle(dev, \"rockchip,grf\");\n+\telse\n+\t\tpriv->grf_regmap = syscon_get_regmap(dev_get_parent(dev));\n+\tif (IS_ERR(priv->grf_regmap))\n+\t\treturn PTR_ERR(priv->grf_regmap);\n+\n+\tdev_for_each_subnode(node, dev) {\n+\t\tif (!ofnode_valid(node)) {\n+\t\t\tdebug(\"subnode %s not found\\n\", dev->name);\n+\t\t\treturn -ENXIO;\n+\t\t}\n+\n+\t\tif (i >= port_cfg->num_phys) {\n+\t\t\tdebug(\"subnode max:%d\\n\", port_cfg->num_phys);\n+\t\t\treturn -ENXIO;\n+\t\t}\n+\n+\t\tret = rockchip_usbphy_init_port(priv, node, i++);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int rockchip_usbphy_bind(struct udevice *dev)\n+{\n+\tstruct udevice *usbphy_dev;\n+\tofnode node;\n+\tconst char *name;\n+\tint ret = 0;\n+\n+\tdev_for_each_subnode(node, dev) {\n+\t\tif (!ofnode_valid(node)) {\n+\t\t\tdebug(\"subnode %s not found\\n\", dev->name);\n+\t\t\treturn -ENXIO;\n+\t\t}\n+\n+\t\tname = ofnode_get_name(node);\n+\t\tdebug(\"subnode %s\\n\", name);\n+\n+\t\tret = device_bind_driver_to_node(dev, \"rockchip_usbphy_port\",\n+\t\t\t\t\t\t name, node, &usbphy_dev);\n+\t\tif (ret) {\n+\t\t\tdebug(\"'%s' cannot bind 'rockchip_usbphy_port'\\n\", name);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static struct phy_ops rockchip_usbphy_ops = {\n+\t.init\t\t= rockchip_usbphy_init,\n+\t.exit\t\t= rockchip_usbphy_exit,\n+\t.power_on\t= rockchip_usbphy_power_on,\n+\t.power_off\t= rockchip_usbphy_power_off,\n+\t.reset\t\t= rockchip_usbphy_reset,\n+\t.of_xlate\t= rockchip_usbphy_of_xlate,\n+};\n+\n+static const struct rockchip_usbphy_port_cfg rk3066a_pdata = {\n+\t.num_phys\t= 2,\n+\t.port_reset\t= {0x00, 12, 12, 0, 1},\n+\t.soft_con\t= {0x08, 2, 2, 0, 1},\n+\t.suspend\t= {0x08, 8, 3, (0x01 << 3), (0x2A << 3)},\n+};\n+\n+static const struct rockchip_usbphy_port_cfg rk3188_pdata = {\n+\t.num_phys\t= 2,\n+\t.port_reset\t= {0x00, 12, 12, 0, 1},\n+\t.soft_con\t= {0x08, 2, 2, 0, 1},\n+\t.suspend\t= {0x0c, 5, 0, 0x01, 0x2A},\n+};\n+\n+static const struct rockchip_usbphy_port_cfg rk3288_pdata = {\n+\t.num_phys\t= 3,\n+\t.port_reset\t= {0x00, 12, 12, 0, 1},\n+\t.soft_con\t= {0x08, 2, 2, 0, 1},\n+\t.suspend\t= {0x0c, 5, 0, 0x01, 0x2A},\n+};\n+\n+static const struct udevice_id rockchip_usbphy_ids[] = {\n+\t{ .compatible = \"rockchip,rk3066a-usb-phy\", .data = (ulong)&rk3066a_pdata },\n+\t{ .compatible = \"rockchip,rk3188-usb-phy\", .data = (ulong)&rk3188_pdata },\n+\t{ .compatible = \"rockchip,rk3288-usb-phy\", .data = (ulong)&rk3288_pdata },\n+\t{}\n+};\n+\n+U_BOOT_DRIVER(rockchip_usbphy_port) = {\n+\t.name\t\t= \"rockchip_usbphy_port\",\n+\t.id\t\t= UCLASS_PHY,\n+\t.ops\t\t= &rockchip_usbphy_ops,\n+};\n+\n+U_BOOT_DRIVER(rockchip_usbphy) = {\n+\t.name\t\t= \"rockchip_usbphy\",\n+\t.id\t\t= UCLASS_NOP,\n+\t.of_match\t= rockchip_usbphy_ids,\n+\t.probe\t\t= rockchip_usbphy_probe,\n+\t.bind\t\t= rockchip_usbphy_bind,\n+\t.priv_auto\t= sizeof(struct rockchip_usbphy_priv),\n+};\n", "prefixes": [ "RFC", "v1", "1/2" ] }