linux-phy.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/2] Add Google Tensor SoC USB PHY support
@ 2025-10-17 23:51 Roy Luo
  2025-10-17 23:51 ` [PATCH v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY Roy Luo
  2025-10-17 23:51 ` [PATCH v4 2/2] phy: Add Google Tensor SoC USB PHY driver Roy Luo
  0 siblings, 2 replies; 12+ messages in thread
From: Roy Luo @ 2025-10-17 23:51 UTC (permalink / raw)
  To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus
  Cc: Joy Chakraborty, Naveen Kumar, Roy Luo, Badhri Jagan Sridharan,
	linux-phy, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc

This series introduces USB PHY support for the Google Tensor G5
SoC (codename: Laguna), a new generation of Google silicon first
launched with Pixel 10 devices.

The Tensor G5 represents a significant architectural overhaul compared
to previous Tensor generations (e.g., gs101), which were based on Samsung
Exynos IP. Although the G5 still utilizes Synopsys IP for the USB
components, the custom top-level integration introduces a completely new
design for clock, reset scheme, register interfaces and programming
sequence, necessitating new drivers and device tree bindings.

The USB subsystem on Tensor G5 integrates a Synopsys DWC3 USB 3.1
DRD-Single Port controller with hibernation support, and a custom PHY
block comprising Synopsys eUSB2 and USB 3.2/DP combo PHYs. The controller
support is sent as a separate patch series.

Co-developed-by: Joy Chakraborty <joychakr@google.com>
Signed-off-by: Joy Chakraborty <joychakr@google.com>
Co-developed-by: Naveen Kumar <mnkumar@google.com>
Signed-off-by: Naveen Kumar <mnkumar@google.com>
Signed-off-by: Roy Luo <royluo@google.com>
---
Changes in v4:
- Separate controller and phy changes into two distinct patch series.
- Remove usb2only mode configuration and the corresponding usb_top_cfg
  reg (moved to controller)
- Add more descriptions to dp_top reg to indicate it's not DP specific.
- Add u2phy_apb clk/reset
Link to v3: https://lore.kernel.org/linux-usb/20251010201607.1190967-1-royluo@google.com

Changes in v3:
- Align binding file name with the compatible string
- Simplify the compatible property in binding to a single const value.
- Add descriptive comments and use item list in binding.
- Rename binding entries for clarity and brevity.
Link to v2: https://lore.kernel.org/linux-usb/20251008060000.3136021-1-royluo@google.com

Changes in v2:
- Reorder patches to present bindings first.
- Update dt binding compatible strings to be SoC-specific (google,gs5-*).
- Better describe the hardware in dt binding commit messages and
  descriptions.
- Adjust PHY driver commit subjects to use correct prefixes ("phy:").
- Move PHY driver from a subdirectory to drivers/phy/.
Link to v1: https://lore.kernel.org/linux-usb/20251006232125.1833979-1-royluo@google.com/
---
Roy Luo (2):
  dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  phy: Add Google Tensor SoC USB PHY driver

 .../bindings/phy/google,gs5-usb-phy.yaml      | 104 +++++++
 drivers/phy/Kconfig                           |  13 +
 drivers/phy/Makefile                          |   1 +
 drivers/phy/phy-google-usb.c                  | 271 ++++++++++++++++++
 4 files changed, 389 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
 create mode 100644 drivers/phy/phy-google-usb.c


base-commit: e5f0a698b34ed76002dc5cff3804a61c80233a7a
-- 
2.51.0.858.gf9c4a03a3a-goog


-- 
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 v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  2025-10-17 23:51 [PATCH v4 0/2] Add Google Tensor SoC USB PHY support Roy Luo
@ 2025-10-17 23:51 ` Roy Luo
  2025-10-23  6:43   ` Krzysztof Kozlowski
  2025-10-17 23:51 ` [PATCH v4 2/2] phy: Add Google Tensor SoC USB PHY driver Roy Luo
  1 sibling, 1 reply; 12+ messages in thread
From: Roy Luo @ 2025-10-17 23:51 UTC (permalink / raw)
  To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus
  Cc: Joy Chakraborty, Naveen Kumar, Roy Luo, Badhri Jagan Sridharan,
	linux-phy, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc

Document the device tree bindings for the USB PHY interfaces integrated
with the DWC3 controller on Google Tensor SoCs, starting with G5
generation. The USB PHY on Tensor G5 includes two integrated Synopsys
PHY IPs: the eUSB 2.0 PHY IP and the USB 3.2/DisplayPort combo PHY IP.

Due to a complete architectural overhaul in the Google Tensor G5, the
existing Samsung/Exynos USB PHY binding for older generations of Google
silicons such as gs101 are no longer compatible, necessitating this new
device tree binding.

Signed-off-by: Roy Luo <royluo@google.com>
---
 .../bindings/phy/google,gs5-usb-phy.yaml      | 104 ++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
new file mode 100644
index 000000000000..c92c20eba1ea
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
@@ -0,0 +1,104 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) 2025, Google LLC
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/google,gs5-usb-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Google Tensor Series (G5+) USB PHY
+
+maintainers:
+  - Roy Luo <royluo@google.com>
+
+description: |
+  Describes the USB PHY interfaces integrated with the DWC3 USB controller on
+  Google Tensor SoCs, starting with the G5 generation.
+  Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP
+  and USB 3.2/DisplayPort combo PHY IP.
+  The hardware can support three PHY interfaces, which are selected using the
+  first phandle argument in the PHY specifier::
+    0 - USB high-speed.
+    1 - USB super-speed.
+    2 - DisplayPort
+
+properties:
+  compatible:
+    const: google,gs5-usb-phy
+
+  reg:
+    items:
+      - description: USB2 PHY configuration registers.
+      - description: USB 3.2/DisplayPort combo PHY top-level registers.
+
+  reg-names:
+    items:
+      - const: u2phy_cfg
+      - const: dp_top
+
+  "#phy-cells":
+    const: 1
+
+  clocks:
+    items:
+      - description: USB2 PHY clock.
+      - description: USB2 PHY APB clock.
+
+  clock-names:
+    items:
+      - const: usb2_phy
+      - const: u2phy_apb
+
+  resets:
+    items:
+      - description: USB2 PHY reset.
+      - description: USB2 PHY APB reset.
+
+  reset-names:
+    items:
+      - const: usb2_phy
+      - const: u2phy_apb
+
+  power-domains:
+    maxItems: 1
+
+  orientation-switch:
+    type: boolean
+    description:
+      Indicates the PHY as a handler of USB Type-C orientation changes
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#phy-cells"
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - power-domains
+  - orientation-switch
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        usb_phy: usb_phy@c450014 {
+            compatible = "google,gs5-usb-phy";
+            reg = <0 0x0c450014 0 0xc>,
+                  <0 0x0c637000 0 0xa0>;
+            reg-names = "u2phy_cfg", "dp_top";
+            #phy-cells = <1>;
+            clocks = <&hsion_usb2_phy_clk>, <&hsion_u2phy_apb_clk>;
+            clock-names = "usb2_phy", "u2phy_apb";
+            resets = <&hsion_resets_usb2_phy>,
+                     <&hsion_resets_u2phy_apb>;
+            reset-names = "usb2_phy", "u2phy_apb";
+            power-domains = <&hsio_n_usb_pd>;
+            orientation-switch;
+        };
+    };
+...
-- 
2.51.0.858.gf9c4a03a3a-goog


-- 
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 v4 2/2] phy: Add Google Tensor SoC USB PHY driver
  2025-10-17 23:51 [PATCH v4 0/2] Add Google Tensor SoC USB PHY support Roy Luo
  2025-10-17 23:51 ` [PATCH v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY Roy Luo
@ 2025-10-17 23:51 ` Roy Luo
  2025-10-18  8:13   ` Ivaylo Ivanov
  1 sibling, 1 reply; 12+ messages in thread
From: Roy Luo @ 2025-10-17 23:51 UTC (permalink / raw)
  To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus
  Cc: Joy Chakraborty, Naveen Kumar, Roy Luo, Badhri Jagan Sridharan,
	linux-phy, devicetree, linux-kernel, linux-arm-kernel,
	linux-samsung-soc

Support the USB PHY found on Google Tensor G5. This particular USB PHY
supports both high-speed and super-speed operations, and is integrated
with the SNPS DWC3 controller that's also on the SoC.
This initial patch specifically adds functionality for high-speed.

Co-developed-by: Joy Chakraborty <joychakr@google.com>
Signed-off-by: Joy Chakraborty <joychakr@google.com>
Co-developed-by: Naveen Kumar <mnkumar@google.com>
Signed-off-by: Naveen Kumar <mnkumar@google.com>
Signed-off-by: Roy Luo <royluo@google.com>
---
 drivers/phy/Kconfig          |  13 ++
 drivers/phy/Makefile         |   1 +
 drivers/phy/phy-google-usb.c | 271 +++++++++++++++++++++++++++++++++++
 3 files changed, 285 insertions(+)
 create mode 100644 drivers/phy/phy-google-usb.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 58c911e1b2d2..fe32d1356002 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -101,6 +101,19 @@ config PHY_NXP_PTN3222
 	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
 	  Speed and High Speed.
 
+config PHY_GOOGLE_USB
+	tristate "Google Tensor SoC USB PHY driver"
+	depends on HAS_IOMEM
+	depends on OF
+	depends on TYPEC
+	select GENERIC_PHY
+	help
+	  Enable support for the USB PHY on Google Tensor SoCs, starting with
+	  the G5 generation. This driver provides the PHY interfaces to
+	  interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY, both
+	  of which are integrated with the DWC3 USB controller.
+	  This driver currently supports USB high-speed.
+
 source "drivers/phy/allwinner/Kconfig"
 source "drivers/phy/amlogic/Kconfig"
 source "drivers/phy/broadcom/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index c670a8dac468..1d7a1331bd19 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PHY_SNPS_EUSB2)		+= phy-snps-eusb2.o
 obj-$(CONFIG_USB_LGM_PHY)		+= phy-lgm-usb.o
 obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o
 obj-$(CONFIG_PHY_NXP_PTN3222)		+= phy-nxp-ptn3222.o
+obj-$(CONFIG_PHY_GOOGLE_USB)		+= phy-google-usb.o
 obj-y					+= allwinner/	\
 					   amlogic/	\
 					   broadcom/	\
diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c
new file mode 100644
index 000000000000..75e4233a5ab5
--- /dev/null
+++ b/drivers/phy/phy-google-usb.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * phy-google-usb.c - Google USB PHY driver
+ *
+ * Copyright (C) 2025, Google LLC
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/cleanup.h>
+#include <linux/usb/typec_mux.h>
+
+#define USBCS_USB2PHY_CFG19_OFFSET 0x0
+#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
+
+#define USBCS_USB2PHY_CFG21_OFFSET 0x8
+#define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12)
+#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
+#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
+
+#define USBCS_PHY_CFG1_OFFSET 0x28
+#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
+
+enum google_usb_phy_id {
+	GOOGLE_USB2_PHY,
+	GOOGLE_USB_PHY_NUM,
+};
+
+struct google_usb_phy_instance {
+	int index;
+	struct phy *phy;
+	int num_clks;
+	struct clk_bulk_data *clks;
+	struct reset_control *rsts;
+};
+
+struct google_usb_phy {
+	struct device *dev;
+	void __iomem *u2phy_cfg_base;
+	void __iomem *dp_top_base;
+	struct google_usb_phy_instance insts[GOOGLE_USB_PHY_NUM];
+	/* serialize phy access */
+	struct mutex phy_mutex;
+	struct typec_switch_dev *sw;
+	enum typec_orientation orientation;
+};
+
+static inline struct google_usb_phy *to_google_usb_phy(struct google_usb_phy_instance *inst)
+{
+	return container_of(inst, struct google_usb_phy, insts[inst->index]);
+}
+
+static void set_vbus_valid(struct google_usb_phy *gphy)
+{
+	u32 reg;
+
+	if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
+		reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
+		reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
+		writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
+	} else {
+		reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
+		reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
+		writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
+	}
+}
+
+static int google_usb_set_orientation(struct typec_switch_dev *sw,
+				      enum typec_orientation orientation)
+{
+	struct google_usb_phy *gphy = typec_switch_get_drvdata(sw);
+
+	dev_dbg(gphy->dev, "set orientation %d\n", orientation);
+
+	gphy->orientation = orientation;
+
+	if (pm_runtime_suspended(gphy->dev))
+		return 0;
+
+	guard(mutex)(&gphy->phy_mutex);
+
+	set_vbus_valid(gphy);
+
+	return 0;
+}
+
+static int google_usb2_phy_init(struct phy *_phy)
+{
+	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+	struct google_usb_phy *gphy = to_google_usb_phy(inst);
+	u32 reg;
+	int ret = 0;
+
+	dev_dbg(gphy->dev, "initializing usb2 phy\n");
+
+	guard(mutex)(&gphy->phy_mutex);
+
+	reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
+	reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL;
+	reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL;
+	reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0);
+	writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
+
+	reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
+	reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV;
+	reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368);
+	writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
+
+	set_vbus_valid(gphy);
+
+	ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
+	if (ret)
+		return ret;
+
+	ret = reset_control_deassert(inst->rsts);
+	if (ret) {
+		clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+		return ret;
+	}
+
+	reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
+	reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE;
+	writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
+
+	return ret;
+}
+
+static int google_usb2_phy_exit(struct phy *_phy)
+{
+	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+	struct google_usb_phy *gphy = to_google_usb_phy(inst);
+	u32 reg;
+
+	dev_dbg(gphy->dev, "exiting usb2 phy\n");
+
+	guard(mutex)(&gphy->phy_mutex);
+
+	reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
+	reg &= ~USBCS_USB2PHY_CFG21_PHY_ENABLE;
+	writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
+
+	reset_control_assert(inst->rsts);
+	clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+
+	return 0;
+}
+
+static const struct phy_ops google_usb2_phy_ops = {
+	.init		= google_usb2_phy_init,
+	.exit		= google_usb2_phy_exit,
+};
+
+static struct phy *google_usb_phy_xlate(struct device *dev,
+					const struct of_phandle_args *args)
+{
+	struct google_usb_phy *gphy = dev_get_drvdata(dev);
+
+	if (args->args[0] >= GOOGLE_USB_PHY_NUM) {
+		dev_err(dev, "invalid PHY index requested from DT\n");
+		return ERR_PTR(-ENODEV);
+	}
+	return gphy->insts[args->args[0]].phy;
+}
+
+static int google_usb_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct google_usb_phy *gphy;
+	struct phy *phy;
+	struct google_usb_phy_instance *inst;
+	struct phy_provider *phy_provider;
+	struct typec_switch_desc sw_desc = { };
+	int ret;
+
+	gphy = devm_kzalloc(dev, sizeof(*gphy), GFP_KERNEL);
+	if (!gphy)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, gphy);
+	gphy->dev = dev;
+
+	ret = devm_mutex_init(dev, &gphy->phy_mutex);
+	if (ret)
+		return ret;
+
+	gphy->u2phy_cfg_base = devm_platform_ioremap_resource_byname(pdev,
+								     "u2phy_cfg");
+	if (IS_ERR(gphy->u2phy_cfg_base))
+		return dev_err_probe(dev, PTR_ERR(gphy->u2phy_cfg_base),
+				    "invalid usb2 cfg\n");
+
+	gphy->dp_top_base = devm_platform_ioremap_resource_byname(pdev,
+								  "dp_top");
+	if (IS_ERR(gphy->dp_top_base))
+		return dev_err_probe(dev, PTR_ERR(gphy->dp_top_base),
+				    "invalid dp top\n");
+
+	inst = &gphy->insts[GOOGLE_USB2_PHY];
+	inst->index = GOOGLE_USB2_PHY;
+	phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy),
+				     "failed to create usb2 phy instance\n");
+	inst->phy = phy;
+	phy_set_drvdata(phy, inst);
+	ret = devm_clk_bulk_get_all_enabled(dev, &inst->clks);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to get u2 phy clks\n");
+	inst->num_clks = ret;
+
+	inst->rsts = devm_reset_control_array_get_exclusive(dev);
+	if (IS_ERR(inst->rsts))
+		return dev_err_probe(dev, PTR_ERR(inst->rsts),
+				     "failed to get u2 phy resets\n");
+
+	phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate);
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(dev, PTR_ERR(phy_provider),
+				     "failed to register phy provider\n");
+
+	pm_runtime_enable(dev);
+
+	sw_desc.fwnode = dev_fwnode(dev);
+	sw_desc.drvdata = gphy;
+	sw_desc.name = fwnode_get_name(dev_fwnode(dev));
+	sw_desc.set = google_usb_set_orientation;
+
+	gphy->sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(gphy->sw))
+		return dev_err_probe(dev, PTR_ERR(gphy->sw),
+				     "failed to register typec switch\n");
+
+	return 0;
+}
+
+static void google_usb_phy_remove(struct platform_device *pdev)
+{
+	struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev);
+
+	typec_switch_unregister(gphy->sw);
+	pm_runtime_disable(&pdev->dev);
+}
+
+static const struct of_device_id google_usb_phy_of_match[] = {
+	{
+		.compatible = "google,gs5-usb-phy",
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, google_usb_phy_of_match);
+
+static struct platform_driver google_usb_phy = {
+	.probe	= google_usb_phy_probe,
+	.remove = google_usb_phy_remove,
+	.driver = {
+		.name		= "google-usb-phy",
+		.of_match_table	= google_usb_phy_of_match,
+	}
+};
+
+module_platform_driver(google_usb_phy);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Google USB phy driver");
-- 
2.51.0.858.gf9c4a03a3a-goog


-- 
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 v4 2/2] phy: Add Google Tensor SoC USB PHY driver
  2025-10-17 23:51 ` [PATCH v4 2/2] phy: Add Google Tensor SoC USB PHY driver Roy Luo
@ 2025-10-18  8:13   ` Ivaylo Ivanov
  2025-10-20 19:55     ` Roy Luo
  0 siblings, 1 reply; 12+ messages in thread
From: Ivaylo Ivanov @ 2025-10-18  8:13 UTC (permalink / raw)
  To: Roy Luo, Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus
  Cc: Joy Chakraborty, Naveen Kumar, Badhri Jagan Sridharan, linux-phy,
	devicetree, linux-kernel, linux-arm-kernel, linux-samsung-soc

On 10/18/25 02:51, Roy Luo wrote:
> Support the USB PHY found on Google Tensor G5. This particular USB PHY
> supports both high-speed and super-speed operations, and is integrated
> with the SNPS DWC3 controller that's also on the SoC.
> This initial patch specifically adds functionality for high-speed.
>
> Co-developed-by: Joy Chakraborty <joychakr@google.com>
> Signed-off-by: Joy Chakraborty <joychakr@google.com>
> Co-developed-by: Naveen Kumar <mnkumar@google.com>
> Signed-off-by: Naveen Kumar <mnkumar@google.com>
> Signed-off-by: Roy Luo <royluo@google.com>
> ---
>  drivers/phy/Kconfig          |  13 ++
>  drivers/phy/Makefile         |   1 +
>  drivers/phy/phy-google-usb.c | 271 +++++++++++++++++++++++++++++++++++
>  3 files changed, 285 insertions(+)
>  create mode 100644 drivers/phy/phy-google-usb.c
>
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index 58c911e1b2d2..fe32d1356002 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -101,6 +101,19 @@ config PHY_NXP_PTN3222
>  	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
>  	  Speed and High Speed.
>  
> +config PHY_GOOGLE_USB
> +	tristate "Google Tensor SoC USB PHY driver"
> +	depends on HAS_IOMEM
> +	depends on OF
> +	depends on TYPEC
> +	select GENERIC_PHY
> +	help
> +	  Enable support for the USB PHY on Google Tensor SoCs, starting with
> +	  the G5 generation. This driver provides the PHY interfaces to
> +	  interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY, both
> +	  of which are integrated with the DWC3 USB controller.

So it's more like a DRD controller, since it encapsulates multiple phys?

> +	  This driver currently supports USB high-speed.
> +
>  source "drivers/phy/allwinner/Kconfig"
>  source "drivers/phy/amlogic/Kconfig"
>  source "drivers/phy/broadcom/Kconfig"
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index c670a8dac468..1d7a1331bd19 100644
...
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/phy/phy.h>
> +#include <linux/platform_device.h>
> +#include <linux/mutex.h>
> +#include <linux/cleanup.h>
> +#include <linux/usb/typec_mux.h>
> +
> +#define USBCS_USB2PHY_CFG19_OFFSET 0x0
> +#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)

I'd suggest implementing the eUSB support in the existing snps-eusb2
driver for the sake of clarity. That way, you can pass it as a phandle
to this driver and probe it when drd is probing.

> +
> +#define USBCS_USB2PHY_CFG21_OFFSET 0x8
> +#define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12)
> +#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
> +#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
> +
> +#define USBCS_PHY_CFG1_OFFSET 0x28
> +#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
> +
> +enum google_usb_phy_id {
> +	GOOGLE_USB2_PHY,
> +	GOOGLE_USB_PHY_NUM,
> +};
> +
> +struct google_usb_phy_instance {
> +	int index;
> +	struct phy *phy;
> +	int num_clks;
> +	struct clk_bulk_data *clks;
> +	struct reset_control *rsts;
> +};
> +
> +struct google_usb_phy {
> +	struct device *dev;
> +	void __iomem *u2phy_cfg_base;
> +	void __iomem *dp_top_base;
> +	struct google_usb_phy_instance insts[GOOGLE_USB_PHY_NUM];
> +	/* serialize phy access */
> +	struct mutex phy_mutex;
> +	struct typec_switch_dev *sw;
> +	enum typec_orientation orientation;
> +};
> +
> +static inline struct google_usb_phy *to_google_usb_phy(struct google_usb_phy_instance *inst)
> +{
> +	return container_of(inst, struct google_usb_phy, insts[inst->index]);
> +}
> +
> +static void set_vbus_valid(struct google_usb_phy *gphy)
> +{
> +	u32 reg;
> +
> +	if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
> +		reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> +		reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
> +		writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> +	} else {
> +		reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> +		reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
> +		writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> +	}
> +}
> +
> +static int google_usb_set_orientation(struct typec_switch_dev *sw,
> +				      enum typec_orientation orientation)
> +{
> +	struct google_usb_phy *gphy = typec_switch_get_drvdata(sw);
> +
> +	dev_dbg(gphy->dev, "set orientation %d\n", orientation);
> +
> +	gphy->orientation = orientation;
> +
> +	if (pm_runtime_suspended(gphy->dev))
> +		return 0;
> +
> +	guard(mutex)(&gphy->phy_mutex);
> +
> +	set_vbus_valid(gphy);
> +
> +	return 0;
> +}
> +
> +static int google_usb2_phy_init(struct phy *_phy)
> +{
> +	struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
> +	struct google_usb_phy *gphy = to_google_usb_phy(inst);
> +	u32 reg;
> +	int ret = 0;
> +
> +	dev_dbg(gphy->dev, "initializing usb2 phy\n");
> +
> +	guard(mutex)(&gphy->phy_mutex);
> +
> +	reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> +	reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL;
> +	reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL;
> +	reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0);
> +	writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> +
> +	reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
> +	reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV;
> +	reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368);

Yeah, it's definitely the eUSB IP, but wired differently.

phy-snps-eusb2.c:
#define EXYNOS_USB_PHY_CFG_PLLCFG0 (0x8)
#define PHY_CFG_PLL_FB_DIV_19_8_MASK GENMASK(19, 8)
#define DIV_19_8_19_2_MHZ_VAL (0x170)

> +	writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
> +
> +	set_vbus_valid(gphy);
> +
> +	ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
> +	if (ret)
> +		return ret;
> +
> +	ret = reset_control_deassert(inst->rsts);
> +	if (ret) {
> +		clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
> +		return ret;
> +	}
> +
> +	reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> +	reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE;
> +	writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> +
> +	return ret;
> +}
> +
...
> +
> +	gphy->sw = typec_switch_register(dev, &sw_desc);
> +	if (IS_ERR(gphy->sw))
> +		return dev_err_probe(dev, PTR_ERR(gphy->sw),
> +				     "failed to register typec switch\n");
> +
> +	return 0;
> +}
> +
> +static void google_usb_phy_remove(struct platform_device *pdev)
> +{
> +	struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev);
> +
> +	typec_switch_unregister(gphy->sw);
> +	pm_runtime_disable(&pdev->dev);
> +}
> +
> +static const struct of_device_id google_usb_phy_of_match[] = {
> +	{
> +		.compatible = "google,gs5-usb-phy",

Did the naming scheme also change from gs{N}01 to gsN?

> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, google_usb_phy_of_match);
> +
> +static struct platform_driver google_usb_phy = {
> +	.probe	= google_usb_phy_probe,
> +	.remove = google_usb_phy_remove,
> +	.driver = {
> +		.name		= "google-usb-phy",
> +		.of_match_table	= google_usb_phy_of_match,
> +	}
> +};
> +
> +module_platform_driver(google_usb_phy);
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("Google USB phy driver");

Great work!

Best regards,
Ivaylo

-- 
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 v4 2/2] phy: Add Google Tensor SoC USB PHY driver
  2025-10-18  8:13   ` Ivaylo Ivanov
@ 2025-10-20 19:55     ` Roy Luo
  2025-10-29 21:56       ` Roy Luo
  0 siblings, 1 reply; 12+ messages in thread
From: Roy Luo @ 2025-10-20 19:55 UTC (permalink / raw)
  To: Ivaylo Ivanov
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On Sat, Oct 18, 2025 at 1:13 AM Ivaylo Ivanov
<ivo.ivanov.ivanov1@gmail.com> wrote:
>
> On 10/18/25 02:51, Roy Luo wrote:
> > Support the USB PHY found on Google Tensor G5. This particular USB PHY
> > supports both high-speed and super-speed operations, and is integrated
> > with the SNPS DWC3 controller that's also on the SoC.
> > This initial patch specifically adds functionality for high-speed.
> >
> > Co-developed-by: Joy Chakraborty <joychakr@google.com>
> > Signed-off-by: Joy Chakraborty <joychakr@google.com>
> > Co-developed-by: Naveen Kumar <mnkumar@google.com>
> > Signed-off-by: Naveen Kumar <mnkumar@google.com>
> > Signed-off-by: Roy Luo <royluo@google.com>
> > ---
> >  drivers/phy/Kconfig          |  13 ++
> >  drivers/phy/Makefile         |   1 +
> >  drivers/phy/phy-google-usb.c | 271 +++++++++++++++++++++++++++++++++++
> >  3 files changed, 285 insertions(+)
> >  create mode 100644 drivers/phy/phy-google-usb.c
> >
> > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> > index 58c911e1b2d2..fe32d1356002 100644
> > --- a/drivers/phy/Kconfig
> > +++ b/drivers/phy/Kconfig
> > @@ -101,6 +101,19 @@ config PHY_NXP_PTN3222
> >         schemes. It supports all three USB 2.0 data rates: Low Speed, Full
> >         Speed and High Speed.
> >
> > +config PHY_GOOGLE_USB
> > +     tristate "Google Tensor SoC USB PHY driver"
> > +     depends on HAS_IOMEM
> > +     depends on OF
> > +     depends on TYPEC
> > +     select GENERIC_PHY
> > +     help
> > +       Enable support for the USB PHY on Google Tensor SoCs, starting with
> > +       the G5 generation. This driver provides the PHY interfaces to
> > +       interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY, both
> > +       of which are integrated with the DWC3 USB controller.
>
> So it's more like a DRD controller, since it encapsulates multiple phys?

