lkml.org 
[lkml]   [2012]   [Apr]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[ 05/68] drm/i915: properly compute dp dithering for user-created modes
    3.2-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Daniel Vetter <daniel.vetter@ffwll.ch>

    commit c4867936474183332db4c19791a65fdad6474fd5 upstream.

    We've only computed whether we need to fall back to 6bpc due to dp
    link bandwidth constrains in mode_valid, but not mode_fixup. Under
    various circumstances X likes to create new modes which then lack
    proper 6bpc flags (if required), resulting in mode_fixup failures and
    ultimately black screens.

    Chris Wilson pointed out that we still get things wrong for bpp > 24,
    but that should be fixed in another patch (and it'll be easier because
    this patch consolidates the logic).

    The likely culprit for this regression is

    commit 3d794f87238f74d80e78a7611c7fbde8a54c85c2
    Author: Keith Packard <keithp@keithp.com>
    Date: Wed Jan 25 08:16:25 2012 -0800

    drm/i915: Force explicit bpp selection for intel_dp_link_required

    v2: Fix indentation and tune down the too bold claim that this should
    fix the world. Both noticed by Chris Wilson.

    v3: Try to really git add things.

    Reported-and-tested-by: Brice Goglin <Brice.Goglin@ens-lyon.org>
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=48170
    Cc: stable@kernel.org
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/gpu/drm/i915/intel_dp.c | 49 ++++++++++++++++++++++++++++------------
    1 file changed, 35 insertions(+), 14 deletions(-)

    --- a/drivers/gpu/drm/i915/intel_dp.c
    +++ b/drivers/gpu/drm/i915/intel_dp.c
    @@ -219,14 +219,38 @@ intel_dp_max_data_rate(int max_link_cloc
    return (max_link_clock * max_lanes * 8) / 10;
    }

    +static bool
    +intel_dp_adjust_dithering(struct intel_dp *intel_dp,
    + struct drm_display_mode *mode,
    + struct drm_display_mode *adjusted_mode)
    +{
    + int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
    + int max_lanes = intel_dp_max_lane_count(intel_dp);
    + int max_rate, mode_rate;
    +
    + mode_rate = intel_dp_link_required(mode->clock, 24);
    + max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
    +
    + if (mode_rate > max_rate) {
    + mode_rate = intel_dp_link_required(mode->clock, 18);
    + if (mode_rate > max_rate)
    + return false;
    +
    + if (adjusted_mode)
    + adjusted_mode->private_flags
    + |= INTEL_MODE_DP_FORCE_6BPC;
    +
    + return true;
    + }
    +
    + return true;
    +}
    +
    static int
    intel_dp_mode_valid(struct drm_connector *connector,
    struct drm_display_mode *mode)
    {
    struct intel_dp *intel_dp = intel_attached_dp(connector);
    - int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp));
    - int max_lanes = intel_dp_max_lane_count(intel_dp);
    - int max_rate, mode_rate;

    if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
    if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay)
    @@ -236,16 +260,8 @@ intel_dp_mode_valid(struct drm_connector
    return MODE_PANEL;
    }

    - mode_rate = intel_dp_link_required(mode->clock, 24);
    - max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
    -
    - if (mode_rate > max_rate) {
    - mode_rate = intel_dp_link_required(mode->clock, 18);
    - if (mode_rate > max_rate)
    - return MODE_CLOCK_HIGH;
    - else
    - mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC;
    - }
    + if (!intel_dp_adjust_dithering(intel_dp, mode, NULL))
    + return MODE_CLOCK_HIGH;

    if (mode->clock < 10000)
    return MODE_CLOCK_LOW;
    @@ -673,7 +689,7 @@ intel_dp_mode_fixup(struct drm_encoder *
    int lane_count, clock;
    int max_lane_count = intel_dp_max_lane_count(intel_dp);
    int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0;
    - int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
    + int bpp;
    static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 };

    if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) {
    @@ -687,6 +703,11 @@ intel_dp_mode_fixup(struct drm_encoder *
    mode->clock = intel_dp->panel_fixed_mode->clock;
    }

    + if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode))
    + return false;
    +
    + bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24;
    +
    for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
    for (clock = 0; clock <= max_clock; clock++) {
    int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count);



    \
     
     \ /
      Last update: 2012-04-19 23:19    [W:0.045 / U:0.740 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site