[PATCH v2 2/2] phy: spacemit: Add USB3/PCIe comb PHY driver for Spacemit K3

sashiko-bot at kernel.org sashiko-bot at kernel.org
Thu Jul 2 19:19:28 PDT 2026


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

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

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

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

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

[ ... ]

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

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

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

[ ... ]

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

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

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

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

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



More information about the linux-phy mailing list