mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
c03342fa6d
commit
58a27471d0
|
@ -1782,6 +1782,11 @@
|
||||||
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
|
#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
|
||||||
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
|
#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
|
||||||
#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
|
#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 0x70030
|
||||||
#define DSPARB_CSTART_MASK (0x7f << 7)
|
#define DSPARB_CSTART_MASK (0x7f << 7)
|
||||||
|
|
|
@ -2082,7 +2082,7 @@ fdi_reduce_ratio(u32 *num, u32 *den)
|
||||||
#define LINK_N 0x80000
|
#define LINK_N 0x80000
|
||||||
|
|
||||||
static void
|
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,
|
int pixel_clock, int link_clock,
|
||||||
struct fdi_m_n *m_n)
|
struct fdi_m_n *m_n)
|
||||||
{
|
{
|
||||||
|
@ -2092,7 +2092,8 @@ igdng_compute_m_n(int bytes_per_pixel, int nlanes,
|
||||||
|
|
||||||
temp = (u64) DATA_N * pixel_clock;
|
temp = (u64) DATA_N * pixel_clock;
|
||||||
temp = div_u64(temp, link_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;
|
m_n->gmch_n = DATA_N;
|
||||||
fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
|
fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
|
||||||
|
|
||||||
|
@ -2766,7 +2767,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
|
|
||||||
/* FDI link */
|
/* FDI link */
|
||||||
if (IS_IGDNG(dev)) {
|
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
|
/* eDP doesn't require FDI link, so just set DP M/N
|
||||||
according to current link config */
|
according to current link config */
|
||||||
if (is_edp) {
|
if (is_edp) {
|
||||||
|
@ -2785,7 +2786,29 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
|
||||||
lane = 4;
|
lane = 4;
|
||||||
link_bw = 270000;
|
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);
|
link_bw, &m_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue