diff options
author | Zhenyu Wang <zhenyuw@linux.intel.com> | 2009-09-25 04:01:28 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-10-13 13:57:10 -0400 |
commit | 58a27471d00dc09945cbcfbbc5cbcdcd3c28211d (patch) | |
tree | f1679ecad026b8f6cb6440156167808195543881 /drivers | |
parent | c03342fa6d4617a77cb867ee0ec71665d520eb69 (diff) |
drm/i915: Fix FDI M/N setting according with correct color depth
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.
Cc: Stable Team <stable@kernel.org>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 31 |
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 5f9272459b71..0dd87a7309e6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -1782,6 +1782,11 @@ | |||
1782 | #define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ | 1782 | #define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */ |
1783 | #define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) | 1783 | #define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1) |
1784 | #define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) | 1784 | #define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0) |
1785 | #define PIPE_BPC_MASK (7 << 5) /* Ironlake */ | ||
1786 | #define PIPE_8BPC (0 << 5) | ||
1787 | #define PIPE_10BPC (1 << 5) | ||
1788 | #define PIPE_6BPC (2 << 5) | ||
1789 | #define PIPE_12BPC (3 << 5) | ||
1785 | 1790 | ||
1786 | #define DSPARB 0x70030 | 1791 | #define DSPARB 0x70030 |
1787 | #define DSPARB_CSTART_MASK (0x7f << 7) | 1792 | #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 be7fada590d4..8278d9d163ad 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2082,7 +2082,7 @@ fdi_reduce_ratio(u32 *num, u32 *den) | |||
2082 | #define LINK_N 0x80000 | 2082 | #define LINK_N 0x80000 |
2083 | 2083 | ||
2084 | static void | 2084 | static void |
2085 | igdng_compute_m_n(int bytes_per_pixel, int nlanes, | 2085 | igdng_compute_m_n(int bits_per_pixel, int nlanes, |
2086 | int pixel_clock, int link_clock, | 2086 | int pixel_clock, int link_clock, |
2087 | struct fdi_m_n *m_n) | 2087 | struct fdi_m_n *m_n) |
2088 | { | 2088 | { |
@@ -2092,7 +2092,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes, | |||
2092 | 2092 | ||
2093 | temp = (u64) DATA_N * pixel_clock; | 2093 | temp = (u64) DATA_N * pixel_clock; |
2094 | temp = div_u64(temp, link_clock); | 2094 | temp = div_u64(temp, link_clock); |
2095 | m_n->gmch_m = div_u64(temp * bytes_per_pixel, nlanes); | 2095 | m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); |
2096 | m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ | ||
2096 | m_n->gmch_n = DATA_N; | 2097 | m_n->gmch_n = DATA_N; |
2097 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 2098 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
2098 | 2099 | ||
@@ -2766,7 +2767,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2766 | 2767 | ||
2767 | /* FDI link */ | 2768 | /* FDI link */ |
2768 | if (IS_IGDNG(dev)) { | 2769 | if (IS_IGDNG(dev)) { |
2769 | int lane, link_bw; | 2770 | int lane, link_bw, bpp; |
2770 | /* eDP doesn't require FDI link, so just set DP M/N | 2771 | /* eDP doesn't require FDI link, so just set DP M/N |
2771 | according to current link config */ | 2772 | according to current link config */ |
2772 | if (is_edp) { | 2773 | if (is_edp) { |
@@ -2785,7 +2786,29 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
2785 | lane = 4; | 2786 | lane = 4; |
2786 | link_bw = 270000; | 2787 | link_bw = 270000; |
2787 | } | 2788 | } |
2788 | igdng_compute_m_n(3, lane, target_clock, | 2789 | |
2790 | /* determine panel color depth */ | ||
2791 | temp = I915_READ(pipeconf_reg); | ||
2792 | |||
2793 | switch (temp & PIPE_BPC_MASK) { | ||
2794 | case PIPE_8BPC: | ||
2795 | bpp = 24; | ||
2796 | break; | ||
2797 | case PIPE_10BPC: | ||
2798 | bpp = 30; | ||
2799 | break; | ||
2800 | case PIPE_6BPC: | ||
2801 | bpp = 18; | ||
2802 | break; | ||
2803 | case PIPE_12BPC: | ||
2804 | bpp = 36; | ||
2805 | break; | ||
2806 | default: | ||
2807 | DRM_ERROR("unknown pipe bpc value\n"); | ||
2808 | bpp = 24; | ||
2809 | } | ||
2810 | |||
2811 | igdng_compute_m_n(bpp, lane, target_clock, | ||
2789 | link_bw, &m_n); | 2812 | link_bw, &m_n); |
2790 | } | 2813 | } |
2791 | 2814 | ||