radeon: pll and interlace updates from the ddx

also some formatting cleanup in radeon_reg.h
This commit is contained in:
Alex Deucher 2008-09-18 17:27:00 -04:00
parent 6988176195
commit 075ed1d6fd
6 changed files with 76 additions and 36 deletions

View file

@ -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,9 +163,16 @@ 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));
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)
@ -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,

View file

@ -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;

View file

@ -520,6 +520,12 @@ static bool radeon_atom_dac_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;
}
@ -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;
}

View file

@ -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)

View file

@ -142,6 +142,11 @@ struct radeon_tmds_pll {
#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;

View file

@ -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