* [PATCH v2 0/3] Add AST2700 USB3.2 PHY driver
@ 2026-01-16 2:53 ` Ryan Chen
0 siblings, 0 replies; 12+ messages in thread
From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel
Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, Ryan Chen, Krzysztof Kozlowski
Add AST2700 USB3.2 PHY support.
- Supports Super Speed Plus Gen2x1 (10 Gbps), Super Speed (5 Gbps),
High Speed (480 Mbps), Full Speed (12Mbps), and Low Speed (1.5 Mbps).
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
Changes in v2:
- aspeed,ast2700-usb3-phy.yaml
- Drop clocks, resets descripton.
- Kconfig
- add COMPILE_TEST, remove default n
- Link to v1: https://lore.kernel.org/r/20260114-upstream_usb3phy-v1-0-2e59590be2d7@aspeedtech.com
---
Ryan Chen (3):
dt-bindings: phy: aspeed: Document AST2700 USB3.0 PHY
phy: add AST2700 usb3.2 phy driver
MAINTAINERS: Add ASPEED USB3 PHY driver
.../bindings/phy/aspeed,ast2700-usb3-phy.yaml | 48 +++++
MAINTAINERS | 8 +
drivers/phy/aspeed/Kconfig | 12 ++
drivers/phy/aspeed/Makefile | 2 +
drivers/phy/aspeed/phy-aspeed-usb3.c | 236 +++++++++++++++++++++
5 files changed, 306 insertions(+)
---
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
change-id: 20260112-upstream_usb3phy-7116f8dfe779
Best regards,
--
Ryan Chen <ryan_chen@aspeedtech.com>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2 0/3] Add AST2700 USB3.2 PHY driver @ 2026-01-16 2:53 ` Ryan Chen 0 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, Ryan Chen, Krzysztof Kozlowski Add AST2700 USB3.2 PHY support. - Supports Super Speed Plus Gen2x1 (10 Gbps), Super Speed (5 Gbps), High Speed (480 Mbps), Full Speed (12Mbps), and Low Speed (1.5 Mbps). Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com> --- Changes in v2: - aspeed,ast2700-usb3-phy.yaml - Drop clocks, resets descripton. - Kconfig - add COMPILE_TEST, remove default n - Link to v1: https://lore.kernel.org/r/20260114-upstream_usb3phy-v1-0-2e59590be2d7@aspeedtech.com --- Ryan Chen (3): dt-bindings: phy: aspeed: Document AST2700 USB3.0 PHY phy: add AST2700 usb3.2 phy driver MAINTAINERS: Add ASPEED USB3 PHY driver .../bindings/phy/aspeed,ast2700-usb3-phy.yaml | 48 +++++ MAINTAINERS | 8 + drivers/phy/aspeed/Kconfig | 12 ++ drivers/phy/aspeed/Makefile | 2 + drivers/phy/aspeed/phy-aspeed-usb3.c | 236 +++++++++++++++++++++ 5 files changed, 306 insertions(+) --- base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8 change-id: 20260112-upstream_usb3phy-7116f8dfe779 Best regards, -- Ryan Chen <ryan_chen@aspeedtech.com> -- linux-phy mailing list linux-phy@lists.infradead.org https://lists.infradead.org/mailman/listinfo/linux-phy ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/3] dt-bindings: phy: aspeed: Document AST2700 USB3.0 PHY 2026-01-16 2:53 ` Ryan Chen @ 2026-01-16 2:53 ` Ryan Chen -1 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, Ryan Chen, Krzysztof Kozlowski Document AST2700 USB3.2 PHY. This IP is connected between USB3 controller and PHY module. Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com> --- .../bindings/phy/aspeed,ast2700-usb3-phy.yaml | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml new file mode 100644 index 000000000000..b83037aa0438 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/aspeed,ast2700-usb3-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ASPEED AST2700 USB 3.2 PHY + +maintainers: + - Ryan Chen <ryan_chen@aspeedtech.com> + +properties: + compatible: + const: aspeed,ast2700-usb3-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + '#phy-cells': + const: 0 + +required: + - compatible + - reg + - clocks + - resets + - '#phy-cells' + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/aspeed,ast2700-scu.h> + #include <dt-bindings/reset/aspeed,ast2700-scu.h> + + usb-phy@12010000 { + compatible = "aspeed,ast2700-usb3-phy"; + reg = <0x12010000 0xc0>; + clocks = <&syscon0 SCU0_CLK_GATE_PORTAUSB2CLK>; + resets = <&syscon0 SCU0_RESET_PORTA_PHY3>; + #phy-cells = <0>; + }; -- 2.34.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 1/3] dt-bindings: phy: aspeed: Document AST2700 USB3.0 PHY @ 2026-01-16 2:53 ` Ryan Chen 0 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, Ryan Chen, Krzysztof Kozlowski Document AST2700 USB3.2 PHY. This IP is connected between USB3 controller and PHY module. Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com> Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com> --- .../bindings/phy/aspeed,ast2700-usb3-phy.yaml | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml new file mode 100644 index 000000000000..b83037aa0438 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/aspeed,ast2700-usb3-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ASPEED AST2700 USB 3.2 PHY + +maintainers: + - Ryan Chen <ryan_chen@aspeedtech.com> + +properties: + compatible: + const: aspeed,ast2700-usb3-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + '#phy-cells': + const: 0 + +required: + - compatible + - reg + - clocks + - resets + - '#phy-cells' + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/aspeed,ast2700-scu.h> + #include <dt-bindings/reset/aspeed,ast2700-scu.h> + + usb-phy@12010000 { + compatible = "aspeed,ast2700-usb3-phy"; + reg = <0x12010000 0xc0>; + clocks = <&syscon0 SCU0_CLK_GATE_PORTAUSB2CLK>; + resets = <&syscon0 SCU0_RESET_PORTA_PHY3>; + #phy-cells = <0>; + }; -- 2.34.1 -- linux-phy mailing list linux-phy@lists.infradead.org https://lists.infradead.org/mailman/listinfo/linux-phy ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver 2026-01-16 2:53 ` Ryan Chen @ 2026-01-16 2:53 ` Ryan Chen -1 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, Ryan Chen Add AST2700 USB3.2 PHY driver support. Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com> --- drivers/phy/aspeed/Kconfig | 12 ++ drivers/phy/aspeed/Makefile | 2 + drivers/phy/aspeed/phy-aspeed-usb3.c | 236 +++++++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) diff --git a/drivers/phy/aspeed/Kconfig b/drivers/phy/aspeed/Kconfig new file mode 100644 index 000000000000..72b4fc17a85e --- /dev/null +++ b/drivers/phy/aspeed/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# +# PHY drivers for ASPEED +# + +config PHY_ASPEED_USB3 + tristate "ASPEED USB3 PHY driver" + select GENERIC_PHY + depends on (ARCH_ASPEED || COMPILE_TEST) + help + Enable driver support for Aspeed AST2700 USB3 PHY. diff --git a/drivers/phy/aspeed/Makefile b/drivers/phy/aspeed/Makefile new file mode 100644 index 000000000000..20b5ac7b7e64 --- /dev/null +++ b/drivers/phy/aspeed/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_ASPEED_USB3_PHY) += phy-aspeed-usb3.o diff --git a/drivers/phy/aspeed/phy-aspeed-usb3.c b/drivers/phy/aspeed/phy-aspeed-usb3.c new file mode 100644 index 000000000000..872d2163fcf5 --- /dev/null +++ b/drivers/phy/aspeed/phy-aspeed-usb3.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2026 Aspeed Technology Inc. + */ + +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/reset.h> + +#define PHY3S00 0x00 +#define PHY3S00_INIT_DONE BIT(15) +#define PHY3S00_SRAM_BYPASS BIT(7) +#define PHY3S00_SRAM_EXT_LOAD BIT(6) +#define PHY3S04 0x04 +#define PHY3C00 0x08 +#define PHY3C04 0x0C +#define PHY3P00 0x10 +#define PHY3P00_RX_ADAPT_AFE_EN_G1 BIT(0) +#define PHY3P00_RX_ADAPT_AFE_EN_G2 BIT(1) +#define PHY3P00_RX_ADAPT_DFE_EN_G1 BIT(2) +#define PHY3P00_RX_ADAPT_DFE_EN_G2 BIT(3) +#define PHY3P00_RX_CDR_VCO_LOWFREQ_G1 BIT(4) +#define PHY3P00_RX_CDR_VCO_LOWFREQ_G2 BIT(5) +#define PHY3P00_RX_EQ_AFE_GAIN_G1 GENMASK(9, 6) +#define PHY3P00_RX_EQ_AFE_GAIN_G2 GENMASK(13, 10) +#define PHY3P00_RX_EQ_ATT_LVL_G1 GENMASK(16, 14) +#define PHY3P00_RX_EQ_ATT_LVL_G2 GENMASK(19, 17) +#define PHY3P00_RX_EQ_CTLE_BOOST_G1 GENMASK(24, 20) +#define PHY3P00_RX_EQ_CTLE_BOOST_G2 GENMASK(29, 25) +#define PHY3P00_RX_EQ_DELTA_IQ_G1_LO GENMASK(31, 30) + +#define PHY3P04 0x14 +#define PHY3P04_RX_EQ_DELTA_IQ_G1_HI GENMASK(1, 0) +#define PHY3P04_RX_EQ_DELTA_IQ_G2 GENMASK(5, 2) +#define PHY3P04_RX_EQ_DFE_TAP1_G1 GENMASK(13, 6) +#define PHY3P04_RX_EQ_DFE_TAP1_G2 GENMASK(21, 14) +#define PHY3P04_RX_LOS_LFPS_EN BIT(22) +#define PHY3P04_RX_LOS_THRESHOLD GENMASK(25, 23) +#define PHY3P04_RX_TERM_CTRL GENMASK(28, 26) +#define PHY3P04_TX_EQ_MAIN_G1_LO GENMASK(31, 29) + +#define PHY3P08 0x18 +#define PHY3P08_TX_EQ_MAIN_G1_HI GENMASK(1, 0) +#define PHY3P08_TX_EQ_MAIN_G2 GENMASK(6, 2) +#define PHY3P08_TX_EQ_OVRD BIT(7) +#define PHY3P08_TX_EQ_POST_G1 GENMASK(12, 9) +#define PHY3P08_TX_EQ_POST_G2 GENMASK(16, 13) +#define PHY3P08_TX_EQ_PRE_G1 GENMASK(20, 17) +#define PHY3P08_TX_EQ_PRE_G2 GENMASK(24, 21) +#define PHY3P08_TX_IBOOST_LVL GENMASK(28, 25) +#define PHY3P08_TX_TERM_CTRL GENMASK(31, 29) + +#define PHY3P0C 0x1C +#define PHY3P0C_TX_VBOOST_EN BIT(0) + +#define PHY3CMD 0x40 + +#define PHY3P_RX_EQ_CTLE_BOOST_G1_DEFAULT 0x7 +#define PHY3P_RX_EQ_CTLE_BOOST_G2_DEFAULT 0x7 +#define PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT 0x3 +#define PHY3P_RX_EQ_DELTA_IQ_G2_DEFAULT 0x5 +#define PHY3P_RX_LOS_THRESHOLD_DEFAULT 0x3 +#define PHY3P_RX_TERM_CTRL_DEFAULT 0x2 +#define PHY3P_TX_EQ_MAIN_G1_DEFAULT 0xa +#define PHY3P_TX_EQ_MAIN_G2_DEFAULT 0x9 +#define PHY3P_TX_EQ_POST_G1_DEFAULT 0x4 +#define PHY3P_TX_EQ_POST_G2_DEFAULT 0x3 +#define PHY3P_TX_EQ_PRE_G2_DEFAULT 0x2 +#define PHY3P_TX_IBOOST_LVL_DEFAULT 0xf +#define PHY3P_TX_TERM_CTRL_DEFAULT 0x2 + +#define PHY3P00_DEFAULT ( \ + PHY3P00_RX_ADAPT_AFE_EN_G1 | \ + PHY3P00_RX_ADAPT_AFE_EN_G2 | \ + PHY3P00_RX_ADAPT_DFE_EN_G1 | \ + PHY3P00_RX_ADAPT_DFE_EN_G2 | \ + FIELD_PREP(PHY3P00_RX_EQ_CTLE_BOOST_G1, PHY3P_RX_EQ_CTLE_BOOST_G1_DEFAULT) | \ + FIELD_PREP(PHY3P00_RX_EQ_CTLE_BOOST_G2, PHY3P_RX_EQ_CTLE_BOOST_G2_DEFAULT) | \ + FIELD_PREP(PHY3P00_RX_EQ_DELTA_IQ_G1_LO, \ + PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT & 0x3) \ +) + +#define PHY3P04_DEFAULT ( \ + FIELD_PREP(PHY3P04_RX_EQ_DELTA_IQ_G1_HI, \ + PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT >> 2) | \ + FIELD_PREP(PHY3P04_RX_EQ_DELTA_IQ_G2, PHY3P_RX_EQ_DELTA_IQ_G2_DEFAULT) | \ + PHY3P04_RX_LOS_LFPS_EN | \ + FIELD_PREP(PHY3P04_RX_LOS_THRESHOLD, PHY3P_RX_LOS_THRESHOLD_DEFAULT) | \ + FIELD_PREP(PHY3P04_RX_TERM_CTRL, PHY3P_RX_TERM_CTRL_DEFAULT) | \ + FIELD_PREP(PHY3P04_TX_EQ_MAIN_G1_LO, \ + PHY3P_TX_EQ_MAIN_G1_DEFAULT & 0x7) \ +) + +#define PHY3P08_DEFAULT ( \ + FIELD_PREP(PHY3P08_TX_EQ_MAIN_G1_HI, PHY3P_TX_EQ_MAIN_G1_DEFAULT >> 3) | \ + FIELD_PREP(PHY3P08_TX_EQ_MAIN_G2, PHY3P_TX_EQ_MAIN_G2_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_EQ_POST_G1, PHY3P_TX_EQ_POST_G1_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_EQ_POST_G2, PHY3P_TX_EQ_POST_G2_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_EQ_PRE_G2, PHY3P_TX_EQ_PRE_G2_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_IBOOST_LVL, PHY3P_TX_IBOOST_LVL_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_TERM_CTRL, PHY3P_TX_TERM_CTRL_DEFAULT) \ +) + +#define PHY3P0C_DEFAULT \ + PHY3P0C_TX_VBOOST_EN + +struct aspeed_usb3_phy { + void __iomem *regs; + struct reset_control *rst; + struct device *dev; + struct clk *clk; +}; + +static int aspeed_usb3_phy_init(struct phy *phy) +{ + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); + u32 val; + int ret; + + ret = clk_prepare_enable(aspeed_phy->clk); + if (ret) { + dev_err(aspeed_phy->dev, "Failed to enable clock %d\n", ret); + return ret; + } + + ret = reset_control_deassert(aspeed_phy->rst); + if (ret) { + clk_disable_unprepare(aspeed_phy->clk); + return ret; + } + + /* Wait for USB3 PHY internal SRAM initialization done */ + ret = readl_poll_timeout(aspeed_phy->regs + PHY3S00, val, + val & PHY3S00_INIT_DONE, + USEC_PER_MSEC, 10 * USEC_PER_MSEC); + if (ret) { + dev_err(aspeed_phy->dev, "SRAM init timeout\n"); + goto err_assert_reset; + } + + val = readl(aspeed_phy->regs + PHY3S00); + val |= PHY3S00_SRAM_BYPASS; + writel(val, aspeed_phy->regs + PHY3S00); + + /* Set protocol1_ext signals as default PHY3 settings based on SNPS documents. + * Including PCFGI[54]: protocol1_ext_rx_los_lfps_en for better compatibility + */ + writel(PHY3P00_DEFAULT, aspeed_phy->regs + PHY3P00); + writel(PHY3P04_DEFAULT, aspeed_phy->regs + PHY3P04); + writel(PHY3P08_DEFAULT, aspeed_phy->regs + PHY3P08); + writel(PHY3P0C_DEFAULT, aspeed_phy->regs + PHY3P0C); + + return 0; + +err_assert_reset: + reset_control_assert(aspeed_phy->rst); + clk_disable_unprepare(aspeed_phy->clk); + return ret; +} + +static int aspeed_usb3_phy_exit(struct phy *phy) +{ + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); + + reset_control_assert(aspeed_phy->rst); + clk_disable_unprepare(aspeed_phy->clk); + + return 0; +} + +static const struct phy_ops aspeed_usb3_phy_ops = { + .init = aspeed_usb3_phy_init, + .exit = aspeed_usb3_phy_exit, + .owner = THIS_MODULE, +}; + +static int aspeed_usb3_phy_probe(struct platform_device *pdev) +{ + struct aspeed_usb3_phy *aspeed_phy; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct phy *phy; + + aspeed_phy = devm_kzalloc(dev, sizeof(*aspeed_phy), GFP_KERNEL); + if (!aspeed_phy) + return -ENOMEM; + + aspeed_phy->dev = dev; + + aspeed_phy->clk = devm_clk_get(dev, NULL); + if (IS_ERR(aspeed_phy->clk)) + return PTR_ERR(aspeed_phy->clk); + + aspeed_phy->rst = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(aspeed_phy->rst)) + return PTR_ERR(aspeed_phy->rst); + + aspeed_phy->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(aspeed_phy->regs)) + return PTR_ERR(aspeed_phy->regs); + + phy = devm_phy_create(dev, NULL, &aspeed_usb3_phy_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + phy_set_drvdata(phy, aspeed_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 aspeed_usb3_phy_match_table[] = { + { + .compatible = "aspeed,ast2700-usb3-phy", + }, + { } +}; +MODULE_DEVICE_TABLE(of, aspeed_usb3_phy_match_table); + +static struct platform_driver aspeed_usb3_phy_driver = { + .probe = aspeed_usb3_phy_probe, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = aspeed_usb3_phy_match_table, + }, +}; +module_platform_driver(aspeed_usb3_phy_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ASPEED USB3.0 PHY Driver"); -- 2.34.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver @ 2026-01-16 2:53 ` Ryan Chen 0 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, Ryan Chen Add AST2700 USB3.2 PHY driver support. Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com> --- drivers/phy/aspeed/Kconfig | 12 ++ drivers/phy/aspeed/Makefile | 2 + drivers/phy/aspeed/phy-aspeed-usb3.c | 236 +++++++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) diff --git a/drivers/phy/aspeed/Kconfig b/drivers/phy/aspeed/Kconfig new file mode 100644 index 000000000000..72b4fc17a85e --- /dev/null +++ b/drivers/phy/aspeed/Kconfig @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# +# PHY drivers for ASPEED +# + +config PHY_ASPEED_USB3 + tristate "ASPEED USB3 PHY driver" + select GENERIC_PHY + depends on (ARCH_ASPEED || COMPILE_TEST) + help + Enable driver support for Aspeed AST2700 USB3 PHY. diff --git a/drivers/phy/aspeed/Makefile b/drivers/phy/aspeed/Makefile new file mode 100644 index 000000000000..20b5ac7b7e64 --- /dev/null +++ b/drivers/phy/aspeed/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_ASPEED_USB3_PHY) += phy-aspeed-usb3.o diff --git a/drivers/phy/aspeed/phy-aspeed-usb3.c b/drivers/phy/aspeed/phy-aspeed-usb3.c new file mode 100644 index 000000000000..872d2163fcf5 --- /dev/null +++ b/drivers/phy/aspeed/phy-aspeed-usb3.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2026 Aspeed Technology Inc. + */ + +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/reset.h> + +#define PHY3S00 0x00 +#define PHY3S00_INIT_DONE BIT(15) +#define PHY3S00_SRAM_BYPASS BIT(7) +#define PHY3S00_SRAM_EXT_LOAD BIT(6) +#define PHY3S04 0x04 +#define PHY3C00 0x08 +#define PHY3C04 0x0C +#define PHY3P00 0x10 +#define PHY3P00_RX_ADAPT_AFE_EN_G1 BIT(0) +#define PHY3P00_RX_ADAPT_AFE_EN_G2 BIT(1) +#define PHY3P00_RX_ADAPT_DFE_EN_G1 BIT(2) +#define PHY3P00_RX_ADAPT_DFE_EN_G2 BIT(3) +#define PHY3P00_RX_CDR_VCO_LOWFREQ_G1 BIT(4) +#define PHY3P00_RX_CDR_VCO_LOWFREQ_G2 BIT(5) +#define PHY3P00_RX_EQ_AFE_GAIN_G1 GENMASK(9, 6) +#define PHY3P00_RX_EQ_AFE_GAIN_G2 GENMASK(13, 10) +#define PHY3P00_RX_EQ_ATT_LVL_G1 GENMASK(16, 14) +#define PHY3P00_RX_EQ_ATT_LVL_G2 GENMASK(19, 17) +#define PHY3P00_RX_EQ_CTLE_BOOST_G1 GENMASK(24, 20) +#define PHY3P00_RX_EQ_CTLE_BOOST_G2 GENMASK(29, 25) +#define PHY3P00_RX_EQ_DELTA_IQ_G1_LO GENMASK(31, 30) + +#define PHY3P04 0x14 +#define PHY3P04_RX_EQ_DELTA_IQ_G1_HI GENMASK(1, 0) +#define PHY3P04_RX_EQ_DELTA_IQ_G2 GENMASK(5, 2) +#define PHY3P04_RX_EQ_DFE_TAP1_G1 GENMASK(13, 6) +#define PHY3P04_RX_EQ_DFE_TAP1_G2 GENMASK(21, 14) +#define PHY3P04_RX_LOS_LFPS_EN BIT(22) +#define PHY3P04_RX_LOS_THRESHOLD GENMASK(25, 23) +#define PHY3P04_RX_TERM_CTRL GENMASK(28, 26) +#define PHY3P04_TX_EQ_MAIN_G1_LO GENMASK(31, 29) + +#define PHY3P08 0x18 +#define PHY3P08_TX_EQ_MAIN_G1_HI GENMASK(1, 0) +#define PHY3P08_TX_EQ_MAIN_G2 GENMASK(6, 2) +#define PHY3P08_TX_EQ_OVRD BIT(7) +#define PHY3P08_TX_EQ_POST_G1 GENMASK(12, 9) +#define PHY3P08_TX_EQ_POST_G2 GENMASK(16, 13) +#define PHY3P08_TX_EQ_PRE_G1 GENMASK(20, 17) +#define PHY3P08_TX_EQ_PRE_G2 GENMASK(24, 21) +#define PHY3P08_TX_IBOOST_LVL GENMASK(28, 25) +#define PHY3P08_TX_TERM_CTRL GENMASK(31, 29) + +#define PHY3P0C 0x1C +#define PHY3P0C_TX_VBOOST_EN BIT(0) + +#define PHY3CMD 0x40 + +#define PHY3P_RX_EQ_CTLE_BOOST_G1_DEFAULT 0x7 +#define PHY3P_RX_EQ_CTLE_BOOST_G2_DEFAULT 0x7 +#define PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT 0x3 +#define PHY3P_RX_EQ_DELTA_IQ_G2_DEFAULT 0x5 +#define PHY3P_RX_LOS_THRESHOLD_DEFAULT 0x3 +#define PHY3P_RX_TERM_CTRL_DEFAULT 0x2 +#define PHY3P_TX_EQ_MAIN_G1_DEFAULT 0xa +#define PHY3P_TX_EQ_MAIN_G2_DEFAULT 0x9 +#define PHY3P_TX_EQ_POST_G1_DEFAULT 0x4 +#define PHY3P_TX_EQ_POST_G2_DEFAULT 0x3 +#define PHY3P_TX_EQ_PRE_G2_DEFAULT 0x2 +#define PHY3P_TX_IBOOST_LVL_DEFAULT 0xf +#define PHY3P_TX_TERM_CTRL_DEFAULT 0x2 + +#define PHY3P00_DEFAULT ( \ + PHY3P00_RX_ADAPT_AFE_EN_G1 | \ + PHY3P00_RX_ADAPT_AFE_EN_G2 | \ + PHY3P00_RX_ADAPT_DFE_EN_G1 | \ + PHY3P00_RX_ADAPT_DFE_EN_G2 | \ + FIELD_PREP(PHY3P00_RX_EQ_CTLE_BOOST_G1, PHY3P_RX_EQ_CTLE_BOOST_G1_DEFAULT) | \ + FIELD_PREP(PHY3P00_RX_EQ_CTLE_BOOST_G2, PHY3P_RX_EQ_CTLE_BOOST_G2_DEFAULT) | \ + FIELD_PREP(PHY3P00_RX_EQ_DELTA_IQ_G1_LO, \ + PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT & 0x3) \ +) + +#define PHY3P04_DEFAULT ( \ + FIELD_PREP(PHY3P04_RX_EQ_DELTA_IQ_G1_HI, \ + PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT >> 2) | \ + FIELD_PREP(PHY3P04_RX_EQ_DELTA_IQ_G2, PHY3P_RX_EQ_DELTA_IQ_G2_DEFAULT) | \ + PHY3P04_RX_LOS_LFPS_EN | \ + FIELD_PREP(PHY3P04_RX_LOS_THRESHOLD, PHY3P_RX_LOS_THRESHOLD_DEFAULT) | \ + FIELD_PREP(PHY3P04_RX_TERM_CTRL, PHY3P_RX_TERM_CTRL_DEFAULT) | \ + FIELD_PREP(PHY3P04_TX_EQ_MAIN_G1_LO, \ + PHY3P_TX_EQ_MAIN_G1_DEFAULT & 0x7) \ +) + +#define PHY3P08_DEFAULT ( \ + FIELD_PREP(PHY3P08_TX_EQ_MAIN_G1_HI, PHY3P_TX_EQ_MAIN_G1_DEFAULT >> 3) | \ + FIELD_PREP(PHY3P08_TX_EQ_MAIN_G2, PHY3P_TX_EQ_MAIN_G2_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_EQ_POST_G1, PHY3P_TX_EQ_POST_G1_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_EQ_POST_G2, PHY3P_TX_EQ_POST_G2_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_EQ_PRE_G2, PHY3P_TX_EQ_PRE_G2_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_IBOOST_LVL, PHY3P_TX_IBOOST_LVL_DEFAULT) | \ + FIELD_PREP(PHY3P08_TX_TERM_CTRL, PHY3P_TX_TERM_CTRL_DEFAULT) \ +) + +#define PHY3P0C_DEFAULT \ + PHY3P0C_TX_VBOOST_EN + +struct aspeed_usb3_phy { + void __iomem *regs; + struct reset_control *rst; + struct device *dev; + struct clk *clk; +}; + +static int aspeed_usb3_phy_init(struct phy *phy) +{ + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); + u32 val; + int ret; + + ret = clk_prepare_enable(aspeed_phy->clk); + if (ret) { + dev_err(aspeed_phy->dev, "Failed to enable clock %d\n", ret); + return ret; + } + + ret = reset_control_deassert(aspeed_phy->rst); + if (ret) { + clk_disable_unprepare(aspeed_phy->clk); + return ret; + } + + /* Wait for USB3 PHY internal SRAM initialization done */ + ret = readl_poll_timeout(aspeed_phy->regs + PHY3S00, val, + val & PHY3S00_INIT_DONE, + USEC_PER_MSEC, 10 * USEC_PER_MSEC); + if (ret) { + dev_err(aspeed_phy->dev, "SRAM init timeout\n"); + goto err_assert_reset; + } + + val = readl(aspeed_phy->regs + PHY3S00); + val |= PHY3S00_SRAM_BYPASS; + writel(val, aspeed_phy->regs + PHY3S00); + + /* Set protocol1_ext signals as default PHY3 settings based on SNPS documents. + * Including PCFGI[54]: protocol1_ext_rx_los_lfps_en for better compatibility + */ + writel(PHY3P00_DEFAULT, aspeed_phy->regs + PHY3P00); + writel(PHY3P04_DEFAULT, aspeed_phy->regs + PHY3P04); + writel(PHY3P08_DEFAULT, aspeed_phy->regs + PHY3P08); + writel(PHY3P0C_DEFAULT, aspeed_phy->regs + PHY3P0C); + + return 0; + +err_assert_reset: + reset_control_assert(aspeed_phy->rst); + clk_disable_unprepare(aspeed_phy->clk); + return ret; +} + +static int aspeed_usb3_phy_exit(struct phy *phy) +{ + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); + + reset_control_assert(aspeed_phy->rst); + clk_disable_unprepare(aspeed_phy->clk); + + return 0; +} + +static const struct phy_ops aspeed_usb3_phy_ops = { + .init = aspeed_usb3_phy_init, + .exit = aspeed_usb3_phy_exit, + .owner = THIS_MODULE, +}; + +static int aspeed_usb3_phy_probe(struct platform_device *pdev) +{ + struct aspeed_usb3_phy *aspeed_phy; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct phy *phy; + + aspeed_phy = devm_kzalloc(dev, sizeof(*aspeed_phy), GFP_KERNEL); + if (!aspeed_phy) + return -ENOMEM; + + aspeed_phy->dev = dev; + + aspeed_phy->clk = devm_clk_get(dev, NULL); + if (IS_ERR(aspeed_phy->clk)) + return PTR_ERR(aspeed_phy->clk); + + aspeed_phy->rst = devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(aspeed_phy->rst)) + return PTR_ERR(aspeed_phy->rst); + + aspeed_phy->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(aspeed_phy->regs)) + return PTR_ERR(aspeed_phy->regs); + + phy = devm_phy_create(dev, NULL, &aspeed_usb3_phy_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + phy_set_drvdata(phy, aspeed_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 aspeed_usb3_phy_match_table[] = { + { + .compatible = "aspeed,ast2700-usb3-phy", + }, + { } +}; +MODULE_DEVICE_TABLE(of, aspeed_usb3_phy_match_table); + +static struct platform_driver aspeed_usb3_phy_driver = { + .probe = aspeed_usb3_phy_probe, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = aspeed_usb3_phy_match_table, + }, +}; +module_platform_driver(aspeed_usb3_phy_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ASPEED USB3.0 PHY Driver"); -- 2.34.1 -- linux-phy mailing list linux-phy@lists.infradead.org https://lists.infradead.org/mailman/listinfo/linux-phy ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver 2026-01-16 2:53 ` Ryan Chen @ 2026-07-09 2:15 ` Andrew Jeffery -1 siblings, 0 replies; 12+ messages in thread From: Andrew Jeffery @ 2026-07-09 2:15 UTC (permalink / raw) To: Ryan Chen, Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel Hi Ryan, On Fri, 2026-01-16 at 10:53 +0800, Ryan Chen wrote: ... > diff --git a/drivers/phy/aspeed/phy-aspeed-usb3.c b/drivers/phy/aspeed/phy-aspeed-usb3.c > new file mode 100644 > index 000000000000..872d2163fcf5 > --- /dev/null > +++ b/drivers/phy/aspeed/phy-aspeed-usb3.c > @@ -0,0 +1,236 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2026 Aspeed Technology Inc. > + */ > + > +#include <linux/bitfield.h> > +#include <linux/clk.h> > +#include <linux/io.h> > +#include <linux/iopoll.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/phy/phy.h> > +#include <linux/platform_device.h> > +#include <linux/reset.h> > + > +#define PHY3S00 0x00 > +#define PHY3S00_INIT_DONE BIT(15) > +#define PHY3S00_SRAM_BYPASS BIT(7) > +#define PHY3S00_SRAM_EXT_LOAD BIT(6) > ... > + > +static int aspeed_usb3_phy_init(struct phy *phy) > +{ > + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); > + u32 val; > + int ret; > + > + ret = clk_prepare_enable(aspeed_phy->clk); > + if (ret) { > + dev_err(aspeed_phy->dev, "Failed to enable clock %d\n", ret); > + return ret; > + } > + > + ret = reset_control_deassert(aspeed_phy->rst); > + if (ret) { > + clk_disable_unprepare(aspeed_phy->clk); > + return ret; Nit: Given we have to do this below if the reset_control_deassert() succeeds, perhaps add a label below and use goto here? > + } > + > + /* Wait for USB3 PHY internal SRAM initialization done */ > + ret = readl_poll_timeout(aspeed_phy->regs + PHY3S00, val, > + val & PHY3S00_INIT_DONE, > + USEC_PER_MSEC, 10 * USEC_PER_MSEC); > + if (ret) { > + dev_err(aspeed_phy->dev, "SRAM init timeout\n"); > + goto err_assert_reset; > + } > + > + val = readl(aspeed_phy->regs + PHY3S00); > + val |= PHY3S00_SRAM_BYPASS; > + writel(val, aspeed_phy->regs + PHY3S00); According to the datasheet PHY3S00[15] (PHY3S00_INIT_DONE above) indicates that the PHY internal SRAM initialisation is complete. The datasheet reports the SRAM is used for configuration of calibration among other things. PHY3S00[6] instructs the PHY that software has completed loading the configuration data into SRAM, however PHY3S00_SRAM_BYPASS (PHY3S00[7]) tells the PHY to load configuration from "hard wired" values. Is it necessary to wait for SRAM initialisation to complete if we're bypassing it? Or are there other side-effects involved in the setting of PHY3S00[15]? > + > + /* Set protocol1_ext signals as default PHY3 settings based on SNPS documents. > + * Including PCFGI[54]: protocol1_ext_rx_los_lfps_en for better compatibility > + */ > + writel(PHY3P00_DEFAULT, aspeed_phy->regs + PHY3P00); > + writel(PHY3P04_DEFAULT, aspeed_phy->regs + PHY3P04); > + writel(PHY3P08_DEFAULT, aspeed_phy->regs + PHY3P08); > + writel(PHY3P0C_DEFAULT, aspeed_phy->regs + PHY3P0C); > + > + return 0; > + > +err_assert_reset: > + reset_control_assert(aspeed_phy->rst); > + clk_disable_unprepare(aspeed_phy->clk); > + return ret; > +} > ... > > +static struct platform_driver aspeed_usb3_phy_driver = { > + .probe = aspeed_usb3_phy_probe, > + .driver = { > + .name = KBUILD_MODNAME, > + .of_match_table = aspeed_usb3_phy_match_table, > + }, > +}; > +module_platform_driver(aspeed_usb3_phy_driver); > + > +MODULE_LICENSE("GPL"); > +MODULE_DESCRIPTION("ASPEED USB3.0 PHY Driver"); MODULE_AUTHOR()? Andrew ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver @ 2026-07-09 2:15 ` Andrew Jeffery 0 siblings, 0 replies; 12+ messages in thread From: Andrew Jeffery @ 2026-07-09 2:15 UTC (permalink / raw) To: Ryan Chen, Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel Hi Ryan, On Fri, 2026-01-16 at 10:53 +0800, Ryan Chen wrote: ... > diff --git a/drivers/phy/aspeed/phy-aspeed-usb3.c b/drivers/phy/aspeed/phy-aspeed-usb3.c > new file mode 100644 > index 000000000000..872d2163fcf5 > --- /dev/null > +++ b/drivers/phy/aspeed/phy-aspeed-usb3.c > @@ -0,0 +1,236 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright 2026 Aspeed Technology Inc. > + */ > + > +#include <linux/bitfield.h> > +#include <linux/clk.h> > +#include <linux/io.h> > +#include <linux/iopoll.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/phy/phy.h> > +#include <linux/platform_device.h> > +#include <linux/reset.h> > + > +#define PHY3S00 0x00 > +#define PHY3S00_INIT_DONE BIT(15) > +#define PHY3S00_SRAM_BYPASS BIT(7) > +#define PHY3S00_SRAM_EXT_LOAD BIT(6) > ... > + > +static int aspeed_usb3_phy_init(struct phy *phy) > +{ > + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); > + u32 val; > + int ret; > + > + ret = clk_prepare_enable(aspeed_phy->clk); > + if (ret) { > + dev_err(aspeed_phy->dev, "Failed to enable clock %d\n", ret); > + return ret; > + } > + > + ret = reset_control_deassert(aspeed_phy->rst); > + if (ret) { > + clk_disable_unprepare(aspeed_phy->clk); > + return ret; Nit: Given we have to do this below if the reset_control_deassert() succeeds, perhaps add a label below and use goto here? > + } > + > + /* Wait for USB3 PHY internal SRAM initialization done */ > + ret = readl_poll_timeout(aspeed_phy->regs + PHY3S00, val, > + val & PHY3S00_INIT_DONE, > + USEC_PER_MSEC, 10 * USEC_PER_MSEC); > + if (ret) { > + dev_err(aspeed_phy->dev, "SRAM init timeout\n"); > + goto err_assert_reset; > + } > + > + val = readl(aspeed_phy->regs + PHY3S00); > + val |= PHY3S00_SRAM_BYPASS; > + writel(val, aspeed_phy->regs + PHY3S00); According to the datasheet PHY3S00[15] (PHY3S00_INIT_DONE above) indicates that the PHY internal SRAM initialisation is complete. The datasheet reports the SRAM is used for configuration of calibration among other things. PHY3S00[6] instructs the PHY that software has completed loading the configuration data into SRAM, however PHY3S00_SRAM_BYPASS (PHY3S00[7]) tells the PHY to load configuration from "hard wired" values. Is it necessary to wait for SRAM initialisation to complete if we're bypassing it? Or are there other side-effects involved in the setting of PHY3S00[15]? > + > + /* Set protocol1_ext signals as default PHY3 settings based on SNPS documents. > + * Including PCFGI[54]: protocol1_ext_rx_los_lfps_en for better compatibility > + */ > + writel(PHY3P00_DEFAULT, aspeed_phy->regs + PHY3P00); > + writel(PHY3P04_DEFAULT, aspeed_phy->regs + PHY3P04); > + writel(PHY3P08_DEFAULT, aspeed_phy->regs + PHY3P08); > + writel(PHY3P0C_DEFAULT, aspeed_phy->regs + PHY3P0C); > + > + return 0; > + > +err_assert_reset: > + reset_control_assert(aspeed_phy->rst); > + clk_disable_unprepare(aspeed_phy->clk); > + return ret; > +} > ... > > +static struct platform_driver aspeed_usb3_phy_driver = { > + .probe = aspeed_usb3_phy_probe, > + .driver = { > + .name = KBUILD_MODNAME, > + .of_match_table = aspeed_usb3_phy_match_table, > + }, > +}; > +module_platform_driver(aspeed_usb3_phy_driver); > + > +MODULE_LICENSE("GPL"); > +MODULE_DESCRIPTION("ASPEED USB3.0 PHY Driver"); MODULE_AUTHOR()? Andrew -- linux-phy mailing list linux-phy@lists.infradead.org https://lists.infradead.org/mailman/listinfo/linux-phy ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver 2026-07-09 2:15 ` Andrew Jeffery @ 2026-07-15 5:55 ` Ryan Chen -1 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-07-15 5:55 UTC (permalink / raw) To: Andrew Jeffery, Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Philipp Zabel Cc: linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org > Subject: Re: [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver > > Hi Ryan, > > On Fri, 2026-01-16 at 10:53 +0800, Ryan Chen wrote: > > > ... > > > diff --git a/drivers/phy/aspeed/phy-aspeed-usb3.c > > b/drivers/phy/aspeed/phy-aspeed-usb3.c > > new file mode 100644 > > index 000000000000..872d2163fcf5 > > --- /dev/null > > +++ b/drivers/phy/aspeed/phy-aspeed-usb3.c > > @@ -0,0 +1,236 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright 2026 Aspeed Technology Inc. > > + */ > > + > > +#include <linux/bitfield.h> > > +#include <linux/clk.h> > > +#include <linux/io.h> > > +#include <linux/iopoll.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/phy/phy.h> > > +#include <linux/platform_device.h> > > +#include <linux/reset.h> > > + > > +#define PHY3S00 0x00 > > +#define PHY3S00_INIT_DONE BIT(15) > > +#define PHY3S00_SRAM_BYPASS BIT(7) > > +#define PHY3S00_SRAM_EXT_LOAD BIT(6) > > > > ... > > > + > > +static int aspeed_usb3_phy_init(struct phy *phy) { > > + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); > > + u32 val; > > + int ret; > > + > > + ret = clk_prepare_enable(aspeed_phy->clk); > > + if (ret) { > > + dev_err(aspeed_phy->dev, "Failed to enable clock %d\n", ret); > > + return ret; > > + } > > + > > + ret = reset_control_deassert(aspeed_phy->rst); > > + if (ret) { > > + clk_disable_unprepare(aspeed_phy->clk); > > + return ret; > > Nit: Given we have to do this below if the reset_control_deassert() succeeds, > perhaps add a label below and use goto here? Will update ret = reset_control_deassert(aspeed_phy->rst); if (ret) goto err_disable_clk; ... if (ret) { dev_err(aspeed_phy->dev, "SRAM init timeout\n"); goto err_assert_reset; } ... return 0; err_assert_reset: reset_control_assert(aspeed_phy->rst); err_disable_clk: clk_disable_unprepare(aspeed_phy->clk); return ret; > > > + } > > + > > + /* Wait for USB3 PHY internal SRAM initialization done */ > > + ret = readl_poll_timeout(aspeed_phy->regs + PHY3S00, val, > > + val & PHY3S00_INIT_DONE, > > + USEC_PER_MSEC, 10 * USEC_PER_MSEC); > > + if (ret) { > > + dev_err(aspeed_phy->dev, "SRAM init timeout\n"); > > + goto err_assert_reset; > > + } > > + > > + val = readl(aspeed_phy->regs + PHY3S00); > > + val |= PHY3S00_SRAM_BYPASS; > > + writel(val, aspeed_phy->regs + PHY3S00); > > According to the datasheet PHY3S00[15] (PHY3S00_INIT_DONE above) > indicates that the PHY internal SRAM initialisation is complete. The datasheet > reports the SRAM is used for configuration of calibration among other things. > PHY3S00[6] instructs the PHY that software has completed loading the > configuration data into SRAM, however PHY3S00_SRAM_BYPASS (PHY3S00[7]) > tells the PHY to load configuration from "hard wired" values. > > Is it necessary to wait for SRAM initialisation to complete if we're bypassing it? > Or are there other side-effects involved in the setting of PHY3S00[15]? Yes, it is necessary to wait SRAM initial, the driver polls PHY3S00[15]. It reports that the boot loader in the PCS has finished initialising the SRAM (loading the contents into the PCS), and that initialisation has to complete before sram_bypass (PHY3S00[7]) may be asserted. > > > + > > + /* Set protocol1_ext signals as default PHY3 settings based on SNPS > documents. > > + * Including PCFGI[54]: protocol1_ext_rx_los_lfps_en for better > compatibility > > + */ > > + writel(PHY3P00_DEFAULT, aspeed_phy->regs + PHY3P00); > > + writel(PHY3P04_DEFAULT, aspeed_phy->regs + PHY3P04); > > + writel(PHY3P08_DEFAULT, aspeed_phy->regs + PHY3P08); > > + writel(PHY3P0C_DEFAULT, aspeed_phy->regs + PHY3P0C); > > + > > + return 0; > > + > > +err_assert_reset: > > + reset_control_assert(aspeed_phy->rst); > > + clk_disable_unprepare(aspeed_phy->clk); > > + return ret; > > +} > > > > ... > > > > > +static struct platform_driver aspeed_usb3_phy_driver = { > > + .probe = aspeed_usb3_phy_probe, > > + .driver = { > > + .name = KBUILD_MODNAME, > > + .of_match_table = aspeed_usb3_phy_match_table, > > + }, > > +}; > > +module_platform_driver(aspeed_usb3_phy_driver); > > + > > +MODULE_LICENSE("GPL"); > > +MODULE_DESCRIPTION("ASPEED USB3.0 PHY Driver"); > > MODULE_AUTHOR()? Will update MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>"); ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver @ 2026-07-15 5:55 ` Ryan Chen 0 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-07-15 5:55 UTC (permalink / raw) To: Andrew Jeffery, Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Philipp Zabel Cc: linux-phy@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org > Subject: Re: [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver > > Hi Ryan, > > On Fri, 2026-01-16 at 10:53 +0800, Ryan Chen wrote: > > > ... > > > diff --git a/drivers/phy/aspeed/phy-aspeed-usb3.c > > b/drivers/phy/aspeed/phy-aspeed-usb3.c > > new file mode 100644 > > index 000000000000..872d2163fcf5 > > --- /dev/null > > +++ b/drivers/phy/aspeed/phy-aspeed-usb3.c > > @@ -0,0 +1,236 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * Copyright 2026 Aspeed Technology Inc. > > + */ > > + > > +#include <linux/bitfield.h> > > +#include <linux/clk.h> > > +#include <linux/io.h> > > +#include <linux/iopoll.h> > > +#include <linux/module.h> > > +#include <linux/of.h> > > +#include <linux/phy/phy.h> > > +#include <linux/platform_device.h> > > +#include <linux/reset.h> > > + > > +#define PHY3S00 0x00 > > +#define PHY3S00_INIT_DONE BIT(15) > > +#define PHY3S00_SRAM_BYPASS BIT(7) > > +#define PHY3S00_SRAM_EXT_LOAD BIT(6) > > > > ... > > > + > > +static int aspeed_usb3_phy_init(struct phy *phy) { > > + struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy); > > + u32 val; > > + int ret; > > + > > + ret = clk_prepare_enable(aspeed_phy->clk); > > + if (ret) { > > + dev_err(aspeed_phy->dev, "Failed to enable clock %d\n", ret); > > + return ret; > > + } > > + > > + ret = reset_control_deassert(aspeed_phy->rst); > > + if (ret) { > > + clk_disable_unprepare(aspeed_phy->clk); > > + return ret; > > Nit: Given we have to do this below if the reset_control_deassert() succeeds, > perhaps add a label below and use goto here? Will update ret = reset_control_deassert(aspeed_phy->rst); if (ret) goto err_disable_clk; ... if (ret) { dev_err(aspeed_phy->dev, "SRAM init timeout\n"); goto err_assert_reset; } ... return 0; err_assert_reset: reset_control_assert(aspeed_phy->rst); err_disable_clk: clk_disable_unprepare(aspeed_phy->clk); return ret; > > > + } > > + > > + /* Wait for USB3 PHY internal SRAM initialization done */ > > + ret = readl_poll_timeout(aspeed_phy->regs + PHY3S00, val, > > + val & PHY3S00_INIT_DONE, > > + USEC_PER_MSEC, 10 * USEC_PER_MSEC); > > + if (ret) { > > + dev_err(aspeed_phy->dev, "SRAM init timeout\n"); > > + goto err_assert_reset; > > + } > > + > > + val = readl(aspeed_phy->regs + PHY3S00); > > + val |= PHY3S00_SRAM_BYPASS; > > + writel(val, aspeed_phy->regs + PHY3S00); > > According to the datasheet PHY3S00[15] (PHY3S00_INIT_DONE above) > indicates that the PHY internal SRAM initialisation is complete. The datasheet > reports the SRAM is used for configuration of calibration among other things. > PHY3S00[6] instructs the PHY that software has completed loading the > configuration data into SRAM, however PHY3S00_SRAM_BYPASS (PHY3S00[7]) > tells the PHY to load configuration from "hard wired" values. > > Is it necessary to wait for SRAM initialisation to complete if we're bypassing it? > Or are there other side-effects involved in the setting of PHY3S00[15]? Yes, it is necessary to wait SRAM initial, the driver polls PHY3S00[15]. It reports that the boot loader in the PCS has finished initialising the SRAM (loading the contents into the PCS), and that initialisation has to complete before sram_bypass (PHY3S00[7]) may be asserted. > > > + > > + /* Set protocol1_ext signals as default PHY3 settings based on SNPS > documents. > > + * Including PCFGI[54]: protocol1_ext_rx_los_lfps_en for better > compatibility > > + */ > > + writel(PHY3P00_DEFAULT, aspeed_phy->regs + PHY3P00); > > + writel(PHY3P04_DEFAULT, aspeed_phy->regs + PHY3P04); > > + writel(PHY3P08_DEFAULT, aspeed_phy->regs + PHY3P08); > > + writel(PHY3P0C_DEFAULT, aspeed_phy->regs + PHY3P0C); > > + > > + return 0; > > + > > +err_assert_reset: > > + reset_control_assert(aspeed_phy->rst); > > + clk_disable_unprepare(aspeed_phy->clk); > > + return ret; > > +} > > > > ... > > > > > +static struct platform_driver aspeed_usb3_phy_driver = { > > + .probe = aspeed_usb3_phy_probe, > > + .driver = { > > + .name = KBUILD_MODNAME, > > + .of_match_table = aspeed_usb3_phy_match_table, > > + }, > > +}; > > +module_platform_driver(aspeed_usb3_phy_driver); > > + > > +MODULE_LICENSE("GPL"); > > +MODULE_DESCRIPTION("ASPEED USB3.0 PHY Driver"); > > MODULE_AUTHOR()? Will update MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>"); -- linux-phy mailing list linux-phy@lists.infradead.org https://lists.infradead.org/mailman/listinfo/linux-phy ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] MAINTAINERS: Add ASPEED USB3 PHY driver 2026-01-16 2:53 ` Ryan Chen @ 2026-01-16 2:53 ` Ryan Chen -1 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, Ryan Chen Add maintainer entry for ASPEED USB3 PHY driver. Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com> --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5b11839cba9d..ad1d12f346f2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3894,6 +3894,14 @@ S: Maintained F: Documentation/devicetree/bindings/usb/aspeed,ast2600-udc.yaml F: drivers/usb/gadget/udc/aspeed_udc.c +ASPEED USB3 PHY DRIVER +M: Ryan Chen <ryan_chen@aspeedtech.com> +L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) +L: linux-phy@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml +F: drivers/phy/aspeed/phy-aspeed-usb3.c + ASPEED VIDEO ENGINE DRIVER M: Eddie James <eajames@linux.ibm.com> L: linux-media@vger.kernel.org -- 2.34.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] MAINTAINERS: Add ASPEED USB3 PHY driver @ 2026-01-16 2:53 ` Ryan Chen 0 siblings, 0 replies; 12+ messages in thread From: Ryan Chen @ 2026-01-16 2:53 UTC (permalink / raw) To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed, linux-kernel, Ryan Chen Add maintainer entry for ASPEED USB3 PHY driver. Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com> --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 5b11839cba9d..ad1d12f346f2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3894,6 +3894,14 @@ S: Maintained F: Documentation/devicetree/bindings/usb/aspeed,ast2600-udc.yaml F: drivers/usb/gadget/udc/aspeed_udc.c +ASPEED USB3 PHY DRIVER +M: Ryan Chen <ryan_chen@aspeedtech.com> +L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) +L: linux-phy@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml +F: drivers/phy/aspeed/phy-aspeed-usb3.c + ASPEED VIDEO ENGINE DRIVER M: Eddie James <eajames@linux.ibm.com> L: linux-media@vger.kernel.org -- 2.34.1 -- linux-phy mailing list linux-phy@lists.infradead.org https://lists.infradead.org/mailman/listinfo/linux-phy ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-07-15 5:55 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-16 2:53 [PATCH v2 0/3] Add AST2700 USB3.2 PHY driver Ryan Chen 2026-01-16 2:53 ` Ryan Chen 2026-01-16 2:53 ` [PATCH v2 1/3] dt-bindings: phy: aspeed: Document AST2700 USB3.0 PHY Ryan Chen 2026-01-16 2:53 ` Ryan Chen 2026-01-16 2:53 ` [PATCH v2 2/3] phy: add AST2700 usb3.2 phy driver Ryan Chen 2026-01-16 2:53 ` Ryan Chen 2026-07-09 2:15 ` Andrew Jeffery 2026-07-09 2:15 ` Andrew Jeffery 2026-07-15 5:55 ` Ryan Chen 2026-07-15 5:55 ` Ryan Chen 2026-01-16 2:53 ` [PATCH v2 3/3] MAINTAINERS: Add ASPEED USB3 PHY driver Ryan Chen 2026-01-16 2:53 ` Ryan Chen
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.