[Intel-gfx] [PATCH] drm/i915/dp/mst : Get clock rate from sink's available PBN

Lee, Shawn C shawn.c.lee at intel.com
Thu Jan 9 03:11:14 UTC 2020


On Jan. 8, 2020, 3:15 p.m, Ville Syrjala wrote:
>On Tue, Jan 07, 2020 at 01:41:56AM +0800, Lee Shawn C wrote:
>> Driver report physcial bandwidth for max dot clock rate.
>> It would caused compatibility issue sometimes when physical
>> bandwidth exceed MST hub output ability.
>> 
>> For example, here is a MST hub with HDMI 1.4 and DP 1.2 output.
>> And source have DP 1.2 output capability. Connect a HDMI 2.0
>> display then source will retrieve EDID from external monitor.
>> Driver got max resolution was 4k at 60fps. DP 1.2 can support
>> this resolution because it did not surpass max physical bandwidth.
>> After modeset, source output display data but MST hub can't
>> output HDMI properly due to it already over HDMI 1.4 spec.
>> 
>> Apply this calculation, source calcualte max dot clock according
>> to available PBN. Driver will remove the mode that over current
>> clock rate. And external display can works normally.
>> 
>> Cc: Manasi Navare <manasi.d.navare at intel.com>
>> Cc: Jani Nikula <jani.nikula at linux.intel.com>
>> Cc: Ville Syrjala <ville.syrjala at linux.intel.com>
>> Cc: Cooper Chiou <cooper.chiou at intel.com>
>> 
>> Signed-off-by: Lee Shawn C <shawn.c.lee at intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 27 ++++++++++++++++++---
>>  1 file changed, 24 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> index 3b066c63816d..eaa440165ad2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> @@ -550,6 +550,27 @@ static int intel_dp_mst_get_modes(struct drm_connector *connector)
>>  	return intel_dp_mst_get_ddc_modes(connector);
>>  }
>>  
>> +static int
>> +intel_dp_mst_downstream_max_dotclock(struct drm_connector *connector)
>> +{
>> +	struct intel_connector *intel_connector = to_intel_connector(connector);
>> +	struct intel_dp *intel_dp = intel_connector->mst_port;
>> +	struct drm_dp_mst_port *port;
>> +	u64 clock_rate = 0;
>> +
>> +	if (intel_dp->mst_mgr.mst_primary)
>> +		list_for_each_entry(port, &intel_dp->mst_mgr.mst_primary->ports, next)
>> +			if (port->connector == connector) {
>> +				clock_rate = ((u64)port->available_pbn * (54 * 8 * 1000 * 1000)) / (64 * 1006);
>
>IIRC avaible pbn is soime kind of dynamic "how much bw we have left
>currently" so we don't want to use it for this purpose. If we really
>wanted to do this we'd have to refilter the modelist and generate
>hotplugs whenever the bw allocations change.
>
>In the current design what should happens is that we check that we
>have enough bw when doing the modeset, and if that fails userspace
>is supposed to handle the situation in some graceful manner.
>
>Also locking totally missing.
>
>So nak.
>

Thanks for comments! In my opinion, branch device (MST hub) would tell
source driver the available PBN for each extended port it owns.
And source driver will renew it everytime after HPD coming. 
That's why we should refer the PBN report by MST branch to calculate
dot clock rate and make sure sink can support the resolution while
creating mode list.

>> +
>> +				// FIXME: We should used pipe bpp to do this calculation.
>> +				//        But can't retrieve bpp setting from drm_connector.
>> +				return (int)(clock_rate / 24);
>> +			}
>> +
>> +	return to_i915(connector->dev)->max_dotclk_freq;
>> +}
>> +

Here try to get the max dot clock according to PBN value from sink. If driver can't
find it, will return the orginal max_dotclk_freq.

>>  static enum drm_mode_status
>>  intel_dp_mst_mode_valid(struct drm_connector *connector,
>>  			struct drm_display_mode *mode)
>> @@ -557,8 +578,7 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
>>  	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;
>> -	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
>> -	int max_rate, mode_rate, max_lanes, max_link_clock;
>> +	int max_rate, mode_rate, max_lanes, max_link_clock, max_dotclk;
>>  
>>  	if (drm_connector_is_unregistered(connector))
>>  		return MODE_ERROR;
>> @@ -572,7 +592,8 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
>>  	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
>>  	mode_rate = intel_dp_link_required(mode->clock, 18);
>>  
>> -	/* TODO - validate mode against available PBN for link */
>> +	max_dotclk = intel_dp_mst_downstream_max_dotclock(connector);
>> +

Then driver would the clock rate exceed max_dotclk or not to create mode list.

	if (mode_rate > max_rate || mode->clock > max_dotclk)
		return MODE_CLOCK_HIGH;

When connect to MST hub with HDMI 1.4 output. If user connect the monitor with
HDMI 2.0 capability. EDID from sink shows it can meet DP 1.2 requirement and
source set the prefer resolution (4k at 60fps) to display. But MST hub can't
output the video data via its HDMI port due to this resolution already exceed
its ability.

This change may increase source driver compatibility at MST mode. Please give us
advice if more concern.

>>  	if (mode->clock < 10000)
>>  		return MODE_CLOCK_LOW;
>>  
>> -- 
>> 2.17.1


More information about the Intel-gfx mailing list