summaryrefslogtreecommitdiff
path: root/src/radeon_driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/radeon_driver.c')
-rw-r--r--src/radeon_driver.c204
1 files changed, 111 insertions, 93 deletions
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e6ccf617..220778d5 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -112,13 +112,6 @@
#include "atipciids.h"
#include "radeon_chipset.h"
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-#ifndef MIN
-#define MIN(a,b) ((a)>(b)?(b):(a))
-#endif
-
/* Forward definitions for driver functions */
static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
@@ -130,8 +123,10 @@ static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn);
static int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
static void RADEONForceSomeClocks(ScrnInfoPtr pScrn);
-static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn);
static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+xf86MonPtr RADEONProbeDDC(ScrnInfoPtr pScrn, int indx);
+static RADEONMonitorType RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac);
+
#ifdef XF86DRI
static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
@@ -1110,9 +1105,12 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
if (info->ChipFamily == CHIP_FAMILY_RV100 && !info->HasCRTC2) {
/* Avoid RN50 corruption due to memory bandwidth starvation.
* 18 is an empirical value based on the databook and Windows driver.
- */
+ *
+ * Empirical value changed to 24 to raise pixel clock limit and
+ * allow higher resolution modes on capable monitors.
+ */
pll->max_pll_freq = min(pll->max_pll_freq,
- 18 * info->mclk * 100 / pScrn->bitsPerPixel *
+ 24 * info->mclk * 100 / pScrn->bitsPerPixel *
info->RamWidth / 16);
}
@@ -2000,7 +1998,8 @@ static void RADEONSortModes(DisplayModePtr *new, DisplayModePtr *first,
p = *last;
while (p) {
- if ((((*new)->HDisplay < p->HDisplay) &&
+ if (((*new)->HDisplay < p->HDisplay) ||
+ (((*new)->HDisplay == p->HDisplay) &&
((*new)->VDisplay < p->VDisplay)) ||
(((*new)->HDisplay == p->HDisplay) &&
((*new)->VDisplay == p->VDisplay) &&
@@ -2707,6 +2706,9 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
int modesFound;
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
char *s;
+ DisplayModePtr first = NULL;
+ DisplayModePtr last = NULL;
+ DisplayModePtr start, mp;
/* This option has two purposes:
*
@@ -2763,7 +2765,7 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"No DDC data available, DDCMode option is dismissed\n");
}
-
+#if 0
if ((info->DisplayType == MT_DFP) ||
(info->DisplayType == MT_LCD)) {
if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
@@ -2817,6 +2819,7 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
} else
RADEONGetPanelInfo(pScrn);
}
+#endif
if (pScrn->monitor->DDC) {
/* If we still don't know sync range yet, let's try EDID.
@@ -2986,6 +2989,35 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
}
}
+ /* Sort the modes, retain the first */
+ if (pScrn->modes && (start = pScrn->modes->next)) {
+ /* Copy modelist into a new sorted modelist */
+ for (mp = start; mp != pScrn->modes; mp = mp->next) {
+ DisplayModePtr new = NULL;
+
+ new = xnfcalloc(1, sizeof (DisplayModeRec));
+ memcpy(new, mp, sizeof (DisplayModeRec));
+ new->name = strdup(mp->name);
+ RADEONSortModes(&new, &first, &last);
+ }
+
+ if (last && first) {
+ /* Clean up the old modelist */
+ start->prev = pScrn->modes->prev;
+ if (start->prev)
+ start->prev->next = start;
+ while (start)
+ xf86DeleteMode(&start, start);
+
+ /* Switch to the new sorted modelist */
+ pScrn->modes->next = first;
+ pScrn->modes->prev = last;
+ first->prev = pScrn->modes;
+ last->next = pScrn->modes;
+
+ }
+ }
+
pScrn->currentMode = pScrn->modes;
if(info->MergedFB) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -3560,15 +3592,18 @@ static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10
return TRUE;
}
-static void
+xf86MonPtr
RADEONProbeDDC(ScrnInfoPtr pScrn, int indx)
{
vbeInfoPtr pVbe;
+ xf86MonPtr monitor;
if (xf86LoadSubModule(pScrn, "vbe")) {
pVbe = VBEInit(NULL,indx);
- ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
- }
+ monitor = vbeDoEDID(pVbe, NULL);
+ return (monitor);
+ } else
+ return (NULL);
}
_X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
@@ -3588,7 +3623,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
info = RADEONPTR(pScrn);
info->IsSecondary = FALSE;
- info->IsPrimary = FALSE;
+ info->IsPrimary = FALSE;
info->MergedFB = FALSE;
info->IsSwitching = FALSE;
info->MMIO = NULL;
@@ -3659,7 +3694,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
}
if (flags & PROBE_DETECT) {
- RADEONProbeDDC(pScrn, info->pEnt->index);
+ ConfiguredMonitor = RADEONProbeDDC(pScrn, info->pEnt->index);
RADEONPostInt10Check(pScrn, int10_save);
if(info->MMIO) RADEONUnmapMMIO(pScrn);
return TRUE;
@@ -3960,7 +3995,6 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
int i;
int idx, j;
unsigned char r, g, b;
- CARD32 tmp = 0;
#ifdef XF86DRI
if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
@@ -3969,13 +4003,6 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
if (info->accelOn && pScrn->pScreen)
RADEON_SYNC(info, pScrn);
- if (info->HasCRTC2) {
- tmp = INPLL (pScrn, RADEON_PIXCLKS_CNTL);
- OUTPLLP (pScrn, RADEON_PIXCLKS_CNTL,
- RADEON_PIX2CLK_SRC_SEL_CPUCLK,
- ~(RADEON_PIX2CLK_SRC_SEL_MASK));
- }
-
if (info->FBDev) {
fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual);
} else {
@@ -4084,47 +4111,11 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
}
}
- if (info->HasCRTC2)
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
-
#ifdef XF86DRI
if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
#endif
}
-#if 1
-/* Write palette data */
-static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int i;
- CARD32 tmp = 0;
-
- if (info->HasCRTC2) {
- tmp = INPLL (pScrn, RADEON_PIXCLKS_CNTL);
- OUTPLLP (pScrn, RADEON_PIXCLKS_CNTL,
- RADEON_PIX2CLK_SRC_SEL_CPUCLK,
- ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
- PAL_SELECT(1);
- OUTPAL_START(0);
- for (i = 0; i < 256; i++) {
- OUTPAL_NEXT_CARD32(restore->palette2[i]);
- }
- }
-
- PAL_SELECT(0);
- OUTPAL_START(0);
- for (i = 0; i < 256; i++) {
- OUTPAL_NEXT_CARD32(restore->palette[i]);
- }
-
- if (info->HasCRTC2)
- OUTREG(RADEON_PIXCLKS_CNTL, tmp);
-}
-#endif
-
static void RADEONBlockHandler(int i, pointer blockData,
pointer pTimeout, pointer pReadmask)
{
@@ -5324,6 +5315,7 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+ /*OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);*/
if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
(info->ChipFamily != CHIP_FAMILY_R200))
OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
@@ -5529,7 +5521,6 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
RADEON_VCLK_SRC_SEL_PPLLCLK,
~(RADEON_VCLK_SRC_SEL_MASK));
-
}
@@ -5590,7 +5581,6 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
}
@@ -5777,6 +5767,32 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
RADEONSaveSurfaces(pScrn, &info->ModeReg);
}
+#if 0
+/* Write palette data */
+static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ int i;
+
+ if (!restore->palette_valid) return;
+
+ PAL_SELECT(1);
+ OUTPAL_START(0);
+ for (i = 0; i < 256; i++) {
+ RADEONWaitForFifo(pScrn, 32); /* delay */
+ OUTPAL_NEXT_CARD32(restore->palette2[i]);
+ }
+
+ PAL_SELECT(0);
+ OUTPAL_START(0);
+ for (i = 0; i < 256; i++) {
+ RADEONWaitForFifo(pScrn, 32); /* delay */
+ OUTPAL_NEXT_CARD32(restore->palette[i]);
+ }
+}
+#endif
+
/* Write out state to define a new video mode */
static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
@@ -5787,6 +5803,16 @@ static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
RADEONTRACE(("RADEONRestoreMode(%p)\n", restore));
+ /* For Non-dual head card, we don't have private field in the Entity */
+ if (!info->HasCRTC2) {
+ RADEONRestoreMemMapRegisters(pScrn, restore);
+ RADEONRestoreCommonRegisters(pScrn, restore);
+ RADEONRestoreCrtcRegisters(pScrn, restore);
+ RADEONRestoreFPRegisters(pScrn, restore);
+ RADEONRestorePLLRegisters(pScrn, restore);
+ return;
+ }
+
/* When changing mode with Dual-head card, care must be taken for
* the special order in setting registers. CRTC2 has to be set
* before changing CRTC_EXT register. In the dual-head setup, X
@@ -5911,7 +5937,6 @@ static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
save->crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
save->crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
save->dac_cntl = INREG(RADEON_DAC_CNTL);
- save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
save->crtc_h_total_disp = INREG(RADEON_CRTC_H_TOTAL_DISP);
save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP);
@@ -5967,6 +5992,7 @@ static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
unsigned char *RADEONMMIO = info->MMIO;
save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL);
save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG);
@@ -6030,26 +6056,17 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
int i;
- CARD32 tmp = 0;
-
- if (info->HasCRTC2) {
- tmp = INPLL (pScrn, RADEON_PIXCLKS_CNTL);
- OUTPLLP (pScrn, RADEON_PIXCLKS_CNTL,
- RADEON_PIX2CLK_SRC_SEL_CPUCLK,
- ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
- PAL_SELECT(1);
- INPAL_START(0);
- for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
- }
+#ifdef ENABLE_FLAT_PANEL
+ /* Select palette 0 (main CRTC) if using FP-enabled chip */
+ /* if (info->Port1 == MT_DFP) PAL_SELECT(1); */
+#endif
+ PAL_SELECT(1);
+ INPAL_START(0);
+ for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
PAL_SELECT(0);
INPAL_START(0);
for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
-
- if (info->HasCRTC2)
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
-
save->palette_valid = TRUE;
}
@@ -6239,7 +6256,8 @@ static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
static void RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->ChipFamily == CHIP_FAMILY_R420) {
+ if (info->ChipFamily == CHIP_FAMILY_R420 ||
+ info->ChipFamily == CHIP_FAMILY_RV410) {
save->tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
RADEON_TV_DAC_BGADJ_MASK |
R420_TV_DAC_DACADJ_MASK |
@@ -6259,7 +6277,7 @@ static void RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
RADEON_TV_DAC_NHOLD |
RADEON_TV_DAC_STD_PS2 |
info->tv_dac_adj);
-}
+}
static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
DisplayModePtr mode, BOOL IsPrimary)
@@ -6564,10 +6582,6 @@ Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
save->crtc_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
save->crtc_pitch |= save->crtc_pitch << 16;
-
- save->vclk_cntl = (info->SavedReg.vclk_cntl &
- ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
-
/* Set following registers for all cases first, if a DFP/LCD is connected on
internal TMDS/LVDS port, they will be set by RADEONInitFPRegister
@@ -6862,13 +6876,7 @@ Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
else
save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
}
- }
-
-
- save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
- ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
- RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
-
+ }
/* We must set SURFACE_CNTL properly on the second screen too */
save->surface_cntl = 0;
@@ -6956,6 +6964,10 @@ static void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
save->ppll_ref_div = pll->reference_div;
save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16));
save->htotal_cntl = 0;
+
+ save->vclk_cntl = (info->SavedReg.vclk_cntl &
+ ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
+
}
/* Define PLL2 registers for requested video mode */
@@ -6963,6 +6975,7 @@ static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
RADEONPLLPtr pll, double dot_clock,
int no_odd_postdiv)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned long freq = dot_clock * 100;
struct {
@@ -7019,6 +7032,11 @@ static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
save->p2pll_div_0 = (save->feedback_div_2 |
(post_div->bitvalue << 16));
save->htotal_cntl2 = 0;
+
+ save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
+
}
#if 0