summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorZhenyu Wang <zhenyuw@linux.intel.com>2009-09-25 08:01:28 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2009-11-09 16:22:36 -0800
commita9d48b3eae33aeb6bc1c366913778d77267e17b7 (patch)
tree059b8ba90c06b92d612a6d7c014816b1a981d1d6 /drivers
parent61ac9e400eb6c0c3d3e9da24c78176fbe272fc1b (diff)
drm/i915: Fix FDI M/N setting according with correct color depth
commit 58a27471d00dc09945cbcfbbc5cbcdcd3c28211d upstream. FDI M/N calculation hasn't taken the current pipe color depth into account, but always set as 24bpp. This one checks current pipe color depth setting, and change FDI M/N calculation a little to use bits_per_pixel first, then convert to bytes_per_pixel later. This fixes display corrupt issue on Arrandle LVDS with 1600x900 panel in 18bpp dual-channel mode. Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h5
-rw-r--r--drivers/gpu/drm/i915/intel_display.c31
2 files changed, 32 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 106a1ae5321e..7ef7e4d81d1e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1616,6 +1616,11 @@
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
+#define PIPE_BPC_MASK (7 << 5) /* Ironlake */
+#define PIPE_8BPC (0 << 5)
+#define PIPE_10BPC (1 << 5)
+#define PIPE_6BPC (2 << 5)
+#define PIPE_12BPC (3 << 5)
#define DSPARB 0x70030
#define DSPARB_CSTART_MASK (0x7f << 7)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8b5af2938282..0fb177e7c817 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1764,7 +1764,7 @@ fdi_reduce_ratio(u32 *num, u32 *den)
#define LINK_N 0x80000
static void
-igdng_compute_m_n(int bytes_per_pixel, int nlanes,
+igdng_compute_m_n(int bits_per_pixel, int nlanes,
int pixel_clock, int link_clock,
struct fdi_m_n *m_n)
{
@@ -1774,7 +1774,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes,
temp = (u64) DATA_N * pixel_clock;
temp = div_u64(temp, link_clock);
- m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes);
+ m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes);
+ m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */
m_n->gmch_n = DATA_N;
fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
@@ -2396,7 +2397,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
/* FDI link */
if (IS_IGDNG(dev)) {
- int lane, link_bw;
+ int lane, link_bw, bpp;
/* eDP doesn't require FDI link, so just set DP M/N
according to current link config */
if (is_edp) {
@@ -2415,7 +2416,29 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
lane = 4;
link_bw = 270000;
}
- igdng_compute_m_n(3, lane, target_clock,
+
+ /* determine panel color depth */
+ temp = I915_READ(pipeconf_reg);
+
+ switch (temp & PIPE_BPC_MASK) {
+ case PIPE_8BPC:
+ bpp = 24;
+ break;
+ case PIPE_10BPC:
+ bpp = 30;
+ break;
+ case PIPE_6BPC:
+ bpp = 18;
+ break;
+ case PIPE_12BPC:
+ bpp = 36;
+ break;
+ default:
+ DRM_ERROR("unknown pipe bpc value\n");
+ bpp = 24;
+ }
+
+ igdng_compute_m_n(bpp, lane, target_clock,
link_bw, &m_n);
}