Yes, it's a DRD controller, I will make it clear in the next version.

>
> > +       This driver currently supports USB high-speed.
> > +
> >  source "drivers/phy/allwinner/Kconfig"
> >  source "drivers/phy/amlogic/Kconfig"
> >  source "drivers/phy/broadcom/Kconfig"
> > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> > index c670a8dac468..1d7a1331bd19 100644
> ...
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/phy/phy.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/mutex.h>
> > +#include <linux/cleanup.h>
> > +#include <linux/usb/typec_mux.h>
> > +
> > +#define USBCS_USB2PHY_CFG19_OFFSET 0x0
> > +#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
>
> I'd suggest implementing the eUSB support in the existing snps-eusb2
> driver for the sake of clarity. That way, you can pass it as a phandle
> to this driver and probe it when drd is probing.

If I understand it correctly, you're referring to the pattern used in
Documentation/devicetree/bindings/phy/samsung,exynos2200-eusb2-phy.yaml and
Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml.
Please correct me if I'm wrong.

At first glance, this approach seems feasible. Custom logic, such
as vbus valid handling, would need to stay within this driver. Most
of the eUSB block configuration in google_usb2_phy_init() could
be moved to the snps-eusb2 driver by adding one more compatible
for Google's version of the SNSP eUSB IP. However, I'd argue
1. This approach would introduce an extra layer of PHY interface,
    which adds unnecessary complexity.
2. Not much of the code is reused in snps-eusb2 driver: the register
    definition and programming sequence are specific to Google,
    hence the logic in google_usb2_phy_init() would have to be
    moved to snps-eusb2 driver almost word-by-word.

I understand this approach was suggested for the sake of clarity,
but I'm not sure whether that makes for the best trade-off. Since
there is a precedent for this approach, I do not have a strong
objection. It would be helpful if the maintainers could also provide
their input on this specific point.

>
> > +
> > +#define USBCS_USB2PHY_CFG21_OFFSET 0x8
> > +#define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12)
> > +#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
> > +#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
> > +
> > +#define USBCS_PHY_CFG1_OFFSET 0x28
> > +#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
> > +
> > +enum google_usb_phy_id {
> > +     GOOGLE_USB2_PHY,
> > +     GOOGLE_USB_PHY_NUM,
> > +};
> > +
> > +struct google_usb_phy_instance {
> > +     int index;
> > +     struct phy *phy;
> > +     int num_clks;
> > +     struct clk_bulk_data *clks;
> > +     struct reset_control *rsts;
> > +};
> > +
> > +struct google_usb_phy {
> > +     struct device *dev;
> > +     void __iomem *u2phy_cfg_base;
> > +     void __iomem *dp_top_base;
> > +     struct google_usb_phy_instance insts[GOOGLE_USB_PHY_NUM];
> > +     /* serialize phy access */
> > +     struct mutex phy_mutex;
> > +     struct typec_switch_dev *sw;
> > +     enum typec_orientation orientation;
> > +};
> > +
> > +static inline struct google_usb_phy *to_google_usb_phy(struct google_usb_phy_instance *inst)
> > +{
> > +     return container_of(inst, struct google_usb_phy, insts[inst->index]);
> > +}
> > +
> > +static void set_vbus_valid(struct google_usb_phy *gphy)
> > +{
> > +     u32 reg;
> > +
> > +     if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
> > +             reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > +             reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
> > +             writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > +     } else {
> > +             reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > +             reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
> > +             writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > +     }
> > +}
> > +
> > +static int google_usb_set_orientation(struct typec_switch_dev *sw,
> > +                                   enum typec_orientation orientation)
> > +{
> > +     struct google_usb_phy *gphy = typec_switch_get_drvdata(sw);
> > +
> > +     dev_dbg(gphy->dev, "set orientation %d\n", orientation);
> > +
> > +     gphy->orientation = orientation;
> > +
> > +     if (pm_runtime_suspended(gphy->dev))
> > +             return 0;
> > +
> > +     guard(mutex)(&gphy->phy_mutex);
> > +
> > +     set_vbus_valid(gphy);
> > +
> > +     return 0;
> > +}
> > +
> > +static int google_usb2_phy_init(struct phy *_phy)
> > +{
> > +     struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
> > +     struct google_usb_phy *gphy = to_google_usb_phy(inst);
> > +     u32 reg;
> > +     int ret = 0;
> > +
> > +     dev_dbg(gphy->dev, "initializing usb2 phy\n");
> > +
> > +     guard(mutex)(&gphy->phy_mutex);
> > +
> > +     reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > +     reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL;
> > +     reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL;
> > +     reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0);
> > +     writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > +
> > +     reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
> > +     reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV;
> > +     reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368);
>
> Yeah, it's definitely the eUSB IP, but wired differently.
>
> phy-snps-eusb2.c:
> #define EXYNOS_USB_PHY_CFG_PLLCFG0 (0x8)
> #define PHY_CFG_PLL_FB_DIV_19_8_MASK GENMASK(19, 8)
> #define DIV_19_8_19_2_MHZ_VAL (0x170)
>
> > +     writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
> > +
> > +     set_vbus_valid(gphy);
> > +
> > +     ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = reset_control_deassert(inst->rsts);
> > +     if (ret) {
> > +             clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
> > +             return ret;
> > +     }
> > +
> > +     reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > +     reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE;
> > +     writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > +
> > +     return ret;
> > +}
> > +
> ...
> > +
> > +     gphy->sw = typec_switch_register(dev, &sw_desc);
> > +     if (IS_ERR(gphy->sw))
> > +             return dev_err_probe(dev, PTR_ERR(gphy->sw),
> > +                                  "failed to register typec switch\n");
> > +
> > +     return 0;
> > +}
> > +
> > +static void google_usb_phy_remove(struct platform_device *pdev)
> > +{
> > +     struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev);
> > +
> > +     typec_switch_unregister(gphy->sw);
> > +     pm_runtime_disable(&pdev->dev);
> > +}
> > +
> > +static const struct of_device_id google_usb_phy_of_match[] = {
> > +     {
> > +             .compatible = "google,gs5-usb-phy",
>
> Did the naming scheme also change from gs{N}01 to gsN?

Starting from Tensor G5, there's no model number [1], hence
the change. The prefix "gs" is kept as their family name.

[1] https://en.wikipedia.org/wiki/Google_Tensor

>
> > +     },
> > +     { }
> > +};
> > +MODULE_DEVICE_TABLE(of, google_usb_phy_of_match);
> > +
> > +static struct platform_driver google_usb_phy = {
> > +     .probe  = google_usb_phy_probe,
> > +     .remove = google_usb_phy_remove,
> > +     .driver = {
> > +             .name           = "google-usb-phy",
> > +             .of_match_table = google_usb_phy_of_match,
> > +     }
> > +};
> > +
> > +module_platform_driver(google_usb_phy);
> > +MODULE_LICENSE("GPL");
> > +MODULE_DESCRIPTION("Google USB phy driver");
>
> Great work!
>
> Best regards,
> Ivaylo

Thank you for the review!

Regards,
Roy Luo

-- 
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 v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  2025-10-17 23:51 ` [PATCH v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY Roy Luo
@ 2025-10-23  6:43   ` Krzysztof Kozlowski
  2025-10-23  6:57     ` Krzysztof Kozlowski
  2025-10-23 22:22     ` Roy Luo
  0 siblings, 2 replies; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-10-23  6:43 UTC (permalink / raw)
  To: Roy Luo
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On Fri, Oct 17, 2025 at 11:51:58PM +0000, Roy Luo wrote:
> Document the device tree bindings for the USB PHY interfaces integrated
> with the DWC3 controller on Google Tensor SoCs, starting with G5
> generation. The USB PHY on Tensor G5 includes two integrated Synopsys
> PHY IPs: the eUSB 2.0 PHY IP and the USB 3.2/DisplayPort combo PHY IP.
> 
> Due to a complete architectural overhaul in the Google Tensor G5, the
> existing Samsung/Exynos USB PHY binding for older generations of Google
> silicons such as gs101 are no longer compatible, necessitating this new
> device tree binding.
> 
> Signed-off-by: Roy Luo <royluo@google.com>
> ---
>  .../bindings/phy/google,gs5-usb-phy.yaml      | 104 ++++++++++++++++++
>  1 file changed, 104 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> new file mode 100644
> index 000000000000..c92c20eba1ea
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> @@ -0,0 +1,104 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2025, Google LLC
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/google,gs5-usb-phy.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Google Tensor Series (G5+) USB PHY
> +
> +maintainers:
> +  - Roy Luo <royluo@google.com>
> +
> +description: |
> +  Describes the USB PHY interfaces integrated with the DWC3 USB controller on
> +  Google Tensor SoCs, starting with the G5 generation.
> +  Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP
> +  and USB 3.2/DisplayPort combo PHY IP.
> +  The hardware can support three PHY interfaces, which are selected using the
> +  first phandle argument in the PHY specifier::

Just one ':', anyway this sentence and below does not belong to
description but to phy-cells. You describe the cells.

Or just mention the header with IDs - here or in phy-cells.

> +    0 - USB high-speed.
> +    1 - USB super-speed.
> +    2 - DisplayPort
> +
> +properties:
> +  compatible:
> +    const: google,gs5-usb-phy
> +
> +  reg:
> +    items:
> +      - description: USB2 PHY configuration registers.
> +      - description: USB 3.2/DisplayPort combo PHY top-level registers.
> +
> +  reg-names:
> +    items:
> +      - const: u2phy_cfg
> +      - const: dp_top
> +
> +  "#phy-cells":
> +    const: 1
> +
> +  clocks:
> +    items:
> +      - description: USB2 PHY clock.
> +      - description: USB2 PHY APB clock.
> +
> +  clock-names:
> +    items:
> +      - const: usb2_phy

core

> +      - const: u2phy_apb

apb

> +
> +  resets:
> +    items:
> +      - description: USB2 PHY reset.
> +      - description: USB2 PHY APB reset.
> +
> +  reset-names:
> +    items:
> +      - const: usb2_phy
> +      - const: u2phy_apb

Same here

> +
> +  power-domains:
> +    maxItems: 1

Best regards,
Krzysztof


-- 
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 v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  2025-10-23  6:43   ` Krzysztof Kozlowski
@ 2025-10-23  6:57     ` Krzysztof Kozlowski
  2025-10-23 21:54       ` Roy Luo
  2025-10-23 22:22     ` Roy Luo
  1 sibling, 1 reply; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-10-23  6:57 UTC (permalink / raw)
  To: Roy Luo
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On 23/10/2025 08:43, Krzysztof Kozlowski wrote:
> On Fri, Oct 17, 2025 at 11:51:58PM +0000, Roy Luo wrote:
>> Document the device tree bindings for the USB PHY interfaces integrated
>> with the DWC3 controller on Google Tensor SoCs, starting with G5
>> generation. The USB PHY on Tensor G5 includes two integrated Synopsys
>> PHY IPs: the eUSB 2.0 PHY IP and the USB 3.2/DisplayPort combo PHY IP.
>>
>> Due to a complete architectural overhaul in the Google Tensor G5, the
>> existing Samsung/Exynos USB PHY binding for older generations of Google
>> silicons such as gs101 are no longer compatible, necessitating this new
>> device tree binding.
>>
>> Signed-off-by: Roy Luo <royluo@google.com>
>> ---
>>  .../bindings/phy/google,gs5-usb-phy.yaml      | 104 ++++++++++++++++++
>>  1 file changed, 104 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
>> new file mode 100644
>> index 000000000000..c92c20eba1ea
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
>> @@ -0,0 +1,104 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +# Copyright (C) 2025, Google LLC
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/google,gs5-usb-phy.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Google Tensor Series (G5+) USB PHY
>> +
>> +maintainers:
>> +  - Roy Luo <royluo@google.com>
>> +
>> +description: |
>> +  Describes the USB PHY interfaces integrated with the DWC3 USB controller on
>> +  Google Tensor SoCs, starting with the G5 generation.
>> +  Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP
>> +  and USB 3.2/DisplayPort combo PHY IP.
>> +  The hardware can support three PHY interfaces, which are selected using the
>> +  first phandle argument in the PHY specifier::
> 
> Just one ':', anyway this sentence and below does not belong to
> description but to phy-cells. You describe the cells.
> 
> Or just mention the header with IDs - here or in phy-cells.


If you go with free-form text description in phy cells, then some
example could be:
renesas,rcar-gen2-usb-phy.yaml

For the header (in this case clocks):
display/msm/dsi-phy-common.yaml


Best regards,
Krzysztof

-- 
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 v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  2025-10-23  6:57     ` Krzysztof Kozlowski
@ 2025-10-23 21:54       ` Roy Luo
  0 siblings, 0 replies; 12+ messages in thread
From: Roy Luo @ 2025-10-23 21:54 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On Wed, Oct 22, 2025 at 11:58 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 23/10/2025 08:43, Krzysztof Kozlowski wrote:
> > On Fri, Oct 17, 2025 at 11:51:58PM +0000, Roy Luo wrote:
> >> Document the device tree bindings for the USB PHY interfaces integrated
> >> with the DWC3 controller on Google Tensor SoCs, starting with G5
> >> generation. The USB PHY on Tensor G5 includes two integrated Synopsys
> >> PHY IPs: the eUSB 2.0 PHY IP and the USB 3.2/DisplayPort combo PHY IP.
> >>
> >> Due to a complete architectural overhaul in the Google Tensor G5, the
> >> existing Samsung/Exynos USB PHY binding for older generations of Google
> >> silicons such as gs101 are no longer compatible, necessitating this new
> >> device tree binding.
> >>
> >> Signed-off-by: Roy Luo <royluo@google.com>
> >> ---
> >>  .../bindings/phy/google,gs5-usb-phy.yaml      | 104 ++++++++++++++++++
> >>  1 file changed, 104 insertions(+)
> >>  create mode 100644 Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> >> new file mode 100644
> >> index 000000000000..c92c20eba1ea
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> >> @@ -0,0 +1,104 @@
> >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >> +# Copyright (C) 2025, Google LLC
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/phy/google,gs5-usb-phy.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Google Tensor Series (G5+) USB PHY
> >> +
> >> +maintainers:
> >> +  - Roy Luo <royluo@google.com>
> >> +
> >> +description: |
> >> +  Describes the USB PHY interfaces integrated with the DWC3 USB controller on
> >> +  Google Tensor SoCs, starting with the G5 generation.
> >> +  Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP
> >> +  and USB 3.2/DisplayPort combo PHY IP.
> >> +  The hardware can support three PHY interfaces, which are selected using the
> >> +  first phandle argument in the PHY specifier::
> >
> > Just one ':', anyway this sentence and below does not belong to
> > description but to phy-cells. You describe the cells.
> >
> > Or just mention the header with IDs - here or in phy-cells.
>
>
> If you go with free-form text description in phy cells, then some
> example could be:
> renesas,rcar-gen2-usb-phy.yaml
>
> For the header (in this case clocks):
> display/msm/dsi-phy-common.yaml
>
>
> Best regards,
> Krzysztof

Krzysztof,

Thanks a lot for providing the reference!
I will go with the free-form text description in phy cells following
renesas,rcar-gen2-usb-phy.yaml in the next version.

Thanks,
Roy Luo

-- 
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 v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  2025-10-23  6:43   ` Krzysztof Kozlowski
  2025-10-23  6:57     ` Krzysztof Kozlowski
@ 2025-10-23 22:22     ` Roy Luo
  2025-10-27 14:02       ` Krzysztof Kozlowski
  1 sibling, 1 reply; 12+ messages in thread
From: Roy Luo @ 2025-10-23 22:22 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On Wed, Oct 22, 2025 at 11:43 PM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Fri, Oct 17, 2025 at 11:51:58PM +0000, Roy Luo wrote:
> > Document the device tree bindings for the USB PHY interfaces integrated
> > with the DWC3 controller on Google Tensor SoCs, starting with G5
> > generation. The USB PHY on Tensor G5 includes two integrated Synopsys
> > PHY IPs: the eUSB 2.0 PHY IP and the USB 3.2/DisplayPort combo PHY IP.
> >
> > Due to a complete architectural overhaul in the Google Tensor G5, the
> > existing Samsung/Exynos USB PHY binding for older generations of Google
> > silicons such as gs101 are no longer compatible, necessitating this new
> > device tree binding.
> >
> > Signed-off-by: Roy Luo <royluo@google.com>
> > ---
> >  .../bindings/phy/google,gs5-usb-phy.yaml      | 104 ++++++++++++++++++
> >  1 file changed, 104 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> > new file mode 100644
> > index 000000000000..c92c20eba1ea
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/phy/google,gs5-usb-phy.yaml
> > @@ -0,0 +1,104 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +# Copyright (C) 2025, Google LLC
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/phy/google,gs5-usb-phy.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Google Tensor Series (G5+) USB PHY
> > +
> > +maintainers:
> > +  - Roy Luo <royluo@google.com>
> > +
> > +description: |
> > +  Describes the USB PHY interfaces integrated with the DWC3 USB controller on
> > +  Google Tensor SoCs, starting with the G5 generation.
> > +  Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP
> > +  and USB 3.2/DisplayPort combo PHY IP.
> > +  The hardware can support three PHY interfaces, which are selected using the
> > +  first phandle argument in the PHY specifier::
>
> Just one ':', anyway this sentence and below does not belong to
> description but to phy-cells. You describe the cells.
>
> Or just mention the header with IDs - here or in phy-cells.
>
> > +    0 - USB high-speed.
> > +    1 - USB super-speed.
> > +    2 - DisplayPort
> > +
> > +properties:
> > +  compatible:
> > +    const: google,gs5-usb-phy
> > +
> > +  reg:
> > +    items:
> > +      - description: USB2 PHY configuration registers.
> > +      - description: USB 3.2/DisplayPort combo PHY top-level registers.
> > +
> > +  reg-names:
> > +    items:
> > +      - const: u2phy_cfg
> > +      - const: dp_top
> > +
> > +  "#phy-cells":
> > +    const: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: USB2 PHY clock.
> > +      - description: USB2 PHY APB clock.
> > +
> > +  clock-names:
> > +    items:
> > +      - const: usb2_phy
>
> core
>
> > +      - const: u2phy_apb
>
> apb
>

Just to provide the full context, these two clocks/resets
(usb2_phy and u2phy_apb) are specifically for eUSB2 PHY.
USB3/DP combo PHY has its own clock/reset that hasn't
been added yet, we would have to differentiate them once
USB3 support is added in the future.
I'm fine with the suggested name change, and we can
address the naming again when USB3 is ready for
integration.

Regards,
Roy Luo

> > +
> > +  resets:
> > +    items:
> > +      - description: USB2 PHY reset.
> > +      - description: USB2 PHY APB reset.
> > +
> > +  reset-names:
> > +    items:
> > +      - const: usb2_phy
> > +      - const: u2phy_apb
>
> Same here
>
> > +
> > +  power-domains:
> > +    maxItems: 1
>
> Best regards,
> Krzysztof
>

-- 
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 v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  2025-10-23 22:22     ` Roy Luo
@ 2025-10-27 14:02       ` Krzysztof Kozlowski
  2025-10-27 23:21         ` Roy Luo
  0 siblings, 1 reply; 12+ messages in thread
From: Krzysztof Kozlowski @ 2025-10-27 14:02 UTC (permalink / raw)
  To: Roy Luo
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On 24/10/2025 00:22, Roy Luo wrote:
>>> +
>>> +  clocks:
>>> +    items:
>>> +      - description: USB2 PHY clock.
>>> +      - description: USB2 PHY APB clock.
>>> +
>>> +  clock-names:
>>> +    items:
>>> +      - const: usb2_phy
>>
>> core
>>
>>> +      - const: u2phy_apb
>>
>> apb
>>
> 
> Just to provide the full context, these two clocks/resets
> (usb2_phy and u2phy_apb) are specifically for eUSB2 PHY.
> USB3/DP combo PHY has its own clock/reset that hasn't
> been added yet, we would have to differentiate them once

That's confusing a bit. You must add all clocks, all resets, all power
domains, all pins etc. Bindings are supposed to be complete, see writing
bindings doc.


Best regards,
Krzysztof

-- 
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 v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY
  2025-10-27 14:02       ` Krzysztof Kozlowski
@ 2025-10-27 23:21         ` Roy Luo
  0 siblings, 0 replies; 12+ messages in thread
From: Roy Luo @ 2025-10-27 23:21 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On Mon, Oct 27, 2025 at 7:02 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On 24/10/2025 00:22, Roy Luo wrote:
> >>> +
> >>> +  clocks:
> >>> +    items:
> >>> +      - description: USB2 PHY clock.
> >>> +      - description: USB2 PHY APB clock.
> >>> +
> >>> +  clock-names:
> >>> +    items:
> >>> +      - const: usb2_phy
> >>
> >> core
> >>
> >>> +      - const: u2phy_apb
> >>
> >> apb
> >>
> >
> > Just to provide the full context, these two clocks/resets
> > (usb2_phy and u2phy_apb) are specifically for eUSB2 PHY.
> > USB3/DP combo PHY has its own clock/reset that hasn't
> > been added yet, we would have to differentiate them once
>
> That's confusing a bit. You must add all clocks, all resets, all power
> domains, all pins etc. Bindings are supposed to be complete, see writing
> bindings doc.
>
>
> Best regards,
> Krzysztof

Ok found this in the writing binding doc:
"DO attempt to make bindings complete even if a driver doesn’t
support some features. For example, if a device has an interrupt,
then include the ‘interrupts’ property even if the driver is only
polled mode."

I will add all the clocks and resets inclusive of usb3 in the
next version.

Thanks,
Roy Luo

-- 
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 v4 2/2] phy: Add Google Tensor SoC USB PHY driver
  2025-10-20 19:55     ` Roy Luo
@ 2025-10-29 21:56       ` Roy Luo
  0 siblings, 0 replies; 12+ messages in thread
From: Roy Luo @ 2025-10-29 21:56 UTC (permalink / raw)
  To: Ivaylo Ivanov
  Cc: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel, Peter Griffin,
	André Draszik, Tudor Ambarus, Joy Chakraborty, Naveen Kumar,
	Badhri Jagan Sridharan, linux-phy, devicetree, linux-kernel,
	linux-arm-kernel, linux-samsung-soc

On Mon, Oct 20, 2025 at 12:55 PM Roy Luo <royluo@google.com> wrote:
>
> On Sat, Oct 18, 2025 at 1:13 AM Ivaylo Ivanov
> <ivo.ivanov.ivanov1@gmail.com> wrote:
> >
> > On 10/18/25 02:51, Roy Luo wrote:
> > > Support the USB PHY found on Google Tensor G5. This particular USB PHY
> > > supports both high-speed and super-speed operations, and is integrated
> > > with the SNPS DWC3 controller that's also on the SoC.
> > > This initial patch specifically adds functionality for high-speed.
> > >
> > > Co-developed-by: Joy Chakraborty <joychakr@google.com>
> > > Signed-off-by: Joy Chakraborty <joychakr@google.com>
> > > Co-developed-by: Naveen Kumar <mnkumar@google.com>
> > > Signed-off-by: Naveen Kumar <mnkumar@google.com>
> > > Signed-off-by: Roy Luo <royluo@google.com>
> > > ---
> > >  drivers/phy/Kconfig          |  13 ++
> > >  drivers/phy/Makefile         |   1 +
> > >  drivers/phy/phy-google-usb.c | 271 +++++++++++++++++++++++++++++++++++
> > >  3 files changed, 285 insertions(+)
> > >  create mode 100644 drivers/phy/phy-google-usb.c
> > >
> > > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> > > index 58c911e1b2d2..fe32d1356002 100644
> > > --- a/drivers/phy/Kconfig
> > > +++ b/drivers/phy/Kconfig
> > > @@ -101,6 +101,19 @@ config PHY_NXP_PTN3222
> > >         schemes. It supports all three USB 2.0 data rates: Low Speed, Full
> > >         Speed and High Speed.
> > >
> > > +config PHY_GOOGLE_USB
> > > +     tristate "Google Tensor SoC USB PHY driver"
> > > +     depends on HAS_IOMEM
> > > +     depends on OF
> > > +     depends on TYPEC
> > > +     select GENERIC_PHY
> > > +     help
> > > +       Enable support for the USB PHY on Google Tensor SoCs, starting with
> > > +       the G5 generation. This driver provides the PHY interfaces to
> > > +       interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY, both
> > > +       of which are integrated with the DWC3 USB controller.
> >
> > So it's more like a DRD controller, since it encapsulates multiple phys?
>
> Yes, it's a DRD controller, I will make it clear in the next version.
>
> >
> > > +       This driver currently supports USB high-speed.
> > > +
> > >  source "drivers/phy/allwinner/Kconfig"
> > >  source "drivers/phy/amlogic/Kconfig"
> > >  source "drivers/phy/broadcom/Kconfig"
> > > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> > > index c670a8dac468..1d7a1331bd19 100644
> > ...
> > > +#include <linux/module.h>
> > > +#include <linux/of.h>
> > > +#include <linux/phy/phy.h>
> > > +#include <linux/platform_device.h>
> > > +#include <linux/mutex.h>
> > > +#include <linux/cleanup.h>
> > > +#include <linux/usb/typec_mux.h>
> > > +
> > > +#define USBCS_USB2PHY_CFG19_OFFSET 0x0
> > > +#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
> >
> > I'd suggest implementing the eUSB support in the existing snps-eusb2
> > driver for the sake of clarity. That way, you can pass it as a phandle
> > to this driver and probe it when drd is probing.
>
> If I understand it correctly, you're referring to the pattern used in
> Documentation/devicetree/bindings/phy/samsung,exynos2200-eusb2-phy.yaml and
> Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml.
> Please correct me if I'm wrong.
>
> At first glance, this approach seems feasible. Custom logic, such
> as vbus valid handling, would need to stay within this driver. Most
> of the eUSB block configuration in google_usb2_phy_init() could
> be moved to the snps-eusb2 driver by adding one more compatible
> for Google's version of the SNSP eUSB IP. However, I'd argue
> 1. This approach would introduce an extra layer of PHY interface,
>     which adds unnecessary complexity.
> 2. Not much of the code is reused in snps-eusb2 driver: the register
>     definition and programming sequence are specific to Google,
>     hence the logic in google_usb2_phy_init() would have to be
>     moved to snps-eusb2 driver almost word-by-word.
>
> I understand this approach was suggested for the sake of clarity,
> but I'm not sure whether that makes for the best trade-off. Since
> there is a precedent for this approach, I do not have a strong
> objection. It would be helpful if the maintainers could also provide
> their input on this specific point.

Hi Ivaylo,

I'm still hesitant to make the changes you suggested without
maintainer input as it involves significant changes in the driver
architecture. I've Incorporated enough changes for review in
the other patch in this series, hence I've sent out a new version
v5 [1] to keep the review process going. Hope I can get some
feedback from phy maintainers there.

Thanks,
Roy Luo

[1]  https://lore.kernel.org/linux-phy/20251029214032.3175261-1-royluo@google.com

>
> >
> > > +
> > > +#define USBCS_USB2PHY_CFG21_OFFSET 0x8
> > > +#define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12)
> > > +#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
> > > +#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
> > > +
> > > +#define USBCS_PHY_CFG1_OFFSET 0x28
> > > +#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
> > > +
> > > +enum google_usb_phy_id {
> > > +     GOOGLE_USB2_PHY,
> > > +     GOOGLE_USB_PHY_NUM,
> > > +};
> > > +
> > > +struct google_usb_phy_instance {
> > > +     int index;
> > > +     struct phy *phy;
> > > +     int num_clks;
> > > +     struct clk_bulk_data *clks;
> > > +     struct reset_control *rsts;
> > > +};
> > > +
> > > +struct google_usb_phy {
> > > +     struct device *dev;
> > > +     void __iomem *u2phy_cfg_base;
> > > +     void __iomem *dp_top_base;
> > > +     struct google_usb_phy_instance insts[GOOGLE_USB_PHY_NUM];
> > > +     /* serialize phy access */
> > > +     struct mutex phy_mutex;
> > > +     struct typec_switch_dev *sw;
> > > +     enum typec_orientation orientation;
> > > +};
> > > +
> > > +static inline struct google_usb_phy *to_google_usb_phy(struct google_usb_phy_instance *inst)
> > > +{
> > > +     return container_of(inst, struct google_usb_phy, insts[inst->index]);
> > > +}
> > > +
> > > +static void set_vbus_valid(struct google_usb_phy *gphy)
> > > +{
> > > +     u32 reg;
> > > +
> > > +     if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
> > > +             reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > > +             reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
> > > +             writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > > +     } else {
> > > +             reg = readl(gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > > +             reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
> > > +             writel(reg, gphy->dp_top_base + USBCS_PHY_CFG1_OFFSET);
> > > +     }
> > > +}
> > > +
> > > +static int google_usb_set_orientation(struct typec_switch_dev *sw,
> > > +                                   enum typec_orientation orientation)
> > > +{
> > > +     struct google_usb_phy *gphy = typec_switch_get_drvdata(sw);
> > > +
> > > +     dev_dbg(gphy->dev, "set orientation %d\n", orientation);
> > > +
> > > +     gphy->orientation = orientation;
> > > +
> > > +     if (pm_runtime_suspended(gphy->dev))
> > > +             return 0;
> > > +
> > > +     guard(mutex)(&gphy->phy_mutex);
> > > +
> > > +     set_vbus_valid(gphy);
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static int google_usb2_phy_init(struct phy *_phy)
> > > +{
> > > +     struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
> > > +     struct google_usb_phy *gphy = to_google_usb_phy(inst);
> > > +     u32 reg;
> > > +     int ret = 0;
> > > +
> > > +     dev_dbg(gphy->dev, "initializing usb2 phy\n");
> > > +
> > > +     guard(mutex)(&gphy->phy_mutex);
> > > +
> > > +     reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > > +     reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL;
> > > +     reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL;
> > > +     reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0);
> > > +     writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > > +
> > > +     reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
> > > +     reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV;
> > > +     reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368);
> >
> > Yeah, it's definitely the eUSB IP, but wired differently.
> >
> > phy-snps-eusb2.c:
> > #define EXYNOS_USB_PHY_CFG_PLLCFG0 (0x8)
> > #define PHY_CFG_PLL_FB_DIV_19_8_MASK GENMASK(19, 8)
> > #define DIV_19_8_19_2_MHZ_VAL (0x170)
> >
> > > +     writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG19_OFFSET);
> > > +
> > > +     set_vbus_valid(gphy);
> > > +
> > > +     ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
> > > +     if (ret)
> > > +             return ret;
> > > +
> > > +     ret = reset_control_deassert(inst->rsts);
> > > +     if (ret) {
> > > +             clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
> > > +             return ret;
> > > +     }
> > > +
> > > +     reg = readl(gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > > +     reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE;
> > > +     writel(reg, gphy->u2phy_cfg_base + USBCS_USB2PHY_CFG21_OFFSET);
> > > +
> > > +     return ret;
> > > +}
> > > +
> > ...
> > > +
> > > +     gphy->sw = typec_switch_register(dev, &sw_desc);
> > > +     if (IS_ERR(gphy->sw))
> > > +             return dev_err_probe(dev, PTR_ERR(gphy->sw),
> > > +                                  "failed to register typec switch\n");
> > > +
> > > +     return 0;
> > > +}
> > > +
> > > +static void google_usb_phy_remove(struct platform_device *pdev)
> > > +{
> > > +     struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev);
> > > +
> > > +     typec_switch_unregister(gphy->sw);
> > > +     pm_runtime_disable(&pdev->dev);
> > > +}
> > > +
> > > +static const struct of_device_id google_usb_phy_of_match[] = {
> > > +     {
> > > +             .compatible = "google,gs5-usb-phy",
> >
> > Did the naming scheme also change from gs{N}01 to gsN?
>
> Starting from Tensor G5, there's no model number [1], hence
> the change. The prefix "gs" is kept as their family name.
>
> [1] https://en.wikipedia.org/wiki/Google_Tensor
>
> >
> > > +     },
> > > +     { }
> > > +};
> > > +MODULE_DEVICE_TABLE(of, google_usb_phy_of_match);
> > > +
> > > +static struct platform_driver google_usb_phy = {
> > > +     .probe  = google_usb_phy_probe,
> > > +     .remove = google_usb_phy_remove,
> > > +     .driver = {
> > > +             .name           = "google-usb-phy",
> > > +             .of_match_table = google_usb_phy_of_match,
> > > +     }
> > > +};
> > > +
> > > +module_platform_driver(google_usb_phy);
> > > +MODULE_LICENSE("GPL");
> > > +MODULE_DESCRIPTION("Google USB phy driver");
> >
> > Great work!
> >
> > Best regards,
> > Ivaylo
>
> Thank you for the review!
>
> Regards,
> Roy Luo

-- 
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

end of thread, other threads:[~2025-10-29 21:56 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-17 23:51 [PATCH v4 0/2] Add Google Tensor SoC USB PHY support Roy Luo
2025-10-17 23:51 ` [PATCH v4 1/2] dt-bindings: phy: google: Add Google Tensor G5 USB PHY Roy Luo
2025-10-23  6:43   ` Krzysztof Kozlowski
2025-10-23  6:57     ` Krzysztof Kozlowski
2025-10-23 21:54       ` Roy Luo
2025-10-23 22:22     ` Roy Luo
2025-10-27 14:02       ` Krzysztof Kozlowski
2025-10-27 23:21         ` Roy Luo
2025-10-17 23:51 ` [PATCH v4 2/2] phy: Add Google Tensor SoC USB PHY driver Roy Luo
2025-10-18  8:13   ` Ivaylo Ivanov
2025-10-20 19:55     ` Roy Luo
2025-10-29 21:56       ` Roy Luo

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).