All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Kahola <mika.kahola@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH 05/20] drm/i915/mtl: Add C10 phy programming for HDMI
Date: Fri, 14 Oct 2022 15:47:25 +0300	[thread overview]
Message-ID: <20221014124740.774835-6-mika.kahola@intel.com> (raw)
In-Reply-To: <20221014124740.774835-1-mika.kahola@intel.com>

From: Radhakrishna Sripada <radhakrishna.sripada@intel.com>

Like DG2, we still don't have a proper algorithm that can be used
for calculating PHY settings, but we do have tables of register
values for a handful of the more common link rates. Some support is
better than none, so let's go ahead and add/use these tables when we
can, and also add some logic to hdmi_port_clock_valid() to filter the
modelist to just the modes we can actually support with these link
rates.

Hopefully we'll have a proper / non-encumbered algorithm to calculate
these registers by the time we upstream and we'll be able to replace
this patch with something more general purpose.

Bspec: 64568

Cc: Imre Deak <imre.deak@intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Cc: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
---
 drivers/gpu/drm/i915/display/intel_cx0_phy.c  | 168 +++++++++++++++++-
 drivers/gpu/drm/i915/display/intel_cx0_phy.h  |   1 +
 .../gpu/drm/i915/display/intel_cx0_reg_defs.h |  31 ++--
 drivers/gpu/drm/i915/display/intel_hdmi.c     |   5 +-
 4 files changed, 185 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index d0e8ddd0a905..dc033174c9c0 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -484,6 +484,152 @@ static const struct intel_c10mpllb_state * const mtl_c10_edp_tables[] = {
 	NULL,
 };
 
+/*
+ * HDMI link rates with 38.4 MHz reference clock.
+ */
+
+static const struct intel_c10mpllb_state mtl_c10_hdmi_25_175 = {
+	.clock = 25175,
+	.pll[0] = 0x4,
+	.pll[1] = 0,
+	.pll[2] = 0xB2,
+	.pll[3] = 0,
+	.pll[4] = 0,
+	.pll[5] = 0,
+	.pll[6] = 0,
+	.pll[7] = 0,
+	.pll[8] = 0x20,
+	.pll[9] = 0x1,
+	.pll[10] = 0,
+	.pll[11] = 0,
+	.pll[12] = 0,
+	.pll[13] = 0,
+	.pll[14] = 0,
+	.pll[15] = 0xD,
+	.pll[16] = 0x6,
+	.pll[17] = 0x8F,
+	.pll[18] = 0x84,
+	.pll[19] = 0x23,
+};
+
+static const struct intel_c10mpllb_state mtl_c10_hdmi_27_0 = {
+	.clock = 27000,
+	.pll[0] = 0x34,
+	.pll[1] = 0,
+	.pll[2] = 0xC0,
+	.pll[3] = 0,
+	.pll[4] = 0,
+	.pll[5] = 0,
+	.pll[6] = 0,
+	.pll[7] = 0,
+	.pll[8] = 0x20,
+	.pll[9] = 0x1,
+	.pll[10] = 0,
+	.pll[11] = 0,
+	.pll[12] = 0x80,
+	.pll[13] = 0,
+	.pll[14] = 0,
+	.pll[15] = 0xD,
+	.pll[16] = 0x6,
+	.pll[17] = 0xCF,
+	.pll[18] = 0x84,
+	.pll[19] = 0x23,
+};
+
+static const struct intel_c10mpllb_state mtl_c10_hdmi_74_25 = {
+	.clock = 74250,
+	.pll[0] = 0xF4,
+	.pll[1] = 0,
+	.pll[2] = 0x7A,
+	.pll[3] = 0,
+	.pll[4] = 0,
+	.pll[5] = 0,
+	.pll[6] = 0,
+	.pll[7] = 0,
+	.pll[8] = 0x20,
+	.pll[9] = 0x1,
+	.pll[10] = 0,
+	.pll[11] = 0,
+	.pll[12] = 0x58,
+	.pll[13] = 0,
+	.pll[14] = 0,
+	.pll[15] = 0xB,
+	.pll[16] = 0x6,
+	.pll[17] = 0xF,
+	.pll[18] = 0x85,
+	.pll[19] = 0x23,
+};
+
+static const struct intel_c10mpllb_state mtl_c10_hdmi_148_5 = {
+	.clock = 148500,
+	.pll[0] = 0xF4,
+	.pll[1] = 0,
+	.pll[2] = 0x7A,
+	.pll[3] = 0,
+	.pll[4] = 0,
+	.pll[5] = 0,
+	.pll[6] = 0,
+	.pll[7] = 0,
+	.pll[8] = 0x20,
+	.pll[9] = 0x1,
+	.pll[10] = 0,
+	.pll[11] = 0,
+	.pll[12] = 0x58,
+	.pll[13] = 0,
+	.pll[14] = 0,
+	.pll[15] = 0xA,
+	.pll[16] = 0x6,
+	.pll[17] = 0xF,
+	.pll[18] = 0x85,
+	.pll[19] = 0x23,
+};
+
+static const struct intel_c10mpllb_state mtl_c10_hdmi_594 = {
+	.clock = 594000,
+	.pll[0] = 0xF4,
+	.pll[1] = 0,
+	.pll[2] = 0x7A,
+	.pll[3] = 0,
+	.pll[4] = 0,
+	.pll[5] = 0,
+	.pll[6] = 0,
+	.pll[7] = 0,
+	.pll[8] = 0x20,
+	.pll[9] = 0x1,
+	.pll[10] = 0,
+	.pll[11] = 0,
+	.pll[12] = 0x58,
+	.pll[13] = 0,
+	.pll[14] = 0,
+	.pll[15] = 0x8,
+	.pll[16] = 0x6,
+	.pll[17] = 0xF,
+	.pll[18] = 0x85,
+	.pll[19] = 0x23,
+};
+
+static const struct intel_c10mpllb_state * const mtl_c10_hdmi_tables[] = {
+	&mtl_c10_hdmi_25_175,
+	&mtl_c10_hdmi_27_0,
+	&mtl_c10_hdmi_74_25,
+	&mtl_c10_hdmi_148_5,
+	&mtl_c10_hdmi_594,
+	NULL,
+};
+
+int intel_c10_phy_check_hdmi_link_rate(int clock)
+{
+	const struct intel_c10mpllb_state * const *tables = mtl_c10_hdmi_tables;
+	int i;
+
+	for (i = 0; tables[i]; i++) {
+		if (clock == tables[i]->clock)
+			return MODE_OK;
+	}
+
+	return MODE_CLOCK_RANGE;
+}
+
 static const struct intel_c10mpllb_state * const *
 intel_c10_mpllb_tables_get(struct intel_crtc_state *crtc_state,
 			   struct intel_encoder *encoder)
@@ -493,9 +639,10 @@ intel_c10_mpllb_tables_get(struct intel_crtc_state *crtc_state,
 			return mtl_c10_edp_tables;
 		else
 			return mtl_c10_dp_tables;
+	} else if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
+		return mtl_c10_hdmi_tables;
 	}
 
-	/* TODO: Add HDMI Support */
 	MISSING_CASE(encoder->type);
 	return NULL;
 }
@@ -503,9 +650,20 @@ intel_c10_mpllb_tables_get(struct intel_crtc_state *crtc_state,
 static int intel_c10mpllb_calc_state(struct intel_crtc_state *crtc_state,
 				     struct intel_encoder *encoder)
 {
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	const struct intel_c10mpllb_state * const *tables;
+	enum phy phy = intel_port_to_phy(i915, encoder->port);
 	int i;
 
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
+		if (intel_c10_phy_check_hdmi_link_rate(crtc_state->port_clock)
+		    != MODE_OK) {
+			drm_dbg_kms(&i915->drm, "Can't support HDMI link rate %d on phy %c.\n",
+				      crtc_state->port_clock, phy_name(phy));
+			return -EINVAL;
+		}
+	}
+
 	tables = intel_c10_mpllb_tables_get(crtc_state, encoder);
 	if (!tables)
 		return -EINVAL;
@@ -557,7 +715,8 @@ void intel_c10mpllb_readout_hw_state(struct intel_encoder *encoder,
 	cmn = intel_cx0_read(i915, encoder->port, lane, PHY_C10_VDR_CMN(0));
 	tx0 = intel_cx0_read(i915, encoder->port, lane, PHY_C10_VDR_TX(0));
 
-	if (tx0 != C10_TX0_VAL || cmn != C10_CMN0_DP_VAL)
+	if (tx0 != C10_TX0_VAL || cmn != (intel_encoder_is_dp(encoder) ?
+					  C10_CMN0_DP_VAL : C10_CMN0_HDMI_VAL))
 		drm_warn(&i915->drm, "Unexpected tx: %x or cmn: %x for phy: %c.\n",
 			 tx0, cmn, phy_name(phy));
 }
@@ -573,11 +732,10 @@ static void intel_c10_pll_program(struct drm_i915_private *i915,
 					 INTEL_CX0_LANE0;
 	u8 follower_lane = lane_reversal ? INTEL_CX0_LANE0 :
 					   INTEL_CX0_LANE1;
-
 	int i;
 	struct intel_dp *intel_dp;
 	bool use_ssc = false;
-	u8 cmn0 = 0;
+	u8 cmn0;
 
 	if (intel_crtc_has_dp_encoder(crtc_state)) {
 		intel_dp = enc_to_intel_dp(encoder);
@@ -588,6 +746,8 @@ static void intel_c10_pll_program(struct drm_i915_private *i915,
 			use_ssc = false;
 
 		cmn0 = C10_CMN0_DP_VAL;
+	} else {
+		cmn0 = C10_CMN0_HDMI_VAL;
 	}
 
 	intel_cx0_write(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
index 8cf340509097..f8023f240727 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
@@ -39,5 +39,6 @@ int intel_c10mpllb_calc_port_clock(struct intel_encoder *encoder,
 				   const struct intel_c10mpllb_state *pll_state);
 void intel_c10mpllb_state_verify(struct intel_atomic_state *state,
 				 struct intel_crtc_state *new_crtc_state);
+int intel_c10_phy_check_hdmi_link_rate(int clock);
 
 #endif /* __INTEL_CX0_PHY_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_reg_defs.h b/drivers/gpu/drm/i915/display/intel_cx0_reg_defs.h
index f91f8824febb..b394f5c23acb 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_reg_defs.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_reg_defs.h
@@ -134,21 +134,22 @@
 #define XELPDP_SSC_ENABLE_PLLB				REG_BIT(0)
 
 /* C10 Vendor Registers */
-#define PHY_C10_VDR_PLL(idx)		(0xC00 + (idx))
-#define  C10_PLL0_FRACEN		REG_BIT8(4)
-#define  C10_PLL3_MULTIPLIERH_MASK	REG_GENMASK8(3, 0)
-#define  C10_PLL15_TXCLKDIV_MASK	REG_GENMASK8(2, 0)
-#define PHY_C10_VDR_CMN(idx)		(0xC20 + (idx))
-#define  C10_CMN0_DP_VAL		0x21
-#define  C10_CMN3_TXVBOOST_MASK		REG_GENMASK8(7, 5)
-#define  C10_CMN3_TXVBOOST(val)		REG_FIELD_PREP8(C10_CMN3_TXVBOOST_MASK, val)
-#define PHY_C10_VDR_TX(idx)		(0xC30 + (idx))
-#define  C10_TX0_VAL			0x10
-#define PHY_C10_VDR_CONTROL(idx)	(0xC70 + (idx) - 1)
-#define  C10_VDR_CTRL_MSGBUS_ACCESS	REG_BIT8(2)
-#define  C10_VDR_CTRL_MASTER_LANE	REG_BIT8(1)
-#define  C10_VDR_CTRL_UPDATE_CFG	REG_BIT8(0)
-#define PHY_C10_VDR_CUSTOM_WIDTH	0xD02
+#define PHY_C10_VDR_PLL(idx)            (0xC00 + (idx))
+#define  C10_PLL0_FRACEN                REG_BIT8(4)
+#define  C10_PLL3_MULTIPLIERH_MASK      REG_GENMASK8(3, 0)
+#define  C10_PLL15_TXCLKDIV_MASK        REG_GENMASK8(2, 0)
+#define PHY_C10_VDR_CMN(idx)            (0xC20 + (idx))
+#define  C10_CMN0_DP_VAL                0x21
+#define  C10_CMN0_HDMI_VAL              0x1
+#define  C10_CMN3_TXVBOOST_MASK         REG_GENMASK8(7, 5)
+#define  C10_CMN3_TXVBOOST(val)         REG_FIELD_PREP8(C10_CMN3_TXVBOOST_MASK, val)
+#define PHY_C10_VDR_TX(idx)             (0xC30 + (idx))
+#define  C10_TX0_VAL                    0x10
+#define PHY_C10_VDR_CONTROL(idx)        (0xC70 + (idx) - 1)
+#define  C10_VDR_CTRL_MSGBUS_ACCESS     REG_BIT8(2)
+#define  C10_VDR_CTRL_MASTER_LANE       REG_BIT8(1)
+#define  C10_VDR_CTRL_UPDATE_CFG        REG_BIT8(0)
+#define PHY_C10_VDR_CUSTOM_WIDTH        0xD02
 
 #define CX0_P0_STATE_ACTIVE             0x0
 #define CX0_P2_STATE_READY              0x2
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 93519fb23d9d..c274098f2196 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -44,6 +44,7 @@
 #include "i915_drv.h"
 #include "intel_atomic.h"
 #include "intel_connector.h"
+#include "intel_cx0_phy.h"
 #include "intel_ddi.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
@@ -1875,7 +1876,9 @@ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
 	 * FIXME: We will hopefully get an algorithmic way of programming
 	 * the MPLLB for HDMI in the future.
 	 */
-	if (IS_DG2(dev_priv))
+	if (IS_METEORLAKE(dev_priv))
+		return intel_c10_phy_check_hdmi_link_rate(clock);
+	else if (IS_DG2(dev_priv))
 		return intel_snps_phy_check_hdmi_link_rate(clock);
 
 	return MODE_OK;
-- 
2.34.1


  parent reply	other threads:[~2022-10-14 12:52 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-14 12:47 [Intel-gfx] [PATCH 00/20] drm/i915/mtl: Add C10 and C20 phy support Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 01/20] drm/i915/mtl: Initial DDI port setup Mika Kahola
2022-11-29  0:23   ` Sripada, Radhakrishna
2022-10-14 12:47 ` [Intel-gfx] [PATCH 02/20] drm/i915/mtl: Add DP rates Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 03/20] drm/i915/mtl: Create separate reg file for PICA registers Mika Kahola
2022-11-02 16:54   ` Jani Nikula
2022-11-02 16:59     ` Jani Nikula
2022-10-14 12:47 ` [Intel-gfx] [PATCH 04/20] drm/i915/mtl: Add Support for C10 PHY message bus and pll programming Mika Kahola
2022-10-14 12:47 ` Mika Kahola [this message]
2022-10-14 12:47 ` [Intel-gfx] [PATCH 06/20] drm/i915/mtl: Add vswing programming for C10 phys Mika Kahola
2022-10-31 20:29   ` Taylor, Clinton A
2022-11-01  7:31     ` Kahola, Mika
2022-10-14 12:47 ` [Intel-gfx] [PATCH 07/20] drm/i915/mtl: Add support for PM DEMAND Mika Kahola
2022-11-01  2:38   ` Sripada, Radhakrishna
2022-11-15 12:56     ` Kahola, Mika
2022-10-14 12:47 ` [Intel-gfx] [PATCH 08/20] drm/i915/mtl: C20 PLL programming Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 09/20] drm/i915/mtl: C20 HW readout Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 10/20] drm/i915/mtl: C20 port clock calculation Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 11/20] drm/i915/mtl: C20 HDMI state calculations Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 12/20] drm/i915/mtl: Add voltage swing sequence for C20 Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 13/20] drm/i915/mtl: For DP2.0 10G and 20G rates use MPLLA Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 14/20] drm/i915/mtl: Enabling/disabling sequence Thunderbolt pll Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 15/20] drm/i915/mtl: Readout Thunderbolt HW state Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 16/20] drm/i915/mtl: Enable TC ports Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 17/20] drm/i915/mtl: MTL PICA hotplug detection Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 18/20] drm/i915/mtl: Define mask for DDI AUX interrupts Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 19/20] drm/i915/mtl: Power up TCSS Mika Kahola
2022-10-14 12:47 ` [Intel-gfx] [PATCH 20/20] drm/i915/mtl: Pin assignment for TypeC Mika Kahola
2022-10-26 14:26   ` Imre Deak
2022-10-27  8:15     ` Kahola, Mika
2022-10-14 13:11 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/mtl: Add C10 and C20 phy support Patchwork
2022-10-14 13:11 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2022-10-14 13:34 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-10-14 14:50 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2022-10-31 21:49 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm/i915/mtl: Add C10 and C20 phy support (rev2) Patchwork
2022-11-01  7:55 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for drm/i915/mtl: Add C10 and C20 phy support (rev3) Patchwork

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=20221014124740.774835-6-mika.kahola@intel.com \
    --to=mika.kahola@intel.com \
    --cc=intel-gfx@lists.freedesktop.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.