From: Luca Leonardo Scorcia <l.scorcia@gmail.com>
To: linux-mediatek@lists.infradead.org
Cc: Luca Leonardo Scorcia <l.scorcia@gmail.com>,
Chunfeng Yun <chunfeng.yun@mediatek.com>,
Vinod Koul <vkoul@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
Manivannan Sadhasivam <mani@kernel.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Matthias Brugger <matthias.bgg@gmail.com>,
AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
Stephen Boyd <sboyd@kernel.org>,
Brian Masney <bmasney+clk@redhat.com>,
Jerome Brunet <jbrunet+clk@baylibre.com>,
Chun-Kuang Hu <chunkuang.hu@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
Chen-Yu Tsai <wenst@chromium.org>,
Nicolas Frattaroli <nicolas.frattaroli@collabora.com>,
Fabien Parent <fparent@baylibre.com>, CK Hu <ck.hu@mediatek.com>,
chunhui dai <chunhui.dai@mediatek.com>,
linux-arm-kernel@lists.infradead.org,
linux-phy@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
dri-devel@lists.freedesktop.org
Subject: [PATCH 2/7] phy: mediatek: hdmi: Add support for mt8167
Date: Sat, 10 Oct 2026 13:54:02 +0200 [thread overview]
Message-ID: <20261010115539.9237-3-l.scorcia@gmail.com> (raw)
In-Reply-To: <20261010115539.9237-1-l.scorcia@gmail.com>
Add support for the HDMI PHY found in MediaTek mt8167.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
drivers/phy/mediatek/Makefile | 1 +
drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c | 217 +++++++++++++++++++++
drivers/phy/mediatek/phy-mtk-hdmi.c | 3 +
drivers/phy/mediatek/phy-mtk-hdmi.h | 1 +
4 files changed, 222 insertions(+)
create mode 100644 drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index ed0da708759b..25ede986a1f3 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o
phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
+phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8167.o
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8173.o
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8195.o
obj-$(CONFIG_PHY_MTK_HDMI) += phy-mtk-hdmi-drv.o
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c
new file mode 100644
index 000000000000..2435054d4e17
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "phy-mtk-hdmi.h"
+#include "phy-mtk-io.h"
+
+#define HDMI_CON0 0x00
+#define RG_HDMITX_DRV_IBIAS GENMASK(5, 0)
+#define RG_HDMITX_EN_SER GENMASK(15, 12)
+#define RG_HDMITX_EN_SLDO GENMASK(19, 16)
+#define RG_HDMITX_EN_PRED GENMASK(23, 20)
+#define RG_HDMITX_EN_IMP GENMASK(27, 24)
+#define RG_HDMITX_EN_DRV GENMASK(31, 28)
+
+#define HDMI_CON1 0x04
+#define RG_HDMITX_PRED_IBIAS GENMASK(21, 18)
+#define RG_HDMITX_PRED_IMP BIT(22)
+#define RG_HDMITX_DRV_IMP GENMASK(31, 26)
+
+#define HDMI_CON2 0x08
+#define RG_HDMITX_EN_TX_CKLDO BIT(0)
+#define RG_HDMITX_EN_TX_POSDIV BIT(1)
+#define RG_HDMITX_TX_POSDIV GENMASK(4, 3)
+#define RG_HDMITX_EN_MBIAS BIT(6)
+#define RG_HDMITX_MBIAS_LPF_EN BIT(7)
+
+#define HDMI_CON4 0x10
+#define RG_HDMITX_D0_IMP GENMASK(7, 0)
+#define RG_HDMITX_D1_IMP GENMASK(15, 8)
+#define RG_HDMITX_D2_IMP GENMASK(23, 16)
+
+#define HDMI_CON6 0x18
+#define RG_HTPLL_BR GENMASK(1, 0)
+#define RG_HTPLL_BC GENMASK(3, 2)
+#define RG_HTPLL_BP GENMASK(7, 4)
+#define RG_HTPLL_IR GENMASK(11, 8)
+#define RG_HTPLL_IC GENMASK(15, 12)
+#define RG_HTPLL_POSDIV GENMASK(17, 16)
+#define RG_HTPLL_PREDIV GENMASK(19, 18)
+#define RG_HTPLL_FBKSEL GENMASK(21, 20)
+#define RG_HTPLL_RLH_EN BIT(22)
+#define RG_HTPLL_FBKDIV GENMASK(30, 24)
+#define RG_HTPLL_EN BIT(31)
+
+#define HDMI_CON7 0x1c
+#define RG_HTPLL_AUTOK_EN BIT(23)
+#define RG_HTPLL_DIVEN GENMASK(30, 28)
+
+static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_set_bits(base + HDMI_CON7, RG_HTPLL_AUTOK_EN);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_RLH_EN);
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_POSDIV);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_EN_MBIAS);
+ usleep_range(80, 100);
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_EN);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+ mtk_phy_set_bits(base + HDMI_CON0, RG_HDMITX_EN_SLDO);
+ usleep_range(80, 100);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
+
+ return 0;
+}
+
+static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+ usleep_range(80, 100);
+ mtk_phy_clear_bits(base + HDMI_CON0, RG_HDMITX_EN_SLDO);
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_EN);
+ usleep_range(80, 100);
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_EN_MBIAS);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_POSDIV);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_RLH_EN);
+ mtk_phy_clear_bits(base + HDMI_CON7, RG_HTPLL_AUTOK_EN);
+ usleep_range(80, 100);
+}
+
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+
+ hdmi_phy->pll_rate = req->rate;
+
+ return 0;
+}
+
+static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+ void __iomem *base = hdmi_phy->regs;
+ u32 pos_div;
+ u32 pre_imp_en = 0x0;
+ u32 pre_ibias = 0xd;
+ u32 imp_en = 0x0;
+ u32 imp_clk = 0x1c;
+ u32 imp_d0 = 0x1c;
+ u32 imp_d1 = 0x1c;
+ u32 imp_d2 = 0x1c;
+ u32 drv_ibias = 0xa;
+
+ if (rate <= 27000000)
+ pos_div = 3;
+ else if (rate <= 74250000)
+ pos_div = 2;
+ else
+ pos_div = 1;
+
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_PREDIV);
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_POSDIV);
+ mtk_phy_update_bits(base + HDMI_CON6,
+ RG_HTPLL_IC | RG_HTPLL_IR,
+ FIELD_PREP(RG_HTPLL_IC, 0x1) |
+ FIELD_PREP(RG_HTPLL_IR, 0x1));
+ mtk_phy_update_field(base + HDMI_CON2, RG_HDMITX_TX_POSDIV, pos_div);
+ mtk_phy_update_field(base + HDMI_CON6, RG_HTPLL_FBKSEL, 1);
+ mtk_phy_update_field(base + HDMI_CON6, RG_HTPLL_FBKDIV, 19);
+ mtk_phy_update_field(base + HDMI_CON7, RG_HTPLL_DIVEN, 0x2);
+ mtk_phy_update_bits(base + HDMI_CON6,
+ RG_HTPLL_BP | RG_HTPLL_BC | RG_HTPLL_BR,
+ FIELD_PREP(RG_HTPLL_BP, 0xc) |
+ FIELD_PREP(RG_HTPLL_BC, 0x2) |
+ FIELD_PREP(RG_HTPLL_BR, 0x1));
+
+ mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_PRED_IMP, pre_imp_en);
+ mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_PRED_IBIAS, pre_ibias);
+ mtk_phy_update_field(base + HDMI_CON0, RG_HDMITX_EN_IMP, imp_en);
+ mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_DRV_IMP, imp_clk);
+ mtk_phy_update_bits(base + HDMI_CON4,
+ RG_HDMITX_D0_IMP | RG_HDMITX_D1_IMP | RG_HDMITX_D2_IMP,
+ FIELD_PREP(RG_HDMITX_D0_IMP, imp_d0) |
+ FIELD_PREP(RG_HDMITX_D1_IMP, imp_d1) |
+ FIELD_PREP(RG_HDMITX_D2_IMP, imp_d2));
+ mtk_phy_update_field(base + HDMI_CON0, RG_HDMITX_DRV_IBIAS, drv_ibias);
+
+ return 0;
+}
+
+static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+
+ unsigned long out_rate, val;
+ u32 tmp;
+
+ tmp = readl(hdmi_phy->regs + HDMI_CON6);
+ val = FIELD_GET(RG_HTPLL_PREDIV, tmp);
+ switch (val) {
+ case 0x00:
+ out_rate = parent_rate;
+ break;
+ case 0x01:
+ out_rate = parent_rate / 2;
+ break;
+ default:
+ out_rate = parent_rate / 4;
+ break;
+ }
+
+ val = FIELD_GET(RG_HTPLL_FBKDIV, tmp);
+ out_rate *= (val + 1) * 2;
+
+ tmp = readl(hdmi_phy->regs + HDMI_CON2);
+ val = FIELD_GET(RG_HDMITX_TX_POSDIV, tmp);
+ out_rate >>= val;
+
+ if (tmp & RG_HDMITX_EN_TX_POSDIV)
+ out_rate /= 5;
+
+ return out_rate;
+}
+
+static const struct clk_ops mtk_hdmi_phy_pll_ops = {
+ .prepare = mtk_hdmi_pll_prepare,
+ .unprepare = mtk_hdmi_pll_unprepare,
+ .set_rate = mtk_hdmi_pll_set_rate,
+ .determine_rate = mtk_hdmi_pll_determine_rate,
+ .recalc_rate = mtk_hdmi_pll_recalc_rate,
+};
+
+static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
+{
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_set_bits(base + HDMI_CON0,
+ RG_HDMITX_EN_DRV | RG_HDMITX_EN_PRED | RG_HDMITX_EN_SER);
+ usleep_range(80, 100);
+}
+
+static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
+{
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_clear_bits(base + HDMI_CON0,
+ RG_HDMITX_EN_DRV | RG_HDMITX_EN_PRED | RG_HDMITX_EN_SER);
+ usleep_range(80, 100);
+}
+
+struct mtk_hdmi_phy_conf mtk_hdmi_phy_8167_conf = {
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
+ .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
+ .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
+ .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
+};
+
+MODULE_DESCRIPTION("MediaTek HDMI PHY Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 52a7d525ff9b..4e167a421f0e 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -186,6 +186,9 @@ static const struct of_device_id mtk_hdmi_phy_match[] = {
{ .compatible = "mediatek,mt2701-hdmi-phy",
.data = &mtk_hdmi_phy_2701_conf,
},
+ { .compatible = "mediatek,mt8167-hdmi-phy",
+ .data = &mtk_hdmi_phy_8167_conf,
+ },
{ .compatible = "mediatek,mt8173-hdmi-phy",
.data = &mtk_hdmi_phy_8173_conf,
},
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy-mtk-hdmi.h
index 99d917e0036a..5137d1c3345b 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
@@ -49,6 +49,7 @@ struct mtk_hdmi_phy {
struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf;
+extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8167_conf;
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf;
--
2.43.0
WARNING: multiple messages have this Message-ID (diff)
From: Luca Leonardo Scorcia <l.scorcia@gmail.com>
To: linux-mediatek@lists.infradead.org
Cc: Luca Leonardo Scorcia <l.scorcia@gmail.com>,
Chunfeng Yun <chunfeng.yun@mediatek.com>,
Vinod Koul <vkoul@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
Manivannan Sadhasivam <mani@kernel.org>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Matthias Brugger <matthias.bgg@gmail.com>,
AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
Stephen Boyd <sboyd@kernel.org>,
Brian Masney <bmasney+clk@redhat.com>,
Jerome Brunet <jbrunet+clk@baylibre.com>,
Chun-Kuang Hu <chunkuang.hu@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
Chen-Yu Tsai <wenst@chromium.org>,
Nicolas Frattaroli <nicolas.frattaroli@collabora.com>,
Fabien Parent <fparent@baylibre.com>, CK Hu <ck.hu@mediatek.com>,
chunhui dai <chunhui.dai@mediatek.com>,
linux-arm-kernel@lists.infradead.org,
linux-phy@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
dri-devel@lists.freedesktop.org
Subject: [PATCH 2/7] phy: mediatek: hdmi: Add support for mt8167
Date: Sat, 10 Oct 2026 13:54:02 +0200 [thread overview]
Message-ID: <20261010115539.9237-3-l.scorcia@gmail.com> (raw)
In-Reply-To: <20261010115539.9237-1-l.scorcia@gmail.com>
Add support for the HDMI PHY found in MediaTek mt8167.
Signed-off-by: Luca Leonardo Scorcia <l.scorcia@gmail.com>
---
drivers/phy/mediatek/Makefile | 1 +
drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c | 217 +++++++++++++++++++++
drivers/phy/mediatek/phy-mtk-hdmi.c | 3 +
drivers/phy/mediatek/phy-mtk-hdmi.h | 1 +
4 files changed, 222 insertions(+)
create mode 100644 drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index ed0da708759b..25ede986a1f3 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_PHY_MTK_XFI_TPHY) += phy-mtk-xfi-tphy.o
phy-mtk-hdmi-drv-y := phy-mtk-hdmi.o
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt2701.o
+phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8167.o
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8173.o
phy-mtk-hdmi-drv-y += phy-mtk-hdmi-mt8195.o
obj-$(CONFIG_PHY_MTK_HDMI) += phy-mtk-hdmi-drv.o
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c
new file mode 100644
index 000000000000..2435054d4e17
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8167.c
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "phy-mtk-hdmi.h"
+#include "phy-mtk-io.h"
+
+#define HDMI_CON0 0x00
+#define RG_HDMITX_DRV_IBIAS GENMASK(5, 0)
+#define RG_HDMITX_EN_SER GENMASK(15, 12)
+#define RG_HDMITX_EN_SLDO GENMASK(19, 16)
+#define RG_HDMITX_EN_PRED GENMASK(23, 20)
+#define RG_HDMITX_EN_IMP GENMASK(27, 24)
+#define RG_HDMITX_EN_DRV GENMASK(31, 28)
+
+#define HDMI_CON1 0x04
+#define RG_HDMITX_PRED_IBIAS GENMASK(21, 18)
+#define RG_HDMITX_PRED_IMP BIT(22)
+#define RG_HDMITX_DRV_IMP GENMASK(31, 26)
+
+#define HDMI_CON2 0x08
+#define RG_HDMITX_EN_TX_CKLDO BIT(0)
+#define RG_HDMITX_EN_TX_POSDIV BIT(1)
+#define RG_HDMITX_TX_POSDIV GENMASK(4, 3)
+#define RG_HDMITX_EN_MBIAS BIT(6)
+#define RG_HDMITX_MBIAS_LPF_EN BIT(7)
+
+#define HDMI_CON4 0x10
+#define RG_HDMITX_D0_IMP GENMASK(7, 0)
+#define RG_HDMITX_D1_IMP GENMASK(15, 8)
+#define RG_HDMITX_D2_IMP GENMASK(23, 16)
+
+#define HDMI_CON6 0x18
+#define RG_HTPLL_BR GENMASK(1, 0)
+#define RG_HTPLL_BC GENMASK(3, 2)
+#define RG_HTPLL_BP GENMASK(7, 4)
+#define RG_HTPLL_IR GENMASK(11, 8)
+#define RG_HTPLL_IC GENMASK(15, 12)
+#define RG_HTPLL_POSDIV GENMASK(17, 16)
+#define RG_HTPLL_PREDIV GENMASK(19, 18)
+#define RG_HTPLL_FBKSEL GENMASK(21, 20)
+#define RG_HTPLL_RLH_EN BIT(22)
+#define RG_HTPLL_FBKDIV GENMASK(30, 24)
+#define RG_HTPLL_EN BIT(31)
+
+#define HDMI_CON7 0x1c
+#define RG_HTPLL_AUTOK_EN BIT(23)
+#define RG_HTPLL_DIVEN GENMASK(30, 28)
+
+static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_set_bits(base + HDMI_CON7, RG_HTPLL_AUTOK_EN);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_RLH_EN);
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_POSDIV);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_EN_MBIAS);
+ usleep_range(80, 100);
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_EN);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+ mtk_phy_set_bits(base + HDMI_CON0, RG_HDMITX_EN_SLDO);
+ usleep_range(80, 100);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+ mtk_phy_set_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
+
+ return 0;
+}
+
+static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+ usleep_range(80, 100);
+ mtk_phy_clear_bits(base + HDMI_CON0, RG_HDMITX_EN_SLDO);
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_EN);
+ usleep_range(80, 100);
+ mtk_phy_clear_bits(base + HDMI_CON2, RG_HDMITX_EN_MBIAS);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_POSDIV);
+ mtk_phy_clear_bits(base + HDMI_CON6, RG_HTPLL_RLH_EN);
+ mtk_phy_clear_bits(base + HDMI_CON7, RG_HTPLL_AUTOK_EN);
+ usleep_range(80, 100);
+}
+
+static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+
+ hdmi_phy->pll_rate = req->rate;
+
+ return 0;
+}
+
+static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+ void __iomem *base = hdmi_phy->regs;
+ u32 pos_div;
+ u32 pre_imp_en = 0x0;
+ u32 pre_ibias = 0xd;
+ u32 imp_en = 0x0;
+ u32 imp_clk = 0x1c;
+ u32 imp_d0 = 0x1c;
+ u32 imp_d1 = 0x1c;
+ u32 imp_d2 = 0x1c;
+ u32 drv_ibias = 0xa;
+
+ if (rate <= 27000000)
+ pos_div = 3;
+ else if (rate <= 74250000)
+ pos_div = 2;
+ else
+ pos_div = 1;
+
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_PREDIV);
+ mtk_phy_set_bits(base + HDMI_CON6, RG_HTPLL_POSDIV);
+ mtk_phy_update_bits(base + HDMI_CON6,
+ RG_HTPLL_IC | RG_HTPLL_IR,
+ FIELD_PREP(RG_HTPLL_IC, 0x1) |
+ FIELD_PREP(RG_HTPLL_IR, 0x1));
+ mtk_phy_update_field(base + HDMI_CON2, RG_HDMITX_TX_POSDIV, pos_div);
+ mtk_phy_update_field(base + HDMI_CON6, RG_HTPLL_FBKSEL, 1);
+ mtk_phy_update_field(base + HDMI_CON6, RG_HTPLL_FBKDIV, 19);
+ mtk_phy_update_field(base + HDMI_CON7, RG_HTPLL_DIVEN, 0x2);
+ mtk_phy_update_bits(base + HDMI_CON6,
+ RG_HTPLL_BP | RG_HTPLL_BC | RG_HTPLL_BR,
+ FIELD_PREP(RG_HTPLL_BP, 0xc) |
+ FIELD_PREP(RG_HTPLL_BC, 0x2) |
+ FIELD_PREP(RG_HTPLL_BR, 0x1));
+
+ mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_PRED_IMP, pre_imp_en);
+ mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_PRED_IBIAS, pre_ibias);
+ mtk_phy_update_field(base + HDMI_CON0, RG_HDMITX_EN_IMP, imp_en);
+ mtk_phy_update_field(base + HDMI_CON1, RG_HDMITX_DRV_IMP, imp_clk);
+ mtk_phy_update_bits(base + HDMI_CON4,
+ RG_HDMITX_D0_IMP | RG_HDMITX_D1_IMP | RG_HDMITX_D2_IMP,
+ FIELD_PREP(RG_HDMITX_D0_IMP, imp_d0) |
+ FIELD_PREP(RG_HDMITX_D1_IMP, imp_d1) |
+ FIELD_PREP(RG_HDMITX_D2_IMP, imp_d2));
+ mtk_phy_update_field(base + HDMI_CON0, RG_HDMITX_DRV_IBIAS, drv_ibias);
+
+ return 0;
+}
+
+static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
+
+ unsigned long out_rate, val;
+ u32 tmp;
+
+ tmp = readl(hdmi_phy->regs + HDMI_CON6);
+ val = FIELD_GET(RG_HTPLL_PREDIV, tmp);
+ switch (val) {
+ case 0x00:
+ out_rate = parent_rate;
+ break;
+ case 0x01:
+ out_rate = parent_rate / 2;
+ break;
+ default:
+ out_rate = parent_rate / 4;
+ break;
+ }
+
+ val = FIELD_GET(RG_HTPLL_FBKDIV, tmp);
+ out_rate *= (val + 1) * 2;
+
+ tmp = readl(hdmi_phy->regs + HDMI_CON2);
+ val = FIELD_GET(RG_HDMITX_TX_POSDIV, tmp);
+ out_rate >>= val;
+
+ if (tmp & RG_HDMITX_EN_TX_POSDIV)
+ out_rate /= 5;
+
+ return out_rate;
+}
+
+static const struct clk_ops mtk_hdmi_phy_pll_ops = {
+ .prepare = mtk_hdmi_pll_prepare,
+ .unprepare = mtk_hdmi_pll_unprepare,
+ .set_rate = mtk_hdmi_pll_set_rate,
+ .determine_rate = mtk_hdmi_pll_determine_rate,
+ .recalc_rate = mtk_hdmi_pll_recalc_rate,
+};
+
+static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
+{
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_set_bits(base + HDMI_CON0,
+ RG_HDMITX_EN_DRV | RG_HDMITX_EN_PRED | RG_HDMITX_EN_SER);
+ usleep_range(80, 100);
+}
+
+static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
+{
+ void __iomem *base = hdmi_phy->regs;
+
+ mtk_phy_clear_bits(base + HDMI_CON0,
+ RG_HDMITX_EN_DRV | RG_HDMITX_EN_PRED | RG_HDMITX_EN_SER);
+ usleep_range(80, 100);
+}
+
+struct mtk_hdmi_phy_conf mtk_hdmi_phy_8167_conf = {
+ .flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_GATE,
+ .hdmi_phy_clk_ops = &mtk_hdmi_phy_pll_ops,
+ .hdmi_phy_enable_tmds = mtk_hdmi_phy_enable_tmds,
+ .hdmi_phy_disable_tmds = mtk_hdmi_phy_disable_tmds,
+};
+
+MODULE_DESCRIPTION("MediaTek HDMI PHY Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 52a7d525ff9b..4e167a421f0e 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -186,6 +186,9 @@ static const struct of_device_id mtk_hdmi_phy_match[] = {
{ .compatible = "mediatek,mt2701-hdmi-phy",
.data = &mtk_hdmi_phy_2701_conf,
},
+ { .compatible = "mediatek,mt8167-hdmi-phy",
+ .data = &mtk_hdmi_phy_8167_conf,
+ },
{ .compatible = "mediatek,mt8173-hdmi-phy",
.data = &mtk_hdmi_phy_8173_conf,
},
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy-mtk-hdmi.h
index 99d917e0036a..5137d1c3345b 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
@@ -49,6 +49,7 @@ struct mtk_hdmi_phy {
struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8195_conf;
+extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8167_conf;
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_2701_conf;
--
2.43.0
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
next prev parent reply other threads:[~2026-10-10 11:55 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-10 11:54 [PATCH 0/7] Add support for Mediatek mt8167 HDMI display output Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia
2026-10-10 11:54 ` [PATCH 1/7] dt-bindings: mediatek: hdmi-phy: Add compatible for mt8167 Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia
2026-10-12 9:19 ` CK Hu (胡俊光)
2026-10-12 9:19 ` CK Hu (胡俊光)
2026-10-12 9:41 ` Krzysztof Kozlowski
2026-10-12 9:41 ` Krzysztof Kozlowski
2026-10-12 9:40 ` Krzysztof Kozlowski
2026-10-12 9:40 ` Krzysztof Kozlowski
2026-10-12 17:43 ` Luca Leonardo Scorcia
2026-10-12 17:43 ` Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia [this message]
2026-10-10 11:54 ` [PATCH 2/7] phy: mediatek: hdmi: Add support " Luca Leonardo Scorcia
2026-10-10 12:12 ` sashiko-bot
2026-10-10 12:12 ` sashiko-bot
2026-10-10 11:54 ` [PATCH 3/7] clk: mediatek: mt8167: Map apmixedsys iomem as shared Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia
2026-10-10 12:02 ` sashiko-bot
2026-10-10 12:02 ` sashiko-bot
2026-10-10 11:54 ` [PATCH 4/7] clk: mediatek: mt8167: Correct HDMI-related clock definitions Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia
2026-10-10 11:54 ` [PATCH 5/7] drm/mediatek: mtk_hdmi: Set tz_disabled for mt8167 Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia
2026-10-12 9:37 ` CK Hu (胡俊光)
2026-10-12 9:37 ` CK Hu (胡俊光)
2026-10-10 11:54 ` [PATCH 6/7] drm/mediatek: mtk_hdmi: Improve the secure output bit toggle Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia
2026-10-10 11:54 ` [PATCH 7/7] arm64: dts: mediatek: mt8167: Add HDMI display nodes Luca Leonardo Scorcia
2026-10-10 11:54 ` Luca Leonardo Scorcia
2026-10-10 12:08 ` sashiko-bot
2026-10-10 12:08 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261010115539.9237-3-l.scorcia@gmail.com \
--to=l.scorcia@gmail.com \
--cc=airlied@gmail.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=bmasney+clk@redhat.com \
--cc=chunfeng.yun@mediatek.com \
--cc=chunhui.dai@mediatek.com \
--cc=chunkuang.hu@kernel.org \
--cc=ck.hu@mediatek.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=fparent@baylibre.com \
--cc=jbrunet+clk@baylibre.com \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-phy@lists.infradead.org \
--cc=mani@kernel.org \
--cc=matthias.bgg@gmail.com \
--cc=neil.armstrong@linaro.org \
--cc=nicolas.frattaroli@collabora.com \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
--cc=sboyd@kernel.org \
--cc=simona@ffwll.ch \
--cc=vkoul@kernel.org \
--cc=wenst@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.