Linux-PHY Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] riscv: spacemit: Add K3 PCIe/USB comb phy support
@ 2026-07-03  2:10 Inochi Amaoto
  2026-07-03  2:10 ` [PATCH v2 1/2] dt-bindings: phy: Add Spacemit K3 USB3/PCIe " Inochi Amaoto
  2026-07-03  2:10 ` [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3 Inochi Amaoto
  0 siblings, 2 replies; 5+ messages in thread
From: Inochi Amaoto @ 2026-07-03  2:10 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Yixun Lan, Kees Cook, Gustavo A. R. Silva,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Inochi Amaoto, Alex Elder, Ze Huang
  Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
	linux-hardening, Yixun Lan, Longbin Li

The PCIe/USB comb phy on K3 is a big phy that contains multiple
standalone phys for each PCIe and USB controllers. This phy is
required to configure a syscon device for mux configuration and
calibration.

Changed from v1:
patch 1:
1. Add extra description for "#phy-cells" and "spacemit,apmu"
patch 2:
1. Fix multiple spelling errors and copy-paste errors.
2. Make some magic number as meaningful macros.
3. Remove USB3 set_speed() callback as it is not needed.
4. Fix the wrong land data config and mask.

Inochi Amaoto (2):
  dt-bindings: phy: Add Spacemit K3 USB3/PCIe comb phy support
  phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3

 .../bindings/phy/spacemit,k3-combo-phy.yaml   |  68 +++
 drivers/phy/spacemit/Kconfig                  |  16 +
 drivers/phy/spacemit/Makefile                 |   2 +
 drivers/phy/spacemit/phy-k3-combo.c           | 252 +++++++++++
 drivers/phy/spacemit/phy-k3-common.c          | 391 ++++++++++++++++++
 drivers/phy/spacemit/phy-k3-common.h          |  27 ++
 6 files changed, 756 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k3-combo-phy.yaml
 create mode 100644 drivers/phy/spacemit/phy-k3-combo.c
 create mode 100644 drivers/phy/spacemit/phy-k3-common.c
 create mode 100644 drivers/phy/spacemit/phy-k3-common.h

--
2.55.0


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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] dt-bindings: phy: Add Spacemit K3 USB3/PCIe comb phy support
  2026-07-03  2:10 [PATCH v2 0/2] riscv: spacemit: Add K3 PCIe/USB comb phy support Inochi Amaoto
@ 2026-07-03  2:10 ` Inochi Amaoto
  2026-07-03  2:10 ` [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3 Inochi Amaoto
  1 sibling, 0 replies; 5+ messages in thread
From: Inochi Amaoto @ 2026-07-03  2:10 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Yixun Lan, Kees Cook, Gustavo A. R. Silva,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Inochi Amaoto, Alex Elder, Ze Huang
  Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
	linux-hardening, Yixun Lan, Longbin Li

The USB3/PCIe comb PHY on the K3 is a complex PHY group that
can provide multiple phy for both PCIe and USB controller.
Its mux configuration is controlled by the APMU syscon device.

Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
---
 .../bindings/phy/spacemit,k3-combo-phy.yaml   | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/spacemit,k3-combo-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/spacemit,k3-combo-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k3-combo-phy.yaml
new file mode 100644
index 000000000000..ed820cf697b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/spacemit,k3-combo-phy.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/spacemit,k3-combo-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Spacemit K3 PCIE/USB3 Comb PHY
+
+maintainers:
+  - Inochi Amaoto <inochiama@gmail.com>
+
+properties:
+  compatible:
+    const: spacemit,k3-combo-phy
+
+  reg:
+    maxItems: 1
+
+  "#phy-cells":
+    const: 2
+    description:
+      The first one is phy id, the second one is phy type. This
+      only supports types are PCIe and USB .
+
+  spacemit,apb-spare:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to APB SPARE system controller interface, used for
+      PHY calibration.
+
+  spacemit,apmu:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle of APMU syscon
+          - description: configuration of the PHY lanes
+    description: |
+      Phandle to control PHY mux configuration. The configuration
+      is described as follows:
+      bit 4: 0 - PCIe A x8 mode, 1 - PCIe lane share mode
+      bit 3: 0 - PCIe A x4 mode, 1 - PCIe A x2 and PCIe B x2 mode
+      bit 2: 0 - PCIe C lane 0 is PCIe mode , 1 - USB mode
+      bit 1: 0 - PCIe C lane 1 is PCIe mode , 1 - USB mode
+      bit 0: 0 - PCIe D lane is PCIe mode , 1 - USB mode
+
+      The bit[3:0] is only valid when bit 4 is 1.
+
+      This mux control does not affect the PHY for PCIe E, it is always
+      in PCIe mode.
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+  - spacemit,apb-spare
+  - spacemit,apmu
+
+additionalProperties: false
+
+examples:
+  - |
+    phy@81d00000 {
+      compatible = "spacemit,k3-combo-phy";
+      reg = <0x81d00000 0x600000>;
+      #phy-cells = <2>;
+      spacemit,apb-spare = <&apb_spare>;
+      spacemit,apmu = <&apmu 0x00>;
+    };
-- 
2.55.0


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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3
  2026-07-03  2:10 [PATCH v2 0/2] riscv: spacemit: Add K3 PCIe/USB comb phy support Inochi Amaoto
  2026-07-03  2:10 ` [PATCH v2 1/2] dt-bindings: phy: Add Spacemit K3 USB3/PCIe " Inochi Amaoto
@ 2026-07-03  2:10 ` Inochi Amaoto
  2026-07-03  2:19   ` sashiko-bot
  2026-07-03 17:12   ` Aurelien Jarno
  1 sibling, 2 replies; 5+ messages in thread
From: Inochi Amaoto @ 2026-07-03  2:10 UTC (permalink / raw)
  To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Yixun Lan, Kees Cook, Gustavo A. R. Silva,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Inochi Amaoto, Alex Elder, Ze Huang
  Cc: linux-phy, devicetree, linux-riscv, spacemit, linux-kernel,
	linux-hardening, Yixun Lan, Longbin Li

The comb PHY on K3 requires to configure a syscon device for the
right mux configuration. And it requires calibration before any
usage.

Add USB3/PCIe comb PHY driver for Spacemit K3.

Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
---
 drivers/phy/spacemit/Kconfig         |  16 ++
 drivers/phy/spacemit/Makefile        |   2 +
 drivers/phy/spacemit/phy-k3-combo.c  | 252 +++++++++++++++++
 drivers/phy/spacemit/phy-k3-common.c | 391 +++++++++++++++++++++++++++
 drivers/phy/spacemit/phy-k3-common.h |  27 ++
 5 files changed, 688 insertions(+)
 create mode 100644 drivers/phy/spacemit/phy-k3-combo.c
 create mode 100644 drivers/phy/spacemit/phy-k3-common.c
 create mode 100644 drivers/phy/spacemit/phy-k3-common.h

diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig
index 50b0005acf66..5fdf18fce499 100644
--- a/drivers/phy/spacemit/Kconfig
+++ b/drivers/phy/spacemit/Kconfig
@@ -23,3 +23,19 @@ 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_K3_COMMON_OPS
+	tristate
+	select MFD_SYSCON
+	select GENERIC_PHY
+
+config PHY_SPACEMIT_K3_COMBO_PHY
+	tristate "SpacemiT K3 USB3/PCIe PHY support"
+	depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF
+	depends on COMMON_CLK
+	select PHY_SPACEMIT_K3_COMMON_OPS
+	help
+	  Enable this to support K3 USB3/PCIe combo PHY driver. This
+	  driver takes care of enabling and clock setup and will be used
+	  by K3 dwc3 driver.
+	  If unsure, say N.
diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile
index a821a21d6142..f679c1851b4f 100644
--- a/drivers/phy/spacemit/Makefile
+++ b/drivers/phy/spacemit/Makefile
@@ -1,3 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE)		+= phy-k1-pcie.o
 obj-$(CONFIG_PHY_SPACEMIT_K1_USB2)		+= phy-k1-usb2.o
+obj-$(CONFIG_PHY_SPACEMIT_K3_COMBO_PHY)		+= phy-k3-combo.o
+obj-$(CONFIG_PHY_SPACEMIT_K3_COMMON_OPS)	+= phy-k3-common.o
diff --git a/drivers/phy/spacemit/phy-k3-combo.c b/drivers/phy/spacemit/phy-k3-combo.c
new file mode 100644
index 000000000000..0bc08bb6247a
--- /dev/null
+++ b/drivers/phy/spacemit/phy-k3-combo.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * phy-k3-combo.c - SpacemiT K3 PCIe/USB3 Combo PHY Driver
+ *
+ * Copyright (c) 2025 SpacemiT Technology Co. Ltd
+ */
+
+#include <linux/bitfield.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/iopoll.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/phy/phy.h>
+
+#include <dt-bindings/phy/phy.h>
+
+#include "phy-k3-common.h"
+
+/*
+ * The PCIE/USB Subsystem on SpacemiT K3 have 3 single lane PIPE3 PHYs
+ * (PHY2/3/4) shared by PCIE PortC/D and USB3 PortB/C/D.
+ *
+ * PMUA_PCIE_SUBSYS_MGMT[4:0]
+ *
+ *   bit4 = 0 : PCIe A X8 mode, all 8 lanes dedicated to PCIe Port A
+ *          1 : PHY lanes shared between PCIe or USB according to [3:0]
+ *
+ * All PHY matrix combinations according to [4:0]:
+ *
+ *   0x0X : PCIe-A X8
+ *   0x10 : PCIe-C x2 (PHY2+PHY3) + PCIe-D x1 (PHY4)
+ *   0x11 : PCIe-C x2 (PHY2+PHY3) + USB-D (PHY4)
+ *   0x12 : PCIe-C x1 (PHY2)      + USB-C (PHY3)
+ *   0x13 : PCIe-C x1 (PHY2)      + USB-C (PHY3) + USB-D (PHY4)
+ *   0x14 : PCIe-C x1 (PHY3)      + USB-B (PHY2)
+ *   0x15 : PCIe-C x1 (PHY3)      + USB-B (PHY2) + USB-D (PHY4)
+ *   0x16 : USB-B (PHY2) + USB-C (PHY3) + PCIe D x1 (PHY4)
+ *   0x17 : USB-B (PHY2) + USB-C (PHY3) + USB-D (PHY4)
+ *
+ * So any USB Port B/C/D operation requires PCIe A X8 mode to be disabled.
+ */
+#define PMUA_PCIE_SUBSYS_MGMT		0x1d8
+#define PU_MATRIX_CONF_MASK		GENMASK(4, 0)
+
+#define COMBPHY_MAX_SUBPHYS		6
+
+struct k3_combo_phy {
+	struct device *dev;
+	struct k3_lane_group groups[COMBPHY_MAX_SUBPHYS];
+	void __iomem *base;
+	struct regmap *apb_spare;
+};
+
+static const struct k3_phy_lane_group_data k3_combphy_lane_group0 = {
+	.lanes		= 2,
+	.config		= 0xff,
+	.mask		= 0x00,
+	.offsets	= {
+		0x0, 0x400
+	},
+};
+
+static const struct k3_phy_lane_group_data k3_combphy_lane_group1 = {
+	.lanes		= 2,
+	.config		= 0xff,
+	.mask		= 0x00,
+	.offsets	= {
+		0x100000, 0x100400
+	},
+};
+
+static const struct k3_phy_lane_group_data k3_combphy_lane_group2 = {
+	.lanes		= 1,
+	.config		= 0x14,
+	.mask		= 0x14,
+	.offsets	= {
+		0x200000
+	},
+};
+
+static const struct k3_phy_lane_group_data k3_combphy_lane_group3 = {
+	.lanes		= 1,
+	.config		= 0x12,
+	.mask		= 0x12,
+	.offsets	= {
+		0x300000
+	},
+};
+
+static const struct k3_phy_lane_group_data k3_combphy_lane_group4 = {
+	.lanes		= 1,
+	.config		= 0x11,
+	.mask		= 0x11,
+	.offsets	= {
+		0x400000
+	},
+};
+
+static const struct k3_phy_lane_group_data k3_combphy_lane_group5 = {
+	.lanes		= 1,
+	.config		= 0xff,
+	.mask		= 0x00,
+	.offsets	= {
+		0x500000
+	},
+};
+
+static const struct k3_phy_lane_group_data *k3_combphy_lane_datas[] = {
+	&k3_combphy_lane_group0,
+	&k3_combphy_lane_group1,
+	&k3_combphy_lane_group2,
+	&k3_combphy_lane_group3,
+	&k3_combphy_lane_group4,
+	&k3_combphy_lane_group5,
+};
+
+static int k3_combo_phy_init_lanes(struct k3_combo_phy *phy, unsigned int config)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(k3_combphy_lane_datas); i++) {
+		const struct k3_phy_lane_group_data *data = k3_combphy_lane_datas[i];
+		struct k3_lane_group *lg = &phy->groups[i];
+		const struct phy_ops *ops;
+		bool is_usb;
+
+		is_usb = (data->mask & config) == data->config;
+		if (is_usb)
+			ops = &k3_usb3_phy_ops;
+		else
+			ops = &k3_pcie_phy_ops;
+
+		dev_dbg(phy->dev, "phy %d is %s\n", i, is_usb ? "usb" : "pcie");
+
+		lg->phy = devm_phy_create(phy->dev, NULL, ops);
+		if (IS_ERR(lg->phy))
+			return PTR_ERR(lg->phy);
+
+		lg->is_pcie = !is_usb;
+		lg->data = data;
+		lg->base = phy->base;
+		phy_set_drvdata(lg->phy, lg);
+	}
+
+	return 0;
+}
+
+static int k3_combo_phy_update_config(struct regmap *apmu, unsigned int config)
+{
+	if (config & ~PU_MATRIX_CONF_MASK)
+		return -EINVAL;
+
+	return regmap_update_bits(apmu, PMUA_PCIE_SUBSYS_MGMT, PU_MATRIX_CONF_MASK, config);
+}
+
+static struct phy *k3_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args)
+{
+	struct k3_combo_phy *phy = dev_get_drvdata(dev);
+	struct k3_lane_group *lg;
+
+	if (args->args_count != 2) {
+		dev_err(dev, "Invalid number of arguments\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (args->args[0] >= ARRAY_SIZE(k3_combphy_lane_datas)) {
+		dev_err(dev, "Invalid PHY id\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	lg = &phy->groups[args->args[0]];
+
+	if ((lg->is_pcie && args->args[1] != PHY_TYPE_PCIE) ||
+	    (!lg->is_pcie && args->args[1] != PHY_TYPE_USB3)) {
+		dev_err(dev, "Invalid PHY mode\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return lg->phy;
+}
+
+static int k3_combo_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
+	struct phy_provider *provider;
+	struct k3_combo_phy *phy;
+	struct regmap *apmu;
+	u32 config = 0;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(phy->base))
+		return PTR_ERR(phy->base);
+
+	phy->apb_spare = syscon_regmap_lookup_by_phandle(node, "spacemit,apb-spare");
+	if (IS_ERR(phy->apb_spare))
+		return dev_err_probe(dev, PTR_ERR(phy->apb_spare),
+				     "Failed to find APB SPARE syscon");
+
+	apmu = syscon_regmap_lookup_by_phandle_args(node, "spacemit,apmu", 1, &config);
+	if (IS_ERR(apmu))
+		return dev_err_probe(dev, PTR_ERR(apmu),
+				     "Failed to find APMU syscon");
+
+	ret = k3_combo_phy_update_config(apmu, config);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to set lane configuration");
+
+	phy->dev = dev;
+	platform_set_drvdata(pdev, phy);
+
+	ret = k3_phy_calibrate(phy->apb_spare);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to calibrate phy");
+
+	ret = k3_combo_phy_init_lanes(phy, config);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to init lanes");
+
+	provider = devm_of_phy_provider_register(dev, k3_combo_phy_xlate);
+	if (IS_ERR(provider))
+		return dev_err_probe(dev, PTR_ERR(provider),
+				     "Failed to register provider\n");
+
+	return 0;
+}
+
+static const struct of_device_id k3_combo_phy_of_match[] = {
+	{ .compatible = "spacemit,k3-combo-phy" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, k3_combo_phy_of_match);
+
+static struct platform_driver k3_combo_phy_driver = {
+	.probe = k3_combo_phy_probe,
+	.driver = {
+		.name = "spacemit,k3-combo-phy",
+		.of_match_table = k3_combo_phy_of_match,
+	},
+};
+module_platform_driver(k3_combo_phy_driver);
+
+MODULE_DESCRIPTION("SpacemiT K3 USB3/PCIe combo PHY driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/spacemit/phy-k3-common.c b/drivers/phy/spacemit/phy-k3-common.c
new file mode 100644
index 000000000000..0b289e63db99
--- /dev/null
+++ b/drivers/phy/spacemit/phy-k3-common.c
@@ -0,0 +1,391 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitfield.h>
+#include <linux/cleanup.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/usb.h>
+
+#include <dt-bindings/phy/phy.h>
+
+#include "phy-k3-common.h"
+
+/* PHY Registers */
+#define PHY_VERSION			0x0
+
+#define PHY_RESET_CFG			0x04
+
+#define PHY_RESET_RXBUF_RST		BIT(0)
+#define PHY_RESET_SOFT_RST_PCS		BIT(1)
+#define PHY_RESET_SOFT_RST_AHB		BIT(2)
+#define PHY_RESET_EN_SD_AFTER_LOCK	BIT(6)
+
+#define PHY_CLK_CFG			0x08
+
+#define PHY_CLK_PLL_READY		BIT(0)
+#define PHY_CLK_TXCLK_INV		BIT(2)
+#define PHY_CLK_RXCLK_EN		BIT(3)
+#define PHY_CLK_TXCLK_EN		BIT(4)
+#define PHY_CLK_PCLK_EN			BIT(5)
+#define PHY_CLK_PIPE_PCLK_EN		BIT(6)
+#define PHY_CLK_REFCLK_FREQ		GENMASK(10, 7)
+#define PHY_CLK_REFCLK_24M		2
+#define PHY_CLK_SW_INIT_DONE		BIT(11)
+#define PHY_CLK_PU_SSC_OUT		BIT(23)
+
+#define PHY_MODE_CFG			0x0C
+
+#define PHY_MODE_PCIE_INT_EN		BIT(0)
+#define PHY_MODE_LFPS_TPERIOD		GENMASK(9, 8)
+#define PHY_MODE_LFPS_TPERIOD_USB	3
+
+#define PHY_PU_SEL			0x40
+
+#define PHY_PU_CFG_STATUS		BIT(9)
+#define PHY_PU_OVRD_STATUS		BIT(10)
+
+#define PHY_PU_CK_REG			0x54
+
+#define PHY_PU_REFCLK_100		BIT(25)
+
+#define PHY_PLL_REG1			0x58
+
+#define PHY_PLL_FREF_SEL		GENMASK(15, 13)
+#define PHY_PLL_FREF_24M		0x1
+#define PHY_PLL_SSC_DEP_SEL		GENMASK(27, 24)
+#define PHY_PLL_SSC_5000PPM		0xa
+#define PHY_PLL_SSC_MODE		GENMASK(29, 28)
+#define PHY_PLL_SSC_MODE_CENTER_SPREAD	0
+#define PHY_PLL_SSC_MODE_UP_SPREAD	1
+#define PHY_PLL_SSC_MODE_DOWN_SPREAD	2
+#define PHY_PLL_SSC_MODE_DOWN_SPREAD1	3
+
+#define PHY_PLL_REG2			0x5c
+
+#define PHY_PLL_SEL_REF100		BIT(21)
+
+/* PHY RX Register Definitions */
+#define PHY_RX_REG_A			0x60
+
+#define PHY_RX_REG0_MASK		GENMASK(7, 0)
+#define PHY_RX_REG1_MASK		GENMASK(15, 8)
+#define PHY_RX_REG2_MASK		GENMASK(23, 16)
+#define PHY_RX_REG3_MASK		GENMASK(31, 24)
+
+#define PHY_RX_REG0_RLOAD		BIT(4)
+#define PHY_RX_REG1_RTERM		GENMASK(11, 8)
+#define PHY_RX_REG1_RC_CALI		GENMASK(15, 12)
+#define PHY_RX_REG2_CSEL		GENMASK(19, 16)
+#define PHY_RX_REG2_FORCE_CSEL		BIT(20)
+#define PHY_RX_REG2_PSEL		GENMASK(23, 21)
+#define PHY_RX_REG3_I_LOAD		GENMASK(26, 24)
+#define PHY_RX_REG3_SEL_CBOOST_CODE	BIT(27)
+#define PHY_RX_REG3_ADJ_BIAS		GENMASK(29, 28)
+#define PHY_RX_REG3_RDEG1		GENMASK(31, 30)
+
+#define PHY_RX_REG_B			0x64
+
+#define PHY_RX_REG4_MASK		GENMASK(7, 0)
+#define PHY_RX_REG5_MASK		GENMASK(15, 8)
+#define PHY_RX_REG6_MASK		GENMASK(23, 16)
+
+#define PHY_RX_REGB_MASK		GENMASK(23, 0)
+
+#define PHY_RX_REG4_RDEG2		GENMASK(2, 1)
+#define PHY_RX_REG4_ENVOS		BIT(4)
+#define PHY_RX_REG4_RTERM_SEL		BIT(5)
+#define PHY_RX_REG4_MANUAL_CFG		BIT(7)
+#define PHY_RX_REG5_RCELL_VCM		GENMASK(11, 8)
+#define PHY_RX_REG5_RCELL_BIAS		GENMASK(15, 12)
+#define PHY_RX_REG6_H1_REG		GENMASK(19, 16)
+#define PHY_RX_REG6_ADAPT_GAIN		GENMASK(21, 20)
+#define PHY_RX_REG6_BYPASS_ADPT		BIT(22)
+
+#define PHY_ADPT_CFG0			0x140
+#define PHY_ADPT_AFE_RST_OVRD_EN	BIT(1)
+#define PHY_ADPT_AFE_RST_OVRD_VAL	BIT(4)
+
+#define PHY_RXEQ_TIME			0xb4
+#define PHY_RXEQ_TIME_OVRD_POST_C_SOC	BIT(21)
+#define PHY_RXEQ_TIME_CFG_AMP_SOC	GENMASK(23, 22)
+#define PHY_RXEQ_TIME_AMP_SOC_650M	0
+#define PHY_RXEQ_TIME_AMP_SOC_800M	1
+#define PHY_RXEQ_TIME_AMP_SOC_870M	2
+#define PHY_RXEQ_TIME_AMP_SOC_900M	3
+#define PHY_RXEQ_TIME_OVRD_AMP_SOC	BIT(24)
+
+#define PCIE_PU_ADDR_CLK_CFG		0x0008
+#define PHY_CLK_PLL_READY		BIT(0)
+#define PCIE_INITAL_TIMER		GENMASK(6, 3)
+#define CFG_INTERNAL_TIMER_ADJ		GENMASK(10, 7)
+#define CFG_SW_PHY_INIT_DONE		BIT(11)
+
+/* Lane RX/TX configuration (per‑lane, at lane_base) */
+#define PCIE_RX_REG1			0x050
+#define PCIE_RX_REFCLK_MODE		GENMASK(1, 0)
+#define PCIE_RX_REFCLK_MODE_DRIVER	1
+#define PCIE_RX_SEL_TRI_CODE		BIT(2)
+#define PCIE_RX_LEGACY			GENMASK(15, 8)
+#define PCIE_RX_LEGACY_DEFAULT		0x65
+
+#define PCIE_TX_REG1			0x064
+
+#define PCIE_PLL_TIMEOUT		500000
+#define PCIE_POLL_DELAY			500
+
+static int k3_usb3phy_init_single(struct k3_lane_group *lg, void __iomem *base)
+{
+	struct phy *phy = lg->phy;
+	u32 val, tmp;
+	int ret;
+
+	/* Do not wait CDR lock before sampling data */
+	val = readl(base + PHY_RESET_CFG);
+	val = u32_replace_bits(val, 0, PHY_RESET_EN_SD_AFTER_LOCK);
+	writel(val, base + PHY_RESET_CFG);
+
+	/* Power down 100MHz refclk buffer */
+	val = readl(base + PHY_PU_CK_REG);
+	val = u32_replace_bits(val, 0, PHY_PU_REFCLK_100);
+	writel(val, base + PHY_PU_CK_REG);
+
+	/* Program PLL REG1 configure the SSC */
+	val = FIELD_PREP(PHY_PLL_SSC_MODE, PHY_PLL_SSC_MODE_DOWN_SPREAD1) |
+	      FIELD_PREP(PHY_PLL_SSC_DEP_SEL, PHY_PLL_SSC_5000PPM) |
+	      FIELD_PREP(PHY_PLL_FREF_SEL, PHY_PLL_FREF_24M);
+	writel(val, base + PHY_PLL_REG1);
+
+	/* Un-select 100MHz PLL reference */
+	val = readl(base + PHY_PLL_REG2);
+	val = u32_replace_bits(val, 0, PHY_PLL_SEL_REF100);
+	writel(val, base + PHY_PLL_REG2);
+
+	/* USB LFPS period configuration */
+	val = readl(base + PHY_MODE_CFG);
+	val = u32_replace_bits(val, PHY_MODE_LFPS_TPERIOD_USB, PHY_MODE_LFPS_TPERIOD);
+	writel(val, base + PHY_MODE_CFG);
+
+	/* Force AFE adaptation reset */
+	val = readl(base + PHY_ADPT_CFG0);
+	val |= PHY_ADPT_AFE_RST_OVRD_EN | PHY_ADPT_AFE_RST_OVRD_VAL;
+	writel(val, base + PHY_ADPT_CFG0);
+
+	/* Override driver amplitude value to 900m */
+	val = readl(base + PHY_RXEQ_TIME);
+	val |= PHY_RXEQ_TIME_OVRD_AMP_SOC;
+	val = u32_replace_bits(val, PHY_RXEQ_TIME_AMP_SOC_900M, PHY_RXEQ_TIME_CFG_AMP_SOC);
+	writel(val, base + PHY_RXEQ_TIME);
+
+	/* Configure RX parameters */
+	val = PHY_RX_REG0_RLOAD |
+		FIELD_PREP(PHY_RX_REG1_RTERM, 0x8) |
+		FIELD_PREP(PHY_RX_REG1_RC_CALI, 0x7) |
+		FIELD_PREP(PHY_RX_REG2_CSEL, 0x8) |
+		PHY_RX_REG2_FORCE_CSEL |
+		FIELD_PREP(PHY_RX_REG2_PSEL, 0x4) |
+		FIELD_PREP(PHY_RX_REG3_I_LOAD, 0x7) |
+		PHY_RX_REG3_SEL_CBOOST_CODE |
+		FIELD_PREP(PHY_RX_REG3_ADJ_BIAS, 0x1) |
+		FIELD_PREP(PHY_RX_REG3_RDEG1, 0x3);
+	writel(val, base + PHY_RX_REG_A);
+
+	val = readl(base + PHY_RX_REG_B);
+	tmp = FIELD_PREP(PHY_RX_REG4_RDEG2, 0x2) |
+		PHY_RX_REG4_ENVOS | PHY_RX_REG4_RTERM_SEL | PHY_RX_REG4_MANUAL_CFG |
+		FIELD_PREP(PHY_RX_REG5_RCELL_VCM, 0x8) |
+		FIELD_PREP(PHY_RX_REG5_RCELL_BIAS, 0x8) |
+		FIELD_PREP(PHY_RX_REG6_H1_REG, 0x8) |
+		FIELD_PREP(PHY_RX_REG6_ADAPT_GAIN, 0x2);
+	val = u32_replace_bits(val, tmp, PHY_RX_REGB_MASK);
+	writel(val, base + PHY_RX_REG_B);
+
+	/*
+	 * Inform PHY that all PLL-related configuration is done.
+	 * PLL will not start locking until PHY_CLK_SW_INIT_DONE is set.
+	 */
+	val = PHY_CLK_SW_INIT_DONE | PHY_CLK_PU_SSC_OUT |
+	      FIELD_PREP(PHY_CLK_REFCLK_FREQ, PHY_CLK_REFCLK_24M) |
+	      PHY_CLK_RXCLK_EN | PHY_CLK_TXCLK_EN |
+	      PHY_CLK_PCLK_EN | PHY_CLK_PIPE_PCLK_EN;
+	writel(val, base + PHY_CLK_CFG);
+
+	ret = readl_poll_timeout(base + PHY_CLK_CFG, val,
+				 (val & PHY_CLK_PLL_READY),
+				 PCIE_POLL_DELAY, PCIE_PLL_TIMEOUT);
+	if (ret) {
+		dev_err(&phy->dev, "PHY PLL polling timeout\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int k3_usb3phy_init(struct phy *phy)
+{
+	struct k3_lane_group *lg = phy_get_drvdata(phy);
+	int ret, i;
+
+	for (i = 0; i < lg->data->lanes; i++) {
+		ret = k3_usb3phy_init_single(lg, lg->base + lg->data->offsets[i]);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+const struct phy_ops k3_usb3_phy_ops = {
+	.init = k3_usb3phy_init,
+	.owner = THIS_MODULE,
+};
+EXPORT_SYMBOL_GPL(k3_usb3_phy_ops);
+
+static int k3_pcie_phy_init(struct phy *phy)
+{
+	struct k3_lane_group *lg = phy_get_drvdata(phy);
+	void __iomem *phy_base = lg->base + lg->data->offsets[0];
+	u32 val;
+	int ret;
+	int i;
+
+	val = readl(phy_base + PHY_PLL_REG1);
+	val = u32_replace_bits(val, 0x2, GENMASK(15, 12));
+	writel(val, phy_base + PHY_PLL_REG1);
+
+	val = readl(phy_base + PHY_PLL_REG2);
+	val = u32_replace_bits(val, 0, BIT(21));
+	writel(val, phy_base + PHY_PLL_REG2);
+
+	for (i = 0; i < lg->data->lanes; i++) {
+		void __iomem *lane_base = lg->base + lg->data->offsets[i];
+
+		val = readl(lane_base + PCIE_RX_REG1);
+		val = u32_replace_bits(val, 0, 0x3);
+		writel(val, lane_base + PCIE_RX_REG1);
+	}
+
+	val = readl(phy_base + PHY_PLL_REG2);
+	val |= BIT(20);
+	writel(val, phy_base + PHY_PLL_REG2);
+
+	/* The write is needed as clock requires renegotiation */
+	val = FIELD_PREP(PCIE_RX_REFCLK_MODE, PCIE_RX_REFCLK_MODE_DRIVER) |
+	      PCIE_RX_SEL_TRI_CODE |
+	      FIELD_PREP(PCIE_RX_LEGACY, PCIE_RX_LEGACY_DEFAULT);
+	writel(val, phy_base + PCIE_RX_REG1);
+
+	/* pll_reg1 of lane0, disable SSC: pll[27:24] = 0 */
+	val = readl(phy_base + PHY_PLL_REG1);
+	val = u32_replace_bits(val, 0, GENMASK(27, 24));
+	writel(val, phy_base + PHY_PLL_REG1);
+
+	for (i = 0; i < lg->data->lanes; i++) {
+		void __iomem *lane_base = lg->base + lg->data->offsets[i];
+
+		/* set cfg_tx_send_dummy_data to be 1'b1 for disable dash data */
+		val = readl(lane_base + PHY_PU_SEL);
+		val = u32_replace_bits(val, 1, BIT(13));
+		writel(val, lane_base + PHY_PU_SEL);
+
+		/* disable en_sample_data_after_cdr_locked */
+		val = readl(lane_base + PHY_RESET_CFG);
+		val = u32_replace_bits(val, 0, BIT(6));
+		writel(val, lane_base + PHY_RESET_CFG);
+
+		/* Dynamic Lock */
+		val = readl(lane_base + PHY_MODE_CFG);
+		val = u32_replace_bits(val, 1, BIT(2));
+		writel(val, lane_base + PHY_MODE_CFG);
+
+		val = FIELD_PREP(PHY_RX_REG0_MASK, 0x10) |
+			FIELD_PREP(PHY_RX_REG1_MASK, 0x78) |
+			FIELD_PREP(PHY_RX_REG2_MASK, 0x98) |
+			FIELD_PREP(PHY_RX_REG3_MASK, 0xdf);
+		writel(val, lane_base + PHY_RX_REG_A);
+
+		val = readl(lane_base + PHY_RX_REG_B);
+		val &= ~PHY_RX_REGB_MASK;
+		val |= FIELD_PREP(PHY_RX_REG4_MASK, 0xb4) |
+			FIELD_PREP(PHY_RX_REG5_MASK, 0x88) |
+			FIELD_PREP(PHY_RX_REG6_MASK, 0x28);
+		writel(val, lane_base + PHY_RX_REG_B);
+
+		/* Set init done */
+		val = readl(lane_base + PCIE_PU_ADDR_CLK_CFG);
+		val = u32_replace_bits(val, 1, CFG_SW_PHY_INIT_DONE);
+		writel(val, lane_base + PCIE_PU_ADDR_CLK_CFG);
+	}
+
+	ret = readl_poll_timeout(phy_base + PCIE_PU_ADDR_CLK_CFG, val,
+				 (val & PHY_CLK_PLL_READY), PCIE_POLL_DELAY,
+				 PCIE_PLL_TIMEOUT);
+	if (ret) {
+		dev_err(&lg->phy->dev, "PHY PLL lock timeout\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+const struct phy_ops k3_pcie_phy_ops = {
+	.init		= k3_pcie_phy_init,
+	.owner		= THIS_MODULE,
+};
+EXPORT_SYMBOL_GPL(k3_pcie_phy_ops);
+
+/* PHY rcal init requires APB_SPARE regmap access */
+
+#define APB_SPARE_PU_CAL		0x178
+#define PU_CAL				BIT(17)
+
+#define APB_SPARE_RCAL_HSIO		0x17c
+#define APB_SPARE_PU_CAL_DONE		BIT(8)
+#define RCAL_OVRD_PTRIM			GENMASK(23, 20)
+#define RCAL_OVRD_NTRIM			GENMASK(27, 24)
+#define RCAL_OVRD_PTRIM_EN		BIT(28)
+#define RCAL_OVRD_NTRIM_EN		BIT(29)
+#define RCAL_OVRD_STABLE_VAL		BIT(30)
+#define RCAL_OVRD_STABLE_EN		BIT(31)
+
+#define RCAL_OVRD_TRIM_EN		(RCAL_OVRD_NTRIM_EN | RCAL_OVRD_PTRIM_EN)
+#define RCAL_OVRD_TRIM_MASK		(RCAL_OVRD_NTRIM | RCAL_OVRD_PTRIM)
+
+#define PU_CAL_TIMEOUT 2000000
+
+static DEFINE_MUTEX(calibrate_lock);
+
+int k3_phy_calibrate(struct regmap *apb_spare)
+{
+	unsigned int val = 0;
+	int ret;
+
+	guard(mutex)(&calibrate_lock);
+
+	regmap_read(apb_spare, APB_SPARE_RCAL_HSIO, &val);
+	if (val & APB_SPARE_PU_CAL_DONE)
+		return 0;
+
+	regmap_update_bits(apb_spare, APB_SPARE_PU_CAL, PU_CAL,
+			   PU_CAL);
+
+	ret = regmap_read_poll_timeout(apb_spare, APB_SPARE_RCAL_HSIO,
+				       val, (val & APB_SPARE_PU_CAL_DONE), PCIE_POLL_DELAY,
+				       PU_CAL_TIMEOUT);
+
+	if (ret)
+		regmap_update_bits(apb_spare, APB_SPARE_RCAL_HSIO,
+				   RCAL_OVRD_TRIM_EN | RCAL_OVRD_STABLE_VAL |
+				   RCAL_OVRD_TRIM_MASK | RCAL_OVRD_STABLE_EN,
+				   RCAL_OVRD_TRIM_EN | RCAL_OVRD_STABLE_VAL |
+				   FIELD_PREP(RCAL_OVRD_NTRIM, 0x6) |
+				   FIELD_PREP(RCAL_OVRD_PTRIM, 0xa) |
+				   RCAL_OVRD_STABLE_EN);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(k3_phy_calibrate);
+
+MODULE_DESCRIPTION("SpacemiT K3 PHY common ops");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/spacemit/phy-k3-common.h b/drivers/phy/spacemit/phy-k3-common.h
new file mode 100644
index 000000000000..49009c3c313a
--- /dev/null
+++ b/drivers/phy/spacemit/phy-k3-common.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _PHY_K3_COMMON_H
+#define _PHY_K3_COMMON_H
+
+#include <linux/phy/phy.h>
+
+struct k3_phy_lane_group_data {
+	u32 lanes;
+	u8 config;
+	u8 mask;
+	u32 offsets[] __counted_by(lanes);
+};
+
+struct k3_lane_group {
+	const struct k3_phy_lane_group_data *data;
+	void __iomem *base;
+	struct phy *phy;
+	bool is_pcie;
+};
+
+extern const struct phy_ops k3_pcie_phy_ops;
+extern const struct phy_ops k3_usb3_phy_ops;
+
+int k3_phy_calibrate(struct regmap *apb_spare);
+
+#endif
-- 
2.55.0


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

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3
  2026-07-03  2:10 ` [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3 Inochi Amaoto
@ 2026-07-03  2:19   ` sashiko-bot
  2026-07-03 17:12   ` Aurelien Jarno
  1 sibling, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-07-03  2:19 UTC (permalink / raw)
  To: Inochi Amaoto
  Cc: linux-phy, vkoul, neil.armstrong, olteanv, robh, conor+dt,
	devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Hardware register clobbering due to missing read-modify-write operations in PHY initialization.
--

commit c71cb5c4ebfcb4fc5aff5c18a7769949e15dae55
Author: Inochi Amaoto <inochiama@gmail.com>

phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3

Adds a USB3/PCIe comb PHY driver for Spacemit K3. The comb PHY requires
configuring a syscon device for the correct mux configuration and needs
calibration before usage.

> diff --git a/drivers/phy/spacemit/phy-k3-common.c b/drivers/phy/spacemit/phy-k3-common.c
> new file mode 100644
> index 0000000000000..0b289e63db999
> --- /dev/null
> +++ b/drivers/phy/spacemit/phy-k3-common.c

[ ... ]

> +	/* Power down 100MHz refclk buffer */
> +	val = readl(base + PHY_PU_CK_REG);
> +	val = u32_replace_bits(val, 0, PHY_PU_REFCLK_100);
> +	writel(val, base + PHY_PU_CK_REG);
> +
> +	/* Program PLL REG1 configure the SSC */
> +	val = FIELD_PREP(PHY_PLL_SSC_MODE, PHY_PLL_SSC_MODE_DOWN_SPREAD1) |
> +	      FIELD_PREP(PHY_PLL_SSC_DEP_SEL, PHY_PLL_SSC_5000PPM) |
> +	      FIELD_PREP(PHY_PLL_FREF_SEL, PHY_PLL_FREF_24M);
> +	writel(val, base + PHY_PLL_REG1);

[Severity: High]
Does this completely overwrite PHY_PLL_REG1 and zero out unspecified bits?

Unlike the PCIe initialization path which uses a read-modify-write for this
register, this direct writel() in k3_usb3phy_init_single() clobbers the
entire register. Could this cause important default settings or calibration
values to be lost?

[ ... ]

> +	for (i = 0; i < lg->data->lanes; i++) {
> +		void __iomem *lane_base = lg->base + lg->data->offsets[i];
> +
> +		val = readl(lane_base + PCIE_RX_REG1);
> +		val = u32_replace_bits(val, 0, 0x3);
> +		writel(val, lane_base + PCIE_RX_REG1);
> +	}
> +
> +	val = readl(phy_base + PHY_PLL_REG2);
> +	val |= BIT(20);
> +	writel(val, phy_base + PHY_PLL_REG2);
> +
> +	/* The write is needed as clock requires renegotiation */
> +	val = FIELD_PREP(PCIE_RX_REFCLK_MODE, PCIE_RX_REFCLK_MODE_DRIVER) |
> +	      PCIE_RX_SEL_TRI_CODE |
> +	      FIELD_PREP(PCIE_RX_LEGACY, PCIE_RX_LEGACY_DEFAULT);
> +	writel(val, phy_base + PCIE_RX_REG1);

[Severity: High]
Does this clobber the entire PCIE_RX_REG1 register for lane 0?

The preceding loop performs a read-modify-write on PCIE_RX_REG1 for all lanes,
but this direct writel() on phy_base (which points to lane 0) invalidates
that previous work and zeroes out any bits not explicitly set here.

Should this also use a read-modify-write operation to preserve the register
state?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260703021024.495433-1-inochiama@gmail.com?part=2

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3
  2026-07-03  2:10 ` [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3 Inochi Amaoto
  2026-07-03  2:19   ` sashiko-bot
@ 2026-07-03 17:12   ` Aurelien Jarno
  1 sibling, 0 replies; 5+ messages in thread
From: Aurelien Jarno @ 2026-07-03 17:12 UTC (permalink / raw)
  To: Inochi Amaoto
  Cc: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Yixun Lan, Kees Cook, Gustavo A. R. Silva,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Alex Elder, Ze Huang, linux-phy, devicetree, linux-riscv,
	spacemit, linux-kernel, linux-hardening, Yixun Lan, Longbin Li

On 2026-07-03 10:10, Inochi Amaoto wrote:
> The comb PHY on K3 requires to configure a syscon device for the
> right mux configuration. And it requires calibration before any
> usage.
> 
> Add USB3/PCIe comb PHY driver for Spacemit K3.
> 
> Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
> ---
>  drivers/phy/spacemit/Kconfig         |  16 ++
>  drivers/phy/spacemit/Makefile        |   2 +
>  drivers/phy/spacemit/phy-k3-combo.c  | 252 +++++++++++++++++
>  drivers/phy/spacemit/phy-k3-common.c | 391 +++++++++++++++++++++++++++
>  drivers/phy/spacemit/phy-k3-common.h |  27 ++
>  5 files changed, 688 insertions(+)
>  create mode 100644 drivers/phy/spacemit/phy-k3-combo.c
>  create mode 100644 drivers/phy/spacemit/phy-k3-common.c
>  create mode 100644 drivers/phy/spacemit/phy-k3-common.h

Tested-by: Aurelien Jarno <aurelien@aurel32.net>

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                     http://aurel32.net

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

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-07-03 17:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-03  2:10 [PATCH v2 0/2] riscv: spacemit: Add K3 PCIe/USB comb phy support Inochi Amaoto
2026-07-03  2:10 ` [PATCH v2 1/2] dt-bindings: phy: Add Spacemit K3 USB3/PCIe " Inochi Amaoto
2026-07-03  2:10 ` [PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3 Inochi Amaoto
2026-07-03  2:19   ` sashiko-bot
2026-07-03 17:12   ` Aurelien Jarno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox