summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyuw@linux.intel.com>2010-01-12 05:38:31 +0800
committerEric Anholt <eric@anholt.net>2010-01-15 14:13:06 -0800
commit885a5fb5b120a5c7e0b3baad7b0feb5a89f76c18 (patch)
treec0a636d952445b79d7e2301e1796b6c175c27c8a
parent500a8cc466a24e2fbc4c86ef9c6467ae2ffdeb0c (diff)
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>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c15
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c16
2 files changed, 27 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4b96a54b8e4..45da78ef4a9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2924,6 +2924,21 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
temp |= PIPE_8BPC;
else
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
temp |= PIPE_8BPC;
I915_WRITE(pipeconf_reg, temp);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0ec07e43d6c..184b6780c44 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -125,9 +125,15 @@ intel_dp_link_clock(uint8_t link_bw)
/* I think this is a fiction */
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
@@ -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_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;
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++) {
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->lane_count = lane_count;
adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw);