From 75fb1a33f9ac4c9730e61bb19aaaab02023a99b2 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 23 Feb 2026 12:12:39 +0530 Subject: [PATCH 01/15] phy: move spacemit pcie driver to its subfolder Commit fe4bc1a08638 ("phy: spacemit: support K1 USB2.0 PHY controller") created spacemit subfolder with usb driver while commit 57e920b92724 ("phy: spacemit: Introduce PCIe/combo PHY") added pcie driver in phy folder. Move latter into spacemit subfolder and rename file to phy-k1-pcie.c Reviewed-by: Alex Elder Reviewed-by: Yixun Lan Link: https://patch.msgid.link/20260223064240.386617-1-vkoul@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/Kconfig | 12 ------------ drivers/phy/Makefile | 1 - drivers/phy/spacemit/Kconfig | 12 ++++++++++++ drivers/phy/spacemit/Makefile | 1 + .../phy-k1-pcie.c} | 0 5 files changed, 13 insertions(+), 13 deletions(-) rename drivers/phy/{phy-spacemit-k1-pcie.c => spacemit/phy-k1-pcie.c} (100%) diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 02467dfd4fb0..c0574e44f0a3 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -134,18 +134,6 @@ config PHY_NXP_PTN3222 schemes. It supports all three USB 2.0 data rates: Low Speed, Full Speed and High Speed. -config PHY_SPACEMIT_K1_PCIE - tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC" - depends on ARCH_SPACEMIT || COMPILE_TEST - depends on COMMON_CLK - depends on HAS_IOMEM - depends on OF - select GENERIC_PHY - default ARCH_SPACEMIT - help - Enable support for the PCIe and USB 3 combo PHY and two - PCIe-only PHYs used in the SpacemiT K1 SoC. - source "drivers/phy/allwinner/Kconfig" source "drivers/phy/amlogic/Kconfig" source "drivers/phy/apple/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index a648c2e02a83..2773d596e543 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -16,7 +16,6 @@ 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_SPACEMIT_K1_PCIE) += phy-spacemit-k1-pcie.o obj-$(CONFIG_GENERIC_PHY) += allwinner/ \ amlogic/ \ apple/ \ diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig index 0136aee2e8a2..50b0005acf66 100644 --- a/drivers/phy/spacemit/Kconfig +++ b/drivers/phy/spacemit/Kconfig @@ -2,6 +2,18 @@ # # Phy drivers for SpacemiT platforms # +config PHY_SPACEMIT_K1_PCIE + tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC" + depends on ARCH_SPACEMIT || COMPILE_TEST + depends on COMMON_CLK + depends on HAS_IOMEM + depends on OF + select GENERIC_PHY + default ARCH_SPACEMIT + help + Enable support for the PCIe and USB 3 combo PHY and two + PCIe-only PHYs used in the SpacemiT K1 SoC. + config PHY_SPACEMIT_K1_USB2 tristate "SpacemiT K1 USB 2.0 PHY support" depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile index fec0b425a948..a821a21d6142 100644 --- a/drivers/phy/spacemit/Makefile +++ b/drivers/phy/spacemit/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-k1-pcie.o obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o diff --git a/drivers/phy/phy-spacemit-k1-pcie.c b/drivers/phy/spacemit/phy-k1-pcie.c similarity index 100% rename from drivers/phy/phy-spacemit-k1-pcie.c rename to drivers/phy/spacemit/phy-k1-pcie.c From d8f0ef2aebaa90c0155e266c1fdd6fa2aef44bb1 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 23 Feb 2026 12:27:43 +0530 Subject: [PATCH 02/15] phy: Sort the subsystem Makefile Makefile is supposed to be sorted alphabetically, sadly it has bitrotted so fix that Link: https://patch.msgid.link/20260223065743.395539-1-vkoul@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 2773d596e543..90cad2b72cfa 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -7,15 +7,16 @@ obj-$(CONFIG_PHY_COMMON_PROPS) += phy-common-props.o obj-$(CONFIG_PHY_COMMON_PROPS_TEST) += phy-common-props-test.o obj-$(CONFIG_GENERIC_PHY) += phy-core.o obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o +obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o obj-$(CONFIG_PHY_CAN_TRANSCEIVER) += phy-can-transceiver.o obj-$(CONFIG_PHY_GOOGLE_USB) += phy-google-usb.o +obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o -obj-$(CONFIG_PHY_XGENE) += phy-xgene.o +obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o 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_XGENE) += phy-xgene.o + obj-$(CONFIG_GENERIC_PHY) += allwinner/ \ amlogic/ \ apple/ \ From dee40773abe543723adab47319bc25dc70de10a2 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 23 Feb 2026 12:28:19 +0530 Subject: [PATCH 03/15] phy: Sort the subsystem Kconfig Kconfig is supposed to be sorted alphabetically, sadly it has bitrotted so fix that Link: https://patch.msgid.link/20260223065819.395612-1-vkoul@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/Kconfig | 88 ++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index c0574e44f0a3..a00266c8256b 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -47,6 +47,26 @@ config GENERIC_PHY_MIPI_DPHY Provides a number of helpers a core functions for MIPI D-PHY drivers to us. +config PHY_AIROHA_PCIE + tristate "Airoha PCIe-PHY Driver" + depends on ARCH_AIROHA || COMPILE_TEST + depends on OF + select GENERIC_PHY + help + Say Y here to add support for Airoha PCIe PHY driver. + This driver create the basic PHY instance and provides initialize + callback for PCIe GEN3 port. + +config PHY_CAN_TRANSCEIVER + tristate "CAN transceiver PHY" + select GENERIC_PHY + select MULTIPLEXER + help + This option enables support for CAN transceivers as a PHY. This + driver provides function for putting the transceivers in various + functional modes using gpios and sets the attribute max link + rate, for CAN drivers. + config PHY_GOOGLE_USB tristate "Google Tensor SoC USB PHY driver" select GENERIC_PHY @@ -58,6 +78,18 @@ config PHY_GOOGLE_USB both of which are integrated with the DWC3 USB DRD controller. This driver currently supports USB high-speed. +config USB_LGM_PHY + tristate "INTEL Lightning Mountain USB PHY Driver" + depends on USB_SUPPORT + depends on X86 || COMPILE_TEST + select USB_PHY + select REGULATOR + select REGULATOR_FIXED_VOLTAGE + help + Enable this to support Intel DWC3 PHY USB phy. This driver provides + interface to interact with USB GEN-II and USB 3.x PHY that is part + of the Intel network SOC. + config PHY_LPC18XX_USB_OTG tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver" depends on OF && (ARCH_LPC18XX || COMPILE_TEST) @@ -69,6 +101,17 @@ config PHY_LPC18XX_USB_OTG This driver is need for USB0 support on LPC18xx/43xx and takes care of enabling and clock setup. +config PHY_NXP_PTN3222 + tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver" + depends on I2C + depends on OF + select GENERIC_PHY + help + Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver. + This redriver performs translation between eUSB2 and USB2 signalling + schemes. It supports all three USB 2.0 data rates: Low Speed, Full + Speed and High Speed. + config PHY_PISTACHIO_USB tristate "IMG Pistachio USB2.0 PHY driver" depends on MIPS || COMPILE_TEST @@ -91,49 +134,6 @@ config PHY_XGENE help This option enables support for APM X-Gene SoC multi-purpose PHY. -config USB_LGM_PHY - tristate "INTEL Lightning Mountain USB PHY Driver" - depends on USB_SUPPORT - depends on X86 || COMPILE_TEST - select USB_PHY - select REGULATOR - select REGULATOR_FIXED_VOLTAGE - help - Enable this to support Intel DWC3 PHY USB phy. This driver provides - interface to interact with USB GEN-II and USB 3.x PHY that is part - of the Intel network SOC. - -config PHY_CAN_TRANSCEIVER - tristate "CAN transceiver PHY" - select GENERIC_PHY - select MULTIPLEXER - help - This option enables support for CAN transceivers as a PHY. This - driver provides function for putting the transceivers in various - functional modes using gpios and sets the attribute max link - rate, for CAN drivers. - -config PHY_AIROHA_PCIE - tristate "Airoha PCIe-PHY Driver" - depends on ARCH_AIROHA || COMPILE_TEST - depends on OF - select GENERIC_PHY - help - Say Y here to add support for Airoha PCIe PHY driver. - This driver create the basic PHY instance and provides initialize - callback for PCIe GEN3 port. - -config PHY_NXP_PTN3222 - tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver" - depends on I2C - depends on OF - select GENERIC_PHY - help - Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver. - This redriver performs translation between eUSB2 and USB2 signalling - schemes. It supports all three USB 2.0 data rates: Low Speed, Full - Speed and High Speed. - source "drivers/phy/allwinner/Kconfig" source "drivers/phy/amlogic/Kconfig" source "drivers/phy/apple/Kconfig" @@ -142,6 +142,7 @@ source "drivers/phy/cadence/Kconfig" source "drivers/phy/freescale/Kconfig" source "drivers/phy/hisilicon/Kconfig" source "drivers/phy/ingenic/Kconfig" +source "drivers/phy/intel/Kconfig" source "drivers/phy/lantiq/Kconfig" source "drivers/phy/marvell/Kconfig" source "drivers/phy/mediatek/Kconfig" @@ -163,7 +164,6 @@ source "drivers/phy/starfive/Kconfig" source "drivers/phy/sunplus/Kconfig" source "drivers/phy/tegra/Kconfig" source "drivers/phy/ti/Kconfig" -source "drivers/phy/intel/Kconfig" source "drivers/phy/xilinx/Kconfig" endmenu From 8d869bc943cfe5db08f5aff355b1d8d3abeda865 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 23 Feb 2026 12:40:32 +0530 Subject: [PATCH 04/15] phy: phy-mtk-tphy: Update names and format of kernel-doc comments mtk_phy_pdata documentation does not use correct tag for struct, while at it fix one of member wrongly documented. Warning: drivers/phy/mediatek/phy-mtk-tphy.c:289 cannot understand function prototype: 'struct mtk_phy_pdata' Warning: drivers/phy/mediatek/phy-mtk-tphy.c:296 struct member 'slew_ref_clock_mhz' not described in 'mtk_phy_pdata' Link: https://patch.msgid.link/20260223071032.408425-1-vkoul@kernel.org Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-tphy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index f6504e0ecd1a..acf506529507 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -276,14 +276,14 @@ enum mtk_phy_version { }; /** - * mtk_phy_pdata - SoC specific platform data + * struct mtk_phy_pdata - SoC specific platform data * @avoid_rx_sen_degradation: Avoid TX Sensitivity level degradation (MT6795/8173 only) * @sw_pll_48m_to_26m: Workaround for V3 IP (MT8195) - switch the 48MHz PLL from * fractional mode to integer to output 26MHz for U2PHY * @sw_efuse_supported: Switches off eFuse auto-load from PHY and applies values * read from different nvmem (usually different eFuse array) * that is pointed at in the device tree node for this PHY - * @slew_ref_clk_mhz: Default reference clock (in MHz) for slew rate calibration + * @slew_ref_clock_mhz: Default reference clock (in MHz) for slew rate calibration * @slew_rate_coefficient: Coefficient for slew rate calibration * @version: PHY IP Version */ From 50357e7d7992ba8f02c87ff7a5c4db17918635da Mon Sep 17 00:00:00 2001 From: Jiayu Du Date: Wed, 21 Jan 2026 22:55:22 +0800 Subject: [PATCH 05/15] dt-bindings: phy: Add Canaan K230 USB PHY K230 SoC USB PHY requires configuring registers for control and configuration. Add USB phy bindings for K230 SoC. Reviewed-by: Rob Herring (Arm) Signed-off-by: Jiayu Du Link: https://patch.msgid.link/20260121145526.14672-2-jiayu.riscv@isrc.iscas.ac.cn Signed-off-by: Vinod Koul --- .../bindings/phy/canaan,k230-usb-phy.yaml | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/canaan,k230-usb-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/canaan,k230-usb-phy.yaml b/Documentation/devicetree/bindings/phy/canaan,k230-usb-phy.yaml new file mode 100644 index 000000000000..b959b381c44c --- /dev/null +++ b/Documentation/devicetree/bindings/phy/canaan,k230-usb-phy.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/canaan,k230-usb-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Canaan K230 USB2.0 PHY + +maintainers: + - Jiayu Du + +properties: + compatible: + const: canaan,k230-usb-phy + + reg: + maxItems: 1 + + "#phy-cells": + const: 1 + +required: + - compatible + - reg + - "#phy-cells" + +additionalProperties: false + +examples: + - | + usbphy: usb-phy@91585000 { + compatible = "canaan,k230-usb-phy"; + reg = <0x91585000 0x400>; + #phy-cells = <1>; + }; From 8787fa1da603e9e51efff11841e97b5d374aef34 Mon Sep 17 00:00:00 2001 From: Jiayu Du Date: Wed, 21 Jan 2026 22:55:24 +0800 Subject: [PATCH 06/15] phy: usb: Add driver for Canaan K230 USB 2.0 PHY Add driver for the USB 2.0 PHY in Canaan K230 SoC, which supports PHY initialization and power management. Add Kconfig/Makefile under drivers/phy/canaan/. Signed-off-by: Jiayu Du Link: https://patch.msgid.link/20260121145526.14672-4-jiayu.riscv@isrc.iscas.ac.cn Signed-off-by: Vinod Koul --- drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/canaan/Kconfig | 14 ++ drivers/phy/canaan/Makefile | 2 + drivers/phy/canaan/phy-k230-usb.c | 284 ++++++++++++++++++++++++++++++ 5 files changed, 302 insertions(+) create mode 100644 drivers/phy/canaan/Kconfig create mode 100644 drivers/phy/canaan/Makefile create mode 100644 drivers/phy/canaan/phy-k230-usb.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index a00266c8256b..e4b7a9b535f4 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -139,6 +139,7 @@ source "drivers/phy/amlogic/Kconfig" source "drivers/phy/apple/Kconfig" source "drivers/phy/broadcom/Kconfig" source "drivers/phy/cadence/Kconfig" +source "drivers/phy/canaan/Kconfig" source "drivers/phy/freescale/Kconfig" source "drivers/phy/hisilicon/Kconfig" source "drivers/phy/ingenic/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 90cad2b72cfa..d08e705175a1 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_GENERIC_PHY) += allwinner/ \ apple/ \ broadcom/ \ cadence/ \ + canaan/ \ freescale/ \ hisilicon/ \ ingenic/ \ diff --git a/drivers/phy/canaan/Kconfig b/drivers/phy/canaan/Kconfig new file mode 100644 index 000000000000..1ff8831846d5 --- /dev/null +++ b/drivers/phy/canaan/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Phy drivers for Canaan platforms +# +config PHY_CANAAN_USB + tristate "Canaan USB2 PHY Driver" + depends on (ARCH_CANAAN || COMPILE_TEST) && OF + select GENERIC_PHY + help + Enable this driver to support the USB 2.0 PHY controller + on Canaan K230 RISC-V SoCs. This PHY controller + provides physical layer functionality for USB 2.0 devices. + If you have a Canaan K230 board and need USB 2.0 support, + say Y or M here. diff --git a/drivers/phy/canaan/Makefile b/drivers/phy/canaan/Makefile new file mode 100644 index 000000000000..d73857ba284e --- /dev/null +++ b/drivers/phy/canaan/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PHY_CANAAN_USB) += phy-k230-usb.o diff --git a/drivers/phy/canaan/phy-k230-usb.c b/drivers/phy/canaan/phy-k230-usb.c new file mode 100644 index 000000000000..52dad35fc6cf --- /dev/null +++ b/drivers/phy/canaan/phy-k230-usb.c @@ -0,0 +1,284 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Canaan usb PHY driver + * + * Copyright (C) 2026 Jiayu Du + */ + +#include +#include +#include +#include +#include + +#define MAX_PHYS 2 + +/* Register offsets within the HiSysConfig system controller */ +#define K230_USB0_TEST_REG_BASE 0x70 +#define K230_USB0_CTL_REG_BASE 0xb0 +#define K230_USB1_TEST_REG_BASE 0x90 +#define K230_USB1_CTL_REG_BASE 0xb8 + +/* Relative offsets within each PHY's control/test block */ +#define CTL0_OFFSET 0x00 +#define CTL1_OFFSET 0x04 +#define TEST_CTL3_OFFSET 0x0c + +/* Bit definitions for TEST_CTL3 */ +#define USB_IDPULLUP0 BIT(4) +#define USB_DMPULLDOWN0 BIT(8) +#define USB_DPPULLDOWN0 BIT(9) + +/* USB control register 0 in HiSysConfig system controller */ +/* PLL Integral Path Tune */ +#define USB_CTL0_PLLITUNE_MASK GENMASK(23, 22) + +/* PLL Proportional Path Tune */ +#define USB_CTL0_PLLPTUNE_MASK GENMASK(21, 18) + +/* PLL Bandwidth Adjustment */ +#define USB_CTL0_PLLBTUNE_MASK GENMASK(17, 17) + +/* VReg18 Bypass Control */ +#define USB_CTL0_VREGBYPASS_MASK GENMASK(16, 16) + +/* Retention Mode Enable */ +#define USB_CTL0_RETENABLEN_MASK GENMASK(15, 15) + +/* Reserved Request Input */ +#define USB_CTL0_RESREQIN_MASK GENMASK(14, 14) + +/* External VBUS Valid Select */ +#define USB_CTL0_VBUSVLDEXTSEL0_MASK GENMASK(13, 13) + +/* OTG Block Disable Control */ +#define USB_CTL0_OTGDISABLE0_MASK GENMASK(12, 12) + +/* Drive VBUS Enable */ +#define USB_CTL0_DRVVBUS0_MASK GENMASK(11, 11) + +/* Autoresume Mode Enable */ +#define USB_CTL0_AUTORSMENB0_MASK GENMASK(10, 10) + +/* HS Transceiver Asynchronous Control */ +#define USB_CTL0_HSXCVREXTCTL0_MASK GENMASK(9, 9) + +/* USB 1.1 Transmit Data */ +#define USB_CTL0_FSDATAEXT0_MASK GENMASK(8, 8) + +/* USB 1.1 SE0 Generation */ +#define USB_CTL0_FSSE0EXT0_MASK GENMASK(7, 7) + +/* USB 1.1 Data Enable */ +#define USB_CTL0_TXENABLEN0_MASK GENMASK(6, 6) + +/* Disconnect Threshold */ +#define USB_CTL0_COMPDISTUNE0_MASK GENMASK(5, 3) + +/* Squelch Threshold */ +#define USB_CTL0_SQRXTUNE0_MASK GENMASK(2, 0) + +/* USB control register 1 in HiSysConfig system controller */ +/* Data Detect Voltage */ +#define USB_CTL1_VDATREFTUNE0_MASK GENMASK(23, 22) + +/* VBUS Valid Threshold */ +#define USB_CTL1_OTGTUNE0_MASK GENMASK(21, 19) + +/* Transmitter High-Speed Crossover */ +#define USB_CTL1_TXHSXVTUNE0_MASK GENMASK(18, 17) + +/* FS/LS Source Impedance */ +#define USB_CTL1_TXFSLSTUNE0_MASK GENMASK(16, 13) + +/* HS DC Voltage Level */ +#define USB_CTL1_TXVREFTUNE0_MASK GENMASK(12, 9) + +/* HS Transmitter Rise/Fall Time */ +#define USB_CTL1_TXRISETUNE0_MASK GENMASK(8, 7) + +/* USB Source Impedance */ +#define USB_CTL1_TXRESTUNE0_MASK GENMASK(6, 5) + +/* HS Transmitter Pre-Emphasis Current Control */ +#define USB_CTL1_TXPREEMPAMPTUNE0_MASK GENMASK(4, 3) + +/* HS Transmitter Pre-Emphasis Duration Control */ +#define USB_CTL1_TXPREEMPPULSETUNE0_MASK GENMASK(2, 2) + +/* charging detection */ +#define USB_CTL1_CHRGSRCPUENB0_MASK GENMASK(1, 0) + +#define K230_PHY_CTL0_VAL \ +( \ + FIELD_PREP(USB_CTL0_PLLITUNE_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_PLLPTUNE_MASK, 0xc) | \ + FIELD_PREP(USB_CTL0_PLLBTUNE_MASK, 0x1) | \ + FIELD_PREP(USB_CTL0_VREGBYPASS_MASK, 0x1) | \ + FIELD_PREP(USB_CTL0_RETENABLEN_MASK, 0x1) | \ + FIELD_PREP(USB_CTL0_RESREQIN_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_VBUSVLDEXTSEL0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_OTGDISABLE0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_DRVVBUS0_MASK, 0x1) | \ + FIELD_PREP(USB_CTL0_AUTORSMENB0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_HSXCVREXTCTL0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_FSDATAEXT0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_FSSE0EXT0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_TXENABLEN0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL0_COMPDISTUNE0_MASK, 0x3) | \ + FIELD_PREP(USB_CTL0_SQRXTUNE0_MASK, 0x3) \ +) + +#define K230_PHY_CTL1_VAL \ +( \ + FIELD_PREP(USB_CTL1_VDATREFTUNE0_MASK, 0x1) | \ + FIELD_PREP(USB_CTL1_OTGTUNE0_MASK, 0x3) | \ + FIELD_PREP(USB_CTL1_TXHSXVTUNE0_MASK, 0x3) | \ + FIELD_PREP(USB_CTL1_TXFSLSTUNE0_MASK, 0x3) | \ + FIELD_PREP(USB_CTL1_TXVREFTUNE0_MASK, 0x3) | \ + FIELD_PREP(USB_CTL1_TXRISETUNE0_MASK, 0x1) | \ + FIELD_PREP(USB_CTL1_TXRESTUNE0_MASK, 0x1) | \ + FIELD_PREP(USB_CTL1_TXPREEMPAMPTUNE0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL1_TXPREEMPPULSETUNE0_MASK, 0x0) | \ + FIELD_PREP(USB_CTL1_CHRGSRCPUENB0_MASK, 0x0) \ +) + +struct k230_usb_phy_instance { + struct k230_usb_phy_global *global; + struct phy *phy; + u32 test_offset; + u32 ctl_offset; + int index; +}; + +struct k230_usb_phy_global { + struct k230_usb_phy_instance phys[MAX_PHYS]; + void __iomem *base; +}; + +static int k230_usb_phy_power_on(struct phy *phy) +{ + struct k230_usb_phy_instance *inst = phy_get_drvdata(phy); + struct k230_usb_phy_global *global = inst->global; + void __iomem *base = global->base; + u32 val; + + /* Apply recommended settings */ + writel(K230_PHY_CTL0_VAL, base + inst->ctl_offset + CTL0_OFFSET); + writel(K230_PHY_CTL1_VAL, base + inst->ctl_offset + CTL1_OFFSET); + + /* Configure test register (pull-ups/pull-downs) */ + val = readl(base + inst->test_offset + TEST_CTL3_OFFSET); + val |= USB_IDPULLUP0; + + if (inst->index == 1) + val |= (USB_DMPULLDOWN0 | USB_DPPULLDOWN0); + else + val &= ~(USB_DMPULLDOWN0 | USB_DPPULLDOWN0); + + writel(val, base + inst->test_offset + TEST_CTL3_OFFSET); + + return 0; +} + +static int k230_usb_phy_power_off(struct phy *phy) +{ + struct k230_usb_phy_instance *inst = phy_get_drvdata(phy); + struct k230_usb_phy_global *global = inst->global; + void __iomem *base = global->base; + u32 val; + + val = readl(base + inst->test_offset + TEST_CTL3_OFFSET); + val &= ~(USB_DMPULLDOWN0 | USB_DPPULLDOWN0); + writel(val, base + inst->test_offset + TEST_CTL3_OFFSET); + + return 0; +} + +static const struct phy_ops k230_usb_phy_ops = { + .power_on = k230_usb_phy_power_on, + .power_off = k230_usb_phy_power_off, + .owner = THIS_MODULE, +}; + +static struct phy *k230_usb_phy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct k230_usb_phy_global *global = dev_get_drvdata(dev); + unsigned int idx = args->args[0]; + + if (idx >= MAX_PHYS) + return ERR_PTR(-EINVAL); + + return global->phys[idx].phy; +} + +static int k230_usb_phy_probe(struct platform_device *pdev) +{ + struct k230_usb_phy_global *global; + struct device *dev = &pdev->dev; + struct phy_provider *provider; + int i; + + global = devm_kzalloc(dev, sizeof(*global), GFP_KERNEL); + if (!global) + return -ENOMEM; + dev_set_drvdata(dev, global); + + global->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(global->base)) + return dev_err_probe(dev, PTR_ERR(global->base), + "failed to map registers\n"); + + static const struct { + u32 test_offset; + u32 ctl_offset; + } phy_reg_info[MAX_PHYS] = { + [0] = { K230_USB0_TEST_REG_BASE, K230_USB0_CTL_REG_BASE }, + [1] = { K230_USB1_TEST_REG_BASE, K230_USB1_CTL_REG_BASE }, + }; + + for (i = 0; i < MAX_PHYS; i++) { + struct k230_usb_phy_instance *inst = &global->phys[i]; + struct phy *phy; + + inst->global = global; + inst->index = i; + inst->test_offset = phy_reg_info[i].test_offset; + inst->ctl_offset = phy_reg_info[i].ctl_offset; + + phy = devm_phy_create(dev, NULL, &k230_usb_phy_ops); + if (IS_ERR(phy)) { + dev_err(dev, "failed to create phy%d\n", i); + return PTR_ERR(phy); + } + + phy_set_drvdata(phy, inst); + inst->phy = phy; + } + + provider = devm_of_phy_provider_register(dev, k230_usb_phy_xlate); + if (IS_ERR(provider)) + return PTR_ERR(provider); + + return 0; +} + +static const struct of_device_id k230_usb_phy_of_match[] = { + { .compatible = "canaan,k230-usb-phy" }, + {} +}; +MODULE_DEVICE_TABLE(of, k230_usb_phy_of_match); + +static struct platform_driver k230_usb_phy_driver = { + .probe = k230_usb_phy_probe, + .driver = { + .name = "k230-usb-phy", + .of_match_table = k230_usb_phy_of_match, + }, +}; +module_platform_driver(k230_usb_phy_driver); + +MODULE_DESCRIPTION("Canaan Kendryte K230 USB 2.0 PHY driver"); +MODULE_AUTHOR("Jiayu Du "); +MODULE_LICENSE("GPL"); From 7df891f2c39442c120fb4f9bfdd7c80e6de84015 Mon Sep 17 00:00:00 2001 From: Luca Leonardo Scorcia Date: Mon, 23 Feb 2026 16:22:47 +0000 Subject: [PATCH 07/15] dt-bindings: phy: mediatek,dsi-phy: Add support for mt8167 Add support for the MediaTek mt8167 SoC: the DSI PHY found in this chip is fully compatible with the one found in the mt2701 SoC. Signed-off-by: Luca Leonardo Scorcia Reviewed-by: AngeloGioacchino Del Regno Acked-by: Krzysztof Kozlowski Reviewed-by: CK Hu Link: https://patch.msgid.link/92530e0a31eca1feb822f5c5fd4ac894937dd6c7.1771863641.git.l.scorcia@gmail.com Signed-off-by: Vinod Koul --- Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml index acdbce937b0a..c6d0bbdbe0e2 100644 --- a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml +++ b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml @@ -23,6 +23,7 @@ properties: - items: - enum: - mediatek,mt7623-mipi-tx + - mediatek,mt8167-mipi-tx - const: mediatek,mt2701-mipi-tx - items: - enum: From b3fddddf3fb49c7472e73680d6ea5d771f9514e8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 16 Feb 2026 12:04:14 +0100 Subject: [PATCH 08/15] phy: apple: atc: Make atcphy_dwc3_reset_ops variable static File-scope 'atcphy_dwc3_reset_ops' is not used outside of this unit, so make it static to silence sparse warning: atc.c:2026:32: warning: symbol 'atcphy_dwc3_reset_ops' was not declared. Should it be static? Signed-off-by: Krzysztof Kozlowski Reviewed-by: Janne Grunau Link: https://patch.msgid.link/20260216110413.159994-4-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/apple/atc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c index dc867f368b68..32d97226e926 100644 --- a/drivers/phy/apple/atc.c +++ b/drivers/phy/apple/atc.c @@ -2023,7 +2023,7 @@ static int atcphy_dwc3_reset_deassert(struct reset_controller_dev *rcdev, unsign return 0; } -const struct reset_control_ops atcphy_dwc3_reset_ops = { +static const struct reset_control_ops atcphy_dwc3_reset_ops = { .assert = atcphy_dwc3_reset_assert, .deassert = atcphy_dwc3_reset_deassert, }; From c77eee5b44b8d32d471cf17fa193b395e321ef37 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 16 Feb 2026 12:04:15 +0100 Subject: [PATCH 09/15] phy: marvell: mmp3-hsic: Avoid re-casting __iomem __iomem annotated memory must be accessed via dedicated accessors, even if actual code is correct (accessing the driver data in mmp3_hsic_phy_init() brings back the __iomem cast), but dropping its cast (with or without __force) when storing as driver data seems like less readable code for any future changes. Instead, add a dedicated wrapping structure just to hold the pointer without changing the __iomem cast. This makes the code explicit, obvious and solves the sparse warning: phy-mmp3-hsic.c:58:31: warning: cast removes address space '__iomem' of expression Signed-off-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260216110413.159994-5-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/marvell/phy-mmp3-hsic.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/phy/marvell/phy-mmp3-hsic.c b/drivers/phy/marvell/phy-mmp3-hsic.c index 271f1a2258ef..72ab6da0ebc3 100644 --- a/drivers/phy/marvell/phy-mmp3-hsic.c +++ b/drivers/phy/marvell/phy-mmp3-hsic.c @@ -14,15 +14,19 @@ #define HSIC_ENABLE BIT(7) #define PLL_BYPASS BIT(4) +struct mmp3_hsic_data { + void __iomem *base; +}; + static int mmp3_hsic_phy_init(struct phy *phy) { - void __iomem *base = (void __iomem *)phy_get_drvdata(phy); + struct mmp3_hsic_data *mmp3 = phy_get_drvdata(phy); u32 hsic_ctrl; - hsic_ctrl = readl_relaxed(base + HSIC_CTRL); + hsic_ctrl = readl_relaxed(mmp3->base + HSIC_CTRL); hsic_ctrl |= HSIC_ENABLE; hsic_ctrl |= PLL_BYPASS; - writel_relaxed(hsic_ctrl, base + HSIC_CTRL); + writel_relaxed(hsic_ctrl, mmp3->base + HSIC_CTRL); return 0; } @@ -41,13 +45,17 @@ MODULE_DEVICE_TABLE(of, mmp3_hsic_phy_of_match); static int mmp3_hsic_phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct mmp3_hsic_data *mmp3; struct phy_provider *provider; - void __iomem *base; struct phy *phy; - base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); - if (IS_ERR(base)) - return PTR_ERR(base); + mmp3 = devm_kzalloc(dev, sizeof(*mmp3), GFP_KERNEL); + if (!mmp3) + return -ENOMEM; + + mmp3->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); + if (IS_ERR(mmp3->base)) + return PTR_ERR(mmp3->base); phy = devm_phy_create(dev, NULL, &mmp3_hsic_phy_ops); if (IS_ERR(phy)) { @@ -55,7 +63,7 @@ static int mmp3_hsic_phy_probe(struct platform_device *pdev) return PTR_ERR(phy); } - phy_set_drvdata(phy, (void *)base); + phy_set_drvdata(phy, mmp3); provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); if (IS_ERR(provider)) { dev_err(dev, "failed to register PHY provider\n"); From b6b7d1ae0653dcaa356be31c0de221311e922ccd Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 16 Feb 2026 12:04:16 +0100 Subject: [PATCH 10/15] phy: qcom: qmp-usbc: Simplify check for non-NULL pointer Pointers should not use explicit '0' comparison, so just use standard evaluation as non-NULL: phy-qcom-qmp-usbc.c:1682:31: warning: Using plain integer as NULL pointer Signed-off-by: Krzysztof Kozlowski Reviewed-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio Link: https://patch.msgid.link/20260216110413.159994-6-krzysztof.kozlowski@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-qmp-usbc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index 14feb77789b3..c342479a3798 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -1679,7 +1679,7 @@ static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np if (ret) return ret; - if (qmp->dp_serdes != 0) { + if (qmp->dp_serdes) { ret = phy_dp_clks_register(qmp, np); if (ret) return ret; @@ -1833,7 +1833,7 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) if (IS_ERR(base)) return PTR_ERR(base); - if (offs->dp_serdes != 0) { + if (offs->dp_serdes) { qmp->dp_serdes = base + offs->dp_serdes; qmp->dp_tx = base + offs->dp_txa; qmp->dp_tx2 = base + offs->dp_txb; @@ -1982,7 +1982,7 @@ static int qmp_usbc_probe(struct platform_device *pdev) phy_set_drvdata(qmp->usb_phy, qmp); - if (qmp->dp_serdes != 0) { + if (qmp->dp_serdes) { qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops); if (IS_ERR(qmp->dp_phy)) { ret = PTR_ERR(qmp->dp_phy); From 290a35756aaef85bbe0527eaf451f533a61b5f6c Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 15 Feb 2026 09:02:51 +0100 Subject: [PATCH 11/15] phy: apple: apple: Use local variable for ioremap return value The indirection through the resources array is unnecessarily complicated and resuling in using IS_ERR() and PTR_ERR() on a valid address. A local variable for the devm_ioremap_resource() return value is both easier to read and matches expectations when reading code. Reported-by: Dan Carpenter Closes: https://lore.kernel.org/asahi/aYXvX1bYOXtYCgfC@stanley.mountain/ Suggested-by: Vladimir Oltean Fixes: 8e98ca1e74db ("phy: apple: Add Apple Type-C PHY") Signed-off-by: Janne Grunau Reviewed-by: Sven Peter Reviewed-by: Vladimir Oltean Link: https://patch.msgid.link/20260215-phy-apple-resource-err-ptr-v2-1-e43c22453682@jannau.net Signed-off-by: Vinod Koul --- drivers/phy/apple/atc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c index 32d97226e926..e9d106f135c5 100644 --- a/drivers/phy/apple/atc.c +++ b/drivers/phy/apple/atc.c @@ -2202,14 +2202,16 @@ static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcph { "pipehandler", &atcphy->regs.pipehandler, NULL }, }; struct resource *res; + void __iomem *addr; for (int i = 0; i < ARRAY_SIZE(resources); i++) { res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name); - *resources[i].addr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(resources[i].addr)) - return dev_err_probe(atcphy->dev, PTR_ERR(resources[i].addr), + addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(addr)) + return dev_err_probe(atcphy->dev, PTR_ERR(addr), "Unable to map %s regs", resources[i].name); + *resources[i].addr = addr; if (resources[i].res) *resources[i].res = res; } From 820265f7b666d588bcb7df06f3332265c59e8cea Mon Sep 17 00:00:00 2001 From: Yulin Lu Date: Thu, 5 Feb 2026 16:21:29 +0800 Subject: [PATCH 12/15] dt-bindings: phy: eswin: Document the EIC7700 SoC SATA PHY Document the SATA PHY on the EIC7700 SoC platform, describing its usage. Signed-off-by: Yulin Lu Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20260205082129.1482-1-luyulin@eswincomputing.com Signed-off-by: Vinod Koul --- .../bindings/phy/eswin,eic7700-sata-phy.yaml | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml diff --git a/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml new file mode 100644 index 000000000000..fc7dbac77acf --- /dev/null +++ b/Documentation/devicetree/bindings/phy/eswin,eic7700-sata-phy.yaml @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/eswin,eic7700-sata-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Eswin EIC7700 SoC SATA PHY + +maintainers: + - Yulin Lu + - Huan He + +properties: + compatible: + const: eswin,eic7700-sata-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + const: phy + + resets: + maxItems: 2 + + reset-names: + items: + - const: port + - const: phy + + eswin,tx-amplitude-tuning: + description: This adjusts the transmitter amplitude signal, and its value + is derived from eye diagram tuning. The three values correspond to Gen1, + Gen2, and Gen3 parameters respectively. + $ref: /schemas/types.yaml#/definitions/uint32-array + items: + - description: Gen1 parameter. + minimum: 0 + maximum: 0x7f + - description: Gen2 parameter. + minimum: 0 + maximum: 0x7f + - description: Gen3 parameter. + minimum: 0 + maximum: 0x7f + default: [0, 0, 0] + + eswin,tx-preemph-tuning: + description: This adjusts the transmitter de-emphasis signal, and its value + is derived from eye diagram tuning. The three values correspond to Gen1, + Gen2, and Gen3 parameters respectively. + $ref: /schemas/types.yaml#/definitions/uint32-array + items: + - description: Gen1 parameter. + minimum: 0 + maximum: 0x3f + - description: Gen2 parameter. + minimum: 0 + maximum: 0x3f + - description: Gen3 parameter. + minimum: 0 + maximum: 0x3f + default: [0, 0, 0] + + "#phy-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - "#phy-cells" + +additionalProperties: false + +examples: + - | + sata-phy@50440300 { + compatible = "eswin,eic7700-sata-phy"; + reg = <0x50440300 0x40>; + clocks = <&hspcrg 17>; + clock-names = "phy"; + resets = <&hspcrg 0>, <&hspcrg 1>; + reset-names = "port", "phy"; + #phy-cells = <0>; + }; From 67ee9ccaa34a11c317411bb8e7d305d93d0b4111 Mon Sep 17 00:00:00 2001 From: Yulin Lu Date: Thu, 5 Feb 2026 16:22:19 +0800 Subject: [PATCH 13/15] phy: eswin: Create eswin directory and add EIC7700 SATA PHY driver Create the eswin phy driver directory and add support for the SATA PHY driver on the EIC7700 SoC platform. Signed-off-by: Yulin Lu Link: https://patch.msgid.link/20260205082219.1521-1-luyulin@eswincomputing.com Signed-off-by: Vinod Koul --- drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 1 + drivers/phy/eswin/Kconfig | 14 ++ drivers/phy/eswin/Makefile | 2 + drivers/phy/eswin/phy-eic7700-sata.c | 273 +++++++++++++++++++++++++++ 5 files changed, 291 insertions(+) create mode 100644 drivers/phy/eswin/Kconfig create mode 100644 drivers/phy/eswin/Makefile create mode 100644 drivers/phy/eswin/phy-eic7700-sata.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index e4b7a9b535f4..3970aa1f300f 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -140,6 +140,7 @@ source "drivers/phy/apple/Kconfig" source "drivers/phy/broadcom/Kconfig" source "drivers/phy/cadence/Kconfig" source "drivers/phy/canaan/Kconfig" +source "drivers/phy/eswin/Kconfig" source "drivers/phy/freescale/Kconfig" source "drivers/phy/hisilicon/Kconfig" source "drivers/phy/ingenic/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index d08e705175a1..f49d83f00a3d 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_GENERIC_PHY) += allwinner/ \ broadcom/ \ cadence/ \ canaan/ \ + eswin/ \ freescale/ \ hisilicon/ \ ingenic/ \ diff --git a/drivers/phy/eswin/Kconfig b/drivers/phy/eswin/Kconfig new file mode 100644 index 000000000000..cf2bf2efc32f --- /dev/null +++ b/drivers/phy/eswin/Kconfig @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Phy drivers for ESWIN platforms +# +config PHY_EIC7700_SATA + tristate "eic7700 Sata SerDes/PHY driver" + depends on ARCH_ESWIN || COMPILE_TEST + depends on HAS_IOMEM + select GENERIC_PHY + help + Enable this to support SerDes/Phy found on ESWIN's + EIC7700 SoC. This Phy supports SATA 1.5 Gb/s, + SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. + It supports one SATA host port to accept one SATA device. diff --git a/drivers/phy/eswin/Makefile b/drivers/phy/eswin/Makefile new file mode 100644 index 000000000000..db08c66be812 --- /dev/null +++ b/drivers/phy/eswin/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PHY_EIC7700_SATA) += phy-eic7700-sata.o diff --git a/drivers/phy/eswin/phy-eic7700-sata.c b/drivers/phy/eswin/phy-eic7700-sata.c new file mode 100644 index 000000000000..c33653d48daa --- /dev/null +++ b/drivers/phy/eswin/phy-eic7700-sata.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ESWIN SATA PHY driver + * + * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd.. + * All rights reserved. + * + * Authors: Yulin Lu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SATA_AXI_LP_CTRL 0x08 +#define SATA_MPLL_CTRL 0x20 +#define SATA_P0_PHY_STAT 0x24 +#define SATA_PHY_CTRL0 0x28 +#define SATA_PHY_CTRL1 0x2c +#define SATA_REF_CTRL 0x34 +#define SATA_REF_CTRL1 0x38 +#define SATA_LOS_IDEN 0x3c + +#define SATA_CLK_RST_SOURCE_PHY BIT(0) +#define SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK GENMASK(6, 0) +#define SATA_P0_PHY_TX_AMPLITUDE_GEN1_DEFAULT 0x42 +#define SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK GENMASK(14, 8) +#define SATA_P0_PHY_TX_AMPLITUDE_GEN2_DEFAULT 0x46 +#define SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK GENMASK(22, 16) +#define SATA_P0_PHY_TX_AMPLITUDE_GEN3_DEFAULT 0x73 +#define SATA_P0_PHY_TX_PREEMPH_GEN1_MASK GENMASK(5, 0) +#define SATA_P0_PHY_TX_PREEMPH_GEN1_DEFAULT 0x5 +#define SATA_P0_PHY_TX_PREEMPH_GEN2_MASK GENMASK(13, 8) +#define SATA_P0_PHY_TX_PREEMPH_GEN2_DEFAULT 0x5 +#define SATA_P0_PHY_TX_PREEMPH_GEN3_MASK GENMASK(21, 16) +#define SATA_P0_PHY_TX_PREEMPH_GEN3_DEFAULT 0x23 +#define SATA_LOS_LEVEL_MASK GENMASK(4, 0) +#define SATA_LOS_BIAS_MASK GENMASK(18, 16) +#define SATA_M_CSYSREQ BIT(0) +#define SATA_S_CSYSREQ BIT(16) +#define SATA_REF_REPEATCLK_EN BIT(0) +#define SATA_REF_USE_PAD BIT(20) +#define SATA_MPLL_MULTIPLIER_MASK GENMASK(22, 16) +#define SATA_P0_PHY_READY BIT(0) + +#define PLL_LOCK_SLEEP_US 10 +#define PLL_LOCK_TIMEOUT_US 1000 + +struct eic7700_sata_phy { + u32 tx_amplitude_tuning_val[3]; + u32 tx_preemph_tuning_val[3]; + struct reset_control *rst; + struct regmap *regmap; + struct clk *clk; + struct phy *phy; +}; + +static const struct regmap_config eic7700_sata_phy_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = SATA_LOS_IDEN, +}; + +static int wait_for_phy_ready(struct regmap *regmap, u32 reg, u32 checkbit, + u32 status) +{ + u32 val; + int ret; + + ret = regmap_read_poll_timeout(regmap, reg, val, + (val & checkbit) == status, + PLL_LOCK_SLEEP_US, PLL_LOCK_TIMEOUT_US); + + return ret; +} + +static int eic7700_sata_phy_init(struct phy *phy) +{ + struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy); + u32 val; + int ret; + + ret = clk_prepare_enable(sata_phy->clk); + if (ret) + return ret; + + regmap_write(sata_phy->regmap, SATA_REF_CTRL1, SATA_CLK_RST_SOURCE_PHY); + + val = FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN1_MASK, + sata_phy->tx_amplitude_tuning_val[0]) | + FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN2_MASK, + sata_phy->tx_amplitude_tuning_val[1]) | + FIELD_PREP(SATA_P0_PHY_TX_AMPLITUDE_GEN3_MASK, + sata_phy->tx_amplitude_tuning_val[2]); + regmap_write(sata_phy->regmap, SATA_PHY_CTRL0, val); + + val = FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN1_MASK, + sata_phy->tx_preemph_tuning_val[0]) | + FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN2_MASK, + sata_phy->tx_preemph_tuning_val[1]) | + FIELD_PREP(SATA_P0_PHY_TX_PREEMPH_GEN3_MASK, + sata_phy->tx_preemph_tuning_val[2]); + regmap_write(sata_phy->regmap, SATA_PHY_CTRL1, val); + + val = FIELD_PREP(SATA_LOS_LEVEL_MASK, 0x9) | + FIELD_PREP(SATA_LOS_BIAS_MASK, 0x2); + regmap_write(sata_phy->regmap, SATA_LOS_IDEN, val); + + val = SATA_M_CSYSREQ | SATA_S_CSYSREQ; + regmap_write(sata_phy->regmap, SATA_AXI_LP_CTRL, val); + + val = SATA_REF_REPEATCLK_EN | SATA_REF_USE_PAD; + regmap_write(sata_phy->regmap, SATA_REF_CTRL, val); + + val = FIELD_PREP(SATA_MPLL_MULTIPLIER_MASK, 0x3c); + regmap_write(sata_phy->regmap, SATA_MPLL_CTRL, val); + + usleep_range(15, 20); + + ret = reset_control_deassert(sata_phy->rst); + if (ret) + goto disable_clk; + + ret = wait_for_phy_ready(sata_phy->regmap, SATA_P0_PHY_STAT, + SATA_P0_PHY_READY, 1); + if (ret < 0) { + dev_err(&sata_phy->phy->dev, "PHY READY check failed\n"); + goto disable_clk; + } + + return 0; + +disable_clk: + clk_disable_unprepare(sata_phy->clk); + return ret; +} + +static int eic7700_sata_phy_exit(struct phy *phy) +{ + struct eic7700_sata_phy *sata_phy = phy_get_drvdata(phy); + int ret; + + ret = reset_control_assert(sata_phy->rst); + if (ret) + return ret; + + clk_disable_unprepare(sata_phy->clk); + + return 0; +} + +static const struct phy_ops eic7700_sata_phy_ops = { + .init = eic7700_sata_phy_init, + .exit = eic7700_sata_phy_exit, + .owner = THIS_MODULE, +}; + +static void eic7700_get_tuning_param(struct device_node *np, + struct eic7700_sata_phy *sata_phy) +{ + if (of_property_read_u32_array + (np, "eswin,tx-amplitude-tuning", + sata_phy->tx_amplitude_tuning_val, + ARRAY_SIZE(sata_phy->tx_amplitude_tuning_val))) { + sata_phy->tx_amplitude_tuning_val[0] = + SATA_P0_PHY_TX_AMPLITUDE_GEN1_DEFAULT; + sata_phy->tx_amplitude_tuning_val[1] = + SATA_P0_PHY_TX_AMPLITUDE_GEN2_DEFAULT; + sata_phy->tx_amplitude_tuning_val[2] = + SATA_P0_PHY_TX_AMPLITUDE_GEN3_DEFAULT; + } + + if (of_property_read_u32_array + (np, "eswin,tx-preemph-tuning", + sata_phy->tx_preemph_tuning_val, + ARRAY_SIZE(sata_phy->tx_preemph_tuning_val))) { + sata_phy->tx_preemph_tuning_val[0] = + SATA_P0_PHY_TX_PREEMPH_GEN1_DEFAULT; + sata_phy->tx_preemph_tuning_val[1] = + SATA_P0_PHY_TX_PREEMPH_GEN2_DEFAULT; + sata_phy->tx_preemph_tuning_val[2] = + SATA_P0_PHY_TX_PREEMPH_GEN3_DEFAULT; + } +} + +static int eic7700_sata_phy_probe(struct platform_device *pdev) +{ + struct eic7700_sata_phy *sata_phy; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct resource *res; + void __iomem *regs; + + sata_phy = devm_kzalloc(dev, sizeof(*sata_phy), GFP_KERNEL); + if (!sata_phy) + return -ENOMEM; + + /* + * Map the I/O resource with platform_get_resource and devm_ioremap + * instead of the devm_platform_ioremap_resource API, because the + * address region of the SATA-PHY falls into the region of the HSP + * clock & reset that has already been obtained by the HSP + * clock-and-reset driver. + */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + + regs = devm_ioremap(dev, res->start, resource_size(res)); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + sata_phy->regmap = devm_regmap_init_mmio + (dev, regs, &eic7700_sata_phy_regmap_config); + if (IS_ERR(sata_phy->regmap)) + return dev_err_probe(dev, PTR_ERR(sata_phy->regmap), + "failed to init regmap\n"); + + dev_set_drvdata(dev, sata_phy); + + eic7700_get_tuning_param(np, sata_phy); + + sata_phy->clk = devm_clk_get(dev, "phy"); + if (IS_ERR(sata_phy->clk)) + return PTR_ERR(sata_phy->clk); + + sata_phy->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(sata_phy->rst)) + return dev_err_probe(dev, PTR_ERR(sata_phy->rst), + "failed to get reset control\n"); + + sata_phy->phy = devm_phy_create(dev, NULL, &eic7700_sata_phy_ops); + if (IS_ERR(sata_phy->phy)) + return dev_err_probe(dev, PTR_ERR(sata_phy->phy), + "failed to create PHY\n"); + + phy_set_drvdata(sata_phy->phy, sata_phy); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + if (IS_ERR(phy_provider)) + return dev_err_probe(dev, PTR_ERR(phy_provider), + "failed to register PHY provider\n"); + + return 0; +} + +static const struct of_device_id eic7700_sata_phy_of_match[] = { + { .compatible = "eswin,eic7700-sata-phy" }, + { }, +}; +MODULE_DEVICE_TABLE(of, eic7700_sata_phy_of_match); + +static struct platform_driver eic7700_sata_phy_driver = { + .probe = eic7700_sata_phy_probe, + .driver = { + .of_match_table = eic7700_sata_phy_of_match, + .name = "eic7700-sata-phy", + } +}; +module_platform_driver(eic7700_sata_phy_driver); + +MODULE_DESCRIPTION("SATA PHY driver for the ESWIN EIC7700 SoC"); +MODULE_AUTHOR("Yulin Lu "); +MODULE_LICENSE("GPL"); From 520a98bdf7ae0130e22d8adced3d69a2e211b41f Mon Sep 17 00:00:00 2001 From: Elson Serrao Date: Tue, 17 Feb 2026 12:11:30 -0800 Subject: [PATCH 14/15] phy: qcom: m31-eusb2: clear PLL_EN during init The driver currently sets bit 0 of USB_PHY_CFG1 (PLL_EN) during PHY initialization. According to the M31 EUSB2 PHY hardware documentation, this bit is intended only for test/debug scenarios and does not control mission mode operation. Keeping PLL_EN asserted causes the PHY to draw additional current during USB bus suspend. Clearing this bit results in lower suspend power consumption without affecting normal operation. Update the driver to leave PLL_EN cleared as recommended by the hardware documentation. Fixes: 9c8504861cc4 ("phy: qcom: Add M31 based eUSB2 PHY driver") Cc: stable@vger.kernel.org Signed-off-by: Elson Serrao Reviewed-by: Konrad Dybcio Link: https://patch.msgid.link/20260217201130.2804550-1-elson.serrao@oss.qualcomm.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-m31-eusb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c index 95cd3175926d..68f1ba8fec4a 100644 --- a/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c +++ b/drivers/phy/qualcomm/phy-qcom-m31-eusb2.c @@ -83,7 +83,7 @@ static const struct m31_phy_tbl_entry m31_eusb2_setup_tbl[] = { M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG0, UTMI_PHY_CMN_CTRL_OVERRIDE_EN, 1), M31_EUSB_PHY_INIT_CFG(USB_PHY_UTMI_CTRL5, POR, 1), M31_EUSB_PHY_INIT_CFG(USB_PHY_HS_PHY_CTRL_COMMON0, PHY_ENABLE, 1), - M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG1, PLL_EN, 1), + M31_EUSB_PHY_INIT_CFG(USB_PHY_CFG1, PLL_EN, 0), M31_EUSB_PHY_INIT_CFG(USB_PHY_FSEL_SEL, FSEL_SEL, 1), }; From caf08514bbee0736c31d8d4f406e3415cdf726bb Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Mon, 23 Feb 2026 10:19:38 +0200 Subject: [PATCH 15/15] dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: document the Eliza QMP UFS PHY Document the QMP UFS PHY compatible for the Eliza Platform. It is fully compatible with the PHY implemented in SM8650, so use the SM8650 compatible as fallback. While at it, move the QCS8300 one so that it is sorted correctly by fallback compatible. Reviewed-by: Konrad Dybcio Reviewed-by: Krzysztof Kozlowski Signed-off-by: Abel Vesa Link: https://patch.msgid.link/20260223-eliza-bindings-phy-ufs-v3-1-2b0c0f00bcb6@oss.qualcomm.com Signed-off-by: Vinod Koul --- .../bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml index a1731b08c9d1..9616c736b6d4 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml @@ -16,6 +16,10 @@ description: properties: compatible: oneOf: + - items: + - enum: + - qcom,qcs8300-qmp-ufs-phy + - const: qcom,sa8775p-qmp-ufs-phy - items: - enum: - qcom,qcs615-qmp-ufs-phy @@ -26,8 +30,8 @@ properties: - const: qcom,sm8550-qmp-ufs-phy - items: - enum: - - qcom,qcs8300-qmp-ufs-phy - - const: qcom,sa8775p-qmp-ufs-phy + - qcom,eliza-qmp-ufs-phy + - const: qcom,sm8650-qmp-ufs-phy - items: - enum: - qcom,kaanapali-qmp-ufs-phy