From patchwork Mon Feb 20 08:20:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sharma, Shashank" X-Patchwork-Id: 9582137 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0709960578 for ; Mon, 20 Feb 2017 08:21:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E948C28849 for ; Mon, 20 Feb 2017 08:21:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DCD8528856; Mon, 20 Feb 2017 08:21:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2688828849 for ; Mon, 20 Feb 2017 08:21:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7829D6E363; Mon, 20 Feb 2017 08:21:02 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id D81286E363; Mon, 20 Feb 2017 08:21:01 +0000 (UTC) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Feb 2017 00:20:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.35,185,1484035200"; d="scan'208";a="227409829" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by fmsmga004.fm.intel.com with ESMTP; 20 Feb 2017 00:20:58 -0800 Received: from bgsmsx151.gar.corp.intel.com (10.224.48.42) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.248.2; Mon, 20 Feb 2017 00:20:57 -0800 Received: from bgsmsx101.gar.corp.intel.com ([169.254.1.43]) by BGSMSX151.gar.corp.intel.com ([169.254.3.235]) with mapi id 14.03.0248.002; Mon, 20 Feb 2017 13:50:55 +0530 From: "Sharma, Shashank" To: "dri-devel@lists.freedesktop.org" , "intel-gfx@lists.freedesktop.org" , "jose.abreu@synopsys.com" , "jani.nikula@linux.intel.com" Thread-Topic: [PATCH v3 5/6] drm/i915: enable scrambling Thread-Index: AQHSg7leFcfvtZgl1E+bCTF2CCgDHKFxm+wg Date: Mon, 20 Feb 2017 08:20:54 +0000 Message-ID: References: <1486744168-7857-1-git-send-email-shashank.sharma@intel.com> <1486744168-7857-6-git-send-email-shashank.sharma@intel.com> In-Reply-To: <1486744168-7857-6-git-send-email-shashank.sharma@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.223.10.10] MIME-Version: 1.0 Cc: "Vetter, Daniel" , "treding@nvidia.com" Subject: Re: [Intel-gfx] [PATCH v3 5/6] drm/i915: enable scrambling X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 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" X-Virus-Scanned: ClamAV using ClamSMTP Hello Ville, Jani I have addressed all your review comments in this patch set (V3). Can you please have a look if this seems ok ? Link: https://patchwork.kernel.org/patch/9567061/ Regards Shashank -----Original Message----- From: Sharma, Shashank Sent: Friday, February 10, 2017 9:59 PM To: dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; jose.abreu@synopsys.com; jani.nikula@linux.intel.com Cc: ville.syrjala@linux.intel.com; treding@nvidia.com; Vetter, Daniel ; Sharma, Shashank Subject: [PATCH v3 5/6] drm/i915: enable scrambling Geminilake platform sports a native HDMI 2.0 controller, and is capable of driving pixel-clocks upto 594Mhz. HDMI 2.0 spec mendates scrambling for these higher clocks, for reduced RF footprint. This patch checks if the monitor supports scrambling, and if required, enables it during the modeset. V2: Addressed review comments from Ville: - Do not track scrambling status in DRM layer, track somewhere in driver like in intel_crtc_state. - Don't talk to monitor at such a low layer, set monitor scrambling in intel_enable_ddi() before enabling the port. V3: Addressed review comments from Jani - In comments, function names, use "sink" instead of "monitor", so that the implementation could be close to the language of HDMI spec. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/i915_reg.h | 4 ++ drivers/gpu/drm/i915/intel_ddi.c | 28 ++++++++++ drivers/gpu/drm/i915/intel_drv.h | 14 +++++ drivers/gpu/drm/i915/intel_hdmi.c | 106 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 141a5c1..81cf10b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7819,7 +7819,11 @@ enum { #define TRANS_DDI_EDP_INPUT_B_ONOFF (5<<12) #define TRANS_DDI_EDP_INPUT_C_ONOFF (6<<12) #define TRANS_DDI_DP_VC_PAYLOAD_ALLOC (1<<8) +#define TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE (1<<7) #define +TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ (1<<6) #define TRANS_DDI_BFI_ENABLE (1<<4) +#define TRANS_DDI_HIGH_TMDS_CHAR_RATE (1<<4) +#define TRANS_DDI_HDMI_SCRAMBLING (1<<0) /* DisplayPort Transport Control */ #define _DP_TP_CTL_A 0x64040 diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index cd6fedd..bd8293d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1278,6 +1278,11 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) temp |= TRANS_DDI_MODE_SELECT_HDMI; else temp |= TRANS_DDI_MODE_SELECT_DVI; + + if (IS_GEMINILAKE(dev_priv)) + temp = intel_hdmi_handle_source_scrambling( + intel_encoder, + &intel_crtc->config->base.adjusted_mode, temp); } else if (type == INTEL_OUTPUT_ANALOG) { temp |= TRANS_DDI_MODE_SELECT_FDI; temp |= (intel_crtc->config->fdi_lanes - 1) << 1; @@ -1843,6 +1848,21 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder, struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); + if (IS_GEMINILAKE(dev_priv)) { + struct intel_crtc *crtc = to_intel_crtc(encoder->crtc); + /* + * GLK sports a native HDMI 2.0 controller. If required + * clock rate is > 340 Mhz && scrambling is supported + * by sink, enable scrambling before enabling the + * HDMI 2.0 port. The sink can choose to disable the + * scrambling if it doesn't detect a scrambled within + * 100 ms. + */ + intel_hdmi_handle_sink_scrambling(intel_encoder, + conn_state->connector, + crtc->config, true); + } + /* In HDMI/DVI mode, the port width, and swing/emphasis values * are ignored so nothing special needs to be done besides * enabling the port. @@ -1875,6 +1895,14 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder, if (old_crtc_state->has_audio) intel_audio_codec_disable(intel_encoder); + if (type == INTEL_OUTPUT_HDMI) { + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); + + intel_hdmi_handle_sink_scrambling(intel_encoder, + old_conn_state->connector, + intel_crtc->config, false); + } + if (type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 6e37fba..df0170b88 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -691,6 +691,12 @@ struct intel_crtc_state { /* Gamma mode programmed on the pipe */ uint32_t gamma_mode; + + /* HDMI scrambling status (sink) */ + bool scrambling; + + /* HDMI High TMDS char rate ratio (sink) */ + bool high_tmds_clock_ratio; }; struct vlv_wm_state { @@ -1609,6 +1615,14 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port, bool intel_hdmi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state); +uint32_t +intel_hdmi_handle_source_scrambling(struct intel_encoder *intel_encoder, + struct drm_display_mode *mode, + uint32_t config); +void intel_hdmi_handle_sink_scrambling(struct intel_encoder *intel_encoder, + struct drm_connector *connector, + struct intel_crtc_state *config, + bool enable); void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable); diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index a580de8..9970131 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "intel_drv.h" #include #include @@ -1795,6 +1796,111 @@ static void intel_hdmi_destroy(struct drm_connector *connector) intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE; } +void intel_hdmi_handle_sink_scrambling(struct intel_encoder *intel_encoder, + struct drm_connector *connector, + struct intel_crtc_state *config, + bool enable) +{ + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base); + struct drm_scdc *scdc = &connector->display_info.hdmi.scdc; + struct drm_scrambling *scrambling = &scdc->scrambling; + struct drm_display_mode *mode = &config->base.adjusted_mode; + struct drm_i915_private *dev_priv = connector->dev->dev_private; + struct i2c_adapter *adptr = intel_gmbus_get_adapter(dev_priv, + intel_hdmi->ddc_bus); + + if (!scrambling->supported) + return; + + DRM_DEBUG_KMS("Setting sink scrambling for enc:%s connector:%s\n", + intel_encoder->base.name, connector->name); + + if (enable) { + + if (mode->clock > 340000) { + /* Set TMDS bit clock ratio to 1/40 */ + config->high_tmds_clock_ratio = + drm_scdc_set_high_tmds_clock_ratio(adptr); + if (!config->high_tmds_clock_ratio) { + DRM_ERROR("Set high TMDS ratio failed\n"); + return; + } + + /* Enable sink scrambling */ + config->scrambling = drm_scdc_enable_scrambling(adptr); + if (!config->scrambling) { + DRM_ERROR("Can't enable sink scrambling\n"); + return; + } + } + + /* Few sinks support scrambling at clocks <=340 MHz too */ + if (!config->scrambling && scrambling->low_rates) { + config->scrambling = drm_scdc_enable_scrambling(adptr); + if (!config->scrambling) + DRM_ERROR("Can't enable sink scrambling\n"); + } + + return; + } + + if (config->high_tmds_clock_ratio) { + /* Set TMDS bit clock ratio back to 1/10 */ + config->high_tmds_clock_ratio = + !(drm_scdc_clear_high_tmds_clock_ratio(adptr)); + if (config->high_tmds_clock_ratio) + DRM_ERROR("Reset high TMDS ratio failed\n"); + } + + if (config->scrambling) { + /* Disable sink scrambling */ + config->scrambling = !(drm_scdc_disable_scrambling(adptr)); + if (config->scrambling) + DRM_ERROR("Disable sink scrambling failed\n"); + } +} + +static inline uint32_t _intel_hdmi_set_source_scrambling(uint32_t +hdmi_config) { + return hdmi_config |= (TRANS_DDI_HDMI_SCRAMBLING | + TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ | + TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE); +} + +uint32_t +intel_hdmi_handle_source_scrambling(struct intel_encoder *intel_encoder, + struct drm_display_mode *mode, uint32_t hdmi_config) { + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&intel_encoder->base); + struct drm_connector *connector = &intel_hdmi->attached_connector->base; + struct drm_hdmi_info *hdmi_info = &connector->display_info.hdmi; + struct drm_scrambling *scrambling = &hdmi_info->scdc.scrambling; + + DRM_DEBUG_KMS("Setting scrambling for enc:%s connector:%s\n", + intel_encoder->base.name, connector->name); + + hdmi_config &= ~(TRANS_DDI_HDMI_SCRAMBLING | + TRANS_DDI_HIGH_TMDS_CHAR_RATE | + TRANS_DDI_HDMI_SCRAMBLER_RESET_FREQ | + TRANS_DDI_HDMI_SCRAMBLER_CTS_ENABLE); + + if (mode->clock <= 340000) { + /* Few sinks support scrambling at rate < 340 MHz too */ + if (scrambling->low_rates) + hdmi_config = + _intel_hdmi_set_source_scrambling(hdmi_config); + return hdmi_config; + } + + /* Scrambling or not, if clock > 340 MHz, set high char rate */ + hdmi_config |= TRANS_DDI_HIGH_TMDS_CHAR_RATE; + + if (scrambling->supported) + hdmi_config = _intel_hdmi_set_source_scrambling(hdmi_config); + + return hdmi_config; +} + static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv, enum port port) { -- 1.9.1