* [PATCH v4 0/4] Add USB2.0 PHY and USB3.0 PHY support for SpacemiT K1
@ 2025-05-26 14:30 Ze Huang
2025-05-26 14:30 ` [PATCH v4 1/4] dt-bindings: phy: spacemit: add K1 USB2 PHY Ze Huang
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Ze Huang @ 2025-05-26 14:30 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
Ze Huang, Junzhong Pan
This patch series introduces support for the USB2.0 PHY and PCIe/USB3.0
Combo PHY on the SpacemiT K1 SoC. The implementation has been tested on the
Milk-V Jupiter and BananaPi-f3.
K1 includes three USB ports as follows[1]:
- A USB2.0 OTG Port
- A USB2.0 Host Only Port
- A USB3.0 Port with a USB2.0 DRD interface
USB3.0 PHY for USB3.0 Port is shared with PCIe port A, meaning that only one of
these interfaces (PCIe or USB3.0) can be active at a given time.
Link: https://developer.spacemit.com/documentation?token=AjHDwrW78igAAEkiHracBI9HnTb#part5 [1]
Signed-off-by: Ze Huang <huangze@whut.edu.cn>
---
Changes in v4:
- combphy driver:
- add in-code comments to indicate that PCIe mode is not yet supported.
- replace custom spacemit_reg_update() with standard regmap API.
- drop spacemit_combphy_wait_ready helper function as only used once.
- Fix PHY init timeout handling: ensure proper error reporting when PLL
lock fails during USB3 PHY initialization
- Link to v3: https://lore.kernel.org/r/20250517-b4-k1-usb3-phy-v2-v3-0-e0655613a163@whut.edu.cn
Changes in v3:
- improve commit message, provide more info about phy hardware
- drop superfluous local variable in `spacemit_combphy_wait_ready`
- replace devm_reset_control_get with devm_reset_control_get_exclusive
- Link to v2: https://lore.kernel.org/r/20250418-b4-k1-usb3-phy-v2-v2-0-b69e02da84eb@whut.edu.cn
Changes in v2:
- combphy dt-bindings:
- fix reg-names
- describe reg
- describe #phy-cells argument
- drop stale ".owner" in driver struct
- add support for usb lfps_thres in combphy
- fix Kconfig depends on
- Link to v1: https://lore.kernel.org/all/20250407-b4-k1-usb3-v3-2-v1-0-bf0bcc41c9ba@whut.edu.cn
---
Ze Huang (4):
dt-bindings: phy: spacemit: add K1 USB2 PHY
dt-bindings: phy: spacemit: add K1 PCIe/USB3 combo PHY
phy: spacemit: support K1 USB2.0 PHY controller
phy: spacemit: add USB3 support for K1 PCIe/USB3 combo PHY
.../bindings/phy/spacemit,k1-combphy.yaml | 72 ++++++
.../devicetree/bindings/phy/spacemit,usb2-phy.yaml | 40 ++++
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/spacemit/Kconfig | 21 ++
drivers/phy/spacemit/Makefile | 3 +
drivers/phy/spacemit/phy-k1-combphy.c | 266 +++++++++++++++++++++
drivers/phy/spacemit/phy-k1-usb2.c | 131 ++++++++++
8 files changed, 535 insertions(+)
---
base-commit: 64e9fdfc89a76fed38d8ddeed72d42ec71957ed9
change-id: 20250417-b4-k1-usb3-phy-v2-fb1e41849049
Best regards,
--
Ze Huang <huangze@whut.edu.cn>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 1/4] dt-bindings: phy: spacemit: add K1 USB2 PHY
2025-05-26 14:30 [PATCH v4 0/4] Add USB2.0 PHY and USB3.0 PHY support for SpacemiT K1 Ze Huang
@ 2025-05-26 14:30 ` Ze Huang
2025-05-26 14:31 ` [PATCH v4 2/4] dt-bindings: phy: spacemit: add K1 PCIe/USB3 combo PHY Ze Huang
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Ze Huang @ 2025-05-26 14:30 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
Ze Huang
Add support for USB2 PHY found on SpacemiT K1 SoC.
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Ze Huang <huangze@whut.edu.cn>
---
.../devicetree/bindings/phy/spacemit,usb2-phy.yaml | 40 ++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8a91b730cb8733ddf29f1b94fc31e6ba920dbc1b
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/spacemit,usb2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT K1 SoC USB 2.0 PHY
+
+maintainers:
+ - Ze Huang <huangze9015@gmail.com>
+
+properties:
+ compatible:
+ const: spacemit,k1-usb2-phy
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ usb-phy@c09c0000 {
+ compatible = "spacemit,k1-usb2-phy";
+ reg = <0xc09c0000 0x200>;
+ clocks = <&syscon_apmu 15>;
+ #phy-cells = <0>;
+ };
--
2.49.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 2/4] dt-bindings: phy: spacemit: add K1 PCIe/USB3 combo PHY
2025-05-26 14:30 [PATCH v4 0/4] Add USB2.0 PHY and USB3.0 PHY support for SpacemiT K1 Ze Huang
2025-05-26 14:30 ` [PATCH v4 1/4] dt-bindings: phy: spacemit: add K1 USB2 PHY Ze Huang
@ 2025-05-26 14:31 ` Ze Huang
2025-05-26 14:31 ` [PATCH v4 3/4] phy: spacemit: support K1 USB2.0 PHY controller Ze Huang
2025-05-26 14:31 ` [PATCH v4 4/4] phy: spacemit: add USB3 support for K1 PCIe/USB3 combo PHY Ze Huang
3 siblings, 0 replies; 8+ messages in thread
From: Ze Huang @ 2025-05-26 14:31 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
Ze Huang, Junzhong Pan
Introduce support for SpacemiT K1 PCIe/USB3 combo PHY controller.
PCIe portA and USB3 controller share this phy, only one of them can work
at any given application scenario.
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Co-developed-by: Junzhong Pan <junzhong.pan@spacemit.com>
Signed-off-by: Junzhong Pan <junzhong.pan@spacemit.com>
Signed-off-by: Ze Huang <huangze@whut.edu.cn>
---
.../bindings/phy/spacemit,k1-combphy.yaml | 72 ++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-combphy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-combphy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..93f7a3bb06bba380def77f87f6db0184af26e9e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combphy.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/spacemit,k1-combphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SpacemiT K1 PCIe/USB3 Combo PHY
+
+maintainers:
+ - Ze Huang <huangze9015@gmail.com>
+
+description:
+ Combo PHY on SpacemiT K1 SoC. PCIe port A and USB3 controller share this
+ phy, only one of PCIe port A and USB3 port can work at any given application
+ scenario.
+
+properties:
+ compatible:
+ const: spacemit,k1-combphy
+
+ reg:
+ items:
+ - description: PHY control registers
+ - description: PCIe/USB3 mode selection register
+
+ reg-names:
+ items:
+ - const: ctrl
+ - const: sel
+
+ resets:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 1
+ description:
+ Indicates the PHY mode to select. The value determines whether the PHY
+ operates in PCIe or USB3 mode.
+
+ spacemit,lfps-threshold:
+ description:
+ Controls the LFPS signal detection threshold, affects polling.LFPS
+ handshake. Lower the threshold when core voltage rises.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 0xff
+
+ spacemit,rx-always-on:
+ description:
+ Affects RX.detect, enhance compatibility of some DFPs in device mode but
+ increase power consumption.
+ type: boolean
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - resets
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ phy@c0b10000 {
+ compatible = "spacemit,k1-combphy";
+ reg = <0xc0b10000 0x800>,
+ <0xd4282910 0x400>;
+ reg-names = "ctrl", "sel";
+ resets = <&syscon_apmu 19>;
+ #phy-cells = <1>;
+ };
--
2.49.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 3/4] phy: spacemit: support K1 USB2.0 PHY controller
2025-05-26 14:30 [PATCH v4 0/4] Add USB2.0 PHY and USB3.0 PHY support for SpacemiT K1 Ze Huang
2025-05-26 14:30 ` [PATCH v4 1/4] dt-bindings: phy: spacemit: add K1 USB2 PHY Ze Huang
2025-05-26 14:31 ` [PATCH v4 2/4] dt-bindings: phy: spacemit: add K1 PCIe/USB3 combo PHY Ze Huang
@ 2025-05-26 14:31 ` Ze Huang
2025-05-26 15:51 ` neil.armstrong
2025-05-26 14:31 ` [PATCH v4 4/4] phy: spacemit: add USB3 support for K1 PCIe/USB3 combo PHY Ze Huang
3 siblings, 1 reply; 8+ messages in thread
From: Ze Huang @ 2025-05-26 14:31 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
Ze Huang
The SpacemiT K1 SoC includes three USB ports:
- One USB2.0 OTG port
- One USB2.0 host-only port
- One USB3.0 port with an integrated USB2.0 DRD interface
Each of these ports is connected to a USB2.0 PHY responsible for USB2
transmission.
This commit adds support for the SpacemiT K1 USB2.0 PHY, which is
compliant with the USB 2.0 specification and supports both 8-bit 60MHz
and 16-bit 30MHz parallel interfaces.
Signed-off-by: Ze Huang <huangze@whut.edu.cn>
---
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/spacemit/Kconfig | 13 ++++
drivers/phy/spacemit/Makefile | 2 +
drivers/phy/spacemit/phy-k1-usb2.c | 131 +++++++++++++++++++++++++++++++++++++
5 files changed, 148 insertions(+)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 8d58efe998ec5fd50054eed2c90d6ecce6bd5dd8..fca589aa7926eb5bce14e99785cf32cf0395202e 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -114,6 +114,7 @@ source "drivers/phy/renesas/Kconfig"
source "drivers/phy/rockchip/Kconfig"
source "drivers/phy/samsung/Kconfig"
source "drivers/phy/socionext/Kconfig"
+source "drivers/phy/spacemit/Kconfig"
source "drivers/phy/st/Kconfig"
source "drivers/phy/starfive/Kconfig"
source "drivers/phy/sunplus/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index e281442acc752820fe0bd638dfe38986a37c2a78..05993ff8a15daf7e2583b5f9b9b37ac584a30609 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -34,6 +34,7 @@ obj-y += allwinner/ \
rockchip/ \
samsung/ \
socionext/ \
+ spacemit/ \
st/ \
starfive/ \
sunplus/ \
diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..0136aee2e8a2f5f484da136b26f80130794b992c
--- /dev/null
+++ b/drivers/phy/spacemit/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Phy drivers for SpacemiT platforms
+#
+config PHY_SPACEMIT_K1_USB2
+ tristate "SpacemiT K1 USB 2.0 PHY support"
+ depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
+ depends on COMMON_CLK
+ depends on USB_COMMON
+ select GENERIC_PHY
+ help
+ Enable this to support K1 USB 2.0 PHY driver. This driver takes care of
+ enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver.
diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..fec0b425a948541b39b814caef0b05e1e002d92f
--- /dev/null
+++ b/drivers/phy/spacemit/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
diff --git a/drivers/phy/spacemit/phy-k1-usb2.c b/drivers/phy/spacemit/phy-k1-usb2.c
new file mode 100644
index 0000000000000000000000000000000000000000..3485064a77baac8bb857aff3da45838c0da28f03
--- /dev/null
+++ b/drivers/phy/spacemit/phy-k1-usb2.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SpacemiT K1 USB 2.0 PHY driver
+ *
+ * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd
+ * Copyright (C) 2025 Ze Huang <huangze9015@gmail.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/platform_device.h>
+#include <linux/usb/of.h>
+
+#define USB2_PHY_REG01 0x04
+#define USB2_PHY_REG01_VAL 0x60ef
+#define USB2_PHY_REG01_PLL_IS_READY BIT(0)
+#define USB2_PHY_REG04 0x10
+#define USB2_PHY_REG04_AUTO_CLEAR_DIS BIT(2)
+#define USB2_PHY_REG0D 0x34
+#define USB2_PHY_REG0D_VAL 0x1c
+#define USB2_PHY_REG26 0x98
+#define USB2_PHY_REG26_VAL 0xbec4
+
+#define USB2D_CTRL_RESET_TIME_MS 50
+
+struct spacemit_usb2phy {
+ struct phy *phy;
+ struct clk *clk;
+ void __iomem *base;
+};
+
+static int spacemit_usb2phy_init(struct phy *phy)
+{
+ struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);
+ void __iomem *base = sphy->base;
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(sphy->clk);
+ if (ret) {
+ dev_err(&phy->dev, "failed to enable clock\n");
+ return ret;
+ }
+
+ /*
+ * make sure the usb controller is not under reset process before
+ * any configuration
+ */
+ usleep_range(150, 200);
+ writel(USB2_PHY_REG26_VAL, base + USB2_PHY_REG26); /* 24M ref clk */
+
+ ret = read_poll_timeout(readl, val, (val & USB2_PHY_REG01_PLL_IS_READY),
+ 500, USB2D_CTRL_RESET_TIME_MS * 1000, true,
+ base + USB2_PHY_REG01);
+ if (ret) {
+ dev_err(&phy->dev, "wait PHY_REG01[PLLREADY] timeout\n");
+ return ret;
+ }
+
+ /* release usb2 phy internal reset and enable clock gating */
+ writel(USB2_PHY_REG01_VAL, base + USB2_PHY_REG01);
+ writel(USB2_PHY_REG0D_VAL, base + USB2_PHY_REG0D);
+
+ /* auto clear host disc */
+ val = readl(base + USB2_PHY_REG04);
+ val |= USB2_PHY_REG04_AUTO_CLEAR_DIS;
+ writel(val, base + USB2_PHY_REG04);
+
+ return 0;
+}
+
+static int spacemit_usb2phy_exit(struct phy *phy)
+{
+ struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);
+
+ clk_disable_unprepare(sphy->clk);
+
+ return 0;
+}
+
+static const struct phy_ops spacemit_usb2phy_ops = {
+ .init = spacemit_usb2phy_init,
+ .exit = spacemit_usb2phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static int spacemit_usb2phy_probe(struct platform_device *pdev)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct spacemit_usb2phy *sphy;
+
+ sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
+ if (!sphy)
+ return -ENOMEM;
+
+ sphy->clk = devm_clk_get_prepared(&pdev->dev, NULL);
+ if (IS_ERR(sphy->clk))
+ return dev_err_probe(dev, PTR_ERR(sphy->clk), "Failed to get clock\n");
+
+ sphy->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(sphy->base))
+ return PTR_ERR(sphy->base);
+
+ sphy->phy = devm_phy_create(dev, NULL, &spacemit_usb2phy_ops);
+ if (IS_ERR(sphy->phy))
+ return dev_err_probe(dev, PTR_ERR(sphy->phy), "Failed to create phy\n");
+
+ phy_set_drvdata(sphy->phy, sphy);
+ 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 spacemit_usb2phy_dt_match[] = {
+ { .compatible = "spacemit,k1-usb2-phy", },
+ { /* sentinal */ }
+};
+MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match);
+
+static struct platform_driver spacemit_usb2_phy_driver = {
+ .probe = spacemit_usb2phy_probe,
+ .driver = {
+ .name = "spacemit-usb2-phy",
+ .of_match_table = spacemit_usb2phy_dt_match,
+ },
+};
+module_platform_driver(spacemit_usb2_phy_driver);
+
+MODULE_DESCRIPTION("Spacemit USB 2.0 PHY driver");
+MODULE_LICENSE("GPL");
--
2.49.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 4/4] phy: spacemit: add USB3 support for K1 PCIe/USB3 combo PHY
2025-05-26 14:30 [PATCH v4 0/4] Add USB2.0 PHY and USB3.0 PHY support for SpacemiT K1 Ze Huang
` (2 preceding siblings ...)
2025-05-26 14:31 ` [PATCH v4 3/4] phy: spacemit: support K1 USB2.0 PHY controller Ze Huang
@ 2025-05-26 14:31 ` Ze Huang
2025-05-26 15:45 ` neil.armstrong
3 siblings, 1 reply; 8+ messages in thread
From: Ze Huang @ 2025-05-26 14:31 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
Ze Huang
Add support for USB 3.0 mode on the K1 PCIe/USB3 combo PHY which
implements PIPE3(125MHz) interface for USB3.0. Currently, only USB mode
is supported; PCIe support is not included in this change.
Signed-off-by: Ze Huang <huangze@whut.edu.cn>
---
drivers/phy/spacemit/Kconfig | 8 +
drivers/phy/spacemit/Makefile | 1 +
drivers/phy/spacemit/phy-k1-combphy.c | 266 ++++++++++++++++++++++++++++++++++
3 files changed, 275 insertions(+)
diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig
index 0136aee2e8a2f5f484da136b26f80130794b992c..ccc6bf9ea49f4988a27f79a4dcd024b18cbd78b0 100644
--- a/drivers/phy/spacemit/Kconfig
+++ b/drivers/phy/spacemit/Kconfig
@@ -11,3 +11,11 @@ config PHY_SPACEMIT_K1_USB2
help
Enable this to support K1 USB 2.0 PHY driver. This driver takes care of
enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver.
+
+config PHY_SPACEMIT_K1_COMBPHY
+ tristate "SpacemiT K1 PCIe/USB3 combo PHY support"
+ depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
+ depends on COMMON_CLK
+ select GENERIC_PHY
+ help
+ USB3/PCIe Combo PHY Support for SpacemiT K1 SoC
diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile
index fec0b425a948541b39b814caef0b05e1e002d92f..1fd0c65f2c5cd10ea2f70e43e62c70588d1ffae9 100644
--- a/drivers/phy/spacemit/Makefile
+++ b/drivers/phy/spacemit/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_PHY_SPACEMIT_K1_COMBPHY) += phy-k1-combphy.o
obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
diff --git a/drivers/phy/spacemit/phy-k1-combphy.c b/drivers/phy/spacemit/phy-k1-combphy.c
new file mode 100644
index 0000000000000000000000000000000000000000..227b1c743f4d981b3d4555c871ef397c1c8df0b5
--- /dev/null
+++ b/drivers/phy/spacemit/phy-k1-combphy.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * SpacemiT K1 PCIE/USB3 PHY driver
+ *
+ * This driver supports the combo PHY found on Spacemit K1 SoC, which integrates
+ * a dual-mode USB3/PCIe PHY shared between the USB3.0 DRD controller and PCIe
+ * PortA. But only one mode can work at any given application scenario.
+ *
+ * PCIe mode is not supported yet and any attempt to use the PHY in PCIe mode
+ * will result in an error.
+ *
+ * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd
+ * Copyright (C) 2025 Ze Huang <huangze9015@gmail.com>
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <linux/clk.h>
+#include <linux/iopoll.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/usb/of.h>
+
+#define COMBPHY_USB_REG1 0x68
+#define COMBPHY_USB_REG1_VAL 0x00
+#define COMBPHY_USB_REG2 0x48
+#define COMBPHY_USB_REG2_VAL 0x603a2276
+#define COMBPHY_USB_REG3 0x08
+#define COMBPHY_USB_REG3_VAL 0x97c
+#define COMBPHY_USB_REG4 0x18
+#define COMBPHY_USB_REG4_VAL 0x00
+#define COMBPHY_USB_TERM_SHORT_MASK 0x3000
+#define COMBPHY_USB_TERM_SHORT_VAL 0x3000
+#define COMBPHY_USB_PLL_REG 0x08
+#define COMBPHY_USB_PLL_MASK 0x01
+#define COMBPHY_USB_PLL_VAL 0x01
+#define COMBPHY_USB_LFPS_REG 0x58
+#define COMBPHY_USB_LFPS_MASK 0x700
+#define COMBPHY_USB_LFPS_THRES_DEFAULT 0x03
+
+#define COMBPHY_MODE_SEL_MASK BIT(3)
+#define COMBPHY_MODE_USB BIT(3)
+#define COMBPHY_WAIT_TIMEOUT 1000
+
+struct spacemit_combphy_priv {
+ struct device *dev;
+ struct phy *phy;
+ struct reset_control *phy_rst;
+ struct regmap *regmap_ctrl;
+ struct regmap *regmap_sel;
+ bool rx_always_on;
+ u8 lfps_threshold;
+ u8 type;
+};
+
+static const struct regmap_config phy_ctrl_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x800,
+};
+
+static const struct regmap_config phy_sel_regmap_config = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = 0x400,
+};
+
+static int spacemit_combphy_set_mode(struct spacemit_combphy_priv *priv)
+{
+ struct regmap *map = priv->regmap_sel;
+ int ret = 0;
+
+ switch (priv->type) {
+ case PHY_TYPE_USB3:
+ regmap_update_bits(map, 0, COMBPHY_MODE_SEL_MASK, COMBPHY_MODE_USB);
+ break;
+ default:
+ dev_err(priv->dev, "PHY type %x not supported\n", priv->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int spacemit_combphy_init_usb(struct spacemit_combphy_priv *priv)
+{
+ struct regmap *map = priv->regmap_ctrl;
+ u32 reg_val;
+ int ret;
+
+ regmap_write(map, COMBPHY_USB_REG1, COMBPHY_USB_REG1_VAL);
+ regmap_write(map, COMBPHY_USB_REG2, COMBPHY_USB_REG2_VAL);
+ regmap_write(map, COMBPHY_USB_REG3, COMBPHY_USB_REG3_VAL);
+ regmap_write(map, COMBPHY_USB_REG4, COMBPHY_USB_REG4_VAL);
+
+ ret = regmap_read_poll_timeout(map, COMBPHY_USB_PLL_REG, reg_val,
+ (reg_val & COMBPHY_USB_PLL_MASK) == COMBPHY_USB_PLL_VAL,
+ 1000, COMBPHY_WAIT_TIMEOUT * 1000);
+ if (ret) {
+ dev_err(priv->dev, "USB3 PHY init timeout!\n");
+ return ret;
+ }
+
+ dev_dbg(priv->dev, "USB3 PHY init lfps threshold %d\n", priv->lfps_threshold);
+ regmap_update_bits(map, COMBPHY_USB_LFPS_REG,
+ COMBPHY_USB_LFPS_MASK,
+ priv->lfps_threshold << 8);
+
+ if (priv->rx_always_on)
+ regmap_update_bits(map, COMBPHY_USB_REG4,
+ COMBPHY_USB_TERM_SHORT_MASK,
+ COMBPHY_USB_TERM_SHORT_VAL);
+
+ return ret;
+}
+
+static int spacemit_combphy_init(struct phy *phy)
+{
+ struct spacemit_combphy_priv *priv = phy_get_drvdata(phy);
+ int ret;
+
+ ret = spacemit_combphy_set_mode(priv);
+ if (ret) {
+ dev_err(priv->dev, "failed to set mode for PHY type %x\n",
+ priv->type);
+ goto out;
+ }
+
+ ret = reset_control_deassert(priv->phy_rst);
+ if (ret) {
+ dev_err(priv->dev, "failed to deassert rst\n");
+ goto err_rst;
+ }
+
+ switch (priv->type) {
+ case PHY_TYPE_USB3:
+ ret = spacemit_combphy_init_usb(priv);
+ break;
+ default:
+ dev_err(priv->dev, "PHY type %x not supported\n", priv->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ goto err_rst;
+
+ return 0;
+
+err_rst:
+ reset_control_assert(priv->phy_rst);
+out:
+ return ret;
+}
+
+static int spacemit_combphy_exit(struct phy *phy)
+{
+ struct spacemit_combphy_priv *priv = phy_get_drvdata(phy);
+
+ reset_control_assert(priv->phy_rst);
+
+ return 0;
+}
+
+static struct phy *spacemit_combphy_xlate(struct device *dev,
+ const struct of_phandle_args *args)
+{
+ struct spacemit_combphy_priv *priv = dev_get_drvdata(dev);
+
+ if (args->args_count != 1) {
+ dev_err(dev, "invalid number of arguments\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (priv->type != PHY_NONE && priv->type != args->args[0])
+ dev_warn(dev, "PHY type %d is selected to override %d\n",
+ args->args[0], priv->type);
+
+ priv->type = args->args[0];
+
+ if (args->args_count > 1)
+ dev_dbg(dev, "combo phy idx: %d selected", args->args[1]);
+
+ return priv->phy;
+}
+
+static const struct phy_ops spacemit_combphy_ops = {
+ .init = spacemit_combphy_init,
+ .exit = spacemit_combphy_exit,
+ .owner = THIS_MODULE,
+};
+
+static int spacemit_combphy_probe(struct platform_device *pdev)
+{
+ struct spacemit_combphy_priv *priv;
+ void __iomem *ctrl_base, *sel_base;
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ ctrl_base = devm_platform_ioremap_resource_byname(pdev, "ctrl");
+ if (IS_ERR(ctrl_base))
+ return PTR_ERR(ctrl_base);
+
+ priv->regmap_ctrl = devm_regmap_init_mmio(dev, ctrl_base, &phy_ctrl_regmap_config);
+ if (IS_ERR(priv->regmap_ctrl))
+ return dev_err_probe(dev, PTR_ERR(priv->regmap_ctrl),
+ "Failed to init regmap for ctrl\n");
+
+ sel_base = devm_platform_ioremap_resource_byname(pdev, "sel");
+ if (IS_ERR(sel_base))
+ return PTR_ERR(sel_base);
+
+ priv->regmap_sel = devm_regmap_init_mmio(dev, sel_base, &phy_sel_regmap_config);
+ if (IS_ERR(priv->regmap_sel))
+ return dev_err_probe(dev, PTR_ERR(priv->regmap_sel),
+ "Failed to init regmap for sel\n");
+
+ priv->lfps_threshold = COMBPHY_USB_LFPS_THRES_DEFAULT;
+ device_property_read_u8(&pdev->dev, "spacemit,lfps-threshold", &priv->lfps_threshold);
+
+ priv->rx_always_on = device_property_read_bool(&pdev->dev, "spacemit,rx-always-on");
+ priv->type = PHY_NONE;
+ priv->dev = dev;
+
+ priv->phy_rst = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(priv->phy_rst))
+ return dev_err_probe(dev, PTR_ERR(priv->phy_rst),
+ "failed to get phy reset\n");
+
+ priv->phy = devm_phy_create(dev, NULL, &spacemit_combphy_ops);
+ if (IS_ERR(priv->phy))
+ return dev_err_probe(dev, PTR_ERR(priv->phy),
+ "failed to create combphy\n");
+
+ dev_set_drvdata(dev, priv);
+ phy_set_drvdata(priv->phy, priv);
+ phy_provider = devm_of_phy_provider_register(dev, spacemit_combphy_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id spacemit_combphy_of_match[] = {
+ { .compatible = "spacemit,k1-combphy", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, spacemit_combphy_of_match);
+
+static struct platform_driver spacemit_combphy_driver = {
+ .probe = spacemit_combphy_probe,
+ .driver = {
+ .name = "spacemit-k1-combphy",
+ .of_match_table = spacemit_combphy_of_match,
+ },
+};
+module_platform_driver(spacemit_combphy_driver);
+
+MODULE_DESCRIPTION("Spacemit PCIE/USB3.0 COMBO PHY driver");
+MODULE_LICENSE("GPL");
--
2.49.0
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 4/4] phy: spacemit: add USB3 support for K1 PCIe/USB3 combo PHY
2025-05-26 14:31 ` [PATCH v4 4/4] phy: spacemit: add USB3 support for K1 PCIe/USB3 combo PHY Ze Huang
@ 2025-05-26 15:45 ` neil.armstrong
0 siblings, 0 replies; 8+ messages in thread
From: neil.armstrong @ 2025-05-26 15:45 UTC (permalink / raw)
To: Ze Huang, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel
On 26/05/2025 16:31, Ze Huang wrote:
> Add support for USB 3.0 mode on the K1 PCIe/USB3 combo PHY which
> implements PIPE3(125MHz) interface for USB3.0. Currently, only USB mode
> is supported; PCIe support is not included in this change.
>
> Signed-off-by: Ze Huang <huangze@whut.edu.cn>
> ---
> drivers/phy/spacemit/Kconfig | 8 +
> drivers/phy/spacemit/Makefile | 1 +
> drivers/phy/spacemit/phy-k1-combphy.c | 266 ++++++++++++++++++++++++++++++++++
> 3 files changed, 275 insertions(+)
>
> diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig
> index 0136aee2e8a2f5f484da136b26f80130794b992c..ccc6bf9ea49f4988a27f79a4dcd024b18cbd78b0 100644
> --- a/drivers/phy/spacemit/Kconfig
> +++ b/drivers/phy/spacemit/Kconfig
> @@ -11,3 +11,11 @@ config PHY_SPACEMIT_K1_USB2
> help
> Enable this to support K1 USB 2.0 PHY driver. This driver takes care of
> enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver.
> +
> +config PHY_SPACEMIT_K1_COMBPHY
> + tristate "SpacemiT K1 PCIe/USB3 combo PHY support"
> + depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
> + depends on COMMON_CLK
> + select GENERIC_PHY
> + help
> + USB3/PCIe Combo PHY Support for SpacemiT K1 SoC
> diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile
> index fec0b425a948541b39b814caef0b05e1e002d92f..1fd0c65f2c5cd10ea2f70e43e62c70588d1ffae9 100644
> --- a/drivers/phy/spacemit/Makefile
> +++ b/drivers/phy/spacemit/Makefile
> @@ -1,2 +1,3 @@
> # SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_PHY_SPACEMIT_K1_COMBPHY) += phy-k1-combphy.o
> obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
> diff --git a/drivers/phy/spacemit/phy-k1-combphy.c b/drivers/phy/spacemit/phy-k1-combphy.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..227b1c743f4d981b3d4555c871ef397c1c8df0b5
> --- /dev/null
> +++ b/drivers/phy/spacemit/phy-k1-combphy.c
> @@ -0,0 +1,266 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * SpacemiT K1 PCIE/USB3 PHY driver
> + *
> + * This driver supports the combo PHY found on Spacemit K1 SoC, which integrates
> + * a dual-mode USB3/PCIe PHY shared between the USB3.0 DRD controller and PCIe
> + * PortA. But only one mode can work at any given application scenario.
> + *
> + * PCIe mode is not supported yet and any attempt to use the PHY in PCIe mode
> + * will result in an error.
> + *
> + * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd
> + * Copyright (C) 2025 Ze Huang <huangze9015@gmail.com>
> + */
> +
> +#include <dt-bindings/phy/phy.h>
> +#include <linux/clk.h>
> +#include <linux/iopoll.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/usb/of.h>
> +
> +#define COMBPHY_USB_REG1 0x68
> +#define COMBPHY_USB_REG1_VAL 0x00
> +#define COMBPHY_USB_REG2 0x48
> +#define COMBPHY_USB_REG2_VAL 0x603a2276
> +#define COMBPHY_USB_REG3 0x08
> +#define COMBPHY_USB_REG3_VAL 0x97c
> +#define COMBPHY_USB_REG4 0x18
> +#define COMBPHY_USB_REG4_VAL 0x00
> +#define COMBPHY_USB_TERM_SHORT_MASK 0x3000
> +#define COMBPHY_USB_TERM_SHORT_VAL 0x3000
> +#define COMBPHY_USB_PLL_REG 0x08
> +#define COMBPHY_USB_PLL_MASK 0x01
> +#define COMBPHY_USB_PLL_VAL 0x01
> +#define COMBPHY_USB_LFPS_REG 0x58
> +#define COMBPHY_USB_LFPS_MASK 0x700
> +#define COMBPHY_USB_LFPS_THRES_DEFAULT 0x03
> +
> +#define COMBPHY_MODE_SEL_MASK BIT(3)
> +#define COMBPHY_MODE_USB BIT(3)
> +#define COMBPHY_WAIT_TIMEOUT 1000
> +
> +struct spacemit_combphy_priv {
> + struct device *dev;
> + struct phy *phy;
> + struct reset_control *phy_rst;
> + struct regmap *regmap_ctrl;
> + struct regmap *regmap_sel;
> + bool rx_always_on;
> + u8 lfps_threshold;
> + u8 type;
> +};
> +
> +static const struct regmap_config phy_ctrl_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x800,
> +};
> +
> +static const struct regmap_config phy_sel_regmap_config = {
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = 0x400,
> +};
> +
> +static int spacemit_combphy_set_mode(struct spacemit_combphy_priv *priv)
> +{
> + struct regmap *map = priv->regmap_sel;
> + int ret = 0;
> +
> + switch (priv->type) {
> + case PHY_TYPE_USB3:
> + regmap_update_bits(map, 0, COMBPHY_MODE_SEL_MASK, COMBPHY_MODE_USB);
> + break;
> + default:
> + dev_err(priv->dev, "PHY type %x not supported\n", priv->type);
> + ret = -EINVAL;
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static int spacemit_combphy_init_usb(struct spacemit_combphy_priv *priv)
> +{
> + struct regmap *map = priv->regmap_ctrl;
> + u32 reg_val;
> + int ret;
> +
> + regmap_write(map, COMBPHY_USB_REG1, COMBPHY_USB_REG1_VAL);
> + regmap_write(map, COMBPHY_USB_REG2, COMBPHY_USB_REG2_VAL);
> + regmap_write(map, COMBPHY_USB_REG3, COMBPHY_USB_REG3_VAL);
> + regmap_write(map, COMBPHY_USB_REG4, COMBPHY_USB_REG4_VAL);
> +
> + ret = regmap_read_poll_timeout(map, COMBPHY_USB_PLL_REG, reg_val,
> + (reg_val & COMBPHY_USB_PLL_MASK) == COMBPHY_USB_PLL_VAL,
> + 1000, COMBPHY_WAIT_TIMEOUT * 1000);
> + if (ret) {
> + dev_err(priv->dev, "USB3 PHY init timeout!\n");
> + return ret;
> + }
> +
> + dev_dbg(priv->dev, "USB3 PHY init lfps threshold %d\n", priv->lfps_threshold);
> + regmap_update_bits(map, COMBPHY_USB_LFPS_REG,
> + COMBPHY_USB_LFPS_MASK,
> + priv->lfps_threshold << 8);
> +
> + if (priv->rx_always_on)
> + regmap_update_bits(map, COMBPHY_USB_REG4,
> + COMBPHY_USB_TERM_SHORT_MASK,
> + COMBPHY_USB_TERM_SHORT_VAL);
> +
> + return ret;
> +}
> +
> +static int spacemit_combphy_init(struct phy *phy)
> +{
> + struct spacemit_combphy_priv *priv = phy_get_drvdata(phy);
> + int ret;
> +
> + ret = spacemit_combphy_set_mode(priv);
> + if (ret) {
> + dev_err(priv->dev, "failed to set mode for PHY type %x\n",
> + priv->type);
> + goto out;
> + }
> +
> + ret = reset_control_deassert(priv->phy_rst);
> + if (ret) {
> + dev_err(priv->dev, "failed to deassert rst\n");
> + goto err_rst;
> + }
> +
> + switch (priv->type) {
> + case PHY_TYPE_USB3:
> + ret = spacemit_combphy_init_usb(priv);
> + break;
> + default:
> + dev_err(priv->dev, "PHY type %x not supported\n", priv->type);
> + ret = -EINVAL;
> + break;
> + }
> +
> + if (ret)
> + goto err_rst;
> +
> + return 0;
> +
> +err_rst:
> + reset_control_assert(priv->phy_rst);
> +out:
> + return ret;
> +}
> +
> +static int spacemit_combphy_exit(struct phy *phy)
> +{
> + struct spacemit_combphy_priv *priv = phy_get_drvdata(phy);
> +
> + reset_control_assert(priv->phy_rst);
> +
> + return 0;
> +}
> +
> +static struct phy *spacemit_combphy_xlate(struct device *dev,
> + const struct of_phandle_args *args)
> +{
> + struct spacemit_combphy_priv *priv = dev_get_drvdata(dev);
> +
> + if (args->args_count != 1) {
> + dev_err(dev, "invalid number of arguments\n");
> + return ERR_PTR(-EINVAL);
> + }
> +
> + if (priv->type != PHY_NONE && priv->type != args->args[0])
> + dev_warn(dev, "PHY type %d is selected to override %d\n",
> + args->args[0], priv->type);
> +
> + priv->type = args->args[0];
> +
> + if (args->args_count > 1)
> + dev_dbg(dev, "combo phy idx: %d selected", args->args[1]);
> +
> + return priv->phy;
> +}
> +
> +static const struct phy_ops spacemit_combphy_ops = {
> + .init = spacemit_combphy_init,
> + .exit = spacemit_combphy_exit,
> + .owner = THIS_MODULE,
> +};
> +
> +static int spacemit_combphy_probe(struct platform_device *pdev)
> +{
> + struct spacemit_combphy_priv *priv;
> + void __iomem *ctrl_base, *sel_base;
> + struct phy_provider *phy_provider;
> + struct device *dev = &pdev->dev;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + ctrl_base = devm_platform_ioremap_resource_byname(pdev, "ctrl");
> + if (IS_ERR(ctrl_base))
> + return PTR_ERR(ctrl_base);
> +
> + priv->regmap_ctrl = devm_regmap_init_mmio(dev, ctrl_base, &phy_ctrl_regmap_config);
> + if (IS_ERR(priv->regmap_ctrl))
> + return dev_err_probe(dev, PTR_ERR(priv->regmap_ctrl),
> + "Failed to init regmap for ctrl\n");
> +
> + sel_base = devm_platform_ioremap_resource_byname(pdev, "sel");
> + if (IS_ERR(sel_base))
> + return PTR_ERR(sel_base);
> +
> + priv->regmap_sel = devm_regmap_init_mmio(dev, sel_base, &phy_sel_regmap_config);
> + if (IS_ERR(priv->regmap_sel))
> + return dev_err_probe(dev, PTR_ERR(priv->regmap_sel),
> + "Failed to init regmap for sel\n");
> +
> + priv->lfps_threshold = COMBPHY_USB_LFPS_THRES_DEFAULT;
> + device_property_read_u8(&pdev->dev, "spacemit,lfps-threshold", &priv->lfps_threshold);
> +
> + priv->rx_always_on = device_property_read_bool(&pdev->dev, "spacemit,rx-always-on");
> + priv->type = PHY_NONE;
> + priv->dev = dev;
> +
> + priv->phy_rst = devm_reset_control_get_exclusive(dev, NULL);
> + if (IS_ERR(priv->phy_rst))
> + return dev_err_probe(dev, PTR_ERR(priv->phy_rst),
> + "failed to get phy reset\n");
> +
> + priv->phy = devm_phy_create(dev, NULL, &spacemit_combphy_ops);
> + if (IS_ERR(priv->phy))
> + return dev_err_probe(dev, PTR_ERR(priv->phy),
> + "failed to create combphy\n");
> +
> + dev_set_drvdata(dev, priv);
> + phy_set_drvdata(priv->phy, priv);
> + phy_provider = devm_of_phy_provider_register(dev, spacemit_combphy_xlate);
> +
> + return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id spacemit_combphy_of_match[] = {
> + { .compatible = "spacemit,k1-combphy", },
> + { /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, spacemit_combphy_of_match);
> +
> +static struct platform_driver spacemit_combphy_driver = {
> + .probe = spacemit_combphy_probe,
> + .driver = {
> + .name = "spacemit-k1-combphy",
> + .of_match_table = spacemit_combphy_of_match,
> + },
> +};
> +module_platform_driver(spacemit_combphy_driver);
> +
> +MODULE_DESCRIPTION("Spacemit PCIE/USB3.0 COMBO PHY driver");
> +MODULE_LICENSE("GPL");
>
Looks all good now
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 3/4] phy: spacemit: support K1 USB2.0 PHY controller
2025-05-26 14:31 ` [PATCH v4 3/4] phy: spacemit: support K1 USB2.0 PHY controller Ze Huang
@ 2025-05-26 15:51 ` neil.armstrong
2025-05-26 16:13 ` Ze Huang
0 siblings, 1 reply; 8+ messages in thread
From: neil.armstrong @ 2025-05-26 15:51 UTC (permalink / raw)
To: Ze Huang, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel
Hi,
On 26/05/2025 16:31, Ze Huang wrote:
> The SpacemiT K1 SoC includes three USB ports:
>
> - One USB2.0 OTG port
> - One USB2.0 host-only port
> - One USB3.0 port with an integrated USB2.0 DRD interface
>
> Each of these ports is connected to a USB2.0 PHY responsible for USB2
> transmission.
>
> This commit adds support for the SpacemiT K1 USB2.0 PHY, which is
> compliant with the USB 2.0 specification and supports both 8-bit 60MHz
> and 16-bit 30MHz parallel interfaces.
>
> Signed-off-by: Ze Huang <huangze@whut.edu.cn>
> ---
> drivers/phy/Kconfig | 1 +
> drivers/phy/Makefile | 1 +
> drivers/phy/spacemit/Kconfig | 13 ++++
> drivers/phy/spacemit/Makefile | 2 +
> drivers/phy/spacemit/phy-k1-usb2.c | 131 +++++++++++++++++++++++++++++++++++++
> 5 files changed, 148 insertions(+)
>
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 8d58efe998ec5fd50054eed2c90d6ecce6bd5dd8..fca589aa7926eb5bce14e99785cf32cf0395202e 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -114,6 +114,7 @@ source "drivers/phy/renesas/Kconfig"
> source "drivers/phy/rockchip/Kconfig"
> source "drivers/phy/samsung/Kconfig"
> source "drivers/phy/socionext/Kconfig"
> +source "drivers/phy/spacemit/Kconfig"
> source "drivers/phy/st/Kconfig"
> source "drivers/phy/starfive/Kconfig"
> source "drivers/phy/sunplus/Kconfig"
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index e281442acc752820fe0bd638dfe38986a37c2a78..05993ff8a15daf7e2583b5f9b9b37ac584a30609 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -34,6 +34,7 @@ obj-y += allwinner/ \
> rockchip/ \
> samsung/ \
> socionext/ \
> + spacemit/ \
> st/ \
> starfive/ \
> sunplus/ \
> diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig
> new file mode 100644
> index 0000000000000000000000000000000000000000..0136aee2e8a2f5f484da136b26f80130794b992c
> --- /dev/null
> +++ b/drivers/phy/spacemit/Kconfig
> @@ -0,0 +1,13 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# Phy drivers for SpacemiT platforms
> +#
> +config PHY_SPACEMIT_K1_USB2
> + tristate "SpacemiT K1 USB 2.0 PHY support"
> + depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
> + depends on COMMON_CLK
> + depends on USB_COMMON
> + select GENERIC_PHY
> + help
> + Enable this to support K1 USB 2.0 PHY driver. This driver takes care of
> + enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver.
> diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile
> new file mode 100644
> index 0000000000000000000000000000000000000000..fec0b425a948541b39b814caef0b05e1e002d92f
> --- /dev/null
> +++ b/drivers/phy/spacemit/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o
> diff --git a/drivers/phy/spacemit/phy-k1-usb2.c b/drivers/phy/spacemit/phy-k1-usb2.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..3485064a77baac8bb857aff3da45838c0da28f03
> --- /dev/null
> +++ b/drivers/phy/spacemit/phy-k1-usb2.c
> @@ -0,0 +1,131 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * SpacemiT K1 USB 2.0 PHY driver
> + *
> + * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd
> + * Copyright (C) 2025 Ze Huang <huangze9015@gmail.com>
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/iopoll.h>
> +#include <linux/platform_device.h>
> +#include <linux/usb/of.h>
> +
> +#define USB2_PHY_REG01 0x04
> +#define USB2_PHY_REG01_VAL 0x60ef
> +#define USB2_PHY_REG01_PLL_IS_READY BIT(0)
> +#define USB2_PHY_REG04 0x10
> +#define USB2_PHY_REG04_AUTO_CLEAR_DIS BIT(2)
> +#define USB2_PHY_REG0D 0x34
> +#define USB2_PHY_REG0D_VAL 0x1c
> +#define USB2_PHY_REG26 0x98
> +#define USB2_PHY_REG26_VAL 0xbec4
> +
> +#define USB2D_CTRL_RESET_TIME_MS 50
> +
> +struct spacemit_usb2phy {
> + struct phy *phy;
> + struct clk *clk;
> + void __iomem *base;
> +};
> +
> +static int spacemit_usb2phy_init(struct phy *phy)
> +{
> + struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);
> + void __iomem *base = sphy->base;
> + u32 val;
> + int ret;
> +
> + ret = clk_prepare_enable(sphy->clk);
> + if (ret) {
> + dev_err(&phy->dev, "failed to enable clock\n");
> + return ret;
> + }
> +
> + /*
> + * make sure the usb controller is not under reset process before
> + * any configuration
> + */
> + usleep_range(150, 200);
> + writel(USB2_PHY_REG26_VAL, base + USB2_PHY_REG26); /* 24M ref clk */
> +
> + ret = read_poll_timeout(readl, val, (val & USB2_PHY_REG01_PLL_IS_READY),
> + 500, USB2D_CTRL_RESET_TIME_MS * 1000, true,
> + base + USB2_PHY_REG01);
> + if (ret) {
> + dev_err(&phy->dev, "wait PHY_REG01[PLLREADY] timeout\n");
> + return ret;
> + }
> +
> + /* release usb2 phy internal reset and enable clock gating */
> + writel(USB2_PHY_REG01_VAL, base + USB2_PHY_REG01);
> + writel(USB2_PHY_REG0D_VAL, base + USB2_PHY_REG0D);
> +
> + /* auto clear host disc */
> + val = readl(base + USB2_PHY_REG04);
> + val |= USB2_PHY_REG04_AUTO_CLEAR_DIS;
> + writel(val, base + USB2_PHY_REG04);
> +
> + return 0;
> +}
> +
> +static int spacemit_usb2phy_exit(struct phy *phy)
> +{
> + struct spacemit_usb2phy *sphy = phy_get_drvdata(phy);
> +
> + clk_disable_unprepare(sphy->clk);
> +
> + return 0;
> +}
> +
> +static const struct phy_ops spacemit_usb2phy_ops = {
> + .init = spacemit_usb2phy_init,
> + .exit = spacemit_usb2phy_exit,
> + .owner = THIS_MODULE,
> +};
> +
> +static int spacemit_usb2phy_probe(struct platform_device *pdev)
> +{
> + struct phy_provider *phy_provider;
> + struct device *dev = &pdev->dev;
> + struct spacemit_usb2phy *sphy;
> +
> + sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL);
> + if (!sphy)
> + return -ENOMEM;
> +
> + sphy->clk = devm_clk_get_prepared(&pdev->dev, NULL);
> + if (IS_ERR(sphy->clk))
> + return dev_err_probe(dev, PTR_ERR(sphy->clk), "Failed to get clock\n");
> +
> + sphy->base = devm_platform_ioremap_resource(pdev, 0);
> + if (IS_ERR(sphy->base))
> + return PTR_ERR(sphy->base);
> +
> + sphy->phy = devm_phy_create(dev, NULL, &spacemit_usb2phy_ops);
> + if (IS_ERR(sphy->phy))
> + return dev_err_probe(dev, PTR_ERR(sphy->phy), "Failed to create phy\n");
> +
> + phy_set_drvdata(sphy->phy, sphy);
> + 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 spacemit_usb2phy_dt_match[] = {
> + { .compatible = "spacemit,k1-usb2-phy", },
> + { /* sentinal */ }
=> sentinel
> +};
> +MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match);
> +
> +static struct platform_driver spacemit_usb2_phy_driver = {
> + .probe = spacemit_usb2phy_probe,
> + .driver = {
> + .name = "spacemit-usb2-phy",
> + .of_match_table = spacemit_usb2phy_dt_match,
> + },
> +};
> +module_platform_driver(spacemit_usb2_phy_driver);
> +
> +MODULE_DESCRIPTION("Spacemit USB 2.0 PHY driver");
> +MODULE_LICENSE("GPL");
>
It looks fine, but why didn't also convert thid driver to regmap ?
Thanks,
Neil
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 3/4] phy: spacemit: support K1 USB2.0 PHY controller
2025-05-26 15:51 ` neil.armstrong
@ 2025-05-26 16:13 ` Ze Huang
0 siblings, 0 replies; 8+ messages in thread
From: Ze Huang @ 2025-05-26 16:13 UTC (permalink / raw)
To: Neil Armstrong, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Philipp Zabel
Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel
On 5/26/25 11:51 PM, neil.armstrong@linaro.org wrote:
> Hi,
>
> On 26/05/2025 16:31, Ze Huang wrote:
>> The SpacemiT K1 SoC includes three USB ports:
>>
>> - One USB2.0 OTG port
>> - One USB2.0 host-only port
>> - One USB3.0 port with an integrated USB2.0 DRD interface
>>
>> Each of these ports is connected to a USB2.0 PHY responsible for USB2
>> transmission.
>>
>> This commit adds support for the SpacemiT K1 USB2.0 PHY, which is
>> compliant with the USB 2.0 specification and supports both 8-bit 60MHz
>> and 16-bit 30MHz parallel interfaces.
>>
>> Signed-off-by: Ze Huang <huangze@whut.edu.cn>
>> ---
>> drivers/phy/Kconfig | 1 +
>> drivers/phy/Makefile | 1 +
>> drivers/phy/spacemit/Kconfig | 13 ++++
>> drivers/phy/spacemit/Makefile | 2 +
>> drivers/phy/spacemit/phy-k1-usb2.c | 131
>> +++++++++++++++++++++++++++++++++++++
>> 5 files changed, 148 insertions(+)
>>
...
>> +
>> +static const struct of_device_id spacemit_usb2phy_dt_match[] = {
>> + { .compatible = "spacemit,k1-usb2-phy", },
>> + { /* sentinal */ }
>
> => sentinel
Thanks!
>
>> +};
>> +MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match);
>> +
>> +static struct platform_driver spacemit_usb2_phy_driver = {
>> + .probe = spacemit_usb2phy_probe,
>> + .driver = {
>> + .name = "spacemit-usb2-phy",
>> + .of_match_table = spacemit_usb2phy_dt_match,
>> + },
>> +};
>> +module_platform_driver(spacemit_usb2_phy_driver);
>> +
>> +MODULE_DESCRIPTION("Spacemit USB 2.0 PHY driver");
>> +MODULE_LICENSE("GPL");
>>
>
> It looks fine, but why didn't also convert thid driver to regmap ?
Will do
>
> Thanks,
> Neil
>
>
>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-05-26 16:13 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-26 14:30 [PATCH v4 0/4] Add USB2.0 PHY and USB3.0 PHY support for SpacemiT K1 Ze Huang
2025-05-26 14:30 ` [PATCH v4 1/4] dt-bindings: phy: spacemit: add K1 USB2 PHY Ze Huang
2025-05-26 14:31 ` [PATCH v4 2/4] dt-bindings: phy: spacemit: add K1 PCIe/USB3 combo PHY Ze Huang
2025-05-26 14:31 ` [PATCH v4 3/4] phy: spacemit: support K1 USB2.0 PHY controller Ze Huang
2025-05-26 15:51 ` neil.armstrong
2025-05-26 16:13 ` Ze Huang
2025-05-26 14:31 ` [PATCH v4 4/4] phy: spacemit: add USB3 support for K1 PCIe/USB3 combo PHY Ze Huang
2025-05-26 15:45 ` neil.armstrong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).