* [PATCH 1/2] dt-bindings: phy: mediatek,dsi-phy: Add support for MT8196
From: AngeloGioacchino Del Regno @ 2026-07-01 12:19 UTC (permalink / raw)
To: chunfeng.yun
Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, chunkuang.hu,
p.zabel, matthias.bgg, angelogioacchino.delregno, justin.yeh,
linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
linux-kernel, dri-devel, kernel
In-Reply-To: <20260701121943.19430-1-angelogioacchino.delregno@collabora.com>
Add support for the MediaTek Kompanio Ultra (MT8196) SoC: this
chip features a DSI PHY that is similar to the one found in the
MT8183 SoC, but is a new (incremental) revision with a different
register layout.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml
index c6d0bbdbe0e2..9df1dbe1253b 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,dsi-phy.yaml
@@ -39,6 +39,7 @@ properties:
- const: mediatek,mt2701-mipi-tx
- const: mediatek,mt8173-mipi-tx
- const: mediatek,mt8183-mipi-tx
+ - const: mediatek,mt8196-mipi-tx
reg:
maxItems: 1
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 2/2] phy: mediatek: Add support for MT8196 MIPI DSI PHY
From: AngeloGioacchino Del Regno @ 2026-07-01 12:19 UTC (permalink / raw)
To: chunfeng.yun
Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, chunkuang.hu,
p.zabel, matthias.bgg, angelogioacchino.delregno, justin.yeh,
linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
linux-kernel, dri-devel, kernel
In-Reply-To: <20260701121943.19430-1-angelogioacchino.delregno@collabora.com>
Add support for the MIPI DSI PHY found in the MediaTek MT8196 SoC
and its variants.
This PHY has a different register layout and provides support for
more hardware features compared to the previous generation.
This initial driver only adds support for basic functionality that
is necessary to drive MIPI DSI displays as a D-PHY.
Feature additions like lane-swap, DPHY/CPHY switching, dual-port,
and others, may be done in the future.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/phy/mediatek/Makefile | 1 +
.../phy/mediatek/phy-mtk-mipi-dsi-mt8196.c | 196 ++++++++++++++++++
drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 1 +
drivers/phy/mediatek/phy-mtk-mipi-dsi.h | 2 +-
4 files changed, 199 insertions(+), 1 deletion(-)
create mode 100644 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index 1b8088df71e8..ed0da708759b 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_PHY_MTK_MIPI_CSI_0_5) += phy-mtk-mipi-csi-0-5.o
phy-mtk-mipi-dsi-drv-y := phy-mtk-mipi-dsi.o
phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8173.o
phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8183.o
+phy-mtk-mipi-dsi-drv-y += phy-mtk-mipi-dsi-mt8196.o
obj-$(CONFIG_PHY_MTK_MIPI_DSI) += phy-mtk-mipi-dsi-drv.o
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c
new file mode 100644
index 000000000000..273f236fa7e9
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: jitao.shi <jitao.shi@mediatek.com>
+ *
+ * Copyright (c) 2026 Collabora Ltd.
+ * AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include "phy-mtk-io.h"
+#include "phy-mtk-mipi-dsi.h"
+
+#define MIPITX_LANE_CON 0x0004
+#define RG_DSI_CPHY_T1DRV_EN BIT(0)
+#define RG_DSI_ANA_CK_SEL BIT(1)
+#define RG_DSI_PHY_CK_SEL BIT(2)
+#define RG_DSI_CPHY_EN BIT(3)
+#define RG_DSI_PHYCK_INV_EN BIT(4)
+#define RG_DSI_PWR04_EN BIT(5)
+#define RG_DSI_BG_LPF_EN BIT(6)
+#define RG_DSI_BG_CORE_EN BIT(7)
+#define RG_DSI_PAD_TIEL_SEL BIT(8)
+
+#define MIPITX_VOLTAGE_SEL 0x0008
+#define RG_DSI_HSTX_LDO_REF_SEL GENMASK(9, 6)
+#define RG_DSI_PRD_REF_SEL GENMASK(5, 0)
+#define RG_DSI_PRD_REF_MINI 0
+#define RG_DSI_PRD_REF_DEF 4
+#define RG_DSI_PRD_REF_MAX 7
+
+#define MIPITX_PRESERVED 0x000c
+#define MIPITX_PRESERVED_DEF 0xffff0040
+#define MIPITX_PRESERVED_MINI 0xffff00f0
+
+#define MIPITX_PLL_PWR 0x0028
+#define AD_DSI_PLL_SDM_PWR_ON BIT(0)
+#define AD_DSI_PLL_SDM_ISO_EN BIT(1)
+#define MIPITX_PLL_CON0 0x002c
+#define MIPITX_PLL_CON1 0x0030
+#define RG_DSI_PLL_EN BIT(0)
+#define RG_DSI_PLL_POSDIV GENMASK(10, 8)
+#define MIPITX_PLL_CON2 0x0034
+#define MIPITX_PLL_CON3 0x0038
+#define MIPITX_PLL_CON4 0x003c
+#define RG_DSI_PLL_IBIAS GENMASK(11, 10)
+
+#define MIPITX_D2_SW_CTL_EN 0x015c
+#define MIPITX_D0_SW_CTL_EN 0x025c
+#define MIPITX_CK_CKMODE_EN 0x0320
+#define DSI_CK_CKMODE_EN BIT(0)
+#define MIPITX_CK_SW_CTL_EN 0x035c
+#define MIPITX_D1_SW_CTL_EN 0x045c
+#define MIPITX_D3_SW_CTL_EN 0x055c
+#define DSI_SW_CTL_EN BIT(0)
+
+#define DSI_PHY_XTAL_CLK_HZ 26000000
+
+static int mtk_mipi_tx_pll_enable(struct clk_hw *hw)
+{
+ struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
+ void __iomem *base = mipi_tx->regs;
+ u32 voltage = RG_DSI_PRD_REF_MINI;
+ u32 pres = MIPITX_PRESERVED_MINI;
+ unsigned long long pcw_calc;
+ unsigned int txdiv, txdiv0;
+ u32 pcw;
+
+ dev_dbg(mipi_tx->dev, "enable: %u bps\n", mipi_tx->data_rate);
+
+ if (mipi_tx->data_rate >= 2000000000) {
+ /* Select higher signaling voltage for fast data rates */
+ voltage = RG_DSI_PRD_REF_DEF;
+ pres = MIPITX_PRESERVED_DEF;
+ txdiv = 1;
+ txdiv0 = 0;
+ } else if (mipi_tx->data_rate >= 1000000000) {
+ txdiv = 2;
+ txdiv0 = 1;
+ } else if (mipi_tx->data_rate >= 500000000) {
+ txdiv = 4;
+ txdiv0 = 2;
+ } else if (mipi_tx->data_rate > 250000000) {
+ txdiv = 8;
+ txdiv0 = 3;
+ } else if (mipi_tx->data_rate >= 125000000) {
+ txdiv = 16;
+ txdiv0 = 4;
+ } else {
+ return -EINVAL;
+ }
+
+ pcw_calc = ((u64)(mipi_tx->data_rate / 2) * txdiv) << 24;
+ pcw_calc = div_u64(pcw_calc, DSI_PHY_XTAL_CLK_HZ);
+
+ if (pcw_calc > U32_MAX) {
+ dev_err(mipi_tx->dev, "Calculated PCW=%llu overflow!\n", pcw_calc);
+ return -EINVAL;
+ }
+ pcw = (u32)pcw_calc;
+
+ mtk_phy_update_field(base + MIPITX_VOLTAGE_SEL, RG_DSI_PRD_REF_SEL, voltage);
+ writel(pres, base + MIPITX_PRESERVED);
+
+ mtk_phy_set_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
+ mtk_phy_clear_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+ usleep_range(30, 60);
+
+ mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
+ writel(pcw, base + MIPITX_PLL_CON0);
+ mtk_phy_update_field(base + MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV, txdiv0);
+ usleep_range(30, 60);
+
+ mtk_phy_set_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+ usleep_range(30, 60);
+
+ return 0;
+}
+
+static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
+{
+ struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
+ void __iomem *base = mipi_tx->regs;
+
+ mtk_phy_clear_bits(base + MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+
+ mtk_phy_set_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
+ mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
+}
+
+static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ req->rate = clamp_val(req->rate, 125000000, 1600000000);
+
+ return 0;
+}
+
+static const struct clk_ops mtk_mipi_tx_pll_ops = {
+ .enable = mtk_mipi_tx_pll_enable,
+ .disable = mtk_mipi_tx_pll_disable,
+ .determine_rate = mtk_mipi_tx_pll_determine_rate,
+ .set_rate = mtk_mipi_tx_pll_set_rate,
+ .recalc_rate = mtk_mipi_tx_pll_recalc_rate,
+};
+
+static void mtk_mipi_tx_power_on_signal(struct phy *phy)
+{
+ struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
+ void __iomem *base = mipi_tx->regs;
+
+ /* BG_LPF_EN / BG_CORE_EN */
+ writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, base + MIPITX_LANE_CON);
+ /* Wait for MIPI core to enable */
+ usleep_range(30, 100);
+ writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN, base + MIPITX_LANE_CON);
+
+ /* Switch OFF each Lane */
+ mtk_phy_clear_bits(base + MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_clear_bits(base + MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_clear_bits(base + MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_clear_bits(base + MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_clear_bits(base + MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
+
+ /*
+ * The MIPI TX drive strength is in the range of 3000 ~ 6000 microamps:
+ * RG_DSI_HSTX_LDO_REF_SEL expresses an offset from the minimum drive
+ * strength (3000uA) and can add a maximum offset of 3000uA, reaching a
+ * maximum drive strength of 3000+3000=6000uA.
+ */
+ mtk_phy_update_field(base + MIPITX_VOLTAGE_SEL, RG_DSI_HSTX_LDO_REF_SEL,
+ (mipi_tx->mipitx_drive - 3000) / 200);
+
+ mtk_phy_set_bits(base + MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN);
+}
+
+static void mtk_mipi_tx_power_off_signal(struct phy *phy)
+{
+ struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
+ void __iomem *base = mipi_tx->regs;
+
+ /* Switch ON each lane one by one */
+ mtk_phy_set_bits(base + MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_set_bits(base + MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_set_bits(base + MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_set_bits(base + MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
+ mtk_phy_set_bits(base + MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
+
+ writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN, base + MIPITX_LANE_CON);
+ writel(RG_DSI_PAD_TIEL_SEL, base + MIPITX_LANE_CON);
+}
+
+const struct mtk_mipitx_data mt8196_mipitx_data = {
+ .mipi_tx_clk_ops = &mtk_mipi_tx_pll_ops,
+ .mipi_tx_enable_signal = mtk_mipi_tx_power_on_signal,
+ .mipi_tx_disable_signal = mtk_mipi_tx_power_off_signal,
+};
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 065ea626093a..46f0cb3ac096 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -183,6 +183,7 @@ static const struct of_device_id mtk_mipi_tx_match[] = {
{ .compatible = "mediatek,mt2701-mipi-tx", .data = &mt2701_mipitx_data },
{ .compatible = "mediatek,mt8173-mipi-tx", .data = &mt8173_mipitx_data },
{ .compatible = "mediatek,mt8183-mipi-tx", .data = &mt8183_mipitx_data },
+ { .compatible = "mediatek,mt8196-mipi-tx", .data = &mt8196_mipitx_data },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mtk_mipi_tx_match);
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
index 5d4876f1dc95..e6f967078e3b 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
@@ -42,5 +42,5 @@ unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
extern const struct mtk_mipitx_data mt2701_mipitx_data;
extern const struct mtk_mipitx_data mt8173_mipitx_data;
extern const struct mtk_mipitx_data mt8183_mipitx_data;
-
+extern const struct mtk_mipitx_data mt8196_mipitx_data;
#endif
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 0/2] PHY: Add support for MT8196 DSI PHY
From: AngeloGioacchino Del Regno @ 2026-07-01 12:19 UTC (permalink / raw)
To: chunfeng.yun
Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, chunkuang.hu,
p.zabel, matthias.bgg, angelogioacchino.delregno, justin.yeh,
linux-arm-kernel, linux-mediatek, linux-phy, devicetree,
linux-kernel, dri-devel, kernel
This series adds support for the DSI PHY found in the newer MediaTek
Dimensity 9400 (MT6991), Genio Pro 5100 (MT8894) and Kompanio Ultra
(MT8196) SoCs.
AngeloGioacchino Del Regno (2):
dt-bindings: phy: mediatek,dsi-phy: Add support for MT8196
phy: mediatek: Add support for MT8196 MIPI DSI PHY
.../bindings/phy/mediatek,dsi-phy.yaml | 1 +
drivers/phy/mediatek/Makefile | 1 +
.../phy/mediatek/phy-mtk-mipi-dsi-mt8196.c | 196 ++++++++++++++++++
drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 1 +
drivers/phy/mediatek/phy-mtk-mipi-dsi.h | 2 +-
5 files changed, 200 insertions(+), 1 deletion(-)
create mode 100644 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8196.c
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH 2/2] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting
From: AngeloGioacchino Del Regno @ 2026-07-01 12:19 UTC (permalink / raw)
To: chunfeng.yun
Cc: p.zabel, chunkuang.hu, vkoul, neil.armstrong, matthias.bgg,
angelogioacchino.delregno, granquet, justin.yeh, dri-devel,
linux-mediatek, linux-arm-kernel, linux-phy, linux-kernel, kernel
In-Reply-To: <20260701121936.19407-1-angelogioacchino.delregno@collabora.com>
The comment in the mtk_phy_tmds_clk_ratio() function clearly and
correctly explains that the TMDS ratio has to be 1/10 for data
rates under 3.4Gbps, and 1/40 over that.
Unfortunately though, the TXC_DIV register setting was wrong, as
in value 3 means to divide by 8 and, in order to achieve the in
spec 1/40 (tmds) data rate, this has to divide by 4 instead!
In order to achieve the correct 1/40 (tmds) data rate, this has
Add definitions for the TXC_DIV register values clearly explaining
the meanings (DIV2, DIV4, DIV8), and program the correct, DIV 4,
value to the register in mtk_phy_tmds_clk_ratio().
This fixes out of spec clocking and, with this change, SoCs using
the MT8195 class HDMI PHYs can now successfully be configured to
output 3840x2160@60Hz over HDMI.
Fixes: 45810d486bb4 ("phy: mediatek: add support for phy-mtk-hdmi-mt8195")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +-
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index e6ee8e080022..a4bc1268946d 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -36,7 +36,7 @@ mtk_phy_tmds_clk_ratio(struct mtk_hdmi_phy *hdmi_phy, bool enable)
* clock bit ratio 1:40, under 3.4Gbps, clock bit ratio 1:10
*/
if (enable)
- mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, 3);
+ mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, VAL_TXC_DIV4);
else
mtk_phy_clear_bits(regs + HDMI20_CLK_CFG, REG_TXC_DIV);
}
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
index e26caaf4d104..58800d7659ca 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
@@ -17,6 +17,9 @@
#define HDMI20_CLK_CFG 0x70
#define REG_TXC_DIV GENMASK(31, 30)
+#define VAL_TXC_DIV2 1
+#define VAL_TXC_DIV4 2
+#define VAL_TXC_DIV8 3
#define HDMI_1_CFG_0 0x00
#define RG_HDMITX21_DRV_IBIAS_CLK GENMASK(10, 5)
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 1/2] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow
From: AngeloGioacchino Del Regno @ 2026-07-01 12:19 UTC (permalink / raw)
To: chunfeng.yun
Cc: p.zabel, chunkuang.hu, vkoul, neil.armstrong, matthias.bgg,
angelogioacchino.delregno, granquet, justin.yeh, dri-devel,
linux-mediatek, linux-arm-kernel, linux-phy, linux-kernel, kernel
In-Reply-To: <20260701121936.19407-1-angelogioacchino.delregno@collabora.com>
When trying to calculate a PLL rate for target display resolutions
above 2560x1440, 24bpp, 30Hz, the pixel clock value will be more
than 32-bits long but the division to finally calculate the digital
clock divider is being done with div_u64(), which expects a 32bit
unsigned divisor.
Fix the overflow by using div64_u64() instead.
Fixes: 9d9ff3d2a4a5 ("phy: mediatek: hdmi: mt8195: fix wrong pll calculus")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index 1426a2db984d..e6ee8e080022 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -290,7 +290,7 @@ static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw,
posdiv2 = 1;
/* Digital clk divider, max /32 */
- digital_div = div_u64(ns_hdmipll_ck, posdiv1 * posdiv2 * pixel_clk);
+ digital_div = div64_u64(ns_hdmipll_ck, posdiv1 * posdiv2 * pixel_clk);
if (!(digital_div <= 32 && digital_div >= 1))
return -EINVAL;
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH 0/2] MediaTek MT8195 HDMI PHY Fixes
From: AngeloGioacchino Del Regno @ 2026-07-01 12:19 UTC (permalink / raw)
To: chunfeng.yun
Cc: p.zabel, chunkuang.hu, vkoul, neil.armstrong, matthias.bgg,
angelogioacchino.delregno, granquet, justin.yeh, dri-devel,
linux-mediatek, linux-arm-kernel, linux-phy, linux-kernel, kernel
This series adds two fixes for the MT8195-class HDMI PHY, found in
MT8195, MT8188 and Genio variants.
This is fixing PLL calculation, and TMDS clock dividers, to achieve
all of the modes requiring data rates higher than 3.4Gbps, with the
successfully tested target being 3840x2160@60Hz.
This was tested on MT8395 MediaTek Genio 1200, Radxa NIO-12L and on
MT8390 MediaTek Genio 700, with 3 different HDMI displays (two TVs
and a 4k LG workstation display).
AngeloGioacchino Del Regno (2):
phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow
phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 4 ++--
drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
--
2.54.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH V2 2/2] arm64: dts: qcom: Enable SD card for Shikra EVK
From: Konrad Dybcio @ 2026-07-01 11:38 UTC (permalink / raw)
To: Monish Chunara, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul, Neil Armstrong,
Wesley Cheng, Ulf Hansson, Kernel Team
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
Nitin Rawat, Pradeep Pragallapati, Komal Bajaj
In-Reply-To: <20260630165700.1886608-3-monish.chunara@oss.qualcomm.com>
On 6/30/26 6:57 PM, Monish Chunara wrote:
> Enable SD card for Shikra CQS, CQM and IQS EVK variants. Configure the
> vmmc/vqmmc regulators and gpio-based card detection for each board
> variant.
>
> Signed-off-by: Monish Chunara <monish.chunara@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 18 ++++++++++++++++++
> arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 18 ++++++++++++++++++
> arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 18 ++++++++++++++++++
Move the commonalities to evk.dtsi and only override regulator
in the board files, please
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH V2 1/2] arm64: dts: qcom: Add SD Card support for Shikra SoC
From: Konrad Dybcio @ 2026-07-01 11:37 UTC (permalink / raw)
To: Monish Chunara, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Vinod Koul, Neil Armstrong,
Wesley Cheng, Ulf Hansson, Kernel Team
Cc: linux-arm-msm, devicetree, linux-kernel, linux-phy, linux-mmc,
Nitin Rawat, Pradeep Pragallapati, Komal Bajaj
In-Reply-To: <20260630165700.1886608-2-monish.chunara@oss.qualcomm.com>
On 6/30/26 6:56 PM, Monish Chunara wrote:
> Add support for SD card on Shikra SoC and enable the required pinctrl
> configurations.
>
> Signed-off-by: Monish Chunara <monish.chunara@oss.qualcomm.com>
> ---
[...]
> + sdhc_2: mmc@4784000 {
> + compatible = "qcom,shikra-sdhci", "qcom,sdhci-msm-v5";
> + reg = <0x0 0x4784000 0x0 0x1000>;
Please pad the address part of reg to 8 hex digits with leading
zeroes, like all the other nodes
otherwise
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 9/9] arm64: dts: qcom: shikra-(cqm/cqs/iqs)-evk: Enable PCIe PHY node
From: Konrad Dybcio @ 2026-07-01 10:36 UTC (permalink / raw)
To: Sushrut Shree Trivedi, Vinod Koul, Neil Armstrong, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Helgaas,
Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Andersson, Chaitanya Chundru,
Bartosz Golaszewski, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci
In-Reply-To: <20260701-shikra-upstream-v1-9-e1a721eb8943@oss.qualcomm.com>
On 6/30/26 9:02 PM, Sushrut Shree Trivedi wrote:
> Enable the PCIe PHY for the single PCIe intance on the Shikra
> CQS, CQM and the IQS platforms.
>
> IQS platform uses a different powergrid than CQS/CQM which explain
> the different PHY supplies for IQS variant.
>
> Signed-off-by: Sushrut Shree Trivedi <sushrut.trivedi@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts | 7 +++++++
> arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts | 7 +++++++
> arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts | 7 +++++++
> 3 files changed, 21 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> index 683b5245923b..06ad32041546 100644
> --- a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
> @@ -60,6 +60,13 @@ vreg_pmu_ch1: ldo4 {
> };
> };
>
> +&pcie_phy {
> + vdda-phy-supply = <&pm4125_l13>;
> + vdda-pll-supply = <&pm4125_l9>;
> +
> + status = "okay";
> +};
I think it makes sense to push the status=okay to the evk file
(because we already describe the PCIe switch there) and only keep
the supplies here (because they differ)
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 8/9] arm64: dts: qcom: shikra-evk: Add TC9563 PCIe switch node for PCIe
From: Konrad Dybcio @ 2026-07-01 10:35 UTC (permalink / raw)
To: Sushrut Shree Trivedi, Vinod Koul, Neil Armstrong, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Helgaas,
Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Andersson, Chaitanya Chundru,
Bartosz Golaszewski, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci
In-Reply-To: <20260701-shikra-upstream-v1-8-e1a721eb8943@oss.qualcomm.com>
On 6/30/26 9:02 PM, Sushrut Shree Trivedi wrote:
> Add a node for the TC9563 PCIe switch connected to PCIe. The switch
> has three downstream ports.Two embedded Ethernet devices are present
> on one of the downstream ports. All the ports present in the
> node represent the downstream ports and embedded endpoints.
>
> Power to the TC9563 is supplied through two LDO regulators, which
> are on by default and are added as fixed regulators. TC9563 can be
> configured through I2C.
>
> Signed-off-by: Sushrut Shree Trivedi <sushrut.trivedi@oss.qualcomm.com>
> ---
[...]
> +&pcie {
> + wake-gpios = <&tlmm 119 GPIO_ACTIVE_LOW>;
This property belongs to the port node
Please also mention in the commit message the reason for the
PERST# pin remaining undescribed
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 7/9] arm64: dts: qcom: shikra: Add PCIe PHY and controller nodes
From: Konrad Dybcio @ 2026-07-01 10:34 UTC (permalink / raw)
To: Sushrut Shree Trivedi, Vinod Koul, Neil Armstrong, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Helgaas,
Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Andersson, Chaitanya Chundru,
Bartosz Golaszewski, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci
In-Reply-To: <20260701-shikra-upstream-v1-7-e1a721eb8943@oss.qualcomm.com>
On 6/30/26 9:02 PM, Sushrut Shree Trivedi wrote:
> Shikra supports single PCIe instance with 5GT/s x1 lane.
> Add PCIe controller and PHY node for this single instance.
>
> Signed-off-by: Sushrut Shree Trivedi <sushrut.trivedi@oss.qualcomm.com>
> ---
[...]
> +
> + max-link-speed = <2>;
Please add a single-line comment right above explaining that the
host supports higher speeds, but the attached PHY is only Gen2,
so we need this manual limitation
Konrad
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 4/9] PCI: qcom: Add support for Shikra
From: Bartosz Golaszewski @ 2026-07-01 9:51 UTC (permalink / raw)
To: Sushrut Shree Trivedi
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Helgaas, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Andersson,
Chaitanya Chundru, Bartosz Golaszewski, Konrad Dybcio
In-Reply-To: <20260701-shikra-upstream-v1-4-e1a721eb8943@oss.qualcomm.com>
On Tue, 30 Jun 2026 21:02:46 +0200, Sushrut Shree Trivedi
<sushrut.trivedi@oss.qualcomm.com> said:
> Add support for the single PCIe controller on Shikra platform
> which is capable of Gen2x1 operation.
>
> Signed-off-by: Sushrut Shree Trivedi <sushrut.trivedi@oss.qualcomm.com>
> ---
> drivers/pci/controller/dwc/pcie-qcom.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index d8eb52857f69..19daadee65f7 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -2309,6 +2309,7 @@ static const struct of_device_id qcom_pcie_match[] = {
> { .compatible = "qcom,pcie-sm8450-pcie1", .data = &cfg_1_9_0 },
> { .compatible = "qcom,pcie-sm8550", .data = &cfg_1_9_0 },
> { .compatible = "qcom,pcie-x1e80100", .data = &cfg_sc8280xp },
> + { .compatible = "qcom,shikra-pcie", .data = &cfg_1_9_0 },
> { }
> };
>
>
> --
> 2.43.0
>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 1/9] dt-bindings: phy: sc8280xp-qmp-pcie: Document Shikra PCIe phy
From: Bartosz Golaszewski @ 2026-07-01 9:50 UTC (permalink / raw)
To: Sushrut Shree Trivedi
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci,
Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Helgaas, Lorenzo Pieralisi,
Krzysztof Wilczyński, Manivannan Sadhasivam, Bjorn Andersson,
Chaitanya Chundru, Bartosz Golaszewski, Konrad Dybcio
In-Reply-To: <20260701-shikra-upstream-v1-1-e1a721eb8943@oss.qualcomm.com>
On Tue, 30 Jun 2026 21:02:43 +0200, Sushrut Shree Trivedi
<sushrut.trivedi@oss.qualcomm.com> said:
> Document the compatible of the Shikra PCIe phy which supports
> Gen2x1.
>
> Signed-off-by: Sushrut Shree Trivedi <sushrut.trivedi@oss.qualcomm.com>
> ---
> Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> index 108cf9dc86ea..b9b0fa26347b 100644
> --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml
> @@ -34,6 +34,7 @@ properties:
> - qcom,sdm845-qmp-pcie-phy
> - qcom,sdx55-qmp-pcie-phy
> - qcom,sdx65-qmp-gen4x2-pcie-phy
> + - qcom,shikra-qmp-gen2x1-pcie-phy
> - qcom,sm8150-qmp-gen3x1-pcie-phy
> - qcom,sm8150-qmp-gen3x2-pcie-phy
> - qcom,sm8250-qmp-gen3x1-pcie-phy
> @@ -166,6 +167,7 @@ allOf:
> - qcom,sdm845-qhp-pcie-phy
> - qcom,sdm845-qmp-pcie-phy
> - qcom,sdx55-qmp-pcie-phy
> + - qcom,shikra-qmp-gen2x1-pcie-phy
> - qcom,sm8150-qmp-gen3x1-pcie-phy
> - qcom,sm8150-qmp-gen3x2-pcie-phy
> - qcom,sm8250-qmp-gen3x1-pcie-phy
>
> --
> 2.43.0
>
>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3 3/3] MAINTAINERS: Add ASPEED USB3 PHY driver
From: Ryan Chen @ 2026-07-01 6:58 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel
Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, Ryan Chen
In-Reply-To: <20260701-upstream_usb3phy-v3-0-00e12315b6f9@aspeedtech.com>
Add maintainer entry for ASPEED USB3 PHY driver.
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 895a87b571c3..10c08f322618 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4062,6 +4062,14 @@ S: Maintained
F: Documentation/devicetree/bindings/usb/aspeed,ast2600-udc.yaml
F: drivers/usb/gadget/udc/aspeed_udc.c
+ASPEED USB3 PHY DRIVER
+M: Ryan Chen <ryan_chen@aspeedtech.com>
+L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers)
+L: linux-phy@lists.infradead.org
+S: Maintained
+F: Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml
+F: drivers/phy/aspeed/phy-aspeed-usb3.c
+
ASPEED VIDEO ENGINE DRIVER
M: Eddie James <eajames@linux.ibm.com>
L: linux-media@vger.kernel.org
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 2/3] phy: aspeed: Add AST2700 USB3.2 PHY driver
From: Ryan Chen @ 2026-07-01 6:58 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel
Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, Ryan Chen
In-Reply-To: <20260701-upstream_usb3phy-v3-0-00e12315b6f9@aspeedtech.com>
Add AST2700 USB3.2 PHY driver support.
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/aspeed/Kconfig | 15 +++
drivers/phy/aspeed/Makefile | 2 +
drivers/phy/aspeed/phy-aspeed-usb3.c | 236 +++++++++++++++++++++++++++++++++++
5 files changed, 255 insertions(+)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 19f3b7d12b7d..85fa381978f8 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -171,6 +171,7 @@ config PHY_XGENE
source "drivers/phy/allwinner/Kconfig"
source "drivers/phy/amlogic/Kconfig"
source "drivers/phy/apple/Kconfig"
+source "drivers/phy/aspeed/Kconfig"
source "drivers/phy/axiado/Kconfig"
source "drivers/phy/broadcom/Kconfig"
source "drivers/phy/cadence/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d7aa516bcc49..c6dd02003bbe 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_GENERIC_PHY) += allwinner/ \
amlogic/ \
apple/ \
+ aspeed/ \
axiado/ \
broadcom/ \
cadence/ \
diff --git a/drivers/phy/aspeed/Kconfig b/drivers/phy/aspeed/Kconfig
new file mode 100644
index 000000000000..7b5f48db2be8
--- /dev/null
+++ b/drivers/phy/aspeed/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+#
+# PHY drivers for ASPEED
+#
+
+config PHY_ASPEED_USB3
+ tristate "ASPEED USB3 PHY driver"
+ select GENERIC_PHY
+ depends on (ARCH_ASPEED || COMPILE_TEST)
+ help
+ Enable this to support the USB 3.2 PHY on the Aspeed AST2700 SoC.
+ It supports SuperSpeedPlus Gen2x1 (10 Gbps), SuperSpeed (5 Gbps),
+ High Speed (480 Mbps), Full Speed (12 Mbps) and Low Speed
+ (1.5 Mbps), and is paired with the DWC3 USB controller.
diff --git a/drivers/phy/aspeed/Makefile b/drivers/phy/aspeed/Makefile
new file mode 100644
index 000000000000..d96d9d73a009
--- /dev/null
+++ b/drivers/phy/aspeed/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PHY_ASPEED_USB3) += phy-aspeed-usb3.o
diff --git a/drivers/phy/aspeed/phy-aspeed-usb3.c b/drivers/phy/aspeed/phy-aspeed-usb3.c
new file mode 100644
index 000000000000..eff148faa14c
--- /dev/null
+++ b/drivers/phy/aspeed/phy-aspeed-usb3.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2026 Aspeed Technology Inc.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+#define PHY3S00 0x00
+#define PHY3S00_INIT_DONE BIT(15)
+#define PHY3S00_SRAM_BYPASS BIT(7)
+#define PHY3S00_SRAM_EXT_LOAD BIT(6)
+#define PHY3S04 0x04
+#define PHY3C00 0x08
+#define PHY3C04 0x0C
+#define PHY3P00 0x10
+#define PHY3P00_RX_ADAPT_AFE_EN_G1 BIT(0)
+#define PHY3P00_RX_ADAPT_AFE_EN_G2 BIT(1)
+#define PHY3P00_RX_ADAPT_DFE_EN_G1 BIT(2)
+#define PHY3P00_RX_ADAPT_DFE_EN_G2 BIT(3)
+#define PHY3P00_RX_CDR_VCO_LOWFREQ_G1 BIT(4)
+#define PHY3P00_RX_CDR_VCO_LOWFREQ_G2 BIT(5)
+#define PHY3P00_RX_EQ_AFE_GAIN_G1 GENMASK(9, 6)
+#define PHY3P00_RX_EQ_AFE_GAIN_G2 GENMASK(13, 10)
+#define PHY3P00_RX_EQ_ATT_LVL_G1 GENMASK(16, 14)
+#define PHY3P00_RX_EQ_ATT_LVL_G2 GENMASK(19, 17)
+#define PHY3P00_RX_EQ_CTLE_BOOST_G1 GENMASK(24, 20)
+#define PHY3P00_RX_EQ_CTLE_BOOST_G2 GENMASK(29, 25)
+#define PHY3P00_RX_EQ_DELTA_IQ_G1_LO GENMASK(31, 30)
+
+#define PHY3P04 0x14
+#define PHY3P04_RX_EQ_DELTA_IQ_G1_HI GENMASK(1, 0)
+#define PHY3P04_RX_EQ_DELTA_IQ_G2 GENMASK(5, 2)
+#define PHY3P04_RX_EQ_DFE_TAP1_G1 GENMASK(13, 6)
+#define PHY3P04_RX_EQ_DFE_TAP1_G2 GENMASK(21, 14)
+#define PHY3P04_RX_LOS_LFPS_EN BIT(22)
+#define PHY3P04_RX_LOS_THRESHOLD GENMASK(25, 23)
+#define PHY3P04_RX_TERM_CTRL GENMASK(28, 26)
+#define PHY3P04_TX_EQ_MAIN_G1_LO GENMASK(31, 29)
+
+#define PHY3P08 0x18
+#define PHY3P08_TX_EQ_MAIN_G1_HI GENMASK(1, 0)
+#define PHY3P08_TX_EQ_MAIN_G2 GENMASK(6, 2)
+#define PHY3P08_TX_EQ_OVRD BIT(7)
+#define PHY3P08_TX_EQ_POST_G1 GENMASK(12, 9)
+#define PHY3P08_TX_EQ_POST_G2 GENMASK(16, 13)
+#define PHY3P08_TX_EQ_PRE_G1 GENMASK(20, 17)
+#define PHY3P08_TX_EQ_PRE_G2 GENMASK(24, 21)
+#define PHY3P08_TX_IBOOST_LVL GENMASK(28, 25)
+#define PHY3P08_TX_TERM_CTRL GENMASK(31, 29)
+
+#define PHY3P0C 0x1C
+#define PHY3P0C_TX_VBOOST_EN BIT(0)
+
+#define PHY3CMD 0x40
+
+#define PHY3P_RX_EQ_CTLE_BOOST_G1_DEFAULT 0x7
+#define PHY3P_RX_EQ_CTLE_BOOST_G2_DEFAULT 0x7
+#define PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT 0x3
+#define PHY3P_RX_EQ_DELTA_IQ_G2_DEFAULT 0x5
+#define PHY3P_RX_LOS_THRESHOLD_DEFAULT 0x3
+#define PHY3P_RX_TERM_CTRL_DEFAULT 0x2
+#define PHY3P_TX_EQ_MAIN_G1_DEFAULT 0xa
+#define PHY3P_TX_EQ_MAIN_G2_DEFAULT 0x9
+#define PHY3P_TX_EQ_POST_G1_DEFAULT 0x4
+#define PHY3P_TX_EQ_POST_G2_DEFAULT 0x3
+#define PHY3P_TX_EQ_PRE_G2_DEFAULT 0x2
+#define PHY3P_TX_IBOOST_LVL_DEFAULT 0xf
+#define PHY3P_TX_TERM_CTRL_DEFAULT 0x2
+
+#define PHY3P00_DEFAULT ( \
+ PHY3P00_RX_ADAPT_AFE_EN_G1 | \
+ PHY3P00_RX_ADAPT_AFE_EN_G2 | \
+ PHY3P00_RX_ADAPT_DFE_EN_G1 | \
+ PHY3P00_RX_ADAPT_DFE_EN_G2 | \
+ FIELD_PREP(PHY3P00_RX_EQ_CTLE_BOOST_G1, PHY3P_RX_EQ_CTLE_BOOST_G1_DEFAULT) | \
+ FIELD_PREP(PHY3P00_RX_EQ_CTLE_BOOST_G2, PHY3P_RX_EQ_CTLE_BOOST_G2_DEFAULT) | \
+ FIELD_PREP(PHY3P00_RX_EQ_DELTA_IQ_G1_LO, \
+ PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT & 0x3) \
+)
+
+#define PHY3P04_DEFAULT ( \
+ FIELD_PREP(PHY3P04_RX_EQ_DELTA_IQ_G1_HI, \
+ PHY3P_RX_EQ_DELTA_IQ_G1_DEFAULT >> 2) | \
+ FIELD_PREP(PHY3P04_RX_EQ_DELTA_IQ_G2, PHY3P_RX_EQ_DELTA_IQ_G2_DEFAULT) | \
+ PHY3P04_RX_LOS_LFPS_EN | \
+ FIELD_PREP(PHY3P04_RX_LOS_THRESHOLD, PHY3P_RX_LOS_THRESHOLD_DEFAULT) | \
+ FIELD_PREP(PHY3P04_RX_TERM_CTRL, PHY3P_RX_TERM_CTRL_DEFAULT) | \
+ FIELD_PREP(PHY3P04_TX_EQ_MAIN_G1_LO, \
+ PHY3P_TX_EQ_MAIN_G1_DEFAULT & 0x7) \
+)
+
+#define PHY3P08_DEFAULT ( \
+ FIELD_PREP(PHY3P08_TX_EQ_MAIN_G1_HI, PHY3P_TX_EQ_MAIN_G1_DEFAULT >> 3) | \
+ FIELD_PREP(PHY3P08_TX_EQ_MAIN_G2, PHY3P_TX_EQ_MAIN_G2_DEFAULT) | \
+ FIELD_PREP(PHY3P08_TX_EQ_POST_G1, PHY3P_TX_EQ_POST_G1_DEFAULT) | \
+ FIELD_PREP(PHY3P08_TX_EQ_POST_G2, PHY3P_TX_EQ_POST_G2_DEFAULT) | \
+ FIELD_PREP(PHY3P08_TX_EQ_PRE_G2, PHY3P_TX_EQ_PRE_G2_DEFAULT) | \
+ FIELD_PREP(PHY3P08_TX_IBOOST_LVL, PHY3P_TX_IBOOST_LVL_DEFAULT) | \
+ FIELD_PREP(PHY3P08_TX_TERM_CTRL, PHY3P_TX_TERM_CTRL_DEFAULT) \
+)
+
+#define PHY3P0C_DEFAULT \
+ PHY3P0C_TX_VBOOST_EN
+
+struct aspeed_usb3_phy {
+ void __iomem *regs;
+ struct reset_control *rst;
+ struct device *dev;
+ struct clk *clk;
+};
+
+static int aspeed_usb3_phy_init(struct phy *phy)
+{
+ struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy);
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(aspeed_phy->clk);
+ if (ret) {
+ dev_err(aspeed_phy->dev, "Failed to enable clock %d\n", ret);
+ return ret;
+ }
+
+ ret = reset_control_deassert(aspeed_phy->rst);
+ if (ret) {
+ clk_disable_unprepare(aspeed_phy->clk);
+ return ret;
+ }
+
+ /* Wait for USB3 PHY internal SRAM initialization done */
+ ret = readl_poll_timeout(aspeed_phy->regs + PHY3S00, val,
+ val & PHY3S00_INIT_DONE,
+ USEC_PER_MSEC, 10 * USEC_PER_MSEC);
+ if (ret) {
+ dev_err(aspeed_phy->dev, "SRAM init timeout\n");
+ goto err_assert_reset;
+ }
+
+ val = readl(aspeed_phy->regs + PHY3S00);
+ val |= PHY3S00_SRAM_BYPASS;
+ writel(val, aspeed_phy->regs + PHY3S00);
+
+ /* Set protocol1_ext signals as default PHY3 settings based on SNPS documents.
+ * Including PCFGI[54]: protocol1_ext_rx_los_lfps_en for better compatibility
+ */
+ writel(PHY3P00_DEFAULT, aspeed_phy->regs + PHY3P00);
+ writel(PHY3P04_DEFAULT, aspeed_phy->regs + PHY3P04);
+ writel(PHY3P08_DEFAULT, aspeed_phy->regs + PHY3P08);
+ writel(PHY3P0C_DEFAULT, aspeed_phy->regs + PHY3P0C);
+
+ return 0;
+
+err_assert_reset:
+ reset_control_assert(aspeed_phy->rst);
+ clk_disable_unprepare(aspeed_phy->clk);
+ return ret;
+}
+
+static int aspeed_usb3_phy_exit(struct phy *phy)
+{
+ struct aspeed_usb3_phy *aspeed_phy = phy_get_drvdata(phy);
+
+ reset_control_assert(aspeed_phy->rst);
+ clk_disable_unprepare(aspeed_phy->clk);
+
+ return 0;
+}
+
+static const struct phy_ops aspeed_usb3_phy_ops = {
+ .init = aspeed_usb3_phy_init,
+ .exit = aspeed_usb3_phy_exit,
+ .owner = THIS_MODULE,
+};
+
+static int aspeed_usb3_phy_probe(struct platform_device *pdev)
+{
+ struct aspeed_usb3_phy *aspeed_phy;
+ struct phy_provider *phy_provider;
+ struct device *dev = &pdev->dev;
+ struct phy *phy;
+
+ aspeed_phy = devm_kzalloc(dev, sizeof(*aspeed_phy), GFP_KERNEL);
+ if (!aspeed_phy)
+ return -ENOMEM;
+
+ aspeed_phy->dev = dev;
+
+ aspeed_phy->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(aspeed_phy->clk))
+ return PTR_ERR(aspeed_phy->clk);
+
+ aspeed_phy->rst = devm_reset_control_get_exclusive(dev, NULL);
+ if (IS_ERR(aspeed_phy->rst))
+ return PTR_ERR(aspeed_phy->rst);
+
+ aspeed_phy->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(aspeed_phy->regs))
+ return PTR_ERR(aspeed_phy->regs);
+
+ phy = devm_phy_create(dev, NULL, &aspeed_usb3_phy_ops);
+ if (IS_ERR(phy))
+ return PTR_ERR(phy);
+
+ phy_set_drvdata(phy, aspeed_phy);
+
+ phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+ return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id aspeed_usb3_phy_match_table[] = {
+ {
+ .compatible = "aspeed,ast2700-usb3-phy",
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, aspeed_usb3_phy_match_table);
+
+static struct platform_driver aspeed_usb3_phy_driver = {
+ .probe = aspeed_usb3_phy_probe,
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = aspeed_usb3_phy_match_table,
+ },
+};
+module_platform_driver(aspeed_usb3_phy_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ASPEED USB3.2 PHY Driver");
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 1/3] dt-bindings: phy: aspeed: Document AST2700 USB3.2 PHY
From: Ryan Chen @ 2026-07-01 6:58 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel
Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, Ryan Chen, Krzysztof Kozlowski
In-Reply-To: <20260701-upstream_usb3phy-v3-0-00e12315b6f9@aspeedtech.com>
Document AST2700 USB3.2 PHY. This IP is connected between
USB3 controller and PHY module.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
.../bindings/phy/aspeed,ast2700-usb3-phy.yaml | 48 ++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml
new file mode 100644
index 000000000000..b83037aa0438
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/aspeed,ast2700-usb3-phy.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/aspeed,ast2700-usb3-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2700 USB 3.2 PHY
+
+maintainers:
+ - Ryan Chen <ryan_chen@aspeedtech.com>
+
+properties:
+ compatible:
+ const: aspeed,ast2700-usb3-phy
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ '#phy-cells':
+ const: 0
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - resets
+ - '#phy-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/aspeed,ast2700-scu.h>
+ #include <dt-bindings/reset/aspeed,ast2700-scu.h>
+
+ usb-phy@12010000 {
+ compatible = "aspeed,ast2700-usb3-phy";
+ reg = <0x12010000 0xc0>;
+ clocks = <&syscon0 SCU0_CLK_GATE_PORTAUSB2CLK>;
+ resets = <&syscon0 SCU0_RESET_PORTA_PHY3>;
+ #phy-cells = <0>;
+ };
--
2.34.1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* [PATCH v3 0/3] Add AST2700 USB3.2 PHY driver
From: Ryan Chen @ 2026-07-01 6:58 UTC (permalink / raw)
To: Vinod Koul, Neil Armstrong, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Joel Stanley, Andrew Jeffery, Philipp Zabel
Cc: linux-phy, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, Ryan Chen, Krzysztof Kozlowski
Add AST2700 USB3.2 PHY support.
- Supports Super Speed Plus Gen2x1 (10 Gbps), Super Speed (5 Gbps),
High Speed (480 Mbps), Full Speed (12Mbps), and Low Speed (1.5 Mbps).
Signed-off-by: Ryan Chen <ryan_chen@aspeedtech.com>
---
Changes in v3:
- Wire drivers/phy/aspeed/ into drivers/phy/Kconfig and
drivers/phy/Makefile so the driver is actually built.
- Fix the Makefile config symbol to CONFIG_PHY_ASPEED_USB3 to match
the Kconfig symbol.
- Expand the Kconfig help text.
- Link to v2: https://lore.kernel.org/r/20260116-upstream_usb3phy-v2-0-0b0c9f3eb6f4@aspeedtech.com
Changes in v2:
- aspeed,ast2700-usb3-phy.yaml
- Drop clocks, resets descripton.
- Kconfig
- add COMPILE_TEST, remove default n
- Link to v1: https://lore.kernel.org/r/20260114-upstream_usb3phy-v1-0-2e59590be2d7@aspeedtech.com
---
Ryan Chen (3):
dt-bindings: phy: aspeed: Document AST2700 USB3.2 PHY
phy: aspeed: Add AST2700 USB3.2 PHY driver
MAINTAINERS: Add ASPEED USB3 PHY driver
.../bindings/phy/aspeed,ast2700-usb3-phy.yaml | 48 +++++
MAINTAINERS | 8 +
drivers/phy/Kconfig | 1 +
drivers/phy/Makefile | 1 +
drivers/phy/aspeed/Kconfig | 15 ++
drivers/phy/aspeed/Makefile | 2 +
drivers/phy/aspeed/phy-aspeed-usb3.c | 236 +++++++++++++++++++++
7 files changed, 311 insertions(+)
---
base-commit: 948efecf22e49aa4bf55bb73ec79a0ddcfd38571
change-id: 20260112-upstream_usb3phy-7116f8dfe779
Best regards,
--
Ryan Chen <ryan_chen@aspeedtech.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 3/9] dt-bindings: PCI: Add bindings for endpoint gpios
From: Krzysztof Kozlowski @ 2026-07-01 6:27 UTC (permalink / raw)
To: Sushrut Shree Trivedi, Vinod Koul, Neil Armstrong, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Helgaas,
Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Andersson, Chaitanya Chundru,
Bartosz Golaszewski, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci
In-Reply-To: <20260701-shikra-upstream-v1-3-e1a721eb8943@oss.qualcomm.com>
On 30/06/2026 21:02, Sushrut Shree Trivedi wrote:
> toshiba,tx-amplitude-microvolt:
> description:
> Change Tx Margin setting for low power consumption.
> @@ -104,7 +120,7 @@ examples:
> #address-cells = <3>;
> #size-cells = <2>;
>
> - pcie@0 {
> + tc9563: pcie@0 {
And you change indentation because?
Just like the other patch, this wasn't tested, right?
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 2/9] dt-bindings: PCI: qcom: Document the Shikra PCIe Controller
From: Krzysztof Kozlowski @ 2026-07-01 6:26 UTC (permalink / raw)
To: Sushrut Shree Trivedi, Vinod Koul, Neil Armstrong, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Bjorn Helgaas,
Lorenzo Pieralisi, Krzysztof Wilczyński,
Manivannan Sadhasivam, Bjorn Andersson, Chaitanya Chundru,
Bartosz Golaszewski, Konrad Dybcio
Cc: linux-arm-msm, linux-phy, devicetree, linux-kernel, linux-pci
In-Reply-To: <20260701-shikra-upstream-v1-2-e1a721eb8943@oss.qualcomm.com>
On 30/06/2026 21:02, Sushrut Shree Trivedi wrote:
> Add a dedicated schema for the PCIe controller found on the Shikra
> platform.
>
> Signed-off-by: Sushrut Shree Trivedi <sushrut.trivedi@oss.qualcomm.com>
> ---
> .../devicetree/bindings/pci/qcom,shikra-pcie.yaml | 211 +++++++++++++++++++++
> 1 file changed, 211 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/pci/qcom,shikra-pcie.yaml b/Documentation/devicetree/bindings/pci/qcom,shikra-pcie.yaml
> new file mode 100644
> index 000000000000..f9d1dba9dd2e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/qcom,shikra-pcie.yaml
> @@ -0,0 +1,211 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/qcom,shikra-pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Shikra PCI Express Root Complex
> +
> +maintainers:
> + - Bjorn Andersson <andersson@kernel.org>
> + - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> +
> +description:
> + Qualcomm Shikra SoC (and compatible) PCIe root complex controller is based on
> + the Synopsys DesignWare PCIe IP.
> +
> +properties:
> + compatible:
> + const: qcom,shikra-pcie
> +
> + reg:
> + minItems: 5
> + maxItems: 6
Same comments as other recent Qualcomm bindings. Don't invent stuff,
take what was reviewed from the list so we won't have to repeat.
...
> + power-domains = <&gcc GCC_PCIE_GDSC>;
> +
> + max-link-speed = <2>;
> +
> + operating-points-v2 = <&pcie_opp_table>;
> +
> + status = "disabled";
Drop, you never tested the binding in such case.
> +
> + pcie_opp_table: opp-table {
> + compatible = "operating-points-v2";
Broken indent.
> +
> + /* GEN 1 x1 */
> + opp-2500000 {
> + opp-hz = /bits/ 64 <2500000>;
> + required-opps = <&rpmpd_opp_nom>;
> + opp-peak-kBps = <250000 1>;
> + opp-level = <1>;
> + };
> +
> + /* GEN 2 x1 */
> + opp-5000000 {
> + opp-hz = /bits/ 64 <5000000>;
> + required-opps = <&rpmpd_opp_nom>;
> + opp-peak-kBps = <500000 1>;
> + opp-level = <2>;
> + };
> + };
> + };
> + };
>
Best regards,
Krzysztof
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH v3] phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
From: sashiko-bot @ 2026-07-01 2:40 UTC (permalink / raw)
To: RD Babiera; +Cc: vkoul, neil.armstrong, olteanv, linux-phy
In-Reply-To: <20260701022827.785674-2-rdbabiera@google.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] The teardown sequence in `google_usb3_phy_exit` violates LIFO ordering, causing a hardware resource sequence mismatch.
- [High] Unconditional TCA programming in `google_usb3_phy_power_on` misconfigures the PHY for a disconnected port.
Pre-existing issues:
- [High] Time-of-Check to Time-of-Use (TOCTOU) race condition in `google_usb_set_orientation` leads to unclocked MMIO accesses.
--
commit cefbad787f1b94bc99ee246cf94e5430283fce0c
Author: RD Babiera <rdbabiera@google.com>
phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
This patch adds USB3 PHY support for the Google Tensor G5 USB PHY driver.
It implements the USB3 phy_ops for phy_init, phy_exit, and phy_power_on,
and adds a combo_phy_state enum to track the PHY bringup state across
API calls.
diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c
--- a/drivers/phy/phy-google-usb.c
+++ b/drivers/phy/phy-google-usb.c
[ ... ]
> @@ -92,6 +261,9 @@ static int google_usb_set_orientation(struct typec_switch_dev *sw,
>
> set_vbus_valid(gphy);
[Severity: High]
This is a pre-existing issue, but does checking pm_runtime_suspended()
earlier in this function without holding a PM reference introduce a race
condition here?
If the PM core suspends the device immediately after that check returns
false, the function will proceed to acquire the mutex and write to MMIO
registers via set_vbus_valid() and program_tca_locked() after the power
domain and clocks have been disabled.
Could this lead to a synchronous external abort when accessing the unclocked
registers? Should this use pm_runtime_get_if_active() instead?
> + if (gphy->phy_state == COMBO_PHY_TCA_READY && orientation != TYPEC_ORIENTATION_NONE)
> + return program_tca_locked(gphy);
> +
> return 0;
> }
[ ... ]
> +static int google_usb3_phy_exit(struct phy *_phy)
> +{
> + struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
> + struct google_usb_phy *gphy = inst->parent;
> +
> + dev_dbg(gphy->dev, "exiting usb3 phy\n");
> +
> + guard(mutex)(&gphy->phy_mutex);
> +
> + set_pmgt_ref_clk_req_n(gphy, false);
> + reset_control_bulk_assert(inst->num_rsts, inst->rsts);
> + clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
[Severity: High]
Is the manual teardown sequence here in the correct order?
In google_usb3_phy_init(), resources are acquired in this order:
1) set_pmgt_ref_clk_req_n(true)
2) clock enable
3) reset deassert
The __free blocks in the init function correctly establish the error cleanup
sequence in reverse order (LIFO). However, here the upstream reference clock
request is disabled before placing the hardware block into reset and
disabling clocks.
Could disabling the clock request before asserting reset freeze the IP in an
invalid state and prevent subsequent wakeups?
> +
> + gphy->phy_state = COMBO_PHY_IDLE;
> +
> + return 0;
> +}
> +
> +static int google_usb3_phy_power_on(struct phy *_phy)
> +{
> + struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
> + struct google_usb_phy *gphy = inst->parent;
> + int ret;
> +
> + dev_dbg(gphy->dev, "power on usb3 phy\n");
> +
> + guard(mutex)(&gphy->phy_mutex);
> +
> + if (gphy->phy_state != COMBO_PHY_TCA_READY) {
> + /* Wait for PoR -> NC transitions*/
> + ret = wait_tca_xa_ack(gphy);
> + if (ret) {
> + dev_err(gphy->dev, "PoR->NC transition timeout");
> + return ret;
> + }
> + gphy->phy_state = COMBO_PHY_TCA_READY;
> + }
> +
> + return program_tca_locked(gphy);
[Severity: High]
Should this check if the Type-C port is actually connected before calling
program_tca_locked()?
If the port is disconnected (gphy->orientation == TYPEC_ORIENTATION_NONE),
program_tca_locked() falls through its else branch, configuring the registers
for TYPEC_ORIENTATION_NORMAL and setting TCA_TCPC_VALID.
Since the Type-C switch callback google_usb_set_orientation() correctly skips
TCA programming if the orientation is NONE, should a similar check be present
here to prevent enabling the SuperSpeed data path for a phantom connection?
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260701022827.785674-2-rdbabiera@google.com?part=1
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* [PATCH v3] phy: Add USB3 PHY support to Google Tensor SoC USB PHY driver
From: RD Babiera @ 2026-07-01 2:28 UTC (permalink / raw)
To: vkoul, peter.griffin, andre.draszik, tudor.ambarus, p.zabel,
neil.armstrong
Cc: badhri, linux-arm-kernel, linux-samsung-soc, linux-phy,
linux-kernel, RD Babiera
Add USB3 PHY support for the Google Tensor G5 USB PHY driver.
This patch adds functionality for the usb3_tca register, usb3 clock,
and usb3 reset as defined in google,lga-usb-phy.yaml. Kconfig now lists
USB SuperSpeed support.
Refactor the probe sequence to initialize the USB2 and USB3 PHYs, and then
initialize clocks and resets for both PHYs afterwards.
Refactor set_vbus_valid to reduce duplicated code.
Implement USB3 phy_ops for phy_init, phy_exit, and phy_power_on.
combo_phy_state enum is added to track PHY bringup state across
PHY API calls.
Signed-off-by: RD Babiera <rdbabiera@google.com>
---
Changes since v1:
* Removed mix of goto-based and scope-based cleanup from usb3 phy_init
* Removed unused usb3_core resource from probe
* Added combo_phy_state enum to interally track ComboPHY bringup state
to allow google_usb_set_orientation() to change TCA orientation.
* Modify Kconfig documentation to reflect SuperSpeed support
Changes since v2:
* google_usb3_phy_init now sets USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N
to false if phy_init fails elsewhere.
* google_usb3_phy_init errors are now handled via DEFINE_FREE structures.
This affects set_pmgt_ref_clk_req_n, clk_bulk_prepare_enable, and
reset_control_bulk_deassert.
* google_usb2_phy_init also handles undoing clk_bulk_prepare_enable via
DEFINE_FREE structure.
* google_usb3_phy_power_on allows program_tca_locked in the
COMBO_PHY_TCA_READY state. Waiting for PoR=>NC is only performed once.
* Note: there are checkpatch errors for the DEFINE_FREE macros resulting
in "ERROR: trailing statements should be on next line". Other cases of
DEFINE_FREE where the line limit would otherwise exceed 100 columns
have the indentation done the same way.
---
drivers/phy/Kconfig | 2 +-
drivers/phy/phy-google-usb.c | 404 +++++++++++++++++++++++++++++++----
2 files changed, 368 insertions(+), 38 deletions(-)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 19f3b7d12b7d..d2d401129af7 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -100,7 +100,7 @@ config PHY_GOOGLE_USB
the G5 generation (Laguna). This driver provides the PHY interfaces
to interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY,
both of which are integrated with the DWC3 USB DRD controller.
- This driver currently supports USB high-speed.
+ This driver currently supports USB high-speed and SuperSpeed.
config USB_LGM_PHY
tristate "INTEL Lightning Mountain USB PHY Driver"
diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c
index ab20bc20f19e..610e3b6f465f 100644
--- a/drivers/phy/phy-google-usb.c
+++ b/drivers/phy/phy-google-usb.c
@@ -20,6 +20,7 @@
#include <linux/reset.h>
#include <linux/usb/typec_mux.h>
+/* USB_CFG_CSR */
#define USBCS_USB2PHY_CFG19_OFFSET 0x0
#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8)
@@ -28,11 +29,41 @@
#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13)
#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19)
+/* USBDP_TOP */
#define USBCS_PHY_CFG1_OFFSET 0x28
+#define USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN BIT(1)
+#define USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE GENMASK(11, 10)
+#define SRAM_BYPASS_MODE_BYPASS_FIRMWARE BIT(0)
+#define SRAM_BYPASS_MODE_BYPASS_CONTEXT BIT(1)
#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17)
+#define USBDP_TOP_CFG_REG_OFFSET 0x44
+#define USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N BIT(0)
+
+#define PHY_POWER_CONFIG_REG1_OFFSET 0x48
+#define PHY_POWER_CONFIG_REG1_PG_MODE_EN BIT(1)
+#define PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG GENMASK(31, 14)
+#define UPCS_PIPE_CONFIG_ISO_CPM BIT(5)
+#define UPCS_PIPE_CONFIG_PG_MODE_STATIC BIT(6)
+#define UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT BIT(9)
+
+/* USB3_TCA */
+#define TCA_INTR_STS_OFFSET 0x8
+#define TCA_INTR_STS_XA_ACT_EVT BIT(0)
+#define TCA_TCPC_OFFSET 0x14
+#define TCA_TCPC_MUX_CONTROL GENMASK(2, 0)
+#define TCA_TCPC_MUX_CONTROL_USB_ONLY 0x1
+#define TCA_TCPC_CONNECTOR_ORIENTATION BIT(3)
+#define TCA_TCPC_VALID BIT(4)
+#define TCA_PSTATE_0_OFFSET 0x50
+#define TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS BIT(8)
+
+#define GPHY_TCA_DELAY_US 10
+#define GPHY_TCA_TIMEOUT_US 2500000
+
enum google_usb_phy_id {
GOOGLE_USB2_PHY,
+ GOOGLE_USB3_PHY,
GOOGLE_USB_PHY_NUM,
};
@@ -46,34 +77,172 @@ struct google_usb_phy_instance {
struct reset_control_bulk_data *rsts;
};
+struct google_usb_phy_config {
+ const char * const *clk_names;
+ unsigned int num_clks;
+ const char * const *rst_names;
+ unsigned int num_rsts;
+};
+
+static const char * const u2phy_clk_names[] = {
+ "usb2",
+ "usb2_apb",
+};
+static const char * const u3phy_clk_names[] = {
+ "usb3"
+};
+static const char * const u2phy_rst_names[] = {
+ "usb2",
+ "usb2_apb",
+};
+static const char * const u3phy_rst_names[] = {
+ "usb3"
+};
+
+static const struct google_usb_phy_config phy_configs[GOOGLE_USB_PHY_NUM] = {
+ [GOOGLE_USB2_PHY] = {
+ .clk_names = u2phy_clk_names,
+ .num_clks = ARRAY_SIZE(u2phy_clk_names),
+ .rst_names = u2phy_rst_names,
+ .num_rsts = ARRAY_SIZE(u2phy_rst_names),
+ },
+ [GOOGLE_USB3_PHY] = {
+ .clk_names = u3phy_clk_names,
+ .num_clks = ARRAY_SIZE(u3phy_clk_names),
+ .rst_names = u3phy_rst_names,
+ .num_rsts = ARRAY_SIZE(u3phy_rst_names),
+ },
+};
+
+static inline void google_usb_phy_clk_disable(struct google_usb_phy_instance *inst)
+{
+ clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+}
+DEFINE_FREE(inst_clk_disable, struct google_usb_phy_instance *,
+ if (_T) google_usb_phy_clk_disable(_T))
+
+static inline void google_usb_phy_rst_disable(struct google_usb_phy_instance *inst)
+{
+ reset_control_bulk_assert(inst->num_rsts, inst->rsts);
+}
+DEFINE_FREE(inst_rst_disable, struct google_usb_phy_instance *,
+ if (_T) google_usb_phy_rst_disable(_T))
+
+/*
+ * combo_phy_state
+ * COMBO_PHY_IDLE: The ComboPHY has been torn down and USB3 has not completed
+ * bringup
+ * COMBO_PHY_INIT_DONE: The ComboPHY bringup sequence is complete.
+ * COMBO_PHY_TCA_READY: The PoR => NC transition is complete, and the TCA can be
+ * moved into USB.
+ */
+enum combo_phy_state {
+ COMBO_PHY_IDLE,
+ COMBO_PHY_INIT_DONE,
+ COMBO_PHY_TCA_READY,
+};
+
struct google_usb_phy {
struct device *dev;
struct regmap *usb_cfg_regmap;
unsigned int usb2_cfg_offset;
void __iomem *usbdp_top_base;
+ void __iomem *usb3_tca_base;
struct google_usb_phy_instance *insts;
/*
* Protect phy registers from concurrent access, specifically via
- * google_usb_set_orientation callback.
+ * google_usb_set_orientation callback. phy_mutex also protects
+ * concurrent access to phy_state.
*/
struct mutex phy_mutex;
struct typec_switch_dev *sw;
enum typec_orientation orientation;
+ enum combo_phy_state phy_state;
};
static void set_vbus_valid(struct google_usb_phy *gphy)
{
u32 reg;
- if (gphy->orientation == TYPEC_ORIENTATION_NONE) {
- reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ if (gphy->orientation == TYPEC_ORIENTATION_NONE)
reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID;
- writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
- } else {
- reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ else
reg |= USBCS_PHY_CFG1_SYS_VBUSVALID;
- writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
- }
+ writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+}
+
+static void set_sram_bypass(struct google_usb_phy *gphy, u32 bypass)
+{
+ u32 reg;
+
+ reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ reg &= ~USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE;
+ reg |= FIELD_PREP(USBCS_PHY_CFG1_PHY0_SRAM_BYPASS_MODE, bypass);
+ writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+}
+
+static void set_pmgt_ref_clk_req_n(struct google_usb_phy *gphy, bool resume)
+{
+ u32 reg;
+
+ reg = readl(gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
+ if (resume)
+ reg |= USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
+ else
+ reg &= ~USBDP_TOP_CFG_REG_PMGT_REF_CLK_REQ_N;
+ writel(reg, gphy->usbdp_top_base + USBDP_TOP_CFG_REG_OFFSET);
+}
+
+static inline void disable_pmgt_ref_clk_req_n(struct google_usb_phy *gphy)
+{
+ set_pmgt_ref_clk_req_n(gphy, false);
+}
+DEFINE_FREE(pmgt_ref_clk_req_n, struct google_usb_phy *, if (_T) disable_pmgt_ref_clk_req_n(_T))
+
+static int wait_tca_xa_ack(struct google_usb_phy *gphy)
+{
+ int ret;
+ u32 reg;
+
+ ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET,
+ reg, !!(reg & TCA_INTR_STS_XA_ACT_EVT),
+ GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
+ if (ret)
+ dev_err(gphy->dev, "tca xa_ack timeout, ret=%d", ret);
+
+ return ret;
+}
+
+static int program_tca_locked(struct google_usb_phy *gphy)
+ __must_hold(&gphy->phy_mutex)
+{
+ int ret;
+ u32 reg;
+
+ reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+ writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+
+ reg = readl(gphy->usb3_tca_base + TCA_TCPC_OFFSET);
+ reg &= ~TCA_TCPC_MUX_CONTROL;
+ reg |= FIELD_PREP(TCA_TCPC_MUX_CONTROL, TCA_TCPC_MUX_CONTROL_USB_ONLY);
+ if (gphy->orientation == TYPEC_ORIENTATION_REVERSE)
+ reg |= TCA_TCPC_CONNECTOR_ORIENTATION;
+ else
+ reg &= ~TCA_TCPC_CONNECTOR_ORIENTATION;
+ reg |= TCA_TCPC_VALID;
+ writel(reg, gphy->usb3_tca_base + TCA_TCPC_OFFSET);
+
+ ret = wait_tca_xa_ack(gphy);
+ dev_dbg(gphy->dev, "TCA switch %s, mux %lu, orientation %s",
+ ret ? "failed" : "success",
+ FIELD_GET(TCA_TCPC_MUX_CONTROL, reg),
+ FIELD_GET(TCA_TCPC_CONNECTOR_ORIENTATION, reg) ? "reverse" : "normal");
+
+ reg = readl(gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+ writel(reg, gphy->usb3_tca_base + TCA_INTR_STS_OFFSET);
+
+ return ret;
}
static int google_usb_set_orientation(struct typec_switch_dev *sw,
@@ -92,6 +261,9 @@ static int google_usb_set_orientation(struct typec_switch_dev *sw,
set_vbus_valid(gphy);
+ if (gphy->phy_state == COMBO_PHY_TCA_READY && orientation != TYPEC_ORIENTATION_NONE)
+ return program_tca_locked(gphy);
+
return 0;
}
@@ -122,17 +294,18 @@ static int google_usb2_phy_init(struct phy *_phy)
ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
if (ret)
return ret;
+ struct google_usb_phy_instance *clk_dev __free(inst_clk_disable) = inst;
ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
- if (ret) {
- clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+ if (ret)
return ret;
- }
regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, ®);
reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE;
regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg);
+ retain_and_null_ptr(clk_dev);
+
return 0;
}
@@ -161,6 +334,116 @@ static const struct phy_ops google_usb2_phy_ops = {
.exit = google_usb2_phy_exit,
};
+static int google_usb3_phy_init(struct phy *_phy)
+{
+ struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+ struct google_usb_phy *gphy = inst->parent;
+ int ret = 0;
+ u32 reg;
+
+ dev_dbg(gphy->dev, "initializing usb3 phy\n");
+
+ guard(mutex)(&gphy->phy_mutex);
+
+ if (gphy->phy_state != COMBO_PHY_IDLE) {
+ dev_warn(gphy->dev, "usb3 phy init called when combo phy state is not idle");
+ return 0;
+ }
+
+ reg = readl(gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
+ reg |= PHY_POWER_CONFIG_REG1_PG_MODE_EN;
+ reg &= ~PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG;
+ reg |= FIELD_PREP(PHY_POWER_CONFIG_REG1_UPCS_PIPE_CONFIG,
+ (UPCS_PIPE_CONFIG_ISO_CPM |
+ UPCS_PIPE_CONFIG_PG_MODE_STATIC |
+ UPCS_PIPE_CONFIG_LANE_RESET_NO_PG_EXIT));
+ writel(reg, gphy->usbdp_top_base + PHY_POWER_CONFIG_REG1_OFFSET);
+
+ set_vbus_valid(gphy);
+
+ reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+ reg |= USBCS_PHY_CFG1_PHY0_MPLLA_SSC_EN;
+ writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET);
+
+ set_sram_bypass(gphy, SRAM_BYPASS_MODE_BYPASS_FIRMWARE |
+ SRAM_BYPASS_MODE_BYPASS_CONTEXT);
+ set_pmgt_ref_clk_req_n(gphy, true);
+ struct google_usb_phy *pmgt_ref_clk_req_dev __free(pmgt_ref_clk_req_n) = gphy;
+
+ ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks);
+ if (ret)
+ return ret;
+ struct google_usb_phy_instance *clk_dev __free(inst_clk_disable) = inst;
+
+ ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts);
+ if (ret)
+ return ret;
+ struct google_usb_phy_instance *rst_dev __free(inst_rst_disable) = inst;
+
+ ret = readl_poll_timeout(gphy->usb3_tca_base + TCA_PSTATE_0_OFFSET,
+ reg, !(reg & TCA_PSTATE_0_UPCS_LANE0_PHYSTATUS),
+ GPHY_TCA_DELAY_US, GPHY_TCA_TIMEOUT_US);
+ if (ret) {
+ dev_err(gphy->dev, "wait for lane0 phystatus timed out");
+ return ret;
+ }
+
+ gphy->phy_state = COMBO_PHY_INIT_DONE;
+
+ retain_and_null_ptr(rst_dev);
+ retain_and_null_ptr(clk_dev);
+ retain_and_null_ptr(pmgt_ref_clk_req_dev);
+
+ return 0;
+}
+
+static int google_usb3_phy_exit(struct phy *_phy)
+{
+ struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+ struct google_usb_phy *gphy = inst->parent;
+
+ dev_dbg(gphy->dev, "exiting usb3 phy\n");
+
+ guard(mutex)(&gphy->phy_mutex);
+
+ set_pmgt_ref_clk_req_n(gphy, false);
+ reset_control_bulk_assert(inst->num_rsts, inst->rsts);
+ clk_bulk_disable_unprepare(inst->num_clks, inst->clks);
+
+ gphy->phy_state = COMBO_PHY_IDLE;
+
+ return 0;
+}
+
+static int google_usb3_phy_power_on(struct phy *_phy)
+{
+ struct google_usb_phy_instance *inst = phy_get_drvdata(_phy);
+ struct google_usb_phy *gphy = inst->parent;
+ int ret;
+
+ dev_dbg(gphy->dev, "power on usb3 phy\n");
+
+ guard(mutex)(&gphy->phy_mutex);
+
+ if (gphy->phy_state != COMBO_PHY_TCA_READY) {
+ /* Wait for PoR -> NC transitions*/
+ ret = wait_tca_xa_ack(gphy);
+ if (ret) {
+ dev_err(gphy->dev, "PoR->NC transition timeout");
+ return ret;
+ }
+ gphy->phy_state = COMBO_PHY_TCA_READY;
+ }
+
+ return program_tca_locked(gphy);
+}
+
+static const struct phy_ops google_usb3_phy_ops = {
+ .init = google_usb3_phy_init,
+ .exit = google_usb3_phy_exit,
+ .power_on = google_usb3_phy_power_on,
+};
+
static struct phy *google_usb_phy_xlate(struct device *dev,
const struct of_phandle_args *args)
{
@@ -173,14 +456,61 @@ static struct phy *google_usb_phy_xlate(struct device *dev,
return gphy->insts[args->args[0]].phy;
}
+static int google_usb_phy_parse_clocks(struct google_usb_phy *gphy)
+{
+ struct device *dev = gphy->dev;
+ int id, i, ret;
+
+ for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
+ const struct google_usb_phy_config *cfg = &phy_configs[id];
+ struct google_usb_phy_instance *inst = &gphy->insts[id];
+
+ inst->num_clks = cfg->num_clks;
+ inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL);
+ if (!inst->clks)
+ return -ENOMEM;
+
+ for (i = 0; i < inst->num_clks; i++)
+ inst->clks[i].id = cfg->clk_names[i];
+
+ ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get phy%d clks\n", id);
+ }
+
+ return 0;
+}
+
+static int google_usb_phy_parse_resets(struct google_usb_phy *gphy)
+{
+ struct device *dev = gphy->dev;
+ int id, i, ret;
+
+ for (id = 0; id < GOOGLE_USB_PHY_NUM; id++) {
+ const struct google_usb_phy_config *cfg = &phy_configs[id];
+ struct google_usb_phy_instance *inst = &gphy->insts[id];
+
+ inst->num_rsts = cfg->num_rsts;
+ inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL);
+ if (!inst->rsts)
+ return -ENOMEM;
+
+ for (i = 0; i < inst->num_rsts; i++)
+ inst->rsts[i].id = cfg->rst_names[i];
+ ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get phy%d resets\n", id);
+ }
+
+ return 0;
+}
+
static int google_usb_phy_probe(struct platform_device *pdev)
{
struct typec_switch_desc sw_desc = { };
- struct google_usb_phy_instance *inst;
struct phy_provider *phy_provider;
struct device *dev = &pdev->dev;
struct google_usb_phy *gphy;
- struct phy *phy;
u32 args[1];
int ret;
@@ -212,39 +542,39 @@ static int google_usb_phy_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(gphy->usbdp_top_base),
"invalid usbdp top\n");
+ gphy->usb3_tca_base = devm_platform_ioremap_resource_byname(pdev,
+ "usb3_tca");
+ if (IS_ERR(gphy->usb3_tca_base))
+ return dev_err_probe(dev, PTR_ERR(gphy->usb3_tca_base),
+ "invalid usb3 tca\n");
+
gphy->insts = devm_kcalloc(dev, GOOGLE_USB_PHY_NUM, sizeof(*gphy->insts), GFP_KERNEL);
if (!gphy->insts)
return -ENOMEM;
- inst = &gphy->insts[GOOGLE_USB2_PHY];
- inst->parent = gphy;
- inst->index = GOOGLE_USB2_PHY;
- phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
- if (IS_ERR(phy))
- return dev_err_probe(dev, PTR_ERR(phy),
+ gphy->insts[GOOGLE_USB2_PHY].phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops);
+ gphy->insts[GOOGLE_USB2_PHY].index = GOOGLE_USB2_PHY;
+ gphy->insts[GOOGLE_USB2_PHY].parent = gphy;
+ if (IS_ERR(gphy->insts[GOOGLE_USB2_PHY].phy))
+ return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB2_PHY].phy),
"failed to create usb2 phy instance\n");
- inst->phy = phy;
- phy_set_drvdata(phy, inst);
+ phy_set_drvdata(gphy->insts[GOOGLE_USB2_PHY].phy, &gphy->insts[GOOGLE_USB2_PHY]);
- inst->num_clks = 2;
- inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL);
- if (!inst->clks)
- return -ENOMEM;
- inst->clks[0].id = "usb2";
- inst->clks[1].id = "usb2_apb";
- ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks);
+ gphy->insts[GOOGLE_USB3_PHY].phy = devm_phy_create(dev, NULL, &google_usb3_phy_ops);
+ gphy->insts[GOOGLE_USB3_PHY].index = GOOGLE_USB3_PHY;
+ gphy->insts[GOOGLE_USB3_PHY].parent = gphy;
+ if (IS_ERR(gphy->insts[GOOGLE_USB3_PHY].phy))
+ return dev_err_probe(dev, PTR_ERR(gphy->insts[GOOGLE_USB3_PHY].phy),
+ "failed to create usb3 phy instance\n");
+ phy_set_drvdata(gphy->insts[GOOGLE_USB3_PHY].phy, &gphy->insts[GOOGLE_USB3_PHY]);
+
+ ret = google_usb_phy_parse_clocks(gphy);
if (ret)
- return dev_err_probe(dev, ret, "failed to get u2 phy clks\n");
+ return ret;
- inst->num_rsts = 2;
- inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL);
- if (!inst->rsts)
- return -ENOMEM;
- inst->rsts[0].id = "usb2";
- inst->rsts[1].id = "usb2_apb";
- ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts);
+ ret = google_usb_phy_parse_resets(gphy);
if (ret)
- return dev_err_probe(dev, ret, "failed to get u2 phy resets\n");
+ return ret;
phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate);
if (IS_ERR(phy_provider))
base-commit: 2ace2e949979b82f82f12dd76d7c5a6145246ca3
--
2.55.0.rc0.799.gd6f94ed593-goog
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply related
* Re: [PATCH 00/13] treewide: replace linux/gpio.h
From: patchwork-bot+netdevbpf @ 2026-07-01 0:00 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-gpio, arnd, brgl, andrew, sebastian.hesselbarth,
gregory.clement, Frank.Li, robert.jarzmik, krzk, gerg, tsbogend,
hauke, zajec5, ysato, glaubitz, linusw, dmitry.torokhov, kuba,
pabeni, linux, linux-kernel, linux-arm-kernel, linux-samsung-soc,
patches, linux-m68k, linux-mips, linux-sh, linux-input,
linux-media, netdev, linux-sunxi, linux-phy, linux-rockchip,
linux-sound
In-Reply-To: <20260629132633.1300009-1-arnd@kernel.org>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 29 Jun 2026 15:26:20 +0200 you wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> The linux/gpio.h header used to be the global definition for the gpio
> interfaces, with 1100 users back in linux-3.17. In linux-7.2, only about
> 130 of those remain, so this series cleans out the rest.
>
> In each subsystem, we can replace the header either with
> linux/gpio/consumer.h for users of the modern gpio descriptor interface,
> or linux/gpio/legacy.h for the few remaining users of the old number
> based interface.
>
> [...]
Here is the summary with links:
- [01/13] ARM: replace linux/gpio.h inclusions
(no matching commit)
- [02/13] m68k/coldfire: replace linux/gpio.h inclusions
(no matching commit)
- [03/13] mips: replace linux/gpio.h inclusions
(no matching commit)
- [04/13] sh: replace linux/gpio.h inclusions
(no matching commit)
- [05/13] mfd: replace linux/gpio.h inclusions
(no matching commit)
- [06/13,net-next] net: replace linux/gpio.h inclusions
https://git.kernel.org/netdev/net-next/c/a53d1872f2be
- [07/13] ASoC: replace linux/gpio.h inclusions
(no matching commit)
- [08/13] pcmcia: replace linux/gpio.h inclusions
(no matching commit)
- [09/13] phy: replace linux/gpio.h inclusions
(no matching commit)
- [10/13] media: replace linux/gpio.h inclusions
(no matching commit)
- [11/13] Input: matrix_keyboard - replace linux/gpio.h inclusion
(no matching commit)
- [12/13] gpib: gpio: replace linux/gpio.h inclusion
(no matching commit)
- [13/13] gpiolib: remove linux/gpio.h
(no matching commit)
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 13/13] gpiolib: remove linux/gpio.h
From: Philippe Mathieu-Daudé @ 2026-06-30 22:09 UTC (permalink / raw)
To: Arnd Bergmann, linux-gpio
Cc: Arnd Bergmann, Bartosz Golaszewski, Andrew Lunn,
Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
linux-mips, linux-sh, linux-input, linux-media, netdev,
linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <20260629132633.1300009-14-arnd@kernel.org>
On 29/6/26 15:26, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> After all other drivers have converted to linux/gpio/consumer.h
> or linux/gpio/legacy.h, remove the final leftover bits here.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> MAINTAINERS | 1 -
> drivers/gpio/TODO | 4 +---
> drivers/gpio/gpiolib-cdev.c | 2 +-
> drivers/gpio/gpiolib-legacy.c | 3 +--
> drivers/gpio/gpiolib.c | 2 +-
> include/linux/gpio.h | 22 ----------------------
> 6 files changed, 4 insertions(+), 30 deletions(-)
> delete mode 100644 include/linux/gpio.h
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 04/13] sh: replace linux/gpio.h inclusions
From: Philippe Mathieu-Daudé @ 2026-06-30 22:08 UTC (permalink / raw)
To: Arnd Bergmann, linux-gpio
Cc: Arnd Bergmann, Bartosz Golaszewski, Andrew Lunn,
Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
linux-mips, linux-sh, linux-input, linux-media, netdev,
linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <20260629132633.1300009-5-arnd@kernel.org>
On 29/6/26 15:26, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> linux/gpio.h should no longer be used, convert these instead to
> linux/gpio/legacy.h for the sh boards using the legacy interfaces,
> or remove it where it is not needed at all.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/sh/boards/board-magicpanelr2.c | 2 +-
> arch/sh/boards/board-sh7757lcr.c | 2 +-
> arch/sh/boards/board-urquell.c | 2 +-
> arch/sh/boards/mach-ap325rxa/setup.c | 2 +-
> arch/sh/boards/mach-ecovec24/setup.c | 2 +-
> arch/sh/boards/mach-highlander/pinmux-r7785rp.c | 2 +-
> arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 2 +-
> arch/sh/boards/mach-kfr2r09/setup.c | 2 +-
> arch/sh/boards/mach-migor/lcd_qvga.c | 2 +-
> arch/sh/boards/mach-migor/setup.c | 2 +-
> arch/sh/boards/mach-rsk/devices-rsk7203.c | 2 +-
> arch/sh/boards/mach-rsk/devices-rsk7269.c | 1 -
> arch/sh/boards/mach-se/7724/setup.c | 2 +-
> arch/sh/include/mach-common/mach/magicpanelr2.h | 2 --
> arch/sh/kernel/cpu/sh4a/setup-shx3.c | 2 +-
> 15 files changed, 13 insertions(+), 16 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
^ permalink raw reply
* Re: [PATCH 03/13] mips: replace linux/gpio.h inclusions
From: Philippe Mathieu-Daudé @ 2026-06-30 22:08 UTC (permalink / raw)
To: Arnd Bergmann, linux-gpio
Cc: Arnd Bergmann, Bartosz Golaszewski, Andrew Lunn,
Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
linux-mips, linux-sh, linux-input, linux-media, netdev,
linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <20260629132633.1300009-4-arnd@kernel.org>
On 29/6/26 15:26, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> linux/gpio.h should no longer be used, convert these instead to
> either linux/gpio/consumer.h or linux/gpio/legacy.h as needed.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/mips/alchemy/board-xxs1500.c | 2 +-
> arch/mips/alchemy/devboards/db1000.c | 2 +-
> arch/mips/alchemy/devboards/db1200.c | 2 +-
> arch/mips/alchemy/devboards/db1550.c | 2 +-
> arch/mips/bcm47xx/workarounds.c | 2 +-
> arch/mips/bcm63xx/boards/board_bcm963xx.c | 1 +
> arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 2 +-
> arch/mips/txx9/rbtx4927/setup.c | 2 +-
> 8 files changed, 8 insertions(+), 7 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
--
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