drm/i915: fix pixel color depth setting on eDP
Original DP mode_valid check didn't take pixel color depth into account, which made one 1600x900 eDP panel's mode check invalid because of overclock, but actually this 6bpc panel does can work with x1 lane at 2.7G. This one trys to take bpp value properly both in mode validation and mode setting. Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
parent
500a8cc466
commit
885a5fb5b1
2 changed files with 27 additions and 4 deletions
|
@ -2924,6 +2924,21 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
temp |= PIPE_8BPC;
|
temp |= PIPE_8BPC;
|
||||||
else
|
else
|
||||||
temp |= PIPE_6BPC;
|
temp |= PIPE_6BPC;
|
||||||
|
} else if (is_edp) {
|
||||||
|
switch (dev_priv->edp_bpp/3) {
|
||||||
|
case 8:
|
||||||
|
temp |= PIPE_8BPC;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
temp |= PIPE_10BPC;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
temp |= PIPE_6BPC;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
temp |= PIPE_12BPC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
temp |= PIPE_8BPC;
|
temp |= PIPE_8BPC;
|
||||||
I915_WRITE(pipeconf_reg, temp);
|
I915_WRITE(pipeconf_reg, temp);
|
||||||
|
|
|
@ -125,9 +125,15 @@ intel_dp_link_clock(uint8_t link_bw)
|
||||||
|
|
||||||
/* I think this is a fiction */
|
/* I think this is a fiction */
|
||||||
static int
|
static int
|
||||||
intel_dp_link_required(int pixel_clock)
|
intel_dp_link_required(struct drm_device *dev,
|
||||||
|
struct intel_output *intel_output, int pixel_clock)
|
||||||
{
|
{
|
||||||
return pixel_clock * 3;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
|
|
||||||
|
if (IS_eDP(intel_output))
|
||||||
|
return (pixel_clock * dev_priv->edp_bpp) / 8;
|
||||||
|
else
|
||||||
|
return pixel_clock * 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -138,7 +144,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
|
||||||
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
|
int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output));
|
||||||
int max_lanes = intel_dp_max_lane_count(intel_output);
|
int max_lanes = intel_dp_max_lane_count(intel_output);
|
||||||
|
|
||||||
if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes)
|
if (intel_dp_link_required(connector->dev, intel_output, mode->clock)
|
||||||
|
> max_link_clock * max_lanes)
|
||||||
return MODE_CLOCK_HIGH;
|
return MODE_CLOCK_HIGH;
|
||||||
|
|
||||||
if (mode->clock < 10000)
|
if (mode->clock < 10000)
|
||||||
|
@ -492,7 +499,8 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
||||||
for (clock = 0; clock <= max_clock; clock++) {
|
for (clock = 0; clock <= max_clock; clock++) {
|
||||||
int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
|
int link_avail = intel_dp_link_clock(bws[clock]) * lane_count;
|
||||||
|
|
||||||
if (intel_dp_link_required(mode->clock) <= link_avail) {
|
if (intel_dp_link_required(encoder->dev, intel_output, mode->clock)
|
||||||
|
<= link_avail) {
|
||||||
dp_priv->link_bw = bws[clock];
|
dp_priv->link_bw = bws[clock];
|
||||||
dp_priv->lane_count = lane_count;
|
dp_priv->lane_count = lane_count;
|
||||||
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
|
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);
|
||||||
|
|
Loading…
Reference in a new issue