All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vinod Koul <vkoul@kernel.org>
To: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Cc: Drew Fustini <fustini@kernel.org>, Guo Ren <guoren@kernel.org>,
	Fu Wei <wefu@redhat.com>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Neil Armstrong <neil.armstrong@linaro.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Paul Walmsley <pjw@kernel.org>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>,
	Jisheng Zhang <jszhang@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-gpio@vger.kernel.org, linux-phy@lists.infradead.org,
	linux-usb@vger.kernel.org, Icenowy Zheng <uwu@icenowy.me>,
	Han Gao <rabenda.cn@gmail.com>, Yao Zi <ziyao@disroot.org>
Subject: Re: [PATCH 05/12] phy: add a driver for T-Head TH1520 USB PHY
Date: Sun, 10 May 2026 13:14:17 +0530	[thread overview]
Message-ID: <agA3URhGA1u6R7LD@vaman> (raw)
In-Reply-To: <20260507081710.4090814-6-zhengxingda@iscas.ac.cn>

On 07-05-26, 16:17, Icenowy Zheng wrote:
> The USB PHY on T-Head TH1520 SoC is a Synopsys USB 3.0 FemtoPHY, with
> some PHY parameters exported as another system controller along with it.
> 
> As a few PHY parameters' default value isn't ready to work, add a driver
> configuring them before letting the PHY run, in addition to
> clock/reset/regulator management.

Is there any dependency on the rest of series, if not please split up!

Some warnings flagged by sashiko, please check
https://sashiko.dev/#/patchset/20260507081710.4090814-1-zhengxingda%40iscas.ac.cn


> 
> Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
> ---
>  drivers/phy/Kconfig                |   1 +
>  drivers/phy/Makefile               |   1 +
>  drivers/phy/thead/Kconfig          |  12 ++
>  drivers/phy/thead/Makefile         |   2 +
>  drivers/phy/thead/phy-th1520-usb.c | 197 +++++++++++++++++++++++++++++
>  5 files changed, 213 insertions(+)
>  create mode 100644 drivers/phy/thead/Kconfig
>  create mode 100644 drivers/phy/thead/Makefile
>  create mode 100644 drivers/phy/thead/phy-th1520-usb.c
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 227b9a4c612e8..ea1a52e14b839 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -164,6 +164,7 @@ source "drivers/phy/st/Kconfig"
>  source "drivers/phy/starfive/Kconfig"
>  source "drivers/phy/sunplus/Kconfig"
>  source "drivers/phy/tegra/Kconfig"
> +source "drivers/phy/thead/Kconfig"
>  source "drivers/phy/ti/Kconfig"
>  source "drivers/phy/xilinx/Kconfig"
>  
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index f49d83f00a3d8..4604522548c91 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -48,5 +48,6 @@ obj-$(CONFIG_GENERIC_PHY)		+= allwinner/	\
>  					   starfive/	\
>  					   sunplus/	\
>  					   tegra/	\
> +					   thead/	\
>  					   ti/		\
>  					   xilinx/
> diff --git a/drivers/phy/thead/Kconfig b/drivers/phy/thead/Kconfig
> new file mode 100644
> index 0000000000000..14012db5973c4
> --- /dev/null
> +++ b/drivers/phy/thead/Kconfig
> @@ -0,0 +1,12 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config PHY_TH1520_USB
> +	tristate "USB PHY driver for T-Head TH1520 SoC"
> +	depends on ARCH_THEAD || COMPILE_TEST
> +	depends on COMMON_CLK
> +	depends on HAS_IOMEM
> +	depends on OF
> +	depends on RESET_CONTROLLER
> +	select GENERIC_PHY
> +	default ARCH_THEAD

Why should this be default?

> +	help
> +	  Enable support for the USB PHY on the T-Head TH1520 SoC.
> diff --git a/drivers/phy/thead/Makefile b/drivers/phy/thead/Makefile
> new file mode 100644
> index 0000000000000..5b459bc7004bd
> --- /dev/null
> +++ b/drivers/phy/thead/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_PHY_TH1520_USB) += phy-th1520-usb.o
> diff --git a/drivers/phy/thead/phy-th1520-usb.c b/drivers/phy/thead/phy-th1520-usb.c
> new file mode 100644
> index 0000000000000..c87bd779bbb74
> --- /dev/null
> +++ b/drivers/phy/thead/phy-th1520-usb.c
> @@ -0,0 +1,197 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 Institute of Software, Chinese Academy of Sciences (ISCAS)
> + *
> + * Authors:
> + * Icenowy Zheng <zhengxingda@iscas.ac.cn>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +
> +#define USB_SYSCON_OFFSET		0xf000
> +
> +/* All the below registers are in the USB syscon region */
> +#define USB_CLK_GATE_STS		0x0
> +#define USB_LOGIC_ANALYZER_TRACE_STS0	0x4
> +#define USB_LOGIC_ANALYZER_TRACE_STS1	0x8
> +#define USB_GPIO			0xc
> +#define USB_DEBUG_STS0			0x10
> +#define USB_DEBUG_STS1			0x14
> +#define USB_DEBUG_STS2			0x18
> +#define USBCTL_CLK_CTRL0		0x1c
> +#define USBPHY_CLK_CTRL1		0x20
> +#define USBPHY_TEST_CTRL0		0x24
> +#define USBPHY_TEST_CTRL1		0x28
> +#define USBPHY_TEST_CTRL2		0x2c
> +#define USBPHY_TEST_CTRL3		0x30
> +#define USB_SSP_EN			0x34
> +#define USB_HADDR_SEL			0x38
> +#define USB_SYS				0x3c
> +#define USB_HOST_STATUS			0x40
> +#define USB_HOST_CTRL			0x44
> +#define USBPHY_HOST_CTRL		0x48
> +#define USBPHY_HOST_STATUS		0x4c
> +#define USB_TEST_REG0			0x50
> +#define USB_TEST_REG1			0x54
> +#define USB_TEST_REG2			0x58
> +#define USB_TEST_REG3			0x5c

Why do need these test registers, they seem unused?

