From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B7F83C433FE for ; Thu, 29 Sep 2022 13:22:29 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6BE0110EA53; Thu, 29 Sep 2022 13:22:28 +0000 (UTC) Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id EFEC310EA50 for ; Thu, 29 Sep 2022 13:22:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1664457737; x=1695993737; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=71kiSa5eTgMJGu6vl2J4evyONYSjRv37omZ12G/6H8A=; b=Id1BE3nxnOEXUDtGZ22AfbckOQ9HdS/fDCfB0bgxDcs1HaRE0BOA2VyW 9u4Z362wMbg63HQOBiv1aP08u4xoRNssndw+pvMaweXdtocAx2zPdbmwC hBMs/B0NahMoPPwn5KZK53unLA6XppjdY4sZQMOtw6L4Xm0cMrLJghzVt f+3xo5Zavii9I5fA4Tf5e0mExSkeZhlW5n/XA5U2jC+mxJSWzIYuq+Pxy lt0NcmumMg4Mb3GledDfa41qDFIH9zhCDtD8/jyRwh4yLDg3/ZLyLerG0 9G1Z8VwiZJyFULtTcacUiFBq94IHyv05yuLVKf+EEk8os/h3KushLAGy3 Q==; X-IronPort-AV: E=McAfee;i="6500,9779,10485"; a="365934672" X-IronPort-AV: E=Sophos;i="5.93,355,1654585200"; d="scan'208";a="365934672" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Sep 2022 06:22:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10485"; a="655550465" X-IronPort-AV: E=Sophos;i="5.93,355,1654585200"; d="scan'208";a="655550465" Received: from sorvi2.fi.intel.com ([10.237.72.194]) by orsmga001.jf.intel.com with ESMTP; 29 Sep 2022 06:22:14 -0700 From: Mika Kahola To: intel-gfx@lists.freedesktop.org Date: Thu, 29 Sep 2022 16:17:46 +0300 Message-Id: <20220929131747.2592092-5-mika.kahola@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220929131747.2592092-1-mika.kahola@intel.com> References: <20220929131747.2592092-1-mika.kahola@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Intel-gfx] [PATCH 4/5] drm/i915/mtl: Add C10 phy programming for HDMI X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" From: Radhakrishna Sripada 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 Cc: Mika Kahola Cc: Uma Shankar Signed-off-by: Radhakrishna Sripada --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 168 ++++++++++++++++++- drivers/gpu/drm/i915/display/intel_cx0_phy.h | 2 + drivers/gpu/drm/i915/display/intel_hdmi.c | 5 +- 3 files changed, 170 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index 6ba11cd7cd75..a08788d2a3bc 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -448,6 +448,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) @@ -457,9 +603,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; } @@ -467,9 +614,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; @@ -521,7 +679,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)); } @@ -537,11 +696,10 @@ static void intel_c10_pll_program(struct drm_i915_private *i915, INTEL_CX0_LANE0; enum intel_cx0_lanes 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); @@ -552,6 +710,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 d12d2e2f02ee..fc8e4041f26f 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h @@ -96,6 +96,7 @@ enum intel_cx0_lanes { #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)) @@ -141,5 +142,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_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