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); 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, void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
int pll_flags)
{ {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev; 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 sclock = mode->clock;
uint32_t ref_div = 0, fb_div = 0, post_div = 0; uint32_t ref_div = 0, fb_div = 0, post_div = 0;
struct radeon_pll *pll; struct radeon_pll *pll;
int pll_flags = 0;
memset(&spc_param, 0, sizeof(SET_PIXEL_CLOCK_PS_ALLOCATION)); 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) if (radeon_crtc->crtc_id == 0)
pll = &dev_priv->mode_info.p1pll; 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, RADEON_WRITE(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
(crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); (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, 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_radeon_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder; struct drm_encoder *encoder;
SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
int pll_flags = 0;
/* TODO color tiling */ /* TODO color tiling */
memset(&crtc_timing, 0, sizeof(crtc_timing)); memset(&crtc_timing, 0, sizeof(crtc_timing));
@ -347,9 +358,10 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc,
else else
radeon_crtc_set_base(crtc, x, y); 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); atombios_crtc_set_timing(crtc, &crtc_timing);
} }
static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, 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_freq = current_freq;
best_error = error; best_error = error;
best_vco_diff = vco_diff; 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_post_div = post_div;
best_ref_div = ref_div; best_ref_div = ref_div;
best_feedback_div = feedback_div; best_feedback_div = feedback_div;

View file

@ -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, static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_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; 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 *mode,
struct drm_display_mode *adjusted_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; 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 post_divider = 0;
uint32_t freq = 0; uint32_t freq = 0;
uint8_t pll_gain; 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; bool use_bios_divs = false;
/* PLL registers */ /* PLL registers */
uint32_t ppll_ref_div = 0; 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 } { 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) { list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) { if (encoder->crtc == crtc) {
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)

View file

@ -137,11 +137,16 @@ struct radeon_tmds_pll {
#define RADEON_MAX_BIOS_CONNECTOR 16 #define RADEON_MAX_BIOS_CONNECTOR 16
#define RADEON_PLL_USE_BIOS_DIVS (1 << 0) #define RADEON_PLL_USE_BIOS_DIVS (1 << 0)
#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) #define RADEON_PLL_NO_ODD_POST_DIV (1 << 1)
#define RADEON_PLL_USE_REF_DIV (1 << 2) #define RADEON_PLL_USE_REF_DIV (1 << 2)
#define RADEON_PLL_LEGACY (1 << 3) #define RADEON_PLL_LEGACY (1 << 3)
#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4) #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 { struct radeon_pll {
uint16_t reference_freq; uint16_t reference_freq;

View file

@ -3583,7 +3583,7 @@
#define AVIVO_D1CRTC_V_SYNC_B_CNTL 0x6034 #define AVIVO_D1CRTC_V_SYNC_B_CNTL 0x6034
#define AVIVO_D1CRTC_CONTROL 0x6080 #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_BLANK_CONTROL 0x6084
#define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088
#define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c
@ -3595,30 +3595,30 @@
#define AVIVO_D1GRPH_ENABLE 0x6100 #define AVIVO_D1GRPH_ENABLE 0x6100
#define AVIVO_D1GRPH_CONTROL 0x6104 #define AVIVO_D1GRPH_CONTROL 0x6104
# define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0<<0) # define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0 << 0)
# define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1<<0) # define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1 << 0)
# define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2<<0) # define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2 << 0)
# define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP (3<<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_ARGB1555 (0 << 8)
# define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1<<8) # define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1 << 8)
# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2<<8) # define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2 << 8)
# define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3<<8) # define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3 << 8)
# define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4<<8) # define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4 << 8)
# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0<<8) # define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0 << 8)
# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1<<8) # define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1 << 8)
# define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2<<8) # define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2 << 8)
# define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3<<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_SWAP_RB (1 << 16)
# define AVIVO_D1GRPH_TILED (1<<20) # define AVIVO_D1GRPH_TILED (1 << 20)
# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1<<21) # define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21)
#define AVIVO_D1GRPH_LUT_SEL 0x6108 #define AVIVO_D1GRPH_LUT_SEL 0x6108
#define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110
@ -3644,7 +3644,7 @@
#define AVIVO_D1CUR_POSITION 0x6414 #define AVIVO_D1CUR_POSITION 0x6414
#define AVIVO_D1CUR_HOT_SPOT 0x6418 #define AVIVO_D1CUR_HOT_SPOT 0x6418
#define AVIVO_D1CUR_UPDATE 0x6424 #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_SELECT 0x6480
#define AVIVO_DC_LUT_RW_MODE 0x6484 #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_GREEN 0x64d4
#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8 #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_DESKTOP_HEIGHT 0x652C
#define AVIVO_D1MODE_VIEWPORT_START 0x6580 #define AVIVO_D1MODE_VIEWPORT_START 0x6580
#define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584
@ -3674,7 +3675,7 @@
#define AVIVO_D1SCL_SCALER_ENABLE 0x6590 #define AVIVO_D1SCL_SCALER_ENABLE 0x6590
#define AVIVO_D1SCL_SCALER_TAP_CONTROL 0x6594 #define AVIVO_D1SCL_SCALER_TAP_CONTROL 0x6594
#define AVIVO_D1SCL_UPDATE 0x65cc #define AVIVO_D1SCL_UPDATE 0x65cc
# define AVIVO_D1SCL_UPDATE_LOCK (1<<16) # define AVIVO_D1SCL_UPDATE_LOCK (1 << 16)
/* second crtc */ /* second crtc */
#define AVIVO_D2CRTC_H_TOTAL 0x6800 #define AVIVO_D2CRTC_H_TOTAL 0x6800