All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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.