summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2010-04-13 11:08:59 -0400
committerAlex Deucher <alexdeucher@gmail.com>2010-04-13 11:08:59 -0400
commit22a46dddd375b2b9399e12fdf168fa5292ff17a4 (patch)
tree8227b869aad03913f3add76fde3d8ad69c64174b /src
parentc1b817c45477c21234abaaebe78feb7ea4fd92b1 (diff)
radeon: add support for pll algo selection
tv-out on atom systems is very particular about it's dividers. force it to use the old algo. Should fix fdo bug 27593.
Diffstat (limited to 'src')
-rw-r--r--src/atombios_crtc.c22
-rw-r--r--src/legacy_crtc.c28
-rw-r--r--src/radeon.h2
-rw-r--r--src/radeon_crtc.c37
-rw-r--r--src/radeon_probe.h6
5 files changed, 65 insertions, 30 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 1d86643b..6f083b48 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -458,6 +458,19 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
unsigned char *space;
memset(&spc_param, 0, sizeof(spc_param));
+
+ if (IS_AVIVO_VARIANT) {
+ if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, TRUE))
+ radeon_crtc->pll_algo = RADEON_PLL_NEW;
+ else
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+ } else {
+ if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE))
+ radeon_crtc->pll_algo = RADEON_PLL_NEW;
+ else
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+ }
+
if (IS_AVIVO_VARIANT) {
if ((info->ChipFamily == CHIP_FAMILY_RS600) ||
(info->ChipFamily == CHIP_FAMILY_RS690) ||
@@ -471,6 +484,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc) {
+ radeon_output = output->driver_private;
radeon_encoder = radeon_get_encoder(output);
/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
/* AdjustDisplayPll handles this on DCE3.x */
@@ -478,6 +492,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
(radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) &&
!IS_DCE3_VARIANT)
sclock *= 2;
+ if (radeon_output->active_device &
+ (ATOM_DEVICE_CV_SUPPORT | ATOM_DEVICE_TV_SUPPORT)) {
+ pll_flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+ }
}
}
@@ -614,7 +633,8 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
}
}
- RADEONComputePLL(pScrn, &info->pll, sclock, &temp, &fb_div, &frac_fb_div, &ref_div, &post_div, pll_flags);
+ RADEONComputePLL(crtc, &info->pll, sclock, &temp,
+ &fb_div, &frac_fb_div, &ref_div, &post_div, pll_flags);
sclock = temp; /* 10 khz */
xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index e4c1f043..0beb54d4 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -1184,10 +1184,12 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
/* Define PLL registers for requested video mode */
static void
-RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+RADEONInitPLLRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
RADEONPLLPtr pll, DisplayModePtr mode,
int flags)
{
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ ScrnInfoPtr pScrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
uint32_t feedback_div = 0;
uint32_t frac_fb_div = 0;
@@ -1223,7 +1225,13 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
return;
}
- RADEONComputePLL(pScrn, pll, mode->Clock, &freq, &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags);
+ if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE))
+ radeon_crtc->pll_algo = RADEON_PLL_NEW;
+ else
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+
+ RADEONComputePLL(crtc, pll, mode->Clock, &freq,
+ &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags);
for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
if (post_div->divider == post_divider)
@@ -1266,10 +1274,12 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
/* Define PLL2 registers for requested video mode */
static void
-RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+RADEONInitPLL2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
RADEONPLLPtr pll, DisplayModePtr mode,
int flags)
{
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ ScrnInfoPtr pScrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
uint32_t feedback_div = 0;
uint32_t frac_fb_div = 0;
@@ -1303,7 +1313,13 @@ RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
return;
}
- RADEONComputePLL(pScrn, pll, mode->Clock, &freq, &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags);
+ if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE))
+ radeon_crtc->pll_algo = RADEON_PLL_NEW;
+ else
+ radeon_crtc->pll_algo = RADEON_PLL_OLD;
+
+ RADEONComputePLL(crtc, pll, mode->Clock, &freq,
+ &feedback_div, &frac_fb_div, &reference_div, &post_divider, flags);
for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
if (post_div->divider == post_divider)
@@ -1795,7 +1811,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
dot_clock = adjusted_mode->Clock / 1000.0;
if (dot_clock) {
ErrorF("init pll1\n");
- RADEONInitPLLRegisters(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
+ RADEONInitPLLRegisters(crtc, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
} else {
info->ModeReg->ppll_ref_div = info->SavedReg->ppll_ref_div;
info->ModeReg->ppll_div_3 = info->SavedReg->ppll_div_3;
@@ -1809,7 +1825,7 @@ legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
dot_clock = adjusted_mode->Clock / 1000.0;
if (dot_clock) {
ErrorF("init pll2\n");
- RADEONInitPLL2Registers(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
+ RADEONInitPLL2Registers(crtc, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
}
break;
}
diff --git a/src/radeon.h b/src/radeon.h
index 88f1516b..388422a6 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -1176,7 +1176,7 @@ extern void radeon_crtc_load_lut(xf86CrtcPtr crtc);
extern void radeon_crtc_modeset_ioctl(xf86CrtcPtr crtc, Bool post);
extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask);
extern void RADEONBlank(ScrnInfoPtr pScrn);
-extern void RADEONComputePLL(ScrnInfoPtr pScrn,
+extern void RADEONComputePLL(xf86CrtcPtr crtc,
RADEONPLLPtr pll, unsigned long freq,
uint32_t *chosen_dot_clock_freq,
uint32_t *chosen_feedback_div,
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 0b071b8b..a4a3302b 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -447,7 +447,7 @@ done:
}
void
-RADEONComputePLL(ScrnInfoPtr pScrn,
+RADEONComputePLL(xf86CrtcPtr crtc,
RADEONPLLPtr pll,
unsigned long freq,
uint32_t *chosen_dot_clock_freq,
@@ -457,28 +457,21 @@ RADEONComputePLL(ScrnInfoPtr pScrn,
uint32_t *chosen_post_div,
int flags)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
- if (IS_AVIVO_VARIANT) {
- if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, TRUE)) {
- /* disable frac fb dividers */
- flags &= ~RADEON_PLL_USE_FRAC_FB_DIV;
- RADEONComputePLL_new(pll, freq, chosen_dot_clock_freq,
- chosen_feedback_div, chosen_frac_feedback_div,
- chosen_reference_div, chosen_post_div, flags);
- } else
- RADEONComputePLL_old(pll, freq, chosen_dot_clock_freq,
- chosen_feedback_div, chosen_frac_feedback_div,
- chosen_reference_div, chosen_post_div, flags);
- } else {
- if (xf86ReturnOptValBool(info->Options, OPTION_NEW_PLL, FALSE))
- RADEONComputePLL_new(pll, freq, chosen_dot_clock_freq,
- chosen_feedback_div, chosen_frac_feedback_div,
- chosen_reference_div, chosen_post_div, flags);
- else
- RADEONComputePLL_old(pll, freq, chosen_dot_clock_freq,
- chosen_feedback_div, chosen_frac_feedback_div,
- chosen_reference_div, chosen_post_div, flags);
+ switch (radeon_crtc->pll_algo) {
+ case RADEON_PLL_OLD:
+ RADEONComputePLL_old(pll, freq, chosen_dot_clock_freq,
+ chosen_feedback_div, chosen_frac_feedback_div,
+ chosen_reference_div, chosen_post_div, flags);
+ break;
+ case RADEON_PLL_NEW:
+ /* disable frac fb dividers */
+ flags &= ~RADEON_PLL_USE_FRAC_FB_DIV;
+ RADEONComputePLL_new(pll, freq, chosen_dot_clock_freq,
+ chosen_feedback_div, chosen_frac_feedback_div,
+ chosen_reference_div, chosen_post_div, flags);
+ break;
}
}
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index dc02bdff..cab077fe 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -147,6 +147,11 @@ typedef struct
Bool hw_capable;
} RADEONI2CBusRec, *RADEONI2CBusPtr;
+enum radeon_pll_algo {
+ RADEON_PLL_OLD,
+ RADEON_PLL_NEW
+};
+
typedef struct _RADEONCrtcPrivateRec {
void *crtc_rotate_mem;
void *cursor_mem;
@@ -164,6 +169,7 @@ typedef struct _RADEONCrtcPrivateRec {
float vsc;
float hsc;
int pll_id;
+ enum radeon_pll_algo pll_algo;
} RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
typedef struct _radeon_encoder {