> +
> +#define USB_SYS_COMMONONN		BIT(0)
> +
> +#define USB_SSP_EN_REF_SSP_EN		BIT(0)
> +
> +struct th1520_usb_phy {
> +	struct platform_device *pdev;
> +	struct phy *phy;
> +	struct regmap *regmap;
> +	struct clk *ref_clk;
> +	struct reset_control *phy_reset;
> +};
> +
> +static int th1520_usb_phy_init(struct phy *phy)
> +{
> +	struct th1520_usb_phy *th1520_phy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = clk_prepare_enable(th1520_phy->ref_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = reset_control_assert(th1520_phy->phy_reset);
> +	if (ret)
> +		goto err_disable_clk;
> +
> +	/*
> +	 * Do some initial PHY setup:
> +	 * - Set COMMONONN to allow the PHY to automatically power down.
> +	 * - Set REF_SSP_EN to enable feeding reference clock to SuperSpeed
> +	 *   PHY clock PLL.
> +	 */
> +	regmap_set_bits(th1520_phy->regmap, USB_SYS, USB_SYS_COMMONONN);
> +	regmap_set_bits(th1520_phy->regmap, USB_SSP_EN, USB_SSP_EN_REF_SSP_EN);
> +
> +	ret = reset_control_deassert(th1520_phy->phy_reset);
> +	if (ret)
> +		goto err_disable_clk;
> +
> +	udelay(10);
> +
> +	return 0;
> +
> +err_disable_clk:
> +	clk_disable_unprepare(th1520_phy->ref_clk);
> +	return ret;
> +}
> +
> +static int th1520_usb_phy_exit(struct phy *phy)
> +{
> +	struct th1520_usb_phy *th1520_phy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = reset_control_assert(th1520_phy->phy_reset);
> +	if (ret)
> +		return ret;
> +
> +	clk_disable_unprepare(th1520_phy->ref_clk);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops th1520_usb_phy_ops = {
> +	.init		= th1520_usb_phy_init,
> +	.exit		= th1520_usb_phy_exit,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static const struct regmap_config phy_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.max_register = USB_TEST_REG3,
> +};
> +
> +static int th1520_usb_phy_probe(struct platform_device *pdev)
> +{
> +	struct phy_provider *phy_provider;
> +	struct device *dev = &pdev->dev;
> +	struct th1520_usb_phy *th1520_phy;
> +	struct reset_control *bus_reset;
> +	void __iomem *base;
> +	int ret;
> +
> +	th1520_phy = devm_kzalloc(dev, sizeof(*th1520_phy), GFP_KERNEL);
> +	if (!th1520_phy)
> +		return -ENOMEM;
> +
> +	th1520_phy->pdev = pdev;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	th1520_phy->ref_clk = devm_clk_get(dev, "ref");
> +	if (IS_ERR(th1520_phy->ref_clk))
> +		return PTR_ERR(th1520_phy->ref_clk);
> +
> +	/* De-assert the bus reset and leave it that way */
> +	bus_reset = devm_reset_control_get_exclusive_deasserted(dev, "bus");
> +	if (IS_ERR(bus_reset))
> +		return PTR_ERR(bus_reset);
> +
> +	th1520_phy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
> +	if (IS_ERR(th1520_phy->phy_reset))
> +		return PTR_ERR(th1520_phy->phy_reset);
> +
> +	/*
> +	 * Schematics of several boards (Lichee Module 4A/Milk-V Meles)
> +	 * describe this power rail as always-on.
> +	 */
> +	ret = devm_regulator_get_enable(dev, "avdd33-usb3");
> +	if (ret)
> +		return ret;
> +
> +	th1520_phy->regmap = devm_regmap_init_mmio_clk(dev, "bus",
> +						       base + USB_SYSCON_OFFSET,
> +						       &phy_regmap_config);
> +	if (IS_ERR(th1520_phy->regmap))
> +		return dev_err_probe(dev, PTR_ERR(th1520_phy->regmap),
> +				     "Failed to init regmap\n");
> +
> +	th1520_phy->phy = devm_phy_create(dev, dev->of_node, &th1520_usb_phy_ops);
> +	if (IS_ERR(th1520_phy->phy)) {
> +		dev_err(dev, "failed to create PHY\n");
> +		return PTR_ERR(th1520_phy->phy);
> +	}
> +
> +	phy_set_drvdata(th1520_phy->phy, th1520_phy);
> +
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id th1520_usb_phy_of_table[] = {
> +	{ .compatible = "thead,th1520-usb-phy" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, th1520_usb_phy_of_table);
> +
> +static struct platform_driver th1520_usb_phy_driver = {
> +	.driver = {
> +		.name = "th1520-usb-phy",
> +		.of_match_table = th1520_usb_phy_of_table,
> +	},
> +	.probe = th1520_usb_phy_probe,
> +};
> +
> +module_platform_driver(th1520_usb_phy_driver);
> +
> +MODULE_DESCRIPTION("T-Head TH1520 USB PHY driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.52.0

-- 
~Vinod

WARNING: multiple messages have this Message-ID (diff)
From: Vinod Koul <vkoul@kernel.org>
To: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Cc: Drew Fustini <fustini@kernel.org>, Guo Ren <guoren@kernel.org>,
	Fu Wei <wefu@redhat.com>,
	Michael Turquette <mturquette@baylibre.com>,
	Stephen Boyd <sboyd@kernel.org>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Neil Armstrong <neil.armstrong@linaro.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Paul Walmsley <pjw@kernel.org>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Alexandre Ghiti <alex@ghiti.fr>,
	Jisheng Zhang <jszhang@kernel.org>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-gpio@vger.kernel.org, linux-phy@lists.infradead.org,
	linux-usb@vger.kernel.org, Icenowy Zheng <uwu@icenowy.me>,
	Han Gao <rabenda.cn@gmail.com>, Yao Zi <ziyao@disroot.org>
Subject: Re: [PATCH 05/12] phy: add a driver for T-Head TH1520 USB PHY
Date: Sun, 10 May 2026 13:14:17 +0530	[thread overview]
Message-ID: <agA3URhGA1u6R7LD@vaman> (raw)
In-Reply-To: <20260507081710.4090814-6-zhengxingda@iscas.ac.cn>

On 07-05-26, 16:17, Icenowy Zheng wrote:
> The USB PHY on T-Head TH1520 SoC is a Synopsys USB 3.0 FemtoPHY, with
> some PHY parameters exported as another system controller along with it.
> 
> As a few PHY parameters' default value isn't ready to work, add a driver
> configuring them before letting the PHY run, in addition to
> clock/reset/regulator management.

Is there any dependency on the rest of series, if not please split up!

Some warnings flagged by sashiko, please check
https://sashiko.dev/#/patchset/20260507081710.4090814-1-zhengxingda%40iscas.ac.cn


> 
> Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
> ---
>  drivers/phy/Kconfig                |   1 +
>  drivers/phy/Makefile               |   1 +
>  drivers/phy/thead/Kconfig          |  12 ++
>  drivers/phy/thead/Makefile         |   2 +
>  drivers/phy/thead/phy-th1520-usb.c | 197 +++++++++++++++++++++++++++++
>  5 files changed, 213 insertions(+)
>  create mode 100644 drivers/phy/thead/Kconfig
>  create mode 100644 drivers/phy/thead/Makefile
>  create mode 100644 drivers/phy/thead/phy-th1520-usb.c
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 227b9a4c612e8..ea1a52e14b839 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -164,6 +164,7 @@ source "drivers/phy/st/Kconfig"
>  source "drivers/phy/starfive/Kconfig"
>  source "drivers/phy/sunplus/Kconfig"
>  source "drivers/phy/tegra/Kconfig"
> +source "drivers/phy/thead/Kconfig"
>  source "drivers/phy/ti/Kconfig"
>  source "drivers/phy/xilinx/Kconfig"
>  
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index f49d83f00a3d8..4604522548c91 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -48,5 +48,6 @@ obj-$(CONFIG_GENERIC_PHY)		+= allwinner/	\
>  					   starfive/	\
>  					   sunplus/	\
>  					   tegra/	\
> +					   thead/	\
>  					   ti/		\
>  					   xilinx/
> diff --git a/drivers/phy/thead/Kconfig b/drivers/phy/thead/Kconfig
> new file mode 100644
> index 0000000000000..14012db5973c4
> --- /dev/null
> +++ b/drivers/phy/thead/Kconfig
> @@ -0,0 +1,12 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config PHY_TH1520_USB
> +	tristate "USB PHY driver for T-Head TH1520 SoC"
> +	depends on ARCH_THEAD || COMPILE_TEST
> +	depends on COMMON_CLK
> +	depends on HAS_IOMEM
> +	depends on OF
> +	depends on RESET_CONTROLLER
> +	select GENERIC_PHY
> +	default ARCH_THEAD

Why should this be default?

> +	help
> +	  Enable support for the USB PHY on the T-Head TH1520 SoC.
> diff --git a/drivers/phy/thead/Makefile b/drivers/phy/thead/Makefile
> new file mode 100644
> index 0000000000000..5b459bc7004bd
> --- /dev/null
> +++ b/drivers/phy/thead/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_PHY_TH1520_USB) += phy-th1520-usb.o
> diff --git a/drivers/phy/thead/phy-th1520-usb.c b/drivers/phy/thead/phy-th1520-usb.c
> new file mode 100644
> index 0000000000000..c87bd779bbb74
> --- /dev/null
> +++ b/drivers/phy/thead/phy-th1520-usb.c
> @@ -0,0 +1,197 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 Institute of Software, Chinese Academy of Sciences (ISCAS)
> + *
> + * Authors:
> + * Icenowy Zheng <zhengxingda@iscas.ac.cn>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +
> +#define USB_SYSCON_OFFSET		0xf000
> +
> +/* All the below registers are in the USB syscon region */
> +#define USB_CLK_GATE_STS		0x0
> +#define USB_LOGIC_ANALYZER_TRACE_STS0	0x4
> +#define USB_LOGIC_ANALYZER_TRACE_STS1	0x8
> +#define USB_GPIO			0xc
> +#define USB_DEBUG_STS0			0x10
> +#define USB_DEBUG_STS1			0x14
> +#define USB_DEBUG_STS2			0x18
> +#define USBCTL_CLK_CTRL0		0x1c
> +#define USBPHY_CLK_CTRL1		0x20
> +#define USBPHY_TEST_CTRL0		0x24
> +#define USBPHY_TEST_CTRL1		0x28
> +#define USBPHY_TEST_CTRL2		0x2c
> +#define USBPHY_TEST_CTRL3		0x30
> +#define USB_SSP_EN			0x34
> +#define USB_HADDR_SEL			0x38
> +#define USB_SYS				0x3c
> +#define USB_HOST_STATUS			0x40
> +#define USB_HOST_CTRL			0x44
> +#define USBPHY_HOST_CTRL		0x48
> +#define USBPHY_HOST_STATUS		0x4c
> +#define USB_TEST_REG0			0x50
> +#define USB_TEST_REG1			0x54
> +#define USB_TEST_REG2			0x58
> +#define USB_TEST_REG3			0x5c

Why do need these test registers, they seem unused?

> +
> +#define USB_SYS_COMMONONN		BIT(0)
> +
> +#define USB_SSP_EN_REF_SSP_EN		BIT(0)
> +
> +struct th1520_usb_phy {
> +	struct platform_device *pdev;
> +	struct phy *phy;
> +	struct regmap *regmap;
> +	struct clk *ref_clk;
> +	struct reset_control *phy_reset;
> +};
> +
> +static int th1520_usb_phy_init(struct phy *phy)
> +{
> +	struct th1520_usb_phy *th1520_phy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = clk_prepare_enable(th1520_phy->ref_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = reset_control_assert(th1520_phy->phy_reset);
> +	if (ret)
> +		goto err_disable_clk;
> +
> +	/*
> +	 * Do some initial PHY setup:
> +	 * - Set COMMONONN to allow the PHY to automatically power down.
> +	 * - Set REF_SSP_EN to enable feeding reference clock to SuperSpeed
> +	 *   PHY clock PLL.
> +	 */
> +	regmap_set_bits(th1520_phy->regmap, USB_SYS, USB_SYS_COMMONONN);
> +	regmap_set_bits(th1520_phy->regmap, USB_SSP_EN, USB_SSP_EN_REF_SSP_EN);
> +
> +	ret = reset_control_deassert(th1520_phy->phy_reset);
> +	if (ret)
> +		goto err_disable_clk;
> +
> +	udelay(10);
> +
> +	return 0;
> +
> +err_disable_clk:
> +	clk_disable_unprepare(th1520_phy->ref_clk);
> +	return ret;
> +}
> +
> +static int th1520_usb_phy_exit(struct phy *phy)
> +{
> +	struct th1520_usb_phy *th1520_phy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = reset_control_assert(th1520_phy->phy_reset);
> +	if (ret)
> +		return ret;
> +
> +	clk_disable_unprepare(th1520_phy->ref_clk);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops th1520_usb_phy_ops = {
> +	.init		= th1520_usb_phy_init,
> +	.exit		= th1520_usb_phy_exit,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static const struct regmap_config phy_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.max_register = USB_TEST_REG3,
> +};
> +
> +static int th1520_usb_phy_probe(struct platform_device *pdev)
> +{
> +	struct phy_provider *phy_provider;
> +	struct device *dev = &pdev->dev;
> +	struct th1520_usb_phy *th1520_phy;
> +	struct reset_control *bus_reset;
> +	void __iomem *base;
> +	int ret;
> +
> +	th1520_phy = devm_kzalloc(dev, sizeof(*th1520_phy), GFP_KERNEL);
> +	if (!th1520_phy)
> +		return -ENOMEM;
> +
> +	th1520_phy->pdev = pdev;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	th1520_phy->ref_clk = devm_clk_get(dev, "ref");
> +	if (IS_ERR(th1520_phy->ref_clk))
> +		return PTR_ERR(th1520_phy->ref_clk);
> +
> +	/* De-assert the bus reset and leave it that way */
> +	bus_reset = devm_reset_control_get_exclusive_deasserted(dev, "bus");
> +	if (IS_ERR(bus_reset))
> +		return PTR_ERR(bus_reset);
> +
> +	th1520_phy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
> +	if (IS_ERR(th1520_phy->phy_reset))
> +		return PTR_ERR(th1520_phy->phy_reset);
> +
> +	/*
> +	 * Schematics of several boards (Lichee Module 4A/Milk-V Meles)
> +	 * describe this power rail as always-on.
> +	 */
> +	ret = devm_regulator_get_enable(dev, "avdd33-usb3");
> +	if (ret)
> +		return ret;
> +
> +	th1520_phy->regmap = devm_regmap_init_mmio_clk(dev, "bus",
> +						       base + USB_SYSCON_OFFSET,
> +						       &phy_regmap_config);
> +	if (IS_ERR(th1520_phy->regmap))
> +		return dev_err_probe(dev, PTR_ERR(th1520_phy->regmap),
> +				     "Failed to init regmap\n");
> +
> +	th1520_phy->phy = devm_phy_create(dev, dev->of_node, &th1520_usb_phy_ops);
> +	if (IS_ERR(th1520_phy->phy)) {
> +		dev_err(dev, "failed to create PHY\n");
> +		return PTR_ERR(th1520_phy->phy);
> +	}
> +
> +	phy_set_drvdata(th1520_phy->phy, th1520_phy);
> +
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id th1520_usb_phy_of_table[] = {
> +	{ .compatible = "thead,th1520-usb-phy" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, th1520_usb_phy_of_table);
> +
> +static struct platform_driver th1520_usb_phy_driver = {
> +	.driver = {
> +		.name = "th1520-usb-phy",
> +		.of_match_table = th1520_usb_phy_of_table,
> +	},
> +	.probe = th1520_usb_phy_probe,
> +};
> +
> +module_platform_driver(th1520_usb_phy_driver);
> +
> +MODULE_DESCRIPTION("T-Head TH1520 USB PHY driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.52.0

-- 
~Vinod

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

WARNING: multiple messages have this Message-ID (diff)
From: Vinod Koul <vkoul@kernel.org>
To: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Cc: Drew Fustini <fustini@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	Guo Ren <guoren@kernel.org>, Jisheng Zhang <jszhang@kernel.org>,
	linux-phy@lists.infradead.org, linux-riscv@lists.infradead.org,
	linux-clk@vger.kernel.org, Rob Herring <robh@kernel.org>,
	Alexandre Ghiti <alex@ghiti.fr>,
	devicetree@vger.kernel.org, Conor Dooley <conor+dt@kernel.org>,
	Albert Ou <aou@eecs.berkeley.edu>, Yao Zi <ziyao@disroot.org>,
	linux-gpio@vger.kernel.org, Paul Walmsley <pjw@kernel.org>,
	Neil Armstrong <neil.armstrong@linaro.org>,
	Stephen Boyd <sboyd@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Philipp Zabel <p.zabel@pengutronix.de>,
	Han Gao <rabenda.cn@gmail.com>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Fu Wei <wefu@redhat.com>
Subject: Re: [PATCH 05/12] phy: add a driver for T-Head TH1520 USB PHY
Date: Sun, 10 May 2026 13:14:17 +0530	[thread overview]
Message-ID: <agA3URhGA1u6R7LD@vaman> (raw)
In-Reply-To: <20260507081710.4090814-6-zhengxingda@iscas.ac.cn>

On 07-05-26, 16:17, Icenowy Zheng wrote:
> The USB PHY on T-Head TH1520 SoC is a Synopsys USB 3.0 FemtoPHY, with
> some PHY parameters exported as another system controller along with it.
> 
> As a few PHY parameters' default value isn't ready to work, add a driver
> configuring them before letting the PHY run, in addition to
> clock/reset/regulator management.

Is there any dependency on the rest of series, if not please split up!

Some warnings flagged by sashiko, please check
https://sashiko.dev/#/patchset/20260507081710.4090814-1-zhengxingda%40iscas.ac.cn


> 
> Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
> ---
>  drivers/phy/Kconfig                |   1 +
>  drivers/phy/Makefile               |   1 +
>  drivers/phy/thead/Kconfig          |  12 ++
>  drivers/phy/thead/Makefile         |   2 +
>  drivers/phy/thead/phy-th1520-usb.c | 197 +++++++++++++++++++++++++++++
>  5 files changed, 213 insertions(+)
>  create mode 100644 drivers/phy/thead/Kconfig
>  create mode 100644 drivers/phy/thead/Makefile
>  create mode 100644 drivers/phy/thead/phy-th1520-usb.c
> 
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 227b9a4c612e8..ea1a52e14b839 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -164,6 +164,7 @@ source "drivers/phy/st/Kconfig"
>  source "drivers/phy/starfive/Kconfig"
>  source "drivers/phy/sunplus/Kconfig"
>  source "drivers/phy/tegra/Kconfig"
> +source "drivers/phy/thead/Kconfig"
>  source "drivers/phy/ti/Kconfig"
>  source "drivers/phy/xilinx/Kconfig"
>  
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index f49d83f00a3d8..4604522548c91 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -48,5 +48,6 @@ obj-$(CONFIG_GENERIC_PHY)		+= allwinner/	\
>  					   starfive/	\
>  					   sunplus/	\
>  					   tegra/	\
> +					   thead/	\
>  					   ti/		\
>  					   xilinx/
> diff --git a/drivers/phy/thead/Kconfig b/drivers/phy/thead/Kconfig
> new file mode 100644
> index 0000000000000..14012db5973c4
> --- /dev/null
> +++ b/drivers/phy/thead/Kconfig
> @@ -0,0 +1,12 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +config PHY_TH1520_USB
> +	tristate "USB PHY driver for T-Head TH1520 SoC"
> +	depends on ARCH_THEAD || COMPILE_TEST
> +	depends on COMMON_CLK
> +	depends on HAS_IOMEM
> +	depends on OF
> +	depends on RESET_CONTROLLER
> +	select GENERIC_PHY
> +	default ARCH_THEAD

Why should this be default?

> +	help
> +	  Enable support for the USB PHY on the T-Head TH1520 SoC.
> diff --git a/drivers/phy/thead/Makefile b/drivers/phy/thead/Makefile
> new file mode 100644
> index 0000000000000..5b459bc7004bd
> --- /dev/null
> +++ b/drivers/phy/thead/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_PHY_TH1520_USB) += phy-th1520-usb.o
> diff --git a/drivers/phy/thead/phy-th1520-usb.c b/drivers/phy/thead/phy-th1520-usb.c
> new file mode 100644
> index 0000000000000..c87bd779bbb74
> --- /dev/null
> +++ b/drivers/phy/thead/phy-th1520-usb.c
> @@ -0,0 +1,197 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 Institute of Software, Chinese Academy of Sciences (ISCAS)
> + *
> + * Authors:
> + * Icenowy Zheng <zhengxingda@iscas.ac.cn>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +
> +#define USB_SYSCON_OFFSET		0xf000
> +
> +/* All the below registers are in the USB syscon region */
> +#define USB_CLK_GATE_STS		0x0
> +#define USB_LOGIC_ANALYZER_TRACE_STS0	0x4
> +#define USB_LOGIC_ANALYZER_TRACE_STS1	0x8
> +#define USB_GPIO			0xc
> +#define USB_DEBUG_STS0			0x10
> +#define USB_DEBUG_STS1			0x14
> +#define USB_DEBUG_STS2			0x18
> +#define USBCTL_CLK_CTRL0		0x1c
> +#define USBPHY_CLK_CTRL1		0x20
> +#define USBPHY_TEST_CTRL0		0x24
> +#define USBPHY_TEST_CTRL1		0x28
> +#define USBPHY_TEST_CTRL2		0x2c
> +#define USBPHY_TEST_CTRL3		0x30
> +#define USB_SSP_EN			0x34
> +#define USB_HADDR_SEL			0x38
> +#define USB_SYS				0x3c
> +#define USB_HOST_STATUS			0x40
> +#define USB_HOST_CTRL			0x44
> +#define USBPHY_HOST_CTRL		0x48
> +#define USBPHY_HOST_STATUS		0x4c
> +#define USB_TEST_REG0			0x50
> +#define USB_TEST_REG1			0x54
> +#define USB_TEST_REG2			0x58
> +#define USB_TEST_REG3			0x5c

Why do need these test registers, they seem unused?

> +
> +#define USB_SYS_COMMONONN		BIT(0)
> +
> +#define USB_SSP_EN_REF_SSP_EN		BIT(0)
> +
> +struct th1520_usb_phy {
> +	struct platform_device *pdev;
> +	struct phy *phy;
> +	struct regmap *regmap;
> +	struct clk *ref_clk;
> +	struct reset_control *phy_reset;
> +};
> +
> +static int th1520_usb_phy_init(struct phy *phy)
> +{
> +	struct th1520_usb_phy *th1520_phy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = clk_prepare_enable(th1520_phy->ref_clk);
> +	if (ret)
> +		return ret;
> +
> +	ret = reset_control_assert(th1520_phy->phy_reset);
> +	if (ret)
> +		goto err_disable_clk;
> +
> +	/*
> +	 * Do some initial PHY setup:
> +	 * - Set COMMONONN to allow the PHY to automatically power down.
> +	 * - Set REF_SSP_EN to enable feeding reference clock to SuperSpeed
> +	 *   PHY clock PLL.
> +	 */
> +	regmap_set_bits(th1520_phy->regmap, USB_SYS, USB_SYS_COMMONONN);
> +	regmap_set_bits(th1520_phy->regmap, USB_SSP_EN, USB_SSP_EN_REF_SSP_EN);
> +
> +	ret = reset_control_deassert(th1520_phy->phy_reset);
> +	if (ret)
> +		goto err_disable_clk;
> +
> +	udelay(10);
> +
> +	return 0;
> +
> +err_disable_clk:
> +	clk_disable_unprepare(th1520_phy->ref_clk);
> +	return ret;
> +}
> +
> +static int th1520_usb_phy_exit(struct phy *phy)
> +{
> +	struct th1520_usb_phy *th1520_phy = phy_get_drvdata(phy);
> +	int ret;
> +
> +	ret = reset_control_assert(th1520_phy->phy_reset);
> +	if (ret)
> +		return ret;
> +
> +	clk_disable_unprepare(th1520_phy->ref_clk);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops th1520_usb_phy_ops = {
> +	.init		= th1520_usb_phy_init,
> +	.exit		= th1520_usb_phy_exit,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static const struct regmap_config phy_regmap_config = {
> +	.reg_bits = 32,
> +	.val_bits = 32,
> +	.reg_stride = 4,
> +	.max_register = USB_TEST_REG3,
> +};
> +
> +static int th1520_usb_phy_probe(struct platform_device *pdev)
> +{
> +	struct phy_provider *phy_provider;
> +	struct device *dev = &pdev->dev;
> +	struct th1520_usb_phy *th1520_phy;
> +	struct reset_control *bus_reset;
> +	void __iomem *base;
> +	int ret;
> +
> +	th1520_phy = devm_kzalloc(dev, sizeof(*th1520_phy), GFP_KERNEL);
> +	if (!th1520_phy)
> +		return -ENOMEM;
> +
> +	th1520_phy->pdev = pdev;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	th1520_phy->ref_clk = devm_clk_get(dev, "ref");
> +	if (IS_ERR(th1520_phy->ref_clk))
> +		return PTR_ERR(th1520_phy->ref_clk);
> +
> +	/* De-assert the bus reset and leave it that way */
> +	bus_reset = devm_reset_control_get_exclusive_deasserted(dev, "bus");
> +	if (IS_ERR(bus_reset))
> +		return PTR_ERR(bus_reset);
> +
> +	th1520_phy->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
> +	if (IS_ERR(th1520_phy->phy_reset))
> +		return PTR_ERR(th1520_phy->phy_reset);
> +
> +	/*
> +	 * Schematics of several boards (Lichee Module 4A/Milk-V Meles)
> +	 * describe this power rail as always-on.
> +	 */
> +	ret = devm_regulator_get_enable(dev, "avdd33-usb3");
> +	if (ret)
> +		return ret;
> +
> +	th1520_phy->regmap = devm_regmap_init_mmio_clk(dev, "bus",
> +						       base + USB_SYSCON_OFFSET,
> +						       &phy_regmap_config);
> +	if (IS_ERR(th1520_phy->regmap))
> +		return dev_err_probe(dev, PTR_ERR(th1520_phy->regmap),
> +				     "Failed to init regmap\n");
> +
> +	th1520_phy->phy = devm_phy_create(dev, dev->of_node, &th1520_usb_phy_ops);
> +	if (IS_ERR(th1520_phy->phy)) {
> +		dev_err(dev, "failed to create PHY\n");
> +		return PTR_ERR(th1520_phy->phy);
> +	}
> +
> +	phy_set_drvdata(th1520_phy->phy, th1520_phy);
> +
> +	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id th1520_usb_phy_of_table[] = {
> +	{ .compatible = "thead,th1520-usb-phy" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, th1520_usb_phy_of_table);
> +
> +static struct platform_driver th1520_usb_phy_driver = {
> +	.driver = {
> +		.name = "th1520-usb-phy",
> +		.of_match_table = th1520_usb_phy_of_table,
> +	},
> +	.probe = th1520_usb_phy_probe,
> +};
> +
> +module_platform_driver(th1520_usb_phy_driver);
> +
> +MODULE_DESCRIPTION("T-Head TH1520 USB PHY driver");
> +MODULE_LICENSE("GPL");
> -- 
> 2.52.0

-- 
~Vinod

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

  reply	other threads:[~2026-05-10  7:44 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-07  8:16 [PATCH 00/12] Add TH1520 USB support Icenowy Zheng
2026-05-07  8:16 ` Icenowy Zheng
2026-05-07  8:16 ` Icenowy Zheng
2026-05-07  8:16 ` [PATCH 01/12] dt-bindings: clock: thead: add TH1520 MISC subsys clock controller Icenowy Zheng
2026-05-07  8:16   ` Icenowy Zheng
2026-05-07  8:16   ` Icenowy Zheng
2026-05-07 17:26   ` Conor Dooley
2026-05-07 17:26     ` Conor Dooley
2026-05-07 17:26     ` Conor Dooley
2026-05-07  8:17 ` [PATCH 02/12] clk: thead: th1520-ap: add support for MISC subsys clocks Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17 ` [PATCH 03/12] riscv: dts: thead: add device tree node for MISC clock controller Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17 ` [PATCH 04/12] dt-bindings: phy: add binding for T-Head TH1520 USB PHY Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07 17:26   ` Conor Dooley
2026-05-07 17:26     ` Conor Dooley
2026-05-07 17:26     ` Conor Dooley
2026-05-07  8:17 ` [PATCH 05/12] phy: add a driver " Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-10  7:44   ` Vinod Koul [this message]
2026-05-10  7:44     ` Vinod Koul
2026-05-10  7:44     ` Vinod Koul
2026-05-10  9:17     ` Icenowy Zheng
2026-05-10  9:17       ` Icenowy Zheng
2026-05-10  9:17       ` Icenowy Zheng
2026-05-11 16:16       ` Vinod Koul
2026-05-11 16:16         ` Vinod Koul
2026-05-11 16:16         ` Vinod Koul
2026-05-07  8:17 ` [PATCH 06/12] riscv: dts: thead: add device nodes for USB Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17 ` [PATCH 07/12] dt-bindings: gpio: dwapb: allow GPIO hogs Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07 17:25   ` Conor Dooley
2026-05-07 17:25     ` Conor Dooley
2026-05-07 17:25     ` Conor Dooley
2026-05-07  8:17 ` [PATCH 08/12] dt-bindings: usb: vialab,vl817: allow ports property Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07 17:25   ` Conor Dooley
2026-05-07 17:25     ` Conor Dooley
2026-05-07 17:25     ` Conor Dooley
2026-05-07  8:17 ` [PATCH 09/12] riscv: dts: thead: lpi4a: sort nodes Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17 ` [PATCH 10/12] riscv: dts: thead: Add TH1520 I2C nodes Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17 ` [PATCH 11/12] riscv: dts: thead: Add Lichee Pi 4A IO expansions Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17 ` [PATCH 12/12] riscv: dts: thead: enable USB3 ports on Lichee Pi 4A Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-07  8:17   ` Icenowy Zheng
2026-05-11 10:54 ` (subset) [PATCH 00/12] Add TH1520 USB support Bartosz Golaszewski
2026-05-11 10:54   ` Bartosz Golaszewski
2026-05-11 10:54   ` Bartosz Golaszewski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=agA3URhGA1u6R7LD@vaman \
    --to=vkoul@kernel.org \
    --cc=alex@ghiti.fr \
    --cc=aou@eecs.berkeley.edu \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=fustini@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=guoren@kernel.org \
    --cc=jszhang@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-phy@lists.infradead.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=neil.armstrong@linaro.org \
    --cc=p.zabel@pengutronix.de \
    --cc=palmer@dabbelt.com \
    --cc=pjw@kernel.org \
    --cc=rabenda.cn@gmail.com \
    --cc=robh@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=uwu@icenowy.me \
    --cc=wefu@redhat.com \
    --cc=zhengxingda@iscas.ac.cn \
    --cc=ziyao@disroot.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.