aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/atombios_crtc.c22
-rw-r--r--linux-core/radeon_display.c7
-rw-r--r--linux-core/radeon_encoders.c16
-rw-r--r--linux-core/radeon_legacy_crtc.c7
-rw-r--r--linux-core/radeon_mode.h15
-rw-r--r--linux-core/radeon_reg.h45
6 files changed, 76 insertions, 36 deletions
diff --git a/linux-core/atombios_crtc.c b/linux-core/atombios_crtc.c
index 03077a13..cefe9225 100644
--- a/linux-core/atombios_crtc.c
+++ b/linux-core/atombios_crtc.c
@@ -150,8 +150,7 @@ void atombios_crtc_set_timing(struct drm_crtc *crtc, SET_CRTC_TIMING_PARAMETERS_
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&conv_param);
}
-void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode,
- int pll_flags)
+void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
@@ -164,10 +163,17 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode,
uint32_t sclock = mode->clock;
uint32_t ref_div = 0, fb_div = 0, post_div = 0;
struct radeon_pll *pll;
+ int pll_flags = 0;
memset(&spc_param, 0, sizeof(SET_PIXEL_CLOCK_PS_ALLOCATION));
- pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+ if (!radeon_is_avivo(dev_priv))
+ pll_flags |= RADEON_PLL_LEGACY;
+
+ if (mode->clock > 120000) /* range limits??? */
+ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
if (radeon_crtc->crtc_id == 0)
pll = &dev_priv->mode_info.p1pll;
@@ -293,6 +299,12 @@ void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y)
RADEON_WRITE(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
+ if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE)
+ RADEON_WRITE(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
+ AVIVO_D1MODE_INTERLEAVE_EN);
+ else
+ RADEON_WRITE(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset,
+ 0);
}
void atombios_crtc_mode_set(struct drm_crtc *crtc,
@@ -305,7 +317,6 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc,
struct drm_radeon_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder;
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
- int pll_flags = 0;
/* TODO color tiling */
memset(&crtc_timing, 0, sizeof(crtc_timing));
@@ -347,9 +358,10 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc,
else
radeon_crtc_set_base(crtc, x, y);
- atombios_crtc_set_pll(crtc, adjusted_mode, pll_flags);
+ atombios_crtc_set_pll(crtc, adjusted_mode);
atombios_crtc_set_timing(crtc, &crtc_timing);
+
}
static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c
index fd0855e5..e2d02be0 100644
--- a/linux-core/radeon_display.c
+++ b/linux-core/radeon_display.c
@@ -451,7 +451,12 @@ void radeon_compute_pll(struct radeon_pll *pll,
best_freq = current_freq;
best_error = error;
best_vco_diff = vco_diff;
- } else if ((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) {
+ } else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) ||
+ ((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) ||
+ ((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) ||
+ ((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) ||
+ ((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) ||
+ ((flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) {
best_post_div = post_div;
best_ref_div = ref_div;
best_feedback_div = feedback_div;
diff --git a/linux-core/radeon_encoders.c b/linux-core/radeon_encoders.c
index 82ffcfb0..98be7057 100644
--- a/linux-core/radeon_encoders.c
+++ b/linux-core/radeon_encoders.c
@@ -517,9 +517,15 @@ static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode)
}
static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder,
- struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
{
+
+ /* hw bug */
+ if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
+ && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
+ adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
+
return true;
}
@@ -987,6 +993,12 @@ static bool radeon_atom_tmds_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
+
+ /* hw bug */
+ if ((mode->flags & DRM_MODE_FLAG_INTERLACE)
+ && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2)))
+ adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2;
+
return true;
}
diff --git a/linux-core/radeon_legacy_crtc.c b/linux-core/radeon_legacy_crtc.c
index f029c478..d51fc52d 100644
--- a/linux-core/radeon_legacy_crtc.c
+++ b/linux-core/radeon_legacy_crtc.c
@@ -401,7 +401,7 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode
uint32_t post_divider = 0;
uint32_t freq = 0;
uint8_t pll_gain;
- int pll_flags = RADEON_PLL_LEGACY | RADEON_PLL_PREFER_LOW_REF_DIV;
+ int pll_flags = RADEON_PLL_LEGACY;
bool use_bios_divs = false;
/* PLL registers */
uint32_t ppll_ref_div = 0;
@@ -431,6 +431,11 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode
{ 0, 0 }
};
+ if (mode->clock > 120000) /* range limits??? */
+ pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
+ else
+ pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
+
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) {
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h
index 62672c33..d4b33dd9 100644
--- a/linux-core/radeon_mode.h
+++ b/linux-core/radeon_mode.h
@@ -137,11 +137,16 @@ struct radeon_tmds_pll {
#define RADEON_MAX_BIOS_CONNECTOR 16
-#define RADEON_PLL_USE_BIOS_DIVS (1 << 0)
-#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
-#define RADEON_PLL_USE_REF_DIV (1 << 2)
-#define RADEON_PLL_LEGACY (1 << 3)
-#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4)
+#define RADEON_PLL_USE_BIOS_DIVS (1 << 0)
+#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
+#define RADEON_PLL_USE_REF_DIV (1 << 2)
+#define RADEON_PLL_LEGACY (1 << 3)
+#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4)
+#define RADEON_PLL_PREFER_HIGH_REF_DIV (1 << 5)
+#define RADEON_PLL_PREFER_LOW_FB_DIV (1 << 6)
+#define RADEON_PLL_PREFER_HIGH_FB_DIV (1 << 7)
+#define RADEON_PLL_PREFER_LOW_POST_DIV (1 << 8)
+#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9)
struct radeon_pll {
uint16_t reference_freq;
diff --git a/linux-core/radeon_reg.h b/linux-core/radeon_reg.h
index 113a8267..8698e861 100644
--- a/linux-core/radeon_reg.h
+++ b/linux-core/radeon_reg.h
@@ -3583,7 +3583,7 @@
#define AVIVO_D1CRTC_V_SYNC_B_CNTL 0x6034
#define AVIVO_D1CRTC_CONTROL 0x6080
-# define AVIVO_CRTC_EN (1<<0)
+# define AVIVO_CRTC_EN (1 << 0)
#define AVIVO_D1CRTC_BLANK_CONTROL 0x6084
#define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088
#define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c
@@ -3595,30 +3595,30 @@
#define AVIVO_D1GRPH_ENABLE 0x6100
#define AVIVO_D1GRPH_CONTROL 0x6104
-# define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0<<0)
-# define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1<<0)
-# define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2<<0)
-# define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP (3<<0)
+# define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0 << 0)
+# define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1 << 0)
+# define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2 << 0)
+# define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP (3 << 0)
-# define AVIVO_D1GRPH_CONTROL_8BPP_INDEXED (0<<8)
+# define AVIVO_D1GRPH_CONTROL_8BPP_INDEXED (0 << 8)
-# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555 (0<<8)
-# define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1<<8)
-# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2<<8)
-# define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3<<8)
-# define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4<<8)
+# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555 (0 << 8)
+# define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1 << 8)
+# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2 << 8)
+# define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3 << 8)
+# define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4 << 8)
-# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0<<8)
-# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1<<8)
-# define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2<<8)
-# define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3<<8)
+# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0 << 8)
+# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1 << 8)
+# define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2 << 8)
+# define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3 << 8)
-# define AVIVO_D1GRPH_CONTROL_64BPP_ARGB16161616 (0<<8)
+# define AVIVO_D1GRPH_CONTROL_64BPP_ARGB16161616 (0 << 8)
-# define AVIVO_D1GRPH_SWAP_RB (1<<16)
-# define AVIVO_D1GRPH_TILED (1<<20)
-# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1<<21)
+# define AVIVO_D1GRPH_SWAP_RB (1 << 16)
+# define AVIVO_D1GRPH_TILED (1 << 20)
+# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21)
#define AVIVO_D1GRPH_LUT_SEL 0x6108
#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110
@@ -3644,7 +3644,7 @@
#define AVIVO_D1CUR_POSITION 0x6414
#define AVIVO_D1CUR_HOT_SPOT 0x6418
#define AVIVO_D1CUR_UPDATE 0x6424
-# define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16)
+# define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16)
#define AVIVO_DC_LUT_RW_SELECT 0x6480
#define AVIVO_DC_LUT_RW_MODE 0x6484
@@ -3664,7 +3664,8 @@
#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4
#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8
-
+#define AVIVO_D1MODE_DATA_FORMAT 0x6528
+# define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0)
#define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C
#define AVIVO_D1MODE_VIEWPORT_START 0x6580
#define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584
@@ -3674,7 +3675,7 @@
#define AVIVO_D1SCL_SCALER_ENABLE 0x6590
#define AVIVO_D1SCL_SCALER_TAP_CONTROL 0x6594
#define AVIVO_D1SCL_UPDATE 0x65cc
-# define AVIVO_D1SCL_UPDATE_LOCK (1<<16)
+# define AVIVO_D1SCL_UPDATE_LOCK (1 << 16)
/* second crtc */
#define AVIVO_D2CRTC_H_TOTAL 0x6800