* [PATCH phy-next 1/2] dt-bindings: phy: add PHY bindings for the TI DS125DF111 Retimer PHY
From: Ioana Ciornei @ 2026-05-13 18:51 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, johan, linux-phy
Cc: devicetree, linux-kernel
In-Reply-To: <20260513185103.1371809-1-ioana.ciornei@nxp.com>
Add device tree binding for the TI DS125DF111 Retimer PHY.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
.../bindings/phy/ti,ds125df111.yaml | 46 +++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/ti,ds125df111.yaml
diff --git a/Documentation/devicetree/bindings/phy/ti,ds125df111.yaml b/Documentation/devicetree/bindings/phy/ti,ds125df111.yaml
new file mode 100644
index 000000000000..47e9ba2a8990
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/ti,ds125df111.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/ti,ds125df111.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI DS125DF111 Retimer PHY
+
+description:
+ This binding describes the TI DS125DF111 multi-protocol Retimer PHY.
+
+maintainers:
+ - Ioana Ciornei <ioana.ciornei@nxp.com>
+
+properties:
+ compatible:
+ const: ti,ds125df111
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 1
+ description: |
+ The phandle's argument in the PHY specifier selects one of the two
+ channels of the retimer
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ti_retimer: retimer@18 {
+ compatible = "ti,ds125df111";
+ reg = <0x18>;
+ #phy-cells = <1>;
+ };
+ };
--
2.25.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH phy-next 0/2] phy: ti: add driver for TI DS125DF111 Dual-Channel Retimer
From: Ioana Ciornei @ 2026-05-13 18:51 UTC (permalink / raw)
To: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, johan, linux-phy
Cc: devicetree, linux-kernel
This patch set adds a generic PHY driver and the corresponding DT
binding for the TI DS125DF111 Dual-Channel retimer. The datasheet on
which this driver was based on can be found at -
https://www.ti.com/lit/gpn/DS125DF111.
A separate generic PHY is registered for each of the two channels of the
retimer, so consumers can drive each channel independently. This allows
for independent control of the channels, which is especially important
since each channel can be routed to different SerDes lanes and it is not
guaranteed that the same retimer will do both directions of SerDes lane.
This was tested on a LS1088ARDB board with the Lynx10G SerDes PHY driver
yet to be submitted.
Ioana Ciornei (2):
dt-bindings: phy: add PHY bindings for the TI DS125DF111 Retimer PHY
phy: ti: add PHY driver for TI DS125DF111 Dual-Channel Retimer
.../bindings/phy/ti,ds125df111.yaml | 46 ++++
drivers/phy/ti/Kconfig | 10 +
drivers/phy/ti/Makefile | 1 +
drivers/phy/ti/phy-ds125df111.c | 245 ++++++++++++++++++
4 files changed, 302 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/ti,ds125df111.yaml
create mode 100644 drivers/phy/ti/phy-ds125df111.c
--
2.25.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v9 5/5] phy: qualcomm: add MSM8974 HDMI PHY support
From: Dmitry Baryshkov @ 2026-05-13 18:14 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Vinod Koul, Neil Armstrong
Cc: linux-kernel, linux-arm-msm, dri-devel, freedreno, linux-phy,
Dmitry Baryshkov, Konrad Dybcio
In-Reply-To: <20260513-fd-hdmi-phy-v9-0-ca98c72f1f9f@oss.qualcomm.com>
Add support for HDMI PHY on Qualcomm MSM8974 / APQ8074 platforms.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c | 282 +++++++++++++++++++++++++++++
1 file changed, 282 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c b/drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c
index 720757f8f393..7d398060b3a3 100644
--- a/drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c
+++ b/drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c
@@ -6,10 +6,13 @@
* Author: Rob Clark <robdclark@gmail.com>
*/
+#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/iopoll.h>
+#include <linux/math64.h>
#include "phy-qcom-hdmi-preqmp.h"
+#include "phy-qcom-uniphy.h"
#define REG_HDMI_8x74_ANA_CFG0 0x00000000
#define REG_HDMI_8x74_ANA_CFG1 0x00000004
@@ -31,8 +34,282 @@
#define REG_HDMI_8x74_BIST_PATN3 0x00000048
#define REG_HDMI_8x74_STATUS 0x0000005c
+#define HDMI_8974_VCO_MAX_FREQ 1800000000UL
+#define HDMI_8974_VCO_MIN_FREQ 600000000UL
+
+#define HDMI_8974_COMMON_DIV 5
+
+static inline void write16(u16 val, void __iomem *reg)
+{
+ writel(val & 0xff, reg);
+ writel(val >> 8, reg + 4);
+}
+
+static inline void write24(u32 val, void __iomem *reg)
+{
+ writel(val & 0xff, reg);
+ writel((val >> 8) & 0xff, reg + 4);
+ writel(val >> 16, reg + 8);
+}
+
+static inline u32 read24(void __iomem *reg)
+{
+ u32 val = readl(reg);
+
+ val |= readl(reg + 4) << 8;
+ val |= readl(reg + 8) << 16;
+
+ return val;
+}
+
+static void qcom_uniphy_setup(void __iomem *base, unsigned int ref_freq,
+ bool sdm_mode,
+ bool ref_freq_mult_2,
+ bool dither,
+ unsigned int refclk_div,
+ unsigned int vco_freq)
+{
+ unsigned int int_ref_freq = ref_freq * (ref_freq_mult_2 ? 2 : 1);
+ unsigned int div_in_freq = vco_freq / refclk_div;
+ unsigned int dc_offset = div_in_freq / int_ref_freq - 1;
+ unsigned int sdm_freq_seed;
+ unsigned int val;
+ u64 tmp = div_in_freq % int_ref_freq;
+
+ tmp *= 0x10000;
+ sdm_freq_seed = div_u64(tmp, int_ref_freq);
+
+ val = FIELD_PREP(UNIPHY_PLL_REFCLK_DBLR, ref_freq_mult_2) |
+ FIELD_PREP(UNIPHY_PLL_REFCLK_DIV, refclk_div - 1);
+ writel(val, base + UNIPHY_PLL_REFCLK_CFG);
+
+ if (sdm_mode) {
+ writel(0, base + UNIPHY_PLL_SDM_CFG0);
+ writel(FIELD_PREP(UNIPHY_PLL_SDM_DITHER_EN, dither) | dc_offset,
+ base + UNIPHY_PLL_SDM_CFG1);
+ write24(sdm_freq_seed, base + UNIPHY_PLL_SDM_CFG2);
+ } else {
+ writel(UNIPHY_PLL_SDM_BYP | dc_offset, base + UNIPHY_PLL_SDM_CFG0);
+ writel(0, base + UNIPHY_PLL_SDM_CFG1);
+ write24(0, base + UNIPHY_PLL_SDM_CFG2);
+ }
+
+ write16(mult_frac(ref_freq, 5, 1000000), base + UNIPHY_PLL_CAL_CFG8);
+ write16(vco_freq / 16, base + UNIPHY_PLL_CAL_CFG10);
+}
+
+static unsigned long qcom_uniphy_recalc(void __iomem *base, unsigned long parent_rate)
+{
+ unsigned long rate;
+ u32 refclk_cfg;
+ u32 dc_offset;
+ u64 fraq_n;
+ u32 val;
+
+ refclk_cfg = readl(base + UNIPHY_PLL_REFCLK_CFG);
+ if (refclk_cfg & UNIPHY_PLL_REFCLK_DBLR)
+ parent_rate *= 2;
+
+ val = readl(base + UNIPHY_PLL_SDM_CFG0);
+ if (FIELD_GET(UNIPHY_PLL_SDM_BYP, val)) {
+ dc_offset = FIELD_GET(UNIPHY_PLL_SDM_BYP_DIV, val);
+ fraq_n = 0;
+ } else {
+ dc_offset = FIELD_GET(UNIPHY_PLL_SDM_DC_OFFSET,
+ readl(base + UNIPHY_PLL_SDM_CFG1));
+ fraq_n = read24(base + UNIPHY_PLL_SDM_CFG2);
+ }
+
+ rate = (dc_offset + 1) * parent_rate;
+ rate += div_u64(fraq_n * parent_rate, 0x10000);
+
+ rate *= FIELD_GET(UNIPHY_PLL_REFCLK_DIV, refclk_cfg) + 1;
+
+ return rate;
+}
+
+static const unsigned int qcom_hdmi_8974_divs[] = {1, 2, 4, 6};
+
+static unsigned long qcom_hdmi_8974_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct qcom_hdmi_preqmp_phy *hdmi_phy = hw_clk_to_phy(hw);
+ u32 div_idx = readl(hdmi_phy->pll_reg + UNIPHY_PLL_POSTDIV1_CFG);
+ unsigned long rate = qcom_uniphy_recalc(hdmi_phy->pll_reg, parent_rate);
+
+ return rate / HDMI_8974_COMMON_DIV / qcom_hdmi_8974_divs[div_idx & 0x3];
+}
+
+static int qcom_hdmi_8974_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ unsigned long min_freq = HDMI_8974_VCO_MIN_FREQ / HDMI_8974_COMMON_DIV;
+ unsigned long max_freq = HDMI_8974_VCO_MAX_FREQ / HDMI_8974_COMMON_DIV;
+
+ req->rate = clamp(req->rate, min_freq / 6, max_freq);
+
+ return 0;
+}
+
+static const struct clk_ops qcom_hdmi_8974_pll_ops = {
+ .recalc_rate = qcom_hdmi_8974_pll_recalc_rate,
+ .determine_rate = qcom_hdmi_8974_pll_determine_rate,
+};
+
+static int qcom_hdmi_msm8974_phy_find_div(unsigned long long pixclk)
+{
+ unsigned long long min_freq = HDMI_8974_VCO_MIN_FREQ / HDMI_8974_COMMON_DIV;
+ int i;
+
+ if (pixclk > HDMI_8974_VCO_MAX_FREQ / HDMI_8974_COMMON_DIV)
+ return -EINVAL;
+
+ for (i = 0; i < ARRAY_SIZE(qcom_hdmi_8974_divs); i++) {
+ if (pixclk >= min_freq / qcom_hdmi_8974_divs[i])
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+static int qcom_hdmi_msm8974_phy_pll_set_rate(struct qcom_hdmi_preqmp_phy *hdmi_phy)
+{
+ unsigned long long pixclk = hdmi_phy->hdmi_opts.tmds_char_rate;
+ unsigned long vco_rate;
+ unsigned int div;
+ int div_idx = 0;
+
+ div_idx = qcom_hdmi_msm8974_phy_find_div(pixclk);
+ if (WARN_ON(div_idx < 0))
+ return div_idx;
+
+ div = qcom_hdmi_8974_divs[div_idx];
+ vco_rate = pixclk * HDMI_8974_COMMON_DIV * div;
+
+ writel(0x81, hdmi_phy->phy_reg + REG_HDMI_8x74_GLB_CFG);
+
+ writel(0x01, hdmi_phy->pll_reg + UNIPHY_PLL_GLB_CFG);
+ writel(0x19, hdmi_phy->pll_reg + UNIPHY_PLL_VCOLPF_CFG);
+ writel(0x0e, hdmi_phy->pll_reg + UNIPHY_PLL_LPFR_CFG);
+ writel(0x20, hdmi_phy->pll_reg + UNIPHY_PLL_LPFC1_CFG);
+ writel(0x0d, hdmi_phy->pll_reg + UNIPHY_PLL_LPFC2_CFG);
+
+ qcom_uniphy_setup(hdmi_phy->pll_reg, 19200000, true, true, true, 1, vco_rate);
+
+ writel(0x10, hdmi_phy->pll_reg + UNIPHY_PLL_LKDET_CFG0);
+ writel(0x1a, hdmi_phy->pll_reg + UNIPHY_PLL_LKDET_CFG1);
+ writel(0x05, hdmi_phy->pll_reg + UNIPHY_PLL_LKDET_CFG2);
+
+ writel(div_idx, hdmi_phy->pll_reg + UNIPHY_PLL_POSTDIV1_CFG);
+
+ writel(0x00, hdmi_phy->pll_reg + UNIPHY_PLL_POSTDIV2_CFG);
+ writel(0x00, hdmi_phy->pll_reg + UNIPHY_PLL_POSTDIV3_CFG);
+ writel(0x01, hdmi_phy->pll_reg + UNIPHY_PLL_CAL_CFG2);
+
+ writel(0x1f, hdmi_phy->phy_reg + REG_HDMI_8x74_PD_CTRL0);
+ udelay(50);
+
+ writel(0x0f, hdmi_phy->pll_reg + UNIPHY_PLL_GLB_CFG);
+
+ writel(0x00, hdmi_phy->phy_reg + REG_HDMI_8x74_PD_CTRL1);
+ writel(0x10, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG2);
+ writel(0xdb, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG0);
+ writel(0x43, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG1);
+ if (pixclk == 297000000) {
+ writel(0x06, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG2);
+ writel(0x03, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG3);
+ } else if (pixclk == 268500000) {
+ writel(0x05, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG2);
+ writel(0x00, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG3);
+ } else {
+ writel(0x02, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG2);
+ writel(0x00, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG3);
+ }
+
+ writel(0x04, hdmi_phy->pll_reg + UNIPHY_PLL_VREG_CFG);
+
+ writel(0xd0, hdmi_phy->phy_reg + REG_HDMI_8x74_DCC_CFG0);
+ writel(0x1a, hdmi_phy->phy_reg + REG_HDMI_8x74_DCC_CFG1);
+ writel(0x00, hdmi_phy->phy_reg + REG_HDMI_8x74_TXCAL_CFG0);
+ writel(0x00, hdmi_phy->phy_reg + REG_HDMI_8x74_TXCAL_CFG1);
+
+ if (pixclk == 268500000)
+ writel(0x11, hdmi_phy->phy_reg + REG_HDMI_8x74_TXCAL_CFG2);
+ else
+ writel(0x02, hdmi_phy->phy_reg + REG_HDMI_8x74_TXCAL_CFG2);
+
+ writel(0x05, hdmi_phy->phy_reg + REG_HDMI_8x74_TXCAL_CFG3);
+ udelay(200);
+
+ return 0;
+}
+
+static int qcom_hdmi_msm8974_phy_pll_enable(struct qcom_hdmi_preqmp_phy *hdmi_phy)
+{
+ int ret;
+ unsigned long status;
+
+ /* Global enable */
+ writel(0x81, hdmi_phy->phy_reg + REG_HDMI_8x74_GLB_CFG);
+
+ /* Power up power gen */
+ writel(0x00, hdmi_phy->phy_reg + REG_HDMI_8x74_PD_CTRL0);
+ udelay(350);
+
+ /* PLL power up */
+ writel(0x01, hdmi_phy->pll_reg + UNIPHY_PLL_GLB_CFG);
+ udelay(5);
+
+ /* Power up PLL LDO */
+ writel(0x03, hdmi_phy->pll_reg + UNIPHY_PLL_GLB_CFG);
+ udelay(350);
+
+ /* PLL power up */
+ writel(0x0f, hdmi_phy->pll_reg + UNIPHY_PLL_GLB_CFG);
+ udelay(350);
+
+ /* Poll for PLL ready status */
+ ret = readl_poll_timeout(hdmi_phy->pll_reg + UNIPHY_PLL_STATUS,
+ status, status & UNIPHY_PLL_LOCK,
+ 100, 2000);
+ if (ret) {
+ dev_warn(hdmi_phy->dev, "HDMI PLL not ready\n");
+ goto err;
+ }
+
+ udelay(350);
+
+ /* Poll for PHY ready status */
+ ret = readl_poll_timeout(hdmi_phy->phy_reg + REG_HDMI_8x74_STATUS,
+ status, status & BIT(0),
+ 100, 2000);
+ if (ret) {
+ dev_warn(hdmi_phy->dev, "HDMI PHY not ready\n");
+ goto err;
+ }
+
+ return 0;
+
+err:
+ writel(0, hdmi_phy->pll_reg + UNIPHY_PLL_GLB_CFG);
+ udelay(5);
+ writel(0, hdmi_phy->phy_reg + REG_HDMI_8x74_GLB_CFG);
+
+ return ret;
+}
+
static int qcom_hdmi_msm8974_phy_power_on(struct qcom_hdmi_preqmp_phy *hdmi_phy)
{
+ int ret;
+
+ ret = qcom_hdmi_msm8974_phy_pll_set_rate(hdmi_phy);
+ if (ret)
+ return ret;
+
+ ret = qcom_hdmi_msm8974_phy_pll_enable(hdmi_phy);
+ if (ret)
+ return ret;
+
writel(0x1b, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG0);
writel(0xf2, hdmi_phy->phy_reg + REG_HDMI_8x74_ANA_CFG1);
writel(0x00, hdmi_phy->phy_reg + REG_HDMI_8x74_BIST_CFG0);
@@ -49,6 +326,10 @@ static int qcom_hdmi_msm8974_phy_power_off(struct qcom_hdmi_preqmp_phy *hdmi_phy
{
writel(0x7f, hdmi_phy->phy_reg + REG_HDMI_8x74_PD_CTRL0);
+ writel(0, hdmi_phy->pll_reg + UNIPHY_PLL_GLB_CFG);
+ udelay(5);
+ writel(0, hdmi_phy->phy_reg + REG_HDMI_8x74_GLB_CFG);
+
return 0;
}
@@ -67,5 +348,6 @@ const struct qcom_hdmi_preqmp_cfg msm8974_hdmi_phy_cfg = {
.power_on = qcom_hdmi_msm8974_phy_power_on,
.power_off = qcom_hdmi_msm8974_phy_power_off,
+ .pll_ops = &qcom_hdmi_8974_pll_ops,
.pll_parent = &msm8974_hdmi_pll_parent,
};
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v9 4/5] phy: qcom-uniphy: add more registers from display PHYs
From: Dmitry Baryshkov @ 2026-05-13 18:14 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Vinod Koul, Neil Armstrong
Cc: linux-kernel, linux-arm-msm, dri-devel, freedreno, linux-phy,
Dmitry Baryshkov
In-Reply-To: <20260513-fd-hdmi-phy-v9-0-ca98c72f1f9f@oss.qualcomm.com>
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Import register definitions from 28nm DSI and HDMI PHYs, adding more UNI
PHY registers.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-uniphy.h | 43 ++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy.h b/drivers/phy/qualcomm/phy-qcom-uniphy.h
index 5f18f9593cda..e02bcc5e8150 100644
--- a/drivers/phy/qualcomm/phy-qcom-uniphy.h
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy.h
@@ -8,10 +8,30 @@
/* PHY registers */
#define UNIPHY_PLL_REFCLK_CFG 0x000
+#define UNIPHY_PLL_REFCLK_DBLR BIT(0)
+#define UNIPHY_PLL_REFCLK_DIV GENMASK(3, 2)
+
+#define UNIPHY_PLL_POSTDIV1_CFG 0x004
+#define UNIPHY_PLL_CHGPUMP_CFG 0x008
+#define UNIPHY_PLL_VCOLPF_CFG 0x00c
+#define UNIPHY_PLL_VREG_CFG 0x010
#define UNIPHY_PLL_PWRGEN_CFG 0x014
+#define UNIPHY_PLL_DMUX_CFG 0x018
+#define UNIPHY_PLL_AMUX_CFG 0x01c
#define UNIPHY_PLL_GLB_CFG 0x020
+#define UNIPHY_PLL_POSTDIV2_CFG 0x024
+#define UNIPHY_PLL_POSTDIV3_CFG 0x028
+#define UNIPHY_PLL_LPFR_CFG 0x02c
+#define UNIPHY_PLL_LPFC1_CFG 0x030
+#define UNIPHY_PLL_LPFC2_CFG 0x034
#define UNIPHY_PLL_SDM_CFG0 0x038
+#define UNIPHY_PLL_SDM_BYP BIT(6)
+#define UNIPHY_PLL_SDM_BYP_DIV GENMASK(5, 0)
+
#define UNIPHY_PLL_SDM_CFG1 0x03c
+#define UNIPHY_PLL_SDM_DITHER_EN BIT(6)
+#define UNIPHY_PLL_SDM_DC_OFFSET GENMASK(5, 0)
+
#define UNIPHY_PLL_SDM_CFG2 0x040
#define UNIPHY_PLL_SDM_CFG3 0x044
#define UNIPHY_PLL_SDM_CFG4 0x048
@@ -22,12 +42,35 @@
#define UNIPHY_PLL_LKDET_CFG0 0x05c
#define UNIPHY_PLL_LKDET_CFG1 0x060
#define UNIPHY_PLL_LKDET_CFG2 0x064
+#define UNIPHY_PLL_TEST_CFG 0x068
#define UNIPHY_PLL_CAL_CFG0 0x06c
+#define UNIPHY_PLL_CAL_CFG1 0x070
+#define UNIPHY_PLL_CAL_CFG2 0x074
+#define UNIPHY_PLL_CAL_CFG3 0x078
+#define UNIPHY_PLL_CAL_CFG4 0x07c
+#define UNIPHY_PLL_CAL_CFG5 0x080
+#define UNIPHY_PLL_CAL_CFG6 0x084
+#define UNIPHY_PLL_CAL_CFG7 0x088
#define UNIPHY_PLL_CAL_CFG8 0x08c
#define UNIPHY_PLL_CAL_CFG9 0x090
#define UNIPHY_PLL_CAL_CFG10 0x094
#define UNIPHY_PLL_CAL_CFG11 0x098
+#define UNIPHY_PLL_EFUSE_CFG 0x09c
+#define UNIPHY_PLL_DEBUG_BUS_SEL 0x0a0
+#define UNIPHY_PLL_CTRL_42 0x0a4
+#define UNIPHY_PLL_CTRL_43 0x0a8
+#define UNIPHY_PLL_CTRL_44 0x0ac
+#define UNIPHY_PLL_CTRL_45 0x0b0
+#define UNIPHY_PLL_CTRL_46 0x0b4
+#define UNIPHY_PLL_CTRL_47 0x0b8
+#define UNIPHY_PLL_CTRL_48 0x0bc
#define UNIPHY_PLL_STATUS 0x0c0
#define UNIPHY_PLL_LOCK BIT(0)
+#define UNIPHY_PLL_DEBUG_BUS0 0x0c4
+#define UNIPHY_PLL_DEBUG_BUS1 0x0c8
+#define UNIPHY_PLL_DEBUG_BUS2 0x0cc
+#define UNIPHY_PLL_DEBUG_BUS3 0x0d0
+#define UNIPHY_PLL_CTRL_54 0x0d4
+
#endif
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v9 3/5] phy: qcom: apq8064-sata: extract UNI PLL register defines
From: Dmitry Baryshkov @ 2026-05-13 18:14 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Vinod Koul, Neil Armstrong
Cc: linux-kernel, linux-arm-msm, dri-devel, freedreno, linux-phy,
Dmitry Baryshkov
In-Reply-To: <20260513-fd-hdmi-phy-v9-0-ca98c72f1f9f@oss.qualcomm.com>
From: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
The "uni" PLL is shared between several PHYS: APQ8064's SATA,
MSM8974/APQ8084 HDMI, MSM8916 DSI, MSM8974/APQ8084 DSI. Extract the
common register names to a separate header with the hope of later having
the common code to handle PLL in those PHYs.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-apq8064-sata.c | 24 +-------------------
drivers/phy/qualcomm/phy-qcom-uniphy.h | 33 ++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c
index cae290a6e19f..52f180e0cfb4 100644
--- a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c
+++ b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c
@@ -15,28 +15,7 @@
#include <linux/platform_device.h>
#include <linux/phy/phy.h>
-/* PHY registers */
-#define UNIPHY_PLL_REFCLK_CFG 0x000
-#define UNIPHY_PLL_PWRGEN_CFG 0x014
-#define UNIPHY_PLL_GLB_CFG 0x020
-#define UNIPHY_PLL_SDM_CFG0 0x038
-#define UNIPHY_PLL_SDM_CFG1 0x03C
-#define UNIPHY_PLL_SDM_CFG2 0x040
-#define UNIPHY_PLL_SDM_CFG3 0x044
-#define UNIPHY_PLL_SDM_CFG4 0x048
-#define UNIPHY_PLL_SSC_CFG0 0x04C
-#define UNIPHY_PLL_SSC_CFG1 0x050
-#define UNIPHY_PLL_SSC_CFG2 0x054
-#define UNIPHY_PLL_SSC_CFG3 0x058
-#define UNIPHY_PLL_LKDET_CFG0 0x05C
-#define UNIPHY_PLL_LKDET_CFG1 0x060
-#define UNIPHY_PLL_LKDET_CFG2 0x064
-#define UNIPHY_PLL_CAL_CFG0 0x06C
-#define UNIPHY_PLL_CAL_CFG8 0x08C
-#define UNIPHY_PLL_CAL_CFG9 0x090
-#define UNIPHY_PLL_CAL_CFG10 0x094
-#define UNIPHY_PLL_CAL_CFG11 0x098
-#define UNIPHY_PLL_STATUS 0x0C0
+#include "phy-qcom-uniphy.h"
#define SATA_PHY_SER_CTRL 0x100
#define SATA_PHY_TX_DRIV_CTRL0 0x104
@@ -58,7 +37,6 @@
#define SATA_PHY_TX_IMCAL_STAT 0x1E4
#define SATA_PHY_RX_IMCAL_STAT 0x1E8
-#define UNIPHY_PLL_LOCK BIT(0)
#define SATA_PHY_TX_CAL BIT(0)
#define SATA_PHY_RX_CAL BIT(0)
diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy.h b/drivers/phy/qualcomm/phy-qcom-uniphy.h
new file mode 100644
index 000000000000..5f18f9593cda
--- /dev/null
+++ b/drivers/phy/qualcomm/phy-qcom-uniphy.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef PHY_QCOM_UNIPHY_H
+#define PHY_QCOM_UNIPHY_H
+
+/* PHY registers */
+#define UNIPHY_PLL_REFCLK_CFG 0x000
+#define UNIPHY_PLL_PWRGEN_CFG 0x014
+#define UNIPHY_PLL_GLB_CFG 0x020
+#define UNIPHY_PLL_SDM_CFG0 0x038
+#define UNIPHY_PLL_SDM_CFG1 0x03c
+#define UNIPHY_PLL_SDM_CFG2 0x040
+#define UNIPHY_PLL_SDM_CFG3 0x044
+#define UNIPHY_PLL_SDM_CFG4 0x048
+#define UNIPHY_PLL_SSC_CFG0 0x04c
+#define UNIPHY_PLL_SSC_CFG1 0x050
+#define UNIPHY_PLL_SSC_CFG2 0x054
+#define UNIPHY_PLL_SSC_CFG3 0x058
+#define UNIPHY_PLL_LKDET_CFG0 0x05c
+#define UNIPHY_PLL_LKDET_CFG1 0x060
+#define UNIPHY_PLL_LKDET_CFG2 0x064
+#define UNIPHY_PLL_CAL_CFG0 0x06c
+#define UNIPHY_PLL_CAL_CFG8 0x08c
+#define UNIPHY_PLL_CAL_CFG9 0x090
+#define UNIPHY_PLL_CAL_CFG10 0x094
+#define UNIPHY_PLL_CAL_CFG11 0x098
+#define UNIPHY_PLL_STATUS 0x0c0
+#define UNIPHY_PLL_LOCK BIT(0)
+
+#endif
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v9 2/5] phy: qualcomm: hdmi-28lpm: provide dynamic configuration
From: Dmitry Baryshkov @ 2026-05-13 18:14 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Vinod Koul, Neil Armstrong
Cc: linux-kernel, linux-arm-msm, dri-devel, freedreno, linux-phy
In-Reply-To: <20260513-fd-hdmi-phy-v9-0-ca98c72f1f9f@oss.qualcomm.com>
Replace fixed value configuration tables with the values calculated at
the runtime. In some cases the values might differ from the original
values. Those were validated on the IFC6410 board.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c | 325 +++++++++--------------------
1 file changed, 104 insertions(+), 221 deletions(-)
diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c b/drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c
index f1e7113e10bd..90d3331313c0 100644
--- a/drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c
+++ b/drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c
@@ -148,222 +148,17 @@
#define HDMI_8960_COMMON_DIV 5
-struct pll_rate {
- unsigned long rate;
- int num_reg;
- struct {
- u32 val;
- u32 reg;
- } conf[32];
-};
-
-/* NOTE: keep sorted highest freq to lowest: */
-static const struct pll_rate freqtbl[] = {
- { 154000000, 14, {
- { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x0d, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x4d, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0x5e, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0x42, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- }
- },
- /* 1080p60/1080p50 case */
- { 148500000, 27, {
- { 0x02, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
- { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG },
- { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
- { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
- { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 },
- { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 },
- { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 },
- { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 },
- { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
- }
- },
- { 108000000, 13, {
- { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x21, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x1c, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- }
- },
- /* 720p60/720p50/1080i60/1080i50/1080p24/1080p30/1080p25 */
- { 74250000, 8, {
- { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
- { 0x12, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- }
- },
- { 74176000, 14, {
- { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0xe5, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x0c, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0x7d, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0xbc, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- }
- },
- { 65000000, 14, {
- { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x8a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x0b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x4b, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0x09, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- }
- },
- /* 480p60/480i60 */
- { 27030000, 18, {
- { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
- { 0x38, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
- { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0xff, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x4e, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0xd7, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0x03, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
- }
- },
- /* 576p50/576i50 */
- { 27000000, 27, {
- { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
- { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG },
- { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
- { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
- { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 },
- { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 },
- { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 },
- { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 },
- { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
- }
- },
- /* 640x480p60 */
- { 25200000, 27, {
- { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG },
- { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
- { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
- { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
- { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG },
- { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
- { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B },
- { 0x77, REG_HDMI_8960_PHY_PLL_SDM_CFG0 },
- { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 },
- { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 },
- { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 },
- { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 },
- { 0x20, REG_HDMI_8960_PHY_PLL_SSC_CFG3 },
- { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 },
- { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 },
- { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 },
- { 0xf4, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 },
- { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 },
- { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 },
- { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 },
- { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 },
- { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 },
- }
- },
-};
-
-static const struct pll_rate *qcom_hdmi_8960_pll_find_rate(unsigned long rate)
+static inline void write16(u16 val, void __iomem *reg)
{
- int i;
-
- for (i = 1; i < ARRAY_SIZE(freqtbl); i++)
- if (rate > freqtbl[i].rate)
- return &freqtbl[i - 1];
+ writel(val & 0xff, reg);
+ writel(val >> 8, reg + 4);
+}
- return &freqtbl[i - 1];
+static inline void write24(u32 val, void __iomem *reg)
+{
+ writel(val & 0xff, reg);
+ writel((val >> 8) & 0xff, reg + 4);
+ writel(val >> 16, reg + 8);
}
static inline u32 read24(void __iomem *reg)
@@ -407,6 +202,70 @@ static unsigned long qcom_28lpm_recalc(struct qcom_hdmi_preqmp_phy *hdmi_phy,
return rate;
}
+/* This function is close to UNIPHY, but it has slighly different fields */
+static int qcom_28lpm_set_rate(struct qcom_hdmi_preqmp_phy *hdmi_phy, unsigned long parent_rate,
+ unsigned long vco_freq, u32 div_idx)
+{
+ unsigned int pixclk = hdmi_phy->hdmi_opts.tmds_char_rate;
+ unsigned int int_ref_freq;
+ unsigned int dc_offset;
+ unsigned int sdm_freq_seed;
+ unsigned int val;
+ bool sdm_mode = false;
+ u32 refclk_cfg;
+ u32 lf_cfg0;
+ u32 lf_cfg1;
+ u64 tmp;
+
+ dev_dbg(hdmi_phy->dev, "rate=%u, div = %d, vco = %lu", pixclk, div_idx, vco_freq);
+
+ if (vco_freq % (parent_rate / 2) == 0) {
+ refclk_cfg = FIELD_PREP(HDMI_8960_PHY_CLK0_DIV, 1);
+ int_ref_freq = parent_rate / 2;
+ } else {
+ refclk_cfg = HDMI_8960_PHY_DBLR_EN;
+ int_ref_freq = parent_rate * 2;
+ sdm_mode = true;
+ }
+
+ dc_offset = vco_freq / int_ref_freq - 1;
+ tmp = vco_freq % int_ref_freq;
+ tmp *= 0x10000;
+ sdm_freq_seed = div_u64(tmp, int_ref_freq);
+
+ val = FIELD_PREP(HDMI_8960_PHY_PLL_VCO_DIV, div_idx) | refclk_cfg;
+ writel(val, hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_REFCLK_CFG);
+
+ lf_cfg0 = dc_offset >= 30 ? 0 : (dc_offset >= 16 ? 0x10 : 0x20);
+ lf_cfg0 += sdm_mode ? 0 : 1;
+
+ /* XXX: 0xc3 instead of 0x33 for qcs404 */
+ lf_cfg1 = dc_offset >= 30 ? 0x33 : (dc_offset >= 16 ? 0xbb : 0xf9);
+
+ writel(lf_cfg0,
+ hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0);
+ writel(lf_cfg1,
+ hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1);
+
+ if (sdm_mode)
+ writel(dc_offset,
+ hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_SDM_CFG0);
+ else
+ writel(HDMI_8960_PHY_SDM_BYP | dc_offset,
+ hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_SDM_CFG0);
+
+ writel(HDMI_8960_PHY_DITHER | dc_offset,
+ hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_SDM_CFG1);
+
+ write24(sdm_freq_seed, hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_SDM_CFG2);
+
+ write16(vco_freq / 1000, hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0);
+
+ writel(0x3b, hdmi_phy->pll_reg + REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2);
+
+ return 0;
+}
+
static const unsigned int qcom_hdmi_8960_divs[] = {1, 2, 4, 6};
static unsigned long qcom_hdmi_8960_pll_recalc_rate(struct clk_hw *hw,
@@ -423,9 +282,10 @@ static unsigned long qcom_hdmi_8960_pll_recalc_rate(struct clk_hw *hw,
static int qcom_hdmi_8960_pll_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
- const struct pll_rate *pll_rate = qcom_hdmi_8960_pll_find_rate(req->rate);
+ unsigned long long min_freq = HDMI_8960_VCO_MIN_FREQ / HDMI_8960_COMMON_DIV;
+ unsigned long long max_freq = HDMI_8960_VCO_MAX_FREQ / HDMI_8960_COMMON_DIV;
- req->rate = pll_rate->rate;
+ req->rate = clamp(req->rate, min_freq / 6, max_freq);
return 0;
}
@@ -510,16 +370,39 @@ static int qcom_hdmi_msm8960_phy_pll_enable(struct qcom_hdmi_preqmp_phy *hdmi_ph
return ret;
}
+static int qcom_hdmi_msm8960_phy_find_div(unsigned long long pixclk)
+{
+ unsigned long long min_freq = HDMI_8960_VCO_MIN_FREQ / HDMI_8960_COMMON_DIV;
+ int i;
+
+ if (pixclk > HDMI_8960_VCO_MAX_FREQ / HDMI_8960_COMMON_DIV)
+ return -E2BIG;
+
+ for (i = 0; i < ARRAY_SIZE(qcom_hdmi_8960_divs); i++) {
+ if (pixclk >= min_freq / qcom_hdmi_8960_divs[i])
+ return i;
+ }
+
+ return -EINVAL;
+}
+
static int qcom_hdmi_msm8960_phy_set_rate(struct qcom_hdmi_preqmp_phy *hdmi_phy)
{
unsigned long long pixclk = hdmi_phy->hdmi_opts.tmds_char_rate;
- const struct pll_rate *pll_rate = qcom_hdmi_8960_pll_find_rate(pixclk);
- int i;
+ /* XXX: 19.2 for qcs404 */
+ unsigned long parent_rate = 27000000;
+ unsigned long vco_freq;
+ int div_idx;
+ u32 div;
- for (i = 0; i < pll_rate->num_reg; i++)
- writel(pll_rate->conf[i].val, hdmi_phy->pll_reg + pll_rate->conf[i].reg);
+ div_idx = qcom_hdmi_msm8960_phy_find_div(pixclk);
+ if (WARN_ON(div_idx < 0))
+ return div_idx;
- return 0;
+ div = qcom_hdmi_8960_divs[div_idx];
+ vco_freq = pixclk * HDMI_8960_COMMON_DIV * div;
+
+ return qcom_28lpm_set_rate(hdmi_phy, parent_rate, vco_freq, div_idx);
}
static void qcom_hdmi_msm8960_phy_pll_disable(struct qcom_hdmi_preqmp_phy *hdmi_phy)
--
2.47.3
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v9 0/5] drm/msm/hdmi & phy: use generic PHY framework
From: Dmitry Baryshkov @ 2026-05-13 18:14 UTC (permalink / raw)
To: Rob Clark, Dmitry Baryshkov, Abhinav Kumar, Jessica Zhang,
Sean Paul, Marijn Suijten, David Airlie, Simona Vetter,
Vinod Koul, Neil Armstrong
Cc: linux-kernel, linux-arm-msm, dri-devel, freedreno, linux-phy,
Dmitry Baryshkov, Konrad Dybcio, Konrad Dybcio
The MSM HDMI PHYs have been using the ad-hoc approach / API instead of
using the generic API framework. Move MSM HDMI PHY drivers to
drivers/phy/qualcomm and rework them to use generic PHY framework. This
way all the QMP-related code is kept at the same place.
Also MSM8974 HDMI PHY, 28nm DSI PHY and apq8964 SATA PHY now can use
common helpers for the UNI PLL.
This also causes some design changes. Currently on MSM8996 the HDMI PLL
implements clock's set_rate(), while other HDMI PHY drivers used the
ad-hoc PHY API for setting the PLL rate (this includes in-tree MSM8960
driver and posted, but not merged, MSM8974 driver). This might result in
the PLL being set to one rate, while the rest of the PHY being tuned to
work at another rate. Adopt the latter idea and always use
phy_configure() to tune the PHY and set the PLL rate.
Merge strategy: Merge the first patch (either through drm/msm or through
the PHY tree), merge the rest of the patches in the next cycle.
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
---
Changes in v9:
- Split 28lpm changes to a separate patch (Sashiko)
- Reworked PHY power up /down sequences in hdmi_bridge.c (Sashiko)
- Switched to pm_runtime_put_sync() (Sashiko)
- Link to v8: https://patch.msgid.link/20260401-fd-hdmi-phy-v8-0-51b0e98edf6c@oss.qualcomm.com
Changes in v8:
- Rebased on linux-next, fixing conflicts
- Added missing ids for APQ8084 and MSM8998 (Sashiko)
- Switched to pm_runtime_put() (Sashiko)
- Fixed several missed *1000 after pixclk -> tmds_char_rate conversion
(Sashiko)
- Fixed several math overflows (Sashiko)
- Moved UNIPHY_PLL_LOCK to the common header (Sashiko)
- Link to v7: https://patch.msgid.link/20260324-fd-hdmi-phy-v7-0-b41dde8d83b8@oss.qualcomm.com
Changes in v7:
- Fixed the build issue between msm8974 patches.
- Dropped even more writel / readl wrappers (now from QMP PHYs)
- Link to v6: https://lore.kernel.org/r/20260319-fd-hdmi-phy-v6-0-cefc08a55470@oss.qualcomm.com
Changes in v6:
- Changed MSM8974 HDMI PHY driver to use FIELD_PREP / FIELD_GET (Konrad)
- Fixed rate recalculation for MSM8974 HDMI PHY (Konrad)
- Dropped register read/write wrappers
- Link to v5: https://lore.kernel.org/r/20260314-fd-hdmi-phy-v5-0-58122ae96d3b@oss.qualcomm.com
Changes in v5:
- Kept only a single place which handles extp clk (after PHY power on,
before PHY power off) (Neil)
- Inlined pm_runtime calls in the HDMI TX driver, replaced
pm_runtime_resume_and_get() with pm_runtime_get_sync(), since
atomic_pre_enable() can not fail.
- Renamed registers defines to drop the REG_ prefix.
- Link to v4: https://lore.kernel.org/r/20250520-fd-hdmi-phy-v4-0-fcbaa652ad75@oss.qualcomm.com
Changes in v3-v4:
- Rebased on top of linux-next, solving conflicts
- Squashed add-and-remove patches into a single git mv patch
- Dropped HDMI PHY header patch (merged upstream)
Changes in v2:
- Changed msm8960 / apq8064 to calculate register data instead of using
fixed tables. This extends the list of supported modes.
(Implementation is based on mdss-hdmi-pll-28lpm.c from msm-4.14).
- Fixed the reprogramming of PLL rate on apq8064.
- Merged all non-QMP HDMI PHY drivers into a common PHY_QCOM_HDMI
driver (suggested by Rob Clark)
---
Dmitry Baryshkov (5):
drm/msm/hdmi: switch to generic PHY subsystem
phy: qualcomm: hdmi-28lpm: provide dynamic configuration
phy: qcom: apq8064-sata: extract UNI PLL register defines
phy: qcom-uniphy: add more registers from display PHYs
phy: qualcomm: add MSM8974 HDMI PHY support
drivers/gpu/drm/msm/Makefile | 7 -
drivers/gpu/drm/msm/hdmi/hdmi.c | 59 +-
drivers/gpu/drm/msm/hdmi/hdmi.h | 83 +--
drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 88 ++-
drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 226 -------
drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | 51 --
drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 761 ----------------------
drivers/gpu/drm/msm/hdmi/hdmi_phy_8998.c | 765 -----------------------
drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c | 141 -----
drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c | 44 --
drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c | 460 --------------
drivers/gpu/drm/msm/registers/display/hdmi.xml | 537 ----------------
drivers/phy/qualcomm/Kconfig | 24 +
drivers/phy/qualcomm/Makefile | 14 +
drivers/phy/qualcomm/phy-qcom-apq8064-sata.c | 24 +-
drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c | 353 +++++++++++
drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c | 477 ++++++++++++++
drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c | 186 ++++++
drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c | 211 +++++++
drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h | 59 ++
drivers/phy/qualcomm/phy-qcom-qmp-hdmi-base.c | 185 ++++++
drivers/phy/qualcomm/phy-qcom-qmp-hdmi-msm8996.c | 440 +++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp-hdmi-msm8998.c | 489 +++++++++++++++
drivers/phy/qualcomm/phy-qcom-qmp-hdmi.h | 49 ++
drivers/phy/qualcomm/phy-qcom-uniphy.h | 76 +++
25 files changed, 2617 insertions(+), 3192 deletions(-)
---
base-commit: e6e0eed7a4199442ad9be37daafafa4503c3f436
change-id: 20240109-fd-hdmi-phy-44b8319fbcc7
Best regards,
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v1 1/6] dt-bindings: usb: ci-hdrc-usb2: Document nvidia,external-control property
From: Svyatoslav Ryhel @ 2026-05-13 17:34 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Svyatoslav Ryhel
Cc: netdev, devicetree, linux-kernel, linux-phy, linux-tegra,
linux-usb
In-Reply-To: <20260511135703.62470-2-clamor95@gmail.com>
пн, 11 трав. 2026 р. о 16:57 Svyatoslav Ryhel <clamor95@gmail.com> пише:
>
> Document the nvidia,external-control property required, for example, for
> USB lines in HSIC mode connected to a modem, where the modem requires
> precise control over the USB bus to properly enumerate all its stages and
> intermediate devices.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
> Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> index 691d6cf02c27..a13c1ef49a57 100644
> --- a/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> +++ b/Documentation/devicetree/bindings/usb/ci-hdrc-usb2.yaml
> @@ -75,6 +75,13 @@ properties:
> type: boolean
> deprecated: true
>
> + nvidia,external-control:
> + description:
> + Indicates that the controller is configured externally and that the host
> + should not attempt to touch it. Usually used by a modem which requires
> + precise bus configuration.
> + type: boolean
> +
Would schema maintainers mind if I create separate schema like
chipidea,usb2-imx.yaml is handled? At the moment ci-hdrc-usb2 holds a
mixed properties of several SoC and can cause unwanted/unsupported
node combinations.
> ulpi:
> type: object
> additionalProperties: false
> --
> 2.51.0
>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v1 2/6] usb: chipidea: tegra: Avoid controller/PHY init if bus is externally controlled
From: Svyatoslav Ryhel @ 2026-05-13 17:30 UTC (permalink / raw)
To: Peter Chen (CIX)
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Vinod Koul, Neil Armstrong, Thierry Reding, Jonathan Hunter,
Greg Kroah-Hartman, netdev, devicetree, linux-kernel, linux-phy,
linux-tegra, linux-usb
In-Reply-To: <agLb6mgP45jHjvNt@nchen-desktop>
вт, 12 трав. 2026 р. о 10:51 Peter Chen (CIX) <peter.chen@kernel.org> пише:
>
> On 26-05-12 09:13:40, Svyatoslav Ryhel wrote:
> > вт, 12 трав. 2026 р. о 04:16 Peter Chen (CIX) <peter.chen@kernel.org> пише:
> > >
> > > On 26-05-11 16:56:57, Svyatoslav Ryhel wrote:
> > > > If the USB controller and PHY are externally controlled, then the
> > > > registration of the controller and the PHY initialization should be
> > > > skipped, since these configurations must be done by the device that
> > > > controls the bus to work correctly.
> > > >
> > >
> > > I find you only control USB controller device add at PHY driver, most of USB drivers
> > > has PHY control, for chipidea, it has PHY control at core.c, would please try to
> > > adapt for it?
> > >
> >
> > Usually yes, but this is not the case for Tegra unfortunately. As you
> > can see Tegra specific section of Chipidea driver specifically
> > describes why it has to set PHY manually.
> >
> > /*
> > * USB controller registers shouldn't be touched before PHY is
> > * initialized, otherwise CPU will hang because clocks are gated.
> > * PHY driver controls gating of internal USB clocks on Tegra.
> > */
> >
> > So in order to provide correct work of USB when set by an external
> > device, both PHY and controller init/add must be skipped.
>
> You could call generic PHY APIs at ci_hdrc_tegra.c, after PHY init or power on,
> call controller initialization.
>
I was tinkering with Chipidea driver for Tegra a bit. If you meant to
use flag only to control usb controller device init and leave PHY to
be handled by controller, then yes, that is possible and that is
better approach.
> >
> > > Peter
> > >
> > > > Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> > > > ---
> > > > drivers/usb/chipidea/ci_hdrc_tegra.c | 36 +++++++++++++++++-----------
> > > > 1 file changed, 22 insertions(+), 14 deletions(-)
> > > >
> > > > diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c
> > > > index 372788f0f970..593390a818d1 100644
> > > > --- a/drivers/usb/chipidea/ci_hdrc_tegra.c
> > > > +++ b/drivers/usb/chipidea/ci_hdrc_tegra.c
> > > > @@ -32,6 +32,7 @@ struct tegra_usb {
> > > > struct clk *clk;
> > > >
> > > > bool needs_double_reset;
> > > > + bool externally_controlled;
> > > > };
> > > >
> > > > struct tegra_usb_soc_info {
> > > > @@ -312,20 +313,25 @@ static int tegra_usb_probe(struct platform_device *pdev)
> > > > if (device_property_present(&pdev->dev, "nvidia,needs-double-reset"))
> > > > usb->needs_double_reset = true;
> > > >
> > > > + if (device_property_present(&pdev->dev, "nvidia,external-control"))
> > > > + usb->externally_controlled = true;
> > > > +
> > > > err = tegra_usb_reset_controller(&pdev->dev);
> > > > if (err) {
> > > > dev_err_probe(&pdev->dev, err, "failed to reset controller");
> > > > goto fail_power_off;
> > > > }
> > > >
> > > > - /*
> > > > - * USB controller registers shouldn't be touched before PHY is
> > > > - * initialized, otherwise CPU will hang because clocks are gated.
> > > > - * PHY driver controls gating of internal USB clocks on Tegra.
> > > > - */
> > > > - err = usb_phy_init(usb->phy);
> > > > - if (err)
> > > > - goto fail_power_off;
> > > > + if (!usb->externally_controlled) {
> > > > + /*
> > > > + * USB controller registers shouldn't be touched before PHY is
> > > > + * initialized, otherwise CPU will hang because clocks are gated.
> > > > + * PHY driver controls gating of internal USB clocks on Tegra.
> > > > + */
> > > > + err = usb_phy_init(usb->phy);
> > > > + if (err)
> > > > + goto fail_power_off;
> > > > + }
> > > >
> > > > /* setup and register ChipIdea HDRC device */
> > > > usb->soc = soc;
> > > > @@ -342,12 +348,14 @@ static int tegra_usb_probe(struct platform_device *pdev)
> > > > if (of_usb_get_phy_mode(pdev->dev.of_node) == USBPHY_INTERFACE_MODE_ULPI)
> > > > usb->data.flags &= ~CI_HDRC_SUPPORTS_RUNTIME_PM;
> > > >
> > > > - usb->dev = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> > > > - pdev->num_resources, &usb->data);
> > > > - if (IS_ERR(usb->dev)) {
> > > > - err = dev_err_probe(&pdev->dev, PTR_ERR(usb->dev),
> > > > - "failed to add HDRC device");
> > > > - goto phy_shutdown;
> > > > + if (!usb->externally_controlled) {
> > > > + usb->dev = ci_hdrc_add_device(&pdev->dev, pdev->resource,
> > > > + pdev->num_resources, &usb->data);
> > > > + if (IS_ERR(usb->dev)) {
> > > > + err = dev_err_probe(&pdev->dev, PTR_ERR(usb->dev),
> > > > + "failed to add HDRC device");
> > > > + goto phy_shutdown;
> > > > + }
> > > > }
> > > >
> > > > return 0;
> > > > --
> > > > 2.51.0
> > > >
> > >
> > > --
> > >
> > > Best regards,
> > > Peter
>
> --
>
> Best regards,
> Peter
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 2/6] phy: rockchip: samsung-hdptx: Handle uncommitted PHY config changes
From: Cristian Ciocaltea @ 2026-05-13 17:15 UTC (permalink / raw)
To: sashiko-reviews; +Cc: vkoul, olteanv, linux-phy, neil.armstrong
In-Reply-To: <20260512235710.A6AC1C2BCB0@smtp.kernel.org>
On 5/13/26 2:57 AM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [High] Abuse of CCF determine_rate corrupts the clock tree rate cache.
> - [High] Ignored return value in clk_ops.prepare masks hardware initialization failures.
> - [High] Missing mutual exclusion between CCF and PHY frameworks causes concurrent hardware corruption.
> - [High] Unbalanced PHY usage count on lane mode configuration failure in rk_hdptx_phy_power_on.
> --
>
> commit 53b6461d3d35f9f83438d0a57cf5379f7c1fcba8
> Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
>
> phy: rockchip: samsung-hdptx: Handle uncommitted PHY config changes
>
> Any changes to the PHY link rate and/or color depth done via the HDMI
> PHY configuration API are not immediately programmed into the hardware,
> but are delayed until the PHY usage count gets incremented from 0 to 1,
> that is when it is powered on or when the PLL clock exposed through
> the CCF API is prepared, whichever comes first.
>
> [ ... ]
>
>> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> index 7fb1c22318bbf..12c259d9544cf 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> @@ -1347,25 +1354,22 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx)
>> return 0;
>>
>> ret = regmap_read(hdptx->grf, GRF_HDPTX_STATUS, &status);
>> - if (ret)
>> - goto dec_usage;
>> -
>> - if (status & HDPTX_O_PLL_LOCK_DONE)
>> - dev_warn(hdptx->dev, "PLL locked by unknown consumer!\n");
>> + if (ret) {
>> + atomic_dec(&hdptx->usage_count);
>> + return ret;
>> + }
>>
>> if (mode == PHY_MODE_DP) {
>> rk_hdptx_dp_reset(hdptx);
>> } else {
>> - ret = rk_hdptx_pll_cmn_config(hdptx);
>> - if (ret)
>> - goto dec_usage;
>> + /*
>> + * Ignore PLL config errors at this point as pll_config_dirty
>> + * was not reset and, therefore, operation will be retried.
>> + */
>> + rk_hdptx_pll_cmn_config(hdptx);
>> }
>>
>> return 0;
>
> Does dropping the return value of rk_hdptx_pll_cmn_config() mask hardware
> initialization failures?
No, it's done on purpose, per the comment above (the error is not critical at
this point and we don't want to bail out too early).
>
> If pll_config_dirty is false (for example, the clock was previously prepared
> and unprepared), a subsequent failure won't be retried later.
The retry is done either by rk_hdptx_phy_clk_set_rate() or
rk_hdptx_phy_power_on(), whichever comes first.
>
> Also, if a caller invokes clk_prepare_enable() but not clk_set_rate() or
> phy_power_on(), will the hardware remain unconfigured while CCF incorrectly
> assumes the clock is running?
That's not a valid usecase, the hardware will be eventually programmed by one of
the two functions above - the clock provider is dependent on the PHY
configuration, which may happen after clk_prepare_enable().
>
>> @@ -1700,16 +1704,20 @@ static int rk_hdptx_phy_power_on(struct phy *phy)
>> if (ret)
>> rk_hdptx_phy_consumer_put(hdptx, true);
>> } else {
>> - regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> - HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
>> + if (hdptx->pll_config_dirty)
>> + ret = rk_hdptx_pll_cmn_config(hdptx);
>>
>> - if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
>> - ret = rk_hdptx_frl_lcpll_mode_config(hdptx);
>> - else
>> - ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
>> + if (!ret) {
>> + regmap_write(hdptx->grf, GRF_HDPTX_CON0,
>> + HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0));
>>
>> - if (ret)
>> + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
>> + ret = rk_hdptx_frl_lcpll_mode_config(hdptx);
>> + else
>> + ret = rk_hdptx_tmds_ropll_mode_config(hdptx);
>> + } else {
>> rk_hdptx_phy_consumer_put(hdptx, true);
>> + }
>> }
>
> If rk_hdptx_tmds_ropll_mode_config() or rk_hdptx_frl_lcpll_mode_config()
> fails, ret is set but the else block is never executed. Does this leave
> usage_count unbalanced and prevent the PHY from being powered down? I noted
> this was addressed later in the series by commit "phy: rockchip:
> samsung-hdptx: Drop TMDS rate setup workaround", but wanted to point it out.
If rk_hdptx_pll_cmn_config() above succeeds, it's very unlikely any of the
*_mode_config() calls fails. The indicated commit does indeed eliminate this
theoretical issue - I can still handle it in this patch if a new revision is
required.
>
> Also, does this logic introduce a race condition between CCF (clk_prepare)
> and the PHY framework (phy_power_on)? The usage_count is atomic, but there
> appears to be no mutual exclusion for the hardware configuration itself.
>
> If Thread A calls clk_prepare() and increments the count to 1, it starts the
> lengthy rk_hdptx_pll_cmn_config() hardware sequence.
>
> If Thread B calls phy_power_on() concurrently and increments the count to 2,
> it returns immediately from rk_hdptx_phy_consumer_get(). Thread B will then
> evaluate hdptx->pll_config_dirty, see it is still true, and concurrently
> execute rk_hdptx_pll_cmn_config() while Thread A is already modifying the
> same registers.
No, that's not a valid usecase - the calls are orchestrated by the DRM subystem,
which guaranties the sequence of operations, e.g. configuring PHY (w/o HW
programming) -> setting clk rate (w/ HW programming) -> powering PHY (w/ HW
progamming).
>
>> @@ -2303,8 +2314,19 @@ static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw,
>> {
>> struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
>>
>> - if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
>> - return hdptx->hdmi_cfg.rate;
>> + /*
>> + * Invalidate current clock rate to ensure rk_hdptx_phy_clk_set_rate()
>> + * will be invoked to commit PLL configuration.
>> + */
>> + if (hdptx->pll_config_dirty) {
>> + req->rate = 0;
>> + return 0;
>> + }
>
> Does returning req->rate = 0 here corrupt the clock tree rate cache?
>
> By returning 0 to bypass CCF's optimization and force set_rate(), the Common
> Clock Framework will cache 0 Hz as the actual hardware rate and propagate it
> downstream.
>
> Could this cause downstream consumers (like the VOP2 display clock dclk)
> or rate change notifiers to receive 0 Hz, potentially leading to
> division-by-zero errors or broken pixel clock math?
No, invalidating the CCF rate doesn't have any negative side effect - this is
very short-lived state which ensures a set_rate() call from VOP2 is imminent.
This is really necessary in order to address the usecases described in the
commit message, e.g. pixel clock rate not varying with bpc (from consumer/VOP2
perspective).
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v2 1/6] phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc
From: Cristian Ciocaltea @ 2026-05-13 16:12 UTC (permalink / raw)
To: sashiko; +Cc: neil.armstrong, olteanv, vkoul, linux-phy
In-Reply-To: <20260512225155.EEA3AC2BCB0@smtp.kernel.org>
On 5/13/26 1:51 AM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Clock rate calculation drops a rounding step, replacing DIV_ROUND_CLOSEST_ULL() with truncation via div_u64(), which can cause a 1 Hz clock rate mismatch.
> --
>
> commit f013b4b7bc1d4ae235d28b10cad3143d009d131c
> Author: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
>
> phy: rockchip: samsung-hdptx: Fix rate recalculation for high bpc
>
> This commit fixes the clock rate recalculation in the HDMI PHY probe path
> by directly reading the bpc value from hardware registers instead of
> relying on uninitialized configuration struct members.
>
>> diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> index 2d973bc37f076..7fb1c22318bbf 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c
>> @@ -2280,7 +2281,7 @@ static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx)
>> fout = fout + sdm;
>> }
>>
>> - return div_u64(fout * 2, ropll_hw.pms_sdiv * 10);
>> + return div_u64(fout * 2 * 8, ropll_hw.pms_sdiv * 10 * bpc);
>> }
>>
>> static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
>> @@ -2288,19 +2289,13 @@ static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw,
>> {
>> struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw);
>> u32 status;
>> - u64 rate;
>> int ret;
>>
>> ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status);
>> if (ret || !(status & HDPTX_I_PLL_EN))
>> return 0;
>>
>> - rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
>> -
>> - if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL)
>> - return rate;
>> -
>> - return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc);
>> + return rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx);
>
> Does this inadvertently change the rounding behavior?
>
> By moving the * 8 and / bpc math into rk_hdptx_phy_clk_calc_rate_from_pll_cfg()
> and using div_u64(), the result is now truncated instead of rounded.
>
> For example, if the exact calculated value ends in .6 or .8, the truncation
> will yield a value 1 Hz lower than the rounded value.
>
> Since rk_hdptx_phy_clk_determine_rate() still calculates the expected rate
> using DIV_ROUND_CLOSEST_ULL(), could this truncation lead to a 1 Hz mismatch
> in the Common Clock Framework?
I couldn't notice any change in the functional behavior, but for consistency we
can stick with DIV_ROUND_CLOSEST_ULL(). I'll make this change in the next
revision, if any required, otherwise it will be submitted as part of the FRL
TxFFE level control series:
https://lore.kernel.org/all/20260328-hdptx-ffe-v1-0-53ebd5dea20a@collabora.com/
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/4] arm64: dts: qcom: Add Shikra CQM SoM platform
From: Dmitry Baryshkov @ 2026-05-13 15:14 UTC (permalink / raw)
To: Rakesh Kota, linux-arm-msm
Cc: sashiko-reviews, Komal Bajaj, robh, linux-phy, neil.armstrong,
vkoul, olteanv, krzk+dt, conor+dt, devicetree
In-Reply-To: <20260513142936.kauwa3czigfs7qs5@hu-kotarake-hyd.qualcomm.com>
On 13/05/2026 17:29, Rakesh Kota wrote:
> On Wed, May 13, 2026 at 03:01:47PM +0300, Dmitry Baryshkov wrote:
>> On Wed, May 13, 2026 at 04:28:35AM +0000, sashiko-bot@kernel.org wrote:
>>> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
>>> - [High] The PMIC regulator definitions omit their required input supply dependencies (e.g., `vdd_s2-supply`, `vdd_l3-supply`), breaking the power hierarchy.
>>> - [Medium] The device tree inaccurately hardcodes the `compatible` string to a different PMIC model (`qcom,rpm-pm2250-regulators`) instead of explicitly identifying the actual hardware (PM4125).
>>> --
>>>
>>> commit 457abf6e7ac410430c866842e08e602ec3daaa51
>>> Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
>>>
>>> arm64: dts: qcom: Add Shikra CQM SoM platform
>>>
>>> Add device tree include for the CQM variant of the Shikra System-on-Module.
>>> This variant integrates the Shikra SoC and PM4125 PMIC. The DTSI includes
>>> the common shikra.dtsi and adds PM4125 PMIC regulator definitions.
>>>
>>>> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
>>>> new file mode 100644
>>>> index 0000000000000..401e71720519d
>>>> --- /dev/null
>>>> +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
>>> [ ... ]
>>>> +&rpm_requests {
>>>> + regulators {
>>>> + compatible = "qcom,rpm-pm2250-regulators";
>>>
>>> Since the commit message indicates this is a PM4125 PMIC, should the
>>> compatible string include a specific identifier for the actual hardware?
>>>
>>> Using a specific identifier like "qcom,rpm-pm4125-regulators" alongside
>>> the fallback allows the kernel to apply specific quirks if PM4125 errata
>>> are discovered later.
>>
>> This can be ignored. The compat is a leftover from the historically
>> incorrect naming.
>>
>>>
>>>> +
>>>> + pm4125_s2: s2 {
>>>> + regulator-min-microvolt = <1000000>;
>>>> + regulator-max-microvolt = <1200000>;
>>>> + };
>>>
>>> Do these regulators need to explicitly define their input supply dependencies
>>> such as vdd_s2-supply?
>>>
>>> Without these properties, the regulator framework might be unaware that the
>>> PMIC regulators draw power from upstream supplies.
>>>
>>> If the kernel dynamically manages the upstream supply and its reference count
>>> drops to zero, could it be disabled, causing an unexpected power loss for
>>> downstream components?
>>
>> And this is a correct comment. Please provide missing supplies.
>>
> As per the Qualcomm system design, the parent-child supply relationship
> is managed by the RPM firmware, not the Linux regulator framework. The
> RPM ensures the parent supply is never disabled until all subsystem
> votes are cleared.
How is this different from other, previous platforms?
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH phy-next 5/5] phy: lynx-28g: add support for 25GBASER
From: Vladimir Oltean @ 2026-05-13 15:10 UTC (permalink / raw)
To: Josua Mayer
Cc: linux-phy@lists.infradead.org, netdev@vger.kernel.org,
Ioana Ciornei, Vinod Koul, Neil Armstrong,
linux-kernel@vger.kernel.org, Rabeeh Khoury, Yazan Shhady
In-Reply-To: <5cc008f1-d2c4-4a56-a1b4-6fd9bd470049@solid-run.com>
On Wed, May 13, 2026 at 02:50:38PM +0000, Josua Mayer wrote:
> With updated compatible string it is working perfectly!
>
> I'll send my tested-by on the series, thanks!
Thanks.
> >
> > You can look at my branch
> > https://github.com/vladimiroltean/linux/commits/net-phy-upstreaming
> > specifically commit "arm64: dts: lx2160a: transition to device-specific
> > SerDes compatible strings".
>
> Thanks!
>
> I will probably have retimer comments i.e. one phy object ehach for rx, and tx,
> instead of combined - as we can not rely on hardware designers making clean choices.
> E.g. imagine two retimer chips, one handling rx direction of 2 ports and one tx of 2 ports.
>
> phys = <&serdes_1 0, &retimer_rx 0>, <&retimer_tx 0>;
>
> Not relevant to this patch.
Correct. For the retimers we will upstream (Ioana is working on the TI
DS125DF111), their channels will be split to separate Generic PHY
objects, to cater specifically to that use case. Hoping that all other
multi-channel retimer submissions where there is no meaningful
distinction between RX and TX will do the same.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH phy-next 0/5] Lynx 28G SerDes: 25GbE support
From: Josua Mayer @ 2026-05-13 14:51 UTC (permalink / raw)
To: Vladimir Oltean, linux-phy@lists.infradead.org
Cc: netdev@vger.kernel.org, Ioana Ciornei, Vinod Koul, Neil Armstrong,
linux-kernel@vger.kernel.org
In-Reply-To: <20260511150023.1903577-1-vladimir.oltean@nxp.com>
Am 11.05.26 um 17:00 schrieb Vladimir Oltean:
> This is the remainder of "Lynx 28G improvements part 2", previously
> submitted here:
> https://lore.kernel.org/linux-phy/176850672122.1082429.444623229961712368.robh@kernel.org/
>
> but split up into smaller portions (merged separately):
> - https://lore.kernel.org/linux-phy/20260226182853.1103616-1-vladimir.oltean@nxp.com/
> - https://lore.kernel.org/linux-phy/20260321011451.1557091-1-vladimir.oltean@nxp.com/
>
> What remains is the highlight feature (patch 5/5): support for dynamic
> protocol changes to/from 25GBase-R, required by SFP28 modules. These are
> used with the NXP LX2160A and the (Ethernet) dpaa2-mac consumer.
>
> Patches 1-4 handle the following situation: with current device trees,
> the driver will think 25GBase-R will work on a lane, but it may work or
> may not. This is because not all lanes support this protocol. So we
> modify the SerDes compatible strings to identify them, and we use a
> driver-internal database to figure out on which lanes does each SerDes
> instance support this protocol.
>
> On current device trees, 25GbE is not supported.
>
> Detailed change log in patches. Summary:
> - reworded commit messages
> - change match condition from dt-bindings change 2/5
> - patch 3/5 is new (reject probing on devices with no OF node)
>
> Ioana Ciornei (1):
> phy: lynx-28g: add support for 25GBASER
>
> Vladimir Oltean (4):
> dt-bindings: phy: lynx-28g: add compatible strings per SerDes and
> instantiation
> dt-bindings: phy: lynx-28g: add constraint on LX2162A lane indices
> phy: lynx-28g: require an OF node to probe
> phy: lynx-28g: probe on per-SoC and per-instance compatible strings
>
> .../devicetree/bindings/phy/fsl,lynx-28g.yaml | 48 +++-
> drivers/phy/freescale/phy-fsl-lynx-28g.c | 221 +++++++++++++++++-
> 2 files changed, 254 insertions(+), 15 deletions(-)
>
Tested-by: Josua Mayer <josua@solid-run.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH phy-next 5/5] phy: lynx-28g: add support for 25GBASER
From: Josua Mayer @ 2026-05-13 14:50 UTC (permalink / raw)
To: Vladimir Oltean
Cc: linux-phy@lists.infradead.org, netdev@vger.kernel.org,
Ioana Ciornei, Vinod Koul, Neil Armstrong,
linux-kernel@vger.kernel.org, Rabeeh Khoury, Yazan Shhady
In-Reply-To: <20260513133721.huu4j3wksxykizz4@skbuf>
Am 13.05.26 um 15:37 schrieb Vladimir Oltean:
> On Wed, May 13, 2026 at 11:37:14AM +0000, Josua Mayer wrote:
>> In order to test this patch with 25Gbps link, additional changes on other drivers are needed.
>> This is not a short-coming of this patch.
>>
>> 1. I tested this patch-set alone on LX2162 Clearfog with SD1 Protocl 18 (i.e. 2x 10G SFP, 2x 25G SFP):
>>
>> 10Gbps ports are working fine!
>>
>> 25Gbps fail to probe (but this is partly expected):
>>
>> [ 8.373048] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
>> [ 8.373065] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
>> [ 8.373074] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
>> [ 8.373078] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): Error connecting to the MAC endpoint: -EINVAL
>> [ 8.725004] fsl_dpaa2_eth dpni.9: probe with driver fsl_dpaa2_eth failed with error -22
>> [ 8.920766] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
>> [ 8.920783] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
>> [ 8.920791] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
>> [ 8.920795] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): Error connecting to the MAC endpoint: -EINVAL
>> [ 9.290005] fsl_dpaa2_eth dpni.8: probe with driver fsl_dpaa2_eth failed with error -22
>>
>> Perhaps driver could switch to 10G instead? However not important in my opinion.
>>
>> 2. Tested with additional out of tree patches:
>>
>> net: phylink: extend phylink_mii_c45_pcs_get_state also for PHY_INTERFACE_MODE_25GBASER
>> net: pcs: lynx: extend support to also handle PHY_INTERFACE_MODE_25GBASER
>>
>> Then insert 10Gbps SFP module and link-up + TX/RX working fine!
>> I.e. driver switched successfully from 25Gbps configuration to 10Gbps.
>>
>> Then insert 25Gbps SFP module. Errors start occuring:
>>
>> [ 357.043894] fsl_dpaa2_eth dpni.9 eth2: Link is Down
>> [ 357.941036] sfp sfp-bt: module removed
>> [ 364.269580] sfp sfp-bt: module FS SFP-25GSL-85 rev 1A sn C2501330127 dc 250203
>> [ 364.269625] fsl_dpaa2_eth dpni.9 eth2: switched to inband/25gbase-r link mode
>> [ 364.271674] fsl_dpaa2_eth dpni.9 eth2: phy_set_mode_ext() = -95
> -95 is -EOPNOTSUPP. Is it coming from lynx_28g_set_mode()? If it is,
> I suppose it is from lynx_28g_supports_lane_mode() returning false.
>
> Assuming your list of additional patches is exhaustive, I think you
> missed from patch 4/5:
>
> For old device trees with just "fsl,lynx-28g", the only things that
> change are:
> (...)
>
> - the feature set is frozen in time (e.g. no 25GbE). Since we cannot
> guarantee that this protocol will work on a lane, just err on the safe
> side and don't offer it (and require a device tree update to get it).
Yes I missed that.
With updated compatible string it is working perfectly!
I'll send my tested-by on the series, thanks!
>
> You can look at my branch
> https://github.com/vladimiroltean/linux/commits/net-phy-upstreaming,
> specifically commit "arm64: dts: lx2160a: transition to device-specific
> SerDes compatible strings".
Thanks!
I will probably have retimer comments i.e. one phy object ehach for rx, and tx,
instead of combined - as we can not rely on hardware designers making clean choices.
E.g. imagine two retimer chips, one handling rx direction of 2 ports and one tx of 2 ports.
phys = <&serdes_1 0, &retimer_rx 0>, <&retimer_tx 0>;
Not relevant to this patch.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/4] arm64: dts: qcom: Add Shikra CQM SoM platform
From: Rakesh Kota @ 2026-05-13 14:29 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: sashiko-reviews, Komal Bajaj, robh, linux-phy, neil.armstrong,
vkoul, olteanv, krzk+dt, conor+dt, devicetree
In-Reply-To: <t2sw6owdxy5iyodjqsldbw6bfaqnezhgvc4hhylxuyrrbjkjto@iwf4dr5nmot3>
On Wed, May 13, 2026 at 03:01:47PM +0300, Dmitry Baryshkov wrote:
> On Wed, May 13, 2026 at 04:28:35AM +0000, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> > - [High] The PMIC regulator definitions omit their required input supply dependencies (e.g., `vdd_s2-supply`, `vdd_l3-supply`), breaking the power hierarchy.
> > - [Medium] The device tree inaccurately hardcodes the `compatible` string to a different PMIC model (`qcom,rpm-pm2250-regulators`) instead of explicitly identifying the actual hardware (PM4125).
> > --
> >
> > commit 457abf6e7ac410430c866842e08e602ec3daaa51
> > Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
> >
> > arm64: dts: qcom: Add Shikra CQM SoM platform
> >
> > Add device tree include for the CQM variant of the Shikra System-on-Module.
> > This variant integrates the Shikra SoC and PM4125 PMIC. The DTSI includes
> > the common shikra.dtsi and adds PM4125 PMIC regulator definitions.
> >
> > > diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> > > new file mode 100644
> > > index 0000000000000..401e71720519d
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> > [ ... ]
> > > +&rpm_requests {
> > > + regulators {
> > > + compatible = "qcom,rpm-pm2250-regulators";
> >
> > Since the commit message indicates this is a PM4125 PMIC, should the
> > compatible string include a specific identifier for the actual hardware?
> >
> > Using a specific identifier like "qcom,rpm-pm4125-regulators" alongside
> > the fallback allows the kernel to apply specific quirks if PM4125 errata
> > are discovered later.
>
> This can be ignored. The compat is a leftover from the historically
> incorrect naming.
>
> >
> > > +
> > > + pm4125_s2: s2 {
> > > + regulator-min-microvolt = <1000000>;
> > > + regulator-max-microvolt = <1200000>;
> > > + };
> >
> > Do these regulators need to explicitly define their input supply dependencies
> > such as vdd_s2-supply?
> >
> > Without these properties, the regulator framework might be unaware that the
> > PMIC regulators draw power from upstream supplies.
> >
> > If the kernel dynamically manages the upstream supply and its reference count
> > drops to zero, could it be disabled, causing an unexpected power loss for
> > downstream components?
>
> And this is a correct comment. Please provide missing supplies.
>
As per the Qualcomm system design, the parent-child supply relationship
is managed by the RPM firmware, not the Linux regulator framework. The
RPM ensures the parent supply is never disabled until all subsystem
votes are cleared.
regards
Rakesh kota
> >
> > [ ... ]
> >
> > --
> > Sashiko AI review · https://sashiko.dev/#/patchset/20260512-shikra-dt-v1-0-716438330dd0@oss.qualcomm.com?part=3
>
> --
> With best wishes
> Dmitry
>
> --
> linux-phy mailing list
> linux-phy@lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH phy-next 5/5] phy: lynx-28g: add support for 25GBASER
From: Vladimir Oltean @ 2026-05-13 13:37 UTC (permalink / raw)
To: Josua Mayer
Cc: linux-phy@lists.infradead.org, netdev@vger.kernel.org,
Ioana Ciornei, Vinod Koul, Neil Armstrong,
linux-kernel@vger.kernel.org, Rabeeh Khoury, Yazan Shhady
In-Reply-To: <1ba1f688-9f68-4749-a18f-20ae91738ae0@solid-run.com>
On Wed, May 13, 2026 at 11:37:14AM +0000, Josua Mayer wrote:
> In order to test this patch with 25Gbps link, additional changes on other drivers are needed.
> This is not a short-coming of this patch.
>
> 1. I tested this patch-set alone on LX2162 Clearfog with SD1 Protocl 18 (i.e. 2x 10G SFP, 2x 25G SFP):
>
> 10Gbps ports are working fine!
>
> 25Gbps fail to probe (but this is partly expected):
>
> [ 8.373048] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.373065] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.373074] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
> [ 8.373078] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): Error connecting to the MAC endpoint: -EINVAL
> [ 8.725004] fsl_dpaa2_eth dpni.9: probe with driver fsl_dpaa2_eth failed with error -22
> [ 8.920766] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.920783] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.920791] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
> [ 8.920795] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): Error connecting to the MAC endpoint: -EINVAL
> [ 9.290005] fsl_dpaa2_eth dpni.8: probe with driver fsl_dpaa2_eth failed with error -22
>
> Perhaps driver could switch to 10G instead? However not important in my opinion.
>
> 2. Tested with additional out of tree patches:
>
> net: phylink: extend phylink_mii_c45_pcs_get_state also for PHY_INTERFACE_MODE_25GBASER
> net: pcs: lynx: extend support to also handle PHY_INTERFACE_MODE_25GBASER
>
> Then insert 10Gbps SFP module and link-up + TX/RX working fine!
> I.e. driver switched successfully from 25Gbps configuration to 10Gbps.
>
> Then insert 25Gbps SFP module. Errors start occuring:
>
> [ 357.043894] fsl_dpaa2_eth dpni.9 eth2: Link is Down
> [ 357.941036] sfp sfp-bt: module removed
> [ 364.269580] sfp sfp-bt: module FS SFP-25GSL-85 rev 1A sn C2501330127 dc 250203
> [ 364.269625] fsl_dpaa2_eth dpni.9 eth2: switched to inband/25gbase-r link mode
> [ 364.271674] fsl_dpaa2_eth dpni.9 eth2: phy_set_mode_ext() = -95
-95 is -EOPNOTSUPP. Is it coming from lynx_28g_set_mode()? If it is,
I suppose it is from lynx_28g_supports_lane_mode() returning false.
Assuming your list of additional patches is exhaustive, I think you
missed from patch 4/5:
For old device trees with just "fsl,lynx-28g", the only things that
change are:
(...)
- the feature set is frozen in time (e.g. no 25GbE). Since we cannot
guarantee that this protocol will work on a lane, just err on the safe
side and don't offer it (and require a device tree update to get it).
You can look at my branch
https://github.com/vladimiroltean/linux/commits/net-phy-upstreaming,
specifically commit "arm64: dts: lx2160a: transition to device-specific
SerDes compatible strings".
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/4] arm64: dts: qcom: Add Shikra CQM SoM platform
From: Rakesh Kota @ 2026-05-13 13:31 UTC (permalink / raw)
To: sashiko-reviews
Cc: Komal Bajaj, robh, linux-phy, neil.armstrong, vkoul, olteanv,
krzk+dt, conor+dt, devicetree
In-Reply-To: <20260513042836.073F9C2BCB7@smtp.kernel.org>
On Wed, May 13, 2026 at 04:28:35AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] The PMIC regulator definitions omit their required input supply dependencies (e.g., `vdd_s2-supply`, `vdd_l3-supply`), breaking the power hierarchy.
> - [Medium] The device tree inaccurately hardcodes the `compatible` string to a different PMIC model (`qcom,rpm-pm2250-regulators`) instead of explicitly identifying the actual hardware (PM4125).
> --
>
> commit 457abf6e7ac410430c866842e08e602ec3daaa51
> Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
>
> arm64: dts: qcom: Add Shikra CQM SoM platform
>
> Add device tree include for the CQM variant of the Shikra System-on-Module.
> This variant integrates the Shikra SoC and PM4125 PMIC. The DTSI includes
> the common shikra.dtsi and adds PM4125 PMIC regulator definitions.
>
> > diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> > new file mode 100644
> > index 0000000000000..401e71720519d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> [ ... ]
> > +&rpm_requests {
> > + regulators {
> > + compatible = "qcom,rpm-pm2250-regulators";
>
> Since the commit message indicates this is a PM4125 PMIC, should the
> compatible string include a specific identifier for the actual hardware?
>
> Using a specific identifier like "qcom,rpm-pm4125-regulators" alongside
> the fallback allows the kernel to apply specific quirks if PM4125 errata
> are discovered later.
>
PM2250 and PM4125 share identical regulator hardware with no functional
differences. Therefore, using qcom,rpm-pm2250-regulators as the
compatible string is sufficient i think.
> > +
> > + pm4125_s2: s2 {
> > + regulator-min-microvolt = <1000000>;
> > + regulator-max-microvolt = <1200000>;
> > + };
>
> Do these regulators need to explicitly define their input supply dependencies
> such as vdd_s2-supply?
>
> Without these properties, the regulator framework might be unaware that the
> PMIC regulators draw power from upstream supplies.
>
> If the kernel dynamically manages the upstream supply and its reference count
> drops to zero, could it be disabled, causing an unexpected power loss for
> downstream components?
>
As per the Qualcomm system design, the parent-child supply relationships
for these regulators are managed by the AOP (Always-On Processor) FW.
regards
Rakesh Kota
> [ ... ]
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260512-shikra-dt-v1-0-716438330dd0@oss.qualcomm.com?part=3
>
> --
> linux-phy mailing list
> linux-phy@lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy
On Wed, May 13, 2026 at 04:28:35AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] The PMIC regulator definitions omit their required input supply dependencies (e.g., `vdd_s2-supply`, `vdd_l3-supply`), breaking the power hierarchy.
> - [Medium] The device tree inaccurately hardcodes the `compatible` string to a different PMIC model (`qcom,rpm-pm2250-regulators`) instead of explicitly identifying the actual hardware (PM4125).
> --
>
> commit 457abf6e7ac410430c866842e08e602ec3daaa51
> Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
>
> arm64: dts: qcom: Add Shikra CQM SoM platform
>
> Add device tree include for the CQM variant of the Shikra System-on-Module.
> This variant integrates the Shikra SoC and PM4125 PMIC. The DTSI includes
> the common shikra.dtsi and adds PM4125 PMIC regulator definitions.
>
> > diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> > new file mode 100644
> > index 0000000000000..401e71720519d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> [ ... ]
> > +&rpm_requests {
> > + regulators {
> > + compatible = "qcom,rpm-pm2250-regulators";
>
> Since the commit message indicates this is a PM4125 PMIC, should the
> compatible string include a specific identifier for the actual hardware?
>
> Using a specific identifier like "qcom,rpm-pm4125-regulators" alongside
> the fallback allows the kernel to apply specific quirks if PM4125 errata
> are discovered later.
>
PM2250 and PM4125 share identical regulator hardware with no functional
differences. Therefore, using qcom,rpm-pm2250-regulators as the
compatible string is sufficient i think.
> > +
> > + pm4125_s2: s2 {
> > + regulator-min-microvolt = <1000000>;
> > + regulator-max-microvolt = <1200000>;
> > + };
>
> Do these regulators need to explicitly define their input supply dependencies
> such as vdd_s2-supply?
>
> Without these properties, the regulator framework might be unaware that the
> PMIC regulators draw power from upstream supplies.
>
> If the kernel dynamically manages the upstream supply and its reference count
> drops to zero, could it be disabled, causing an unexpected power loss for
> downstream components?
>
As per the Qualcomm system design, the parent-child supply relationships
for these regulators are managed by the AOP (Always-On Processor) FW.
regards
Rakesh Kota
> [ ... ]
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260512-shikra-dt-v1-0-716438330dd0@oss.qualcomm.com?part=3
>
> --
> linux-phy mailing list
> linux-phy@lists.infradead.org
> https://lists.infradead.org/mailman/listinfo/linux-phy
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v5 1/2] dt-bindings: phy: add support for NXPs TJA1145 CAN transceiver
From: Dimitri Fedrau via B4 Relay @ 2026-05-13 13:12 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Neil Armstrong
Cc: linux-phy, devicetree, linux-kernel, Dimitri Fedrau,
Dimitri Fedrau, Conor Dooley
In-Reply-To: <20260513-tja1145-support-v5-0-38720a7ee63e@liebherr.com>
From: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
Adding documentation for NXPs TJA1145 CAN transceiver, which resides like
the ti,tcan104x-can.yaml in the same directory as other generic PHY
subsystem bindings. At the moment there is only support for simple PHYs
by using regulator bindings in combination with can-transceiver.yaml or
PHYs that implement the generic PHY subsystem like the NXP TJA1145.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
---
.../devicetree/bindings/phy/nxp,tja1145.yaml | 80 ++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/nxp,tja1145.yaml b/Documentation/devicetree/bindings/phy/nxp,tja1145.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..46de6d0f2dd9b9fd41c97eb4c9340e3ac36090a3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/nxp,tja1145.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/nxp,tja1145.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TJA1145 CAN transceiver
+
+maintainers:
+ - Dimitri Fedrau <dimitri.fedrau@liebherr.com>
+
+allOf:
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+ compatible:
+ const: nxp,tja1145
+
+ reg:
+ maxItems: 1
+
+ "#phy-cells":
+ const: 0
+
+ spi-cpha: true
+
+ spi-max-frequency:
+ maximum: 4000000
+
+ spi-cs-setup-delay-ns:
+ minimum: 50
+ default: 50
+
+ spi-cs-hold-delay-ns:
+ minimum: 50
+ default: 50
+
+ spi-cs-inactive-delay-ns:
+ minimum: 250
+ default: 250
+
+ vcc-supply:
+ description:
+ CAN transceiver supply voltage
+
+ vio-supply:
+ description:
+ Supply voltage for I/O level adaptor
+
+ vbat-supply:
+ description:
+ Battery supply voltage
+
+required:
+ - compatible
+ - reg
+ - "#phy-cells"
+ - spi-cpha
+
+additionalProperties: false
+
+examples:
+ - |
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ can-phy@0 {
+ compatible = "nxp,tja1145";
+ reg = <0>;
+ #phy-cells = <0>;
+ spi-cpha;
+ spi-max-frequency = <4000000>;
+ spi-cs-setup-delay-ns = <50>;
+ spi-cs-hold-delay-ns = <50>;
+ spi-cs-inactive-delay-ns = <250>;
+ vcc-supply = <®_5v0>;
+ vio-supply = <®_3v3>;
+ vbat-supply = <®_24v0>;
+ };
+ };
--
2.39.5
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v5 2/2] phy: add basic support for NXPs TJA1145 CAN transceiver
From: Dimitri Fedrau via B4 Relay @ 2026-05-13 13:12 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Neil Armstrong
Cc: linux-phy, devicetree, linux-kernel, Dimitri Fedrau,
Dimitri Fedrau, lee.lockhey, Marc Kleine-Budde
In-Reply-To: <20260513-tja1145-support-v5-0-38720a7ee63e@liebherr.com>
From: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
Add basic driver support for NXPs TJA1145 CAN transceiver which brings the
PHY up/down by switching to normal/standby mode using SPI commands.
Tested-by: <lee.lockhey@gmail.com>
Reviewed-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
---
drivers/phy/Kconfig | 10 +++
drivers/phy/Makefile | 1 +
drivers/phy/phy-nxp-tja1145.c | 184 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 195 insertions(+)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index ab96ee5858c1a9dee2aea3a896c09b397cc30c7f..a3f9a05e222002e23d5080aa22b56f2a822a4b97 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -124,6 +124,16 @@ config PHY_NXP_PTN3222
schemes. It supports all three USB 2.0 data rates: Low Speed, Full
Speed and High Speed.
+config PHY_NXP_TJA1145
+ tristate "NXP TJA1145 CAN transceiver PHY"
+ select GENERIC_PHY
+ select REGMAP_SPI
+ depends on SPI
+ help
+ This option enables support for NXPs TJA1145 CAN transceiver as a PHY.
+ This driver provides function for putting the transceiver in various
+ functional modes using SPI commands.
+
config PHY_PISTACHIO_USB
tristate "IMG Pistachio USB2.0 PHY driver"
depends on MIPS || COMPILE_TEST
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index f31767745123773757e84b0b5fb85ec286c1d977..65ea9f0bc7f151378caa6e161f8b8a5c6884d7e5 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -14,6 +14,7 @@ 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_NXP_PTN3222) += phy-nxp-ptn3222.o
+obj-$(CONFIG_PHY_NXP_TJA1145) += phy-nxp-tja1145.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_PHY_SNPS_EUSB2) += phy-snps-eusb2.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
diff --git a/drivers/phy/phy-nxp-tja1145.c b/drivers/phy/phy-nxp-tja1145.c
new file mode 100644
index 0000000000000000000000000000000000000000..1e8bd169743abfaeee6948d200e6ac320cd616ff
--- /dev/null
+++ b/drivers/phy/phy-nxp-tja1145.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 Liebherr-Electronics and Drives GmbH
+ */
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <linux/phy/phy.h>
+#include <linux/spi/spi.h>
+
+#define TJA1145_MODE_CTRL 0x01
+#define TJA1145_MODE_CTRL_MC GENMASK(2, 0)
+#define TJA1145_MODE_CTRL_STBY BIT(2)
+#define TJA1145_MODE_CTRL_NORMAL TJA1145_MODE_CTRL_MC
+
+#define TJA1145_CAN_CTRL 0x20
+#define TJA1145_CAN_CTRL_CMC GENMASK(1, 0)
+#define TJA1145_CAN_CTRL_ACTIVE BIT(1)
+
+#define TJA1145_IDENT 0x7e
+#define TJA1145_IDENT_TJA1145T 0x70
+
+#define TJA1145_SPI_READ_BIT BIT(0)
+#define TJA1145T_MAX_BITRATE 1000000
+
+static int tja1145_phy_power_on(struct phy *phy)
+{
+ struct regmap *map = phy_get_drvdata(phy);
+ int ret;
+
+ /*
+ * Switch operating mode to normal which is the active operating mode.
+ * In this mode, the device is fully operational.
+ */
+ ret = regmap_update_bits(map, TJA1145_MODE_CTRL, TJA1145_MODE_CTRL_MC,
+ TJA1145_MODE_CTRL_NORMAL);
+ if (ret)
+ return ret;
+
+ /*
+ * Switch to CAN operating mode active where the PHY can transmit and
+ * receive data.
+ */
+ return regmap_update_bits(map, TJA1145_CAN_CTRL, TJA1145_CAN_CTRL_CMC,
+ TJA1145_CAN_CTRL_ACTIVE);
+}
+
+static int tja1145_phy_power_off(struct phy *phy)
+{
+ struct regmap *map = phy_get_drvdata(phy);
+
+ /*
+ * Switch to operating mode standby, the PHY is unable to transmit or
+ * receive data in standby mode.
+ */
+ return regmap_update_bits(map, TJA1145_MODE_CTRL, TJA1145_MODE_CTRL_MC,
+ TJA1145_MODE_CTRL_STBY);
+}
+
+static const struct phy_ops tja1145_phy_ops = {
+ .power_on = tja1145_phy_power_on,
+ .power_off = tja1145_phy_power_off,
+ .owner = THIS_MODULE,
+};
+
+static const struct regmap_range tja1145_wr_holes_ranges[] = {
+ regmap_reg_range(0x00, 0x00),
+ regmap_reg_range(0x02, 0x03),
+ regmap_reg_range(0x05, 0x05),
+ regmap_reg_range(0x0b, 0x1f),
+ regmap_reg_range(0x21, 0x22),
+ regmap_reg_range(0x24, 0x25),
+ regmap_reg_range(0x30, 0x4b),
+ regmap_reg_range(0x4d, 0x60),
+ regmap_reg_range(0x62, 0x62),
+ regmap_reg_range(0x65, 0x67),
+ regmap_reg_range(0x70, 0xff),
+};
+
+static const struct regmap_access_table tja1145_wr_table = {
+ .no_ranges = tja1145_wr_holes_ranges,
+ .n_no_ranges = ARRAY_SIZE(tja1145_wr_holes_ranges),
+};
+
+static const struct regmap_range tja1145_rd_holes_ranges[] = {
+ regmap_reg_range(0x00, 0x00),
+ regmap_reg_range(0x02, 0x02),
+ regmap_reg_range(0x05, 0x05),
+ regmap_reg_range(0x0b, 0x1f),
+ regmap_reg_range(0x21, 0x21),
+ regmap_reg_range(0x24, 0x25),
+ regmap_reg_range(0x30, 0x4a),
+ regmap_reg_range(0x4d, 0x5f),
+ regmap_reg_range(0x62, 0x62),
+ regmap_reg_range(0x65, 0x67),
+ regmap_reg_range(0x70, 0x7d),
+ regmap_reg_range(0x7f, 0xff),
+};
+
+static const struct regmap_access_table tja1145_rd_table = {
+ .no_ranges = tja1145_rd_holes_ranges,
+ .n_no_ranges = ARRAY_SIZE(tja1145_rd_holes_ranges),
+};
+
+static const struct regmap_config tja1145_regmap_config = {
+ .reg_bits = 8,
+ .reg_shift = -1,
+ .val_bits = 8,
+ .wr_table = &tja1145_wr_table,
+ .rd_table = &tja1145_rd_table,
+ .read_flag_mask = TJA1145_SPI_READ_BIT,
+ .max_register = TJA1145_IDENT,
+};
+
+static int tja1145_check_ident(struct device *dev, struct regmap *map)
+{
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(map, TJA1145_IDENT, &val);
+ if (ret)
+ return ret;
+
+ if (val != TJA1145_IDENT_TJA1145T) {
+ dev_err(dev, "Expected device id: 0x%02x, got: 0x%02x\n",
+ TJA1145_IDENT_TJA1145T, val);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static int tja1145_probe(struct spi_device *spi)
+{
+ struct phy_provider *phy_provider;
+ struct device *dev = &spi->dev;
+ struct regmap *map;
+ struct phy *phy;
+ int ret;
+
+ map = devm_regmap_init_spi(spi, &tja1145_regmap_config);
+ if (IS_ERR(map))
+ return dev_err_probe(dev, PTR_ERR(map), "failed to init regmap\n");
+
+ ret = tja1145_check_ident(dev, map);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to identify device\n");
+
+ phy = devm_phy_create(dev, dev->of_node, &tja1145_phy_ops);
+ if (IS_ERR(phy))
+ return dev_err_probe(dev, PTR_ERR(phy), "failed to create PHY\n");
+
+ phy->attrs.max_link_rate = TJA1145T_MAX_BITRATE;
+ phy_set_drvdata(phy, map);
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct spi_device_id tja1145_spi_id[] = {
+ { "tja1145" },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, tja1145_spi_id);
+
+static const struct of_device_id tja1145_of_match[] = {
+ { .compatible = "nxp,tja1145" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, tja1145_of_match);
+
+static struct spi_driver tja1145_driver = {
+ .driver = {
+ .name = "tja1145",
+ .of_match_table = tja1145_of_match,
+ },
+ .probe = tja1145_probe,
+ .id_table = tja1145_spi_id,
+};
+module_spi_driver(tja1145_driver);
+
+MODULE_DESCRIPTION("NXP TJA1145 CAN transceiver PHY driver");
+MODULE_AUTHOR("Dimitri Fedrau <dimitri.fedrau@liebherr.com>");
+MODULE_LICENSE("GPL");
--
2.39.5
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v5 0/2] phy: add basic support for NXPs TJA1145 CAN transceiver
From: Dimitri Fedrau via B4 Relay @ 2026-05-13 13:12 UTC (permalink / raw)
To: Vinod Koul, Kishon Vijay Abraham I, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Neil Armstrong
Cc: linux-phy, devicetree, linux-kernel, Dimitri Fedrau,
Dimitri Fedrau, Conor Dooley, lee.lockhey, Marc Kleine-Budde
Add basic driver support for NXPs TJA1145 CAN transceiver which brings the
PHY up/down by switching to normal/standby mode using SPI commands.
Signed-off-by: Dimitri Fedrau <dimitri.fedrau@liebherr.com>
---
Changes in v5:
- No functional change, basically a resend with added tags
- fixed typo in define TJA1145_MODE_CRTL_STBY to TJA1145_MODE_CTRL_STBY
and TJA1145_MODE_CRTL_NORMAL to TJA1145_MODE_CTRL_NORMAL
- remove unneeded include -#include <linux/bitfield.h>
- added owner to tja1145_phy_ops
- Link to v4: https://lore.kernel.org/r/20251015-tja1145-support-v4-0-4d3ca13c8881@liebherr.com
Changes in v4:
- Change compatible to: nxp,tja1145 (Connor)
- Mark spi-cpha as required (Connor)
- Switch from unevaluatedProperties: false to
additionalProperties: false (Connor)
- Remove double newline after tja1145_rd_table (Marc)
- Link to v3: https://lore.kernel.org/r/20251013-tja1145-support-v3-0-4a9d245fe067@liebherr.com
Changes in v3:
- bindings: fix SPI bus unit address format error
- bindings: added resolution of discussion into commit msg
- Checked binding with:
make dt_binding_check DT_SCHEMA_FILES=nxp,tja1145-can.yaml
Missed it for V2, didn't do it intentionally. Sorry.
- Link to v2: https://lore.kernel.org/r/20250829-tja1145-support-v2-0-60997f328979@liebherr.com
Changes in v2:
- bindings: Change node name in example to can-phy
- bindings: Fix order of properties, reg property is second
- bindings: Change compatible to match filename
- change compatible to nxp,tja1145-can
- Link to v1: https://lore.kernel.org/r/20250728-tja1145-support-v1-0-ebd8494d545c@liebherr.com
---
Dimitri Fedrau (2):
dt-bindings: phy: add support for NXPs TJA1145 CAN transceiver
phy: add basic support for NXPs TJA1145 CAN transceiver
.../devicetree/bindings/phy/nxp,tja1145.yaml | 80 +++++++++
drivers/phy/Kconfig | 10 ++
drivers/phy/Makefile | 1 +
drivers/phy/phy-nxp-tja1145.c | 184 +++++++++++++++++++++
4 files changed, 275 insertions(+)
---
base-commit: 29b4d8a7637f027b538787896bee520f2dacc904
change-id: 20250726-tja1145-support-d6ccdc4d2da3
Best regards,
--
Dimitri Fedrau <dimitri.fedrau@liebherr.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 4/4] arm64: dts: qcom: Add Shikra CQM and CQS EVK boards
From: Dmitry Baryshkov @ 2026-05-13 12:04 UTC (permalink / raw)
To: Komal Bajaj
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Vinod Koul, Neil Armstrong, Wesley Cheng,
Ulf Hansson, linux-arm-msm, devicetree, linux-kernel, linux-phy,
linux-mmc, Imran Shaik, Krishna Kurapati, Monish Chunara,
Rakesh Kota, Raviteja Laggyshetty, Sneh Mankad, Vishnu Santhosh,
Xueyao An
In-Reply-To: <20260512-shikra-dt-v1-4-716438330dd0@oss.qualcomm.com>
On Tue, May 12, 2026 at 09:38:07AM +0530, Komal Bajaj wrote:
> Add device trees for the Shikra EVK platform, which combines the CQM
> SoM variant with a common carrier board.
>
> Two EVK boards are introduced:
> - shikra-cqm-evk.dts: pairs with CQM SoM (retail, with modem)
> - shikra-cqs-evk.dts: pairs with CQM SoM (retail, board has no modem
CQS
> support)
>
> Also add shikra-evk.dtsi common across both EVK boards.
What is the split between shikra-cq[ms]-evk.dts and shikra-evk.dtsi?
>
> Each board DTS enables USB (peripheral mode) with the appropriate PMIC
> regulator supplies for the QUSB2 and QMP PHYs, and eMMC with the
> correct vmmc/vqmmc supplies for the CQM SoM's PMIC.
>
> Co-developed-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> Co-developed-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
> Co-developed-by: Monish Chunara <quic_mchunara@quicinc.com>
> Signed-off-by: Monish Chunara <quic_mchunara@quicinc.com>
> Co-developed-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
> Signed-off-by: Rakesh Kota <rakesh.kota@oss.qualcomm.com>
> Co-developed-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
> Signed-off-by: Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
> Co-developed-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> Signed-off-by: Sneh Mankad <sneh.mankad@oss.qualcomm.com>
> Co-developed-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
> Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
> Co-developed-by: Xueyao An <xueyao.an@oss.qualcomm.com>
> Signed-off-by: Xueyao An <xueyao.an@oss.qualcomm.com>
> Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/Makefile | 2 +
> arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 61 +++++++++++++++++++++++++++++
> arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 61 +++++++++++++++++++++++++++++
> arch/arm64/boot/dts/qcom/shikra-evk.dtsi | 13 ++++++
> 4 files changed, 137 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
> index cc42829f92eb..6de783bcd133 100644
> --- a/arch/arm64/boot/dts/qcom/Makefile
> +++ b/arch/arm64/boot/dts/qcom/Makefile
> @@ -328,6 +328,8 @@ dtb-$(CONFIG_ARCH_QCOM) += sdm850-huawei-matebook-e-2019.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sdm850-lenovo-yoga-c630.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sdm850-samsung-w737.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sdx75-idp.dtb
> +dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk.dtb
> +dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb
> dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb
> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> new file mode 100644
> index 000000000000..12eeca84832c
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +/dts-v1/;
> +
> +#include "shikra-cqm-som.dtsi"
> +#include "shikra-evk.dtsi"
> +
> +/ {
> + model = "Qualcomm Technologies, Inc. Shikra CQM EVK";
> + compatible = "qcom,shikra-cqm-evk", "qcom,shikra-cqm-som", "qcom,shikra";
> + chassis-type = "embedded";
> +
> + aliases {
> + mmc0 = &sdhc_1;
> + serial0 = &uart0;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +};
> +
> +&sdhc_1 {
> + vmmc-supply = <&pm4125_l20>;
> + vqmmc-supply = <&pm4125_l14>;
> +
> + pinctrl-0 = <&sdc1_state_on>;
> + pinctrl-1 = <&sdc1_state_off>;
> + pinctrl-names = "default", "sleep";
> +
> + non-removable;
> + supports-cqe;
> + no-sdio;
> + no-sd;
> +
> + status = "okay";
> +};
> +
> +&usb_1 {
> + dr_mode = "peripheral";
> +
> + status = "okay";
> +};
> +
> +&usb_1_hsphy {
> + vdd-supply = <&pm4125_l12>;
> + vdda-pll-supply = <&pm4125_l13>;
> + vdda-phy-dpdm-supply = <&pm4125_l21>;
> +
> + status = "okay";
> +};
> +
> +&usb_qmpphy {
> + vdda-phy-supply = <&pm4125_l8>;
> + vdda-pll-supply = <&pm4125_l13>;
> +
> + status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
> new file mode 100644
> index 000000000000..bc93282f64cf
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +/dts-v1/;
> +
> +#include "shikra-cqm-som.dtsi"
> +#include "shikra-evk.dtsi"
> +
> +/ {
> + model = "Qualcomm Technologies, Inc. Shikra CQS EVK";
> + compatible = "qcom,shikra-cqs-evk", "qcom,shikra-cqm-som", "qcom,shikra";
> + chassis-type = "embedded";
> +
> + aliases {
> + mmc0 = &sdhc_1;
> + serial0 = &uart0;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +};
> +
> +&sdhc_1 {
> + vmmc-supply = <&pm4125_l20>;
> + vqmmc-supply = <&pm4125_l14>;
> +
> + pinctrl-0 = <&sdc1_state_on>;
> + pinctrl-1 = <&sdc1_state_off>;
> + pinctrl-names = "default", "sleep";
> +
> + non-removable;
> + supports-cqe;
> + no-sdio;
> + no-sd;
> +
> + status = "okay";
> +};
> +
> +&usb_1 {
> + dr_mode = "peripheral";
> +
> + status = "okay";
> +};
> +
> +&usb_1_hsphy {
> + vdd-supply = <&pm4125_l12>;
> + vdda-pll-supply = <&pm4125_l13>;
> + vdda-phy-dpdm-supply = <&pm4125_l21>;
> +
> + status = "okay";
> +};
> +
> +&usb_qmpphy {
> + vdda-phy-supply = <&pm4125_l8>;
> + vdda-pll-supply = <&pm4125_l13>;
> +
> + status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/qcom/shikra-evk.dtsi b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi
> new file mode 100644
> index 000000000000..fae8c75b68b3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: BSD-3-Clause
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +&qupv3_0 {
> + firmware-name = "qcom/shikra/qupv3fw.elf";
> + status = "okay";
> +};
> +
> +&uart0 {
> + status = "okay";
> +};
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/4] arm64: dts: qcom: Add Shikra CQM SoM platform
From: Dmitry Baryshkov @ 2026-05-13 12:01 UTC (permalink / raw)
To: sashiko-reviews
Cc: Komal Bajaj, robh, linux-phy, neil.armstrong, vkoul, olteanv,
krzk+dt, conor+dt, devicetree
In-Reply-To: <20260513042836.073F9C2BCB7@smtp.kernel.org>
On Wed, May 13, 2026 at 04:28:35AM +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] The PMIC regulator definitions omit their required input supply dependencies (e.g., `vdd_s2-supply`, `vdd_l3-supply`), breaking the power hierarchy.
> - [Medium] The device tree inaccurately hardcodes the `compatible` string to a different PMIC model (`qcom,rpm-pm2250-regulators`) instead of explicitly identifying the actual hardware (PM4125).
> --
>
> commit 457abf6e7ac410430c866842e08e602ec3daaa51
> Author: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
>
> arm64: dts: qcom: Add Shikra CQM SoM platform
>
> Add device tree include for the CQM variant of the Shikra System-on-Module.
> This variant integrates the Shikra SoC and PM4125 PMIC. The DTSI includes
> the common shikra.dtsi and adds PM4125 PMIC regulator definitions.
>
> > diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> > new file mode 100644
> > index 0000000000000..401e71720519d
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
> [ ... ]
> > +&rpm_requests {
> > + regulators {
> > + compatible = "qcom,rpm-pm2250-regulators";
>
> Since the commit message indicates this is a PM4125 PMIC, should the
> compatible string include a specific identifier for the actual hardware?
>
> Using a specific identifier like "qcom,rpm-pm4125-regulators" alongside
> the fallback allows the kernel to apply specific quirks if PM4125 errata
> are discovered later.
This can be ignored. The compat is a leftover from the historically
incorrect naming.
>
> > +
> > + pm4125_s2: s2 {
> > + regulator-min-microvolt = <1000000>;
> > + regulator-max-microvolt = <1200000>;
> > + };
>
> Do these regulators need to explicitly define their input supply dependencies
> such as vdd_s2-supply?
>
> Without these properties, the regulator framework might be unaware that the
> PMIC regulators draw power from upstream supplies.
>
> If the kernel dynamically manages the upstream supply and its reference count
> drops to zero, could it be disabled, causing an unexpected power loss for
> downstream components?
And this is a correct comment. Please provide missing supplies.
>
> [ ... ]
>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260512-shikra-dt-v1-0-716438330dd0@oss.qualcomm.com?part=3
--
With best wishes
Dmitry
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH phy-next 5/5] phy: lynx-28g: add support for 25GBASER
From: Josua Mayer @ 2026-05-13 11:44 UTC (permalink / raw)
To: Vladimir Oltean, linux-phy@lists.infradead.org
Cc: netdev@vger.kernel.org, Ioana Ciornei, Vinod Koul, Neil Armstrong,
linux-kernel@vger.kernel.org, Rabeeh Khoury, Yazan Shhady
In-Reply-To: <1ba1f688-9f68-4749-a18f-20ae91738ae0@solid-run.com>
Am 13.05.26 um 13:37 schrieb Josua Mayer:
> Am 11.05.26 um 17:00 schrieb Vladimir Oltean:
>> From: Ioana Ciornei <ioana.ciornei@nxp.com>
>>
>> Add support for 25GBASE-R in the Lynx 28G SerDes PHY driver. This will
>> be used by the dpaa2-mac consumer on LX2160A with:
>> - phy_validate(phy, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_25GBASER) to
>> detect support.
>> - phy_set_mode_ext(phy, PHY_MODE_ETHERNET, PHY_INTERFACE_MODE_25GBASER)
>> to reconfigure the lane for this protocol.
>>
>> The intended use case for dynamic protocol switching to 25GBase-R is
>> with SFP28 modules, and protocol switching is triggered by the SFP
>> module insertion. There also exists a 25GBase-KR use case, where the
>> protocol switching is covered by IEEE 802.3 clause 73 auto-negotiation.
>> However, that is not handled here; it merely needs the support added
>> here as basic ground work.
>>
>> The lane frequency for 25GbE is sourced from a clock net frequency of
>> 12.890625 GHz, as produced by PLLF or PLLS, further multiplied by the
>> lane by 2. The clock net frequencies produced by the PLLs are treated as
>> read-only by the driver, so the absence of a PLL provisioned for the
>> right clock net frequency implies absence of 25GbE support, even though
>> a lane might have the appropriate protocol converter for it.
>>
>> In terms of implementation, the change consists of:
>> - determining at probe time if any PLL was preconfigured for the
>> required clock net frequency for 25GbE
>> - adding the default lane parameters for reconfiguring a lane to 25GbE
>> irrespective of the original protocol
>> - allowing this operating mode only on supported lanes, i.e. all lanes
>> of LX2162A SerDes #1, and LX2160A SerDes lanes 0-1, 4-7.
>>
>> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
>> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
>> ---
>> Change previously submitted at:
>> https://lore.kernel.org/linux-phy/20260114152111.625350-6-vladimir.oltean@nxp.com/
>>
>> Changes:
>> - reword commit message
>> ---
>> drivers/phy/freescale/phy-fsl-lynx-28g.c | 90 +++++++++++++++++++++++-
>> 1 file changed, 88 insertions(+), 2 deletions(-)
> In order to test this patch with 25Gbps link, additional changes on other drivers are needed.
> This is not a short-coming of this patch.
>
> 1. I tested this patch-set alone on LX2162 Clearfog with SD1 Protocl 18 (i.e. 2x 10G SFP, 2x 25G SFP):
>
> 10Gbps ports are working fine!
>
> 25Gbps fail to probe (but this is partly expected):
>
> [ 8.373048] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.373065] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.373074] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
> [ 8.373078] fsl_dpaa2_eth dpni.9 (unnamed net_device) (uninitialized): Error connecting to the MAC endpoint: -EINVAL
> [ 8.725004] fsl_dpaa2_eth dpni.9: probe with driver fsl_dpaa2_eth failed with error -22
> [ 8.920766] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.920783] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): MAC returned PCS which does not support 25gbase-r
> [ 8.920791] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): failed to validate link configuration for in-band status
> [ 8.920795] fsl_dpaa2_eth dpni.8 (unnamed net_device) (uninitialized): Error connecting to the MAC endpoint: -EINVAL
> [ 9.290005] fsl_dpaa2_eth dpni.8: probe with driver fsl_dpaa2_eth failed with error -22
>
> Perhaps driver could switch to 10G instead? However not important in my opinion.
>
> 2. Tested with additional out of tree patches:
>
> net: phylink: extend phylink_mii_c45_pcs_get_state also for PHY_INTERFACE_MODE_25GBASER
> net: pcs: lynx: extend support to also handle PHY_INTERFACE_MODE_25GBASER
>
> Then insert 10Gbps SFP module and link-up + TX/RX working fine!
> I.e. driver switched successfully from 25Gbps configuration to 10Gbps.
>
> Then insert 25Gbps SFP module. Errors start occuring:
>
> [ 357.043894] fsl_dpaa2_eth dpni.9 eth2: Link is Down
> [ 357.941036] sfp sfp-bt: module removed
> [ 364.269580] sfp sfp-bt: module FS SFP-25GSL-85 rev 1A sn C2501330127 dc 250203
> [ 364.269625] fsl_dpaa2_eth dpni.9 eth2: switched to inband/25gbase-r link mode
> [ 364.271674] fsl_dpaa2_eth dpni.9 eth2: phy_set_mode_ext() = -95
> [ 364.293232] hwmon hwmon8: temp1_input not attached to any thermal zone
>
> The link starts flapping, which is likely due to a combination of:
>
> 1. the lane has been halted but not stopped
> 2. the lane is still configured for 10G speed
> 3. the retimer (not supported by kernel) is still configured for 10G speed
>
> [ 364.333777] fsl_dpaa2_eth dpni.9 eth2: Link is Up - 25Gbps/Full - flow control off
> [ 365.280234] fsl_dpaa2_eth dpni.9 eth2: Link is Down
> [ 365.287750] fsl_dpaa2_eth dpni.9 eth2: Link is Up - 25Gbps/Full - flow control off
> [ 366.304434] fsl_dpaa2_eth dpni.9 eth2: Link is Down
> [ 366.311868] fsl_dpaa2_eth dpni.9 eth2: Link is Up - 25Gbps/Full - flow control off
> [ 367.328306] fsl_dpaa2_eth dpni.9 eth2: Link is Down
> ...
>
> So I reconfigure the retimer by i2cset for 25Gbps speed, and link goes down permanently.
>
> root@localhost:~# ethtool eth2
> Settings for eth2:
> Supported ports: [ FIBRE ]
> Supported link modes: 25000baseSR/Full
> Supported pause frame use: Symmetric Receive-only
> Supports auto-negotiation: No
> Supported FEC modes: Not reported
> Advertised link modes: Not reported
> Advertised pause frame use: No
> Advertised auto-negotiation: No
> Advertised FEC modes: Not reported
> Speed: Unknown!
> Duplex: Half
> Auto-negotiation: off
> Port: FIBRE
> PHYAD: 0
> Transceiver: internal
> Link detected: no
>
> I would give this a partial tested-by, considering it switched successfully to 10G,
> but failed switching to 25G, which is new with this patch. and needs extra patches.
I should clarify testing was done on v7.1-rc2, plus:
https://lore.kernel.org/r/0-v1-44b2fef88b25+d3-iommupt_map_rc_jgg@nvidia.com
https://lore.kernel.org/r/20260226182853.1103616-1-vladimir.oltean@nxp.com
https://lore.kernel.org/r/20260321011451.1557091-1-vladimir.oltean@nxp.com
https://lore.kernel.org/r/20260511150023.1903577-1-vladimir.oltean@nxp.com
I may have missed something important.
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH phy-next 5/5] phy: lynx-28g: add support for 25GBASER
From: Josua Mayer @ 2026-05-13 11:41 UTC (permalink / raw)
To: Vladimir Oltean
Cc: linux-phy@lists.infradead.org, netdev@vger.kernel.org,
Ioana Ciornei, Vinod Koul, Neil Armstrong,
linux-kernel@vger.kernel.org
In-Reply-To: <20260513112222.2szwvxptk2udv7ga@skbuf>
Am 13.05.26 um 13:22 schrieb Vladimir Oltean:
> On Wed, May 13, 2026 at 11:00:32AM +0000, Josua Mayer wrote:
>> Wouldn't it be more clear instead of indirect lane offset shift with
>> lynx_28g_e25g_pcvt, to instead fix the E25G_CFG definition?:
>>
>> -#define E25G_CFG(id) (28 - (id) * 4) /* Offset into PCCD */
>> +#define E25G_CFG(id) ((id) * 4) /* Offset into PCCD */
>>
>> This is equivalent when inserting (7 - lane) into E25G_CFG id:
>>
>> (28 - (id) * 4) = (28 - (7 - lane) * 4) = (28 - 7*4 + lane*4)
> The 'indirect' lane offset shift is actually a two-step lookup:
> lane -> protocol converter index
> protocol converted index -> offset into PCCD
>
> LX2160ARM documents PCCD fields as:
> E25GA_CFG, aka E25G_CFG(0) in code: 30:28
> E25GB_CFG, aka E25G_CFG(1) in code: 26:24
> ...
> E25GH_CFG, aka E25G_CFG(7) in code: 2:0
>
> The odd bit is that lane 0 uses E25G protocol converter 7, unlike, say,
> 1G and 10G where we have a lane:pcvt identity mapping.
> lynx_28g_e25g_pcvt() performs that translation.
>
> Additionally, for locating E40GA_CFG, E40GB_CFG in PCCE, I've adopted
> the same scheme downstream, where E40G_CFG() returns bits 30:28 for
> argument 0 (pcvt A) and bits 26:24 for argument 1 (pcvt B), and it is
> called with this lane->pcvt translation function:
>
> static int lynx_28g_e40g_pcvt(int lane)
> {
> return lane < 4 ? 1 : 0;
> }
>
> Are you saying that merging the two lookups would be more clear because
> as a reader you'd get to ask yourself less questions (the code would
> flow more naturally) despite the non-trivial lane<->pcvt mapping,
Exactly for this reason. Fewer look-up steps.
RM dos not document this mapping, but now you do in source-code.
Perhaps a short comment on the function will help, e.g.
/* get protocol converter id for lane */
> or why
> exactly? For me it is the exact opposite. I can follow the RM
> definitions and then I have a separate function that tells me how lanes
> are mapped to the protocol converters.
I think you give a good reason here!
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox