Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp892477ybt; Fri, 10 Jul 2020 15:25:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxWy2WIwrjVVNeX9Irbb5+FIbdeUMyYwVPZnJxjFcpgzTBHrgSvC+NMmx/bLV/VBvoAsx5p X-Received: by 2002:a17:906:26c7:: with SMTP id u7mr59930968ejc.13.1594419938955; Fri, 10 Jul 2020 15:25:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594419938; cv=none; d=google.com; s=arc-20160816; b=S8mFryONmrGAD2EVyNpyd1Tm3iPJsR4s4oR3clxLrjMEAk9nKjMU7Hy80Tt7kSRhZy DfaYrjAbBnqDYtE7mKxdpn4Xn1j1nQ2AsWwRbrlXg5b79sVjtVG0XNTRTenueYA/L9UX Y4lvJffMiCCHiJGqNfLBhtBARir9we77CF6YGyvgu9vTdarjMz4e7byHyMscOXTgGx+e 0uDLGuB0lKGMMsxT9O16L7MPzML8ATfLJrw1n960tN1pY6mBM/CNH/pE52WrBJlMwEb5 JwUNOS7rfyUXd8I7KIpFbmzURT5jafnc4/W1BH5qQDIcsrbXzUZ7RNJ0/RUb+kdyM3A/ RAbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:reply-to:message-id :subject:cc:to:from:date:ironport-sdr:ironport-sdr; bh=P0jocTLPCVgJpyDaE1DVSnVHZPU7N2idpV7cPGG4g4g=; b=ns9qaN7HKTLJcsTF+x6OOs4v+U6xsPAd45S5oBCH2vbncQPElj3gtaA367WPVInTZy EShv4R3pId/ajoK9pe8q/WO2ZaRHooQcGbv4pEnV5WLrLV/XdQWI/keQbRmnv8pDorNZ klIXS/b+Mixm4dFfif3TKr+ntnnfFFlr4t9ruQM4142RHNV9hGqxRt/MKJRMd+Urb/dv 3mhGIxDjsBRFz/nT9167TNatzBXmrCFRETvJEsXfS0n8q8eZw9+JQBnSC1h5yLlZ7Sl9 xBH4ldKk4iy0ZGHcuHf2x3NFuSq0v4HeMsS0qEnnw/GLWO+Bl5P/eM+/D8BwzuuFv+Y0 3kzw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t7si4805604ejx.225.2020.07.10.15.25.11; Fri, 10 Jul 2020 15:25:38 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726533AbgGJWY5 (ORCPT + 99 others); Fri, 10 Jul 2020 18:24:57 -0400 Received: from mga12.intel.com ([192.55.52.136]:36378 "EHLO mga12.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726476AbgGJWY5 (ORCPT ); Fri, 10 Jul 2020 18:24:57 -0400 IronPort-SDR: DQ+ePe7RYilR01sMbszQ4FG3shMEV6NuY4v0YGZh43Hd7v7dX5eX+EShXOlxHCiNWsVHahodfT hVd2woB5uclQ== X-IronPort-AV: E=McAfee;i="6000,8403,9678"; a="127888362" X-IronPort-AV: E=Sophos;i="5.75,336,1589266800"; d="scan'208";a="127888362" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2020 15:24:56 -0700 IronPort-SDR: QTrIxQ9gFItrcLdTgCaiZz6+5IqtsmFMfnikhpSabdxGcjxuYy3sTOz0Mx24WUt/rjZyPzOLqo rqrfhd+yurAg== X-IronPort-AV: E=Sophos;i="5.75,336,1589266800"; d="scan'208";a="269197913" Received: from ideak-desk.fi.intel.com ([10.237.68.147]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Jul 2020 15:24:53 -0700 Date: Sat, 11 Jul 2020 01:24:47 +0300 From: Imre Deak To: Lyude Paul Cc: intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, Lee Shawn C , Manasi Navare , Jani Nikula , Ville Syrjala , Cooper Chiou , Joonas Lahtinen , Rodrigo Vivi , David Airlie , Daniel Vetter , =?iso-8859-1?Q?Jos=E9?= Roberto de Souza , Lucas De Marchi , Pankaj Bharadiya , open list Subject: Re: [PATCH v3 2/2] drm/i915/mst: filter out the display mode exceed sink's capability Message-ID: <20200710222447.GB29318@ideak-desk.fi.intel.com> Reply-To: imre.deak@intel.com References: <20200710193144.94751-1-lyude@redhat.com> <20200710193144.94751-3-lyude@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200710193144.94751-3-lyude@redhat.com> User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jul 10, 2020 at 03:31:44PM -0400, Lyude Paul wrote: > From: Lee Shawn C > > So far, max dot clock rate for MST mode rely on physcial > bandwidth limitation. It would caused compatibility issue > if source display resolution exceed MST hub output ability. > > For example, source DUT had DP 1.2 output capability. > And MST docking just support HDMI 1.4 spec. When a HDMI 2.0 > monitor connected. Source would retrieve EDID from external > and get max resolution 4k@60fps. DP 1.2 can support 4K@60fps > because it did not surpass DP physical bandwidth limitation. > Do modeset to 4k@60fps, source output display data but MST > docking can't output HDMI properly due to this resolution > already over HDMI 1.4 spec. > > Refer to commit ("drm/dp_mst: Use full_pbn > instead of available_pbn for bandwidth checks"). > Source driver should refer to full_pbn to evaluate sink > output capability. And filter out the resolution surpass > sink output limitation. > > Changes since v1: > * Using mgr->base.lock to protect full_pbn. > Changes since v2: > * Add ctx lock. > Changes since v3: > * s/intel_dp_mst_mode_clock_exceed_pbn_bandwidth/ > intel_dp_mst_mode_clock_exceeds_pbn_bw/ > * Use the new drm_connector_helper_funcs.mode_valid_ctx to properly pipe > down the drm_modeset_acquire_ctx that the probe helpers are using, so > we can safely grab &mgr->base.lock without deadlocking > Changes since v4: > * Move drm_dp_calc_pbn_mode(mode->clock, bpp, false) > port->full_pbn > check > * Fix the bpp we use in drm_dp_calc_pbn_mode() > * Drop leftover (!mgr) check > * Don't check for if full_pbn is unset. To be clear - it _can_ be unset, > but if it is then it's certainly a bug in DRM or a non-compliant sink > as full_pbn should always be populated by the time we call > ->mode_valid_ctx. > We should workaround non-compliant sinks with full_pbn=0, but that > should happen in the DP MST helpers so we can estimate the full_pbn > value as best we can. I guess when the connector gets unplugged full_pbn would also get reset but pruning all modes in that case is ok. > > Cc: Manasi Navare > Cc: Jani Nikula > Cc: Ville Syrjala > Cc: Cooper Chiou > Co-developed-by: Lyude Paul > Signed-off-by: Lee Shawn C > Signed-off-by: Lyude Paul Reviewed-and-tested-by: Imre Deak > --- > drivers/gpu/drm/i915/display/intel_dp_mst.c | 55 ++++++++++++++------- > 1 file changed, 38 insertions(+), 17 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c > index bdc19b04b2c10..a2d91a4997001 100644 > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c > @@ -639,39 +639,60 @@ static int intel_dp_mst_get_modes(struct drm_connector *connector) > return intel_dp_mst_get_ddc_modes(connector); > } > > -static enum drm_mode_status > -intel_dp_mst_mode_valid(struct drm_connector *connector, > - struct drm_display_mode *mode) > +static int > +intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, > + struct drm_display_mode *mode, > + struct drm_modeset_acquire_ctx *ctx, > + enum drm_mode_status *status) > { > struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_connector *intel_connector = to_intel_connector(connector); > struct intel_dp *intel_dp = intel_connector->mst_port; > + struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; > + struct drm_dp_mst_port *port = intel_connector->port; > + const int min_bpp = 18; > int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; > int max_rate, mode_rate, max_lanes, max_link_clock; > + int ret; > > - if (drm_connector_is_unregistered(connector)) > - return MODE_ERROR; > + if (drm_connector_is_unregistered(connector)) { > + *status = MODE_ERROR; > + return 0; > + } > > - if (mode->flags & DRM_MODE_FLAG_DBLSCAN) > - return MODE_NO_DBLESCAN; > + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { > + *status = MODE_NO_DBLESCAN; > + return 0; > + } > > max_link_clock = intel_dp_max_link_rate(intel_dp); > max_lanes = intel_dp_max_lane_count(intel_dp); > > max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); > - mode_rate = intel_dp_link_required(mode->clock, 18); > + mode_rate = intel_dp_link_required(mode->clock, min_bpp); > > - /* TODO - validate mode against available PBN for link */ > - if (mode->clock < 10000) > - return MODE_CLOCK_LOW; > + ret = drm_modeset_lock(&mgr->base.lock, ctx); > + if (ret) > + return ret; > > - if (mode->flags & DRM_MODE_FLAG_DBLCLK) > - return MODE_H_ILLEGAL; > + if (mode_rate > max_rate || mode->clock > max_dotclk || > + drm_dp_calc_pbn_mode(mode->clock, min_bpp, false) > port->full_pbn) { > + *status = MODE_CLOCK_HIGH; > + return 0; > + } > + > + if (mode->clock < 10000) { > + *status = MODE_CLOCK_LOW; > + return 0; > + } > > - if (mode_rate > max_rate || mode->clock > max_dotclk) > - return MODE_CLOCK_HIGH; > + if (mode->flags & DRM_MODE_FLAG_DBLCLK) { > + *status = MODE_H_ILLEGAL; > + return 0; > + } > > - return intel_mode_valid_max_plane_size(dev_priv, mode); > + *status = intel_mode_valid_max_plane_size(dev_priv, mode); > + return 0; > } > > static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector, > @@ -700,7 +721,7 @@ intel_dp_mst_detect(struct drm_connector *connector, > > static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { > .get_modes = intel_dp_mst_get_modes, > - .mode_valid = intel_dp_mst_mode_valid, > + .mode_valid_ctx = intel_dp_mst_mode_valid_ctx, > .atomic_best_encoder = intel_mst_atomic_best_encoder, > .atomic_check = intel_dp_mst_atomic_check, > .detect_ctx = intel_dp_mst_detect, > -- > 2.26.2 >