summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel@tungstengraphics.com>2007-05-30 18:56:53 +0200
committerMichel Dänzer <michel@tungstengraphics.com>2007-05-30 20:25:39 +0200
commit0e0946e0aa2527794e07473199e851bbfbc47cb1 (patch)
tree53ded2d6d1f83947d66535541c3cc8565b2c0fc5
parent31c1be420d5277dd15505bd73e6144827a0580cd (diff)
radeon: Lots of warning fixes.
Move code where it's used, remove unused variables, etc.
-rw-r--r--src/radeon.h22
-rw-r--r--src/radeon_bios.c2
-rw-r--r--src/radeon_crtc.c635
-rw-r--r--src/radeon_cursor.c52
-rw-r--r--src/radeon_display.c677
-rw-r--r--src/radeon_driver.c926
-rw-r--r--src/radeon_modes.c6
-rw-r--r--src/radeon_output.c1007
-rw-r--r--src/radeon_video.c1
9 files changed, 1643 insertions, 1685 deletions
diff --git a/src/radeon.h b/src/radeon.h
index eb4902b..62faee0 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -816,6 +816,26 @@ extern Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output);
extern Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
extern Bool RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
+extern void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+extern void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore);
+
+extern void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr save,
+ RADEONInfoPtr info);
extern void RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
extern Bool RADEONI2cInit(ScrnInfoPtr pScrn);
extern void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
@@ -859,6 +879,8 @@ void
radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
void
RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num);
+void
+RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox);
#ifdef XF86DRI
#ifdef USE_XAA
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 8d5c0ec..76b0a72 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -44,7 +44,6 @@
int RADEONBIOSApplyConnectorQuirks(ScrnInfoPtr pScrn, int connector_found)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
/* quirk for compaq nx6125 - the bios lies about the VGA DDC */
if (info->PciInfo->subsysVendor == PCI_VENDOR_HP) {
@@ -145,7 +144,6 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR (pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
int i = 0, j, tmp, tmp0=0, tmp1=0;
if(!info->VBIOS) return FALSE;
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 0e1d82e..79ab578 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -47,6 +47,13 @@
#include "radeon_probe.h"
#include "radeon_version.h"
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "radeon_dri.h"
+#include "radeon_sarea.h"
+#include "sarea.h"
+#endif
+
void radeon_crtc_load_lut(xf86CrtcPtr crtc);
static void
@@ -113,6 +120,619 @@ radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
radeon_crtc_dpms(crtc, DPMSModeOff);
}
+/* Define common registers for requested video mode */
+static void
+RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
+{
+ save->ovr_clr = 0;
+ save->ovr_wid_left_right = 0;
+ save->ovr_wid_top_bottom = 0;
+ save->ov0_scale_cntl = 0;
+ save->subpic_cntl = 0;
+ save->viph_control = 0;
+ save->i2c_cntl_1 = 0;
+ save->rbbm_soft_reset = 0;
+ save->cap0_trig_cntl = 0;
+ save->cap1_trig_cntl = 0;
+ save->bus_cntl = info->BusCntl;
+ /*
+ * If bursts are enabled, turn on discards
+ * Radeon doesn't have write bursts
+ */
+ if (save->bus_cntl & (RADEON_BUS_READ_BURST))
+ save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
+}
+
+/* Define CRTC registers for requested video mode */
+static Bool
+RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
+ DisplayModePtr mode, int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ //RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ int format;
+ int hsync_start;
+ int hsync_wid;
+ int vsync_wid;
+ int Base;
+#ifdef XF86DRI
+ RADEONSAREAPrivPtr pSAREAPriv;
+ XF86DRISAREAPtr pSAREA;
+#endif
+
+ switch (info->CurrentLayout.pixel_code) {
+ case 4: format = 1; break;
+ case 8: format = 2; break;
+ case 15: format = 3; break; /* 555 */
+ case 16: format = 4; break; /* 565 */
+ case 24: format = 5; break; /* RGB */
+ case 32: format = 6; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n",
+ info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+
+ save->bios_4_scratch = info->SavedReg.bios_4_scratch;
+ save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
+ | RADEON_CRTC_EN
+ | (format << 8)
+ | ((mode->Flags & V_DBLSCAN)
+ ? RADEON_CRTC_DBL_SCAN_EN
+ : 0)
+ | ((mode->Flags & V_CSYNC)
+ ? RADEON_CRTC_CSYNC_EN
+ : 0)
+ | ((mode->Flags & V_INTERLACE)
+ ? RADEON_CRTC_INTERLACE_EN
+ : 0));
+
+ save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
+ RADEON_CRTC_VSYNC_DIS |
+ RADEON_CRTC_HSYNC_DIS |
+ RADEON_CRTC_DISPLAY_DIS);
+
+ save->surface_cntl = 0;
+ save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
+ save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* We must set both apertures as they can be both used to map the entire
+ * video memory. -BenH.
+ */
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
+ break;
+
+ case 32:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
+ break;
+ }
+#endif
+
+ save->crtc_more_cntl = 0;
+ if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
+ (info->ChipFamily == CHIP_FAMILY_RS200)) {
+ /* This is to workaround the asic bug for RMX, some versions
+ of BIOS dosen't have this register initialized correctly.
+ */
+ save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
+ }
+
+ save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+ | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
+ << 16));
+
+ hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+ if (!hsync_wid) hsync_wid = 1;
+ if (hsync_wid > 0x3f) hsync_wid = 0x3f;
+ hsync_start = mode->CrtcHSyncStart - 8;
+
+ save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
+ | (hsync_wid << 16)
+ | ((mode->Flags & V_NHSYNC)
+ ? RADEON_CRTC_H_SYNC_POL
+ : 0));
+
+ /* This works for double scan mode. */
+ save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay - 1) << 16));
+
+ vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ if (!vsync_wid) vsync_wid = 1;
+ if (vsync_wid > 0x1f) vsync_wid = 0x1f;
+
+ save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+ | (vsync_wid << 16)
+ | ((mode->Flags & V_NVSYNC)
+ ? RADEON_CRTC_V_SYNC_POL
+ : 0));
+
+ save->crtc_offset = pScrn->fbOffset;
+ if (info->allowPageFlip)
+ save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+
+ if (info->tilingEnabled) {
+ if (IS_R300_VARIANT)
+ save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
+ }
+ else {
+ if (IS_R300_VARIANT)
+ save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+ }
+
+ save->crtc_pitch = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
+ ((pScrn->bitsPerPixel * 8) -1)) /
+ (pScrn->bitsPerPixel * 8));
+ save->crtc_pitch |= save->crtc_pitch << 16;
+
+ save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+ save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
+ save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
+ save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
+
+ Base = pScrn->fbOffset;
+
+ if (info->tilingEnabled) {
+ if (IS_R300_VARIANT) {
+ /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+ * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
+ * Makes tiling MUCH easier.
+ */
+ save->crtc_tile_x0_y0 = x | (y << 16);
+ Base &= ~0x7ff;
+ } else {
+ /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+ drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+ flickering when scrolling vertically in a virtual screen, possibly because crtc will
+ pick up the new offset value at the end of each scanline, but the new offset_cntl value
+ only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+ OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+ save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL) & ~0xf;
+#if 0
+ /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+ if (!info->have3DWindows)
+#endif
+ save->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+ int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+ /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+ int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+ Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+ save->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
+ }
+ }
+ else {
+ int offset = y * info->CurrentLayout.displayWidth + x;
+ switch (info->CurrentLayout.pixel_code) {
+ case 15:
+ case 16: offset *= 2; break;
+ case 24: offset *= 3; break;
+ case 32: offset *= 4; break;
+ }
+ Base += offset;
+ }
+
+ Base &= ~7; /* 3 lower bits are always 0 */
+
+
+#ifdef XF86DRI
+ if (info->directRenderingInited) {
+ /* note cannot use pScrn->pScreen since this is unitialized when called from
+ RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+ /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+ *** pageflipping!
+ ***/
+ pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+ /* can't get at sarea in a semi-sane way? */
+ pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+ pSAREA->frame.x = (Base / info->CurrentLayout.pixel_bytes)
+ % info->CurrentLayout.displayWidth;
+ pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
+ / info->CurrentLayout.displayWidth;
+ pSAREA->frame.width = pScrn->frameX1 - x + 1;
+ pSAREA->frame.height = pScrn->frameY1 - y + 1;
+
+ if (pSAREAPriv->pfCurrentPage == 1) {
+ Base += info->backOffset - info->frontOffset;
+ }
+ }
+#endif
+ save->crtc_offset = Base;
+
+
+ if (info->IsDellServer) {
+ save->dac2_cntl = info->SavedReg.dac2_cntl;
+ save->tv_dac_cntl = info->SavedReg.tv_dac_cntl;
+ save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl;
+ save->disp_hw_debug = info->SavedReg.disp_hw_debug;
+
+ save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
+ save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+
+ /* For CRT on DAC2, don't turn it on if BIOS didn't
+ enable it, even it's detected.
+ */
+ save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+ save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
+ save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
+ }
+
+ return TRUE;
+}
+
+/* Define CRTC2 registers for requested video mode */
+static Bool
+RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
+ DisplayModePtr mode, int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ //RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ int format;
+ int hsync_start;
+ int hsync_wid;
+ int vsync_wid;
+ int Base;
+#ifdef XF86DRI
+ RADEONSAREAPrivPtr pSAREAPriv;
+ XF86DRISAREAPtr pSAREA;
+#endif
+
+ switch (info->CurrentLayout.pixel_code) {
+ case 4: format = 1; break;
+ case 8: format = 2; break;
+ case 15: format = 3; break; /* 555 */
+ case 16: format = 4; break; /* 565 */
+ case 24: format = 5; break; /* RGB */
+ case 32: format = 6; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n",
+ info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+
+ save->crtc2_h_total_disp =
+ ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+ | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
+
+ hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+ if (!hsync_wid) hsync_wid = 1;
+ if (hsync_wid > 0x3f) hsync_wid = 0x3f;
+ hsync_start = mode->CrtcHSyncStart - 8;
+
+ save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
+ | (hsync_wid << 16)
+ | ((mode->Flags & V_NHSYNC)
+ ? RADEON_CRTC_H_SYNC_POL
+ : 0));
+
+ /* This works for double scan mode. */
+ save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay - 1) << 16));
+
+ vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ if (!vsync_wid) vsync_wid = 1;
+ if (vsync_wid > 0x1f) vsync_wid = 0x1f;
+
+ save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+ | (vsync_wid << 16)
+ | ((mode->Flags & V_NVSYNC)
+ ? RADEON_CRTC2_V_SYNC_POL
+ : 0));
+
+ /* It seems all fancy options apart from pflip can be safely disabled
+ */
+ save->crtc2_offset = pScrn->fbOffset;
+ if (info->allowPageFlip)
+ save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+
+ if (info->tilingEnabled) {
+ if (IS_R300_VARIANT)
+ save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
+ }
+ else {
+ if (IS_R300_VARIANT)
+ save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+ }
+
+ save->crtc2_pitch = ((info->CurrentLayout.displayWidth * pScrn->bitsPerPixel) +
+ ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
+ save->crtc2_pitch |= save->crtc2_pitch << 16;
+
+ save->crtc2_gen_cntl = (RADEON_CRTC2_EN
+ | (format << 8)
+ | RADEON_CRTC2_VSYNC_DIS
+ | RADEON_CRTC2_HSYNC_DIS
+ | RADEON_CRTC2_DISP_DIS
+ | ((mode->Flags & V_DBLSCAN)
+ ? RADEON_CRTC2_DBL_SCAN_EN
+ : 0)
+ | ((mode->Flags & V_CSYNC)
+ ? RADEON_CRTC2_CSYNC_EN
+ : 0)
+ | ((mode->Flags & V_INTERLACE)
+ ? RADEON_CRTC2_INTERLACE_EN
+ : 0));
+
+ save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl;
+ save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
+
+ save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
+ save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
+
+ Base = pScrn->fbOffset;
+
+ if (info->tilingEnabled) {
+ if (IS_R300_VARIANT) {
+ /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+ * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
+ * Makes tiling MUCH easier.
+ */
+ save->crtc2_tile_x0_y0 = x | (y << 16);
+ Base &= ~0x7ff;
+ } else {
+ /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+ drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+ flickering when scrolling vertically in a virtual screen, possibly because crtc will
+ pick up the new offset value at the end of each scanline, but the new offset_cntl value
+ only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+ OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+ save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL) & ~0xf;
+#if 0
+ /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+ if (!info->have3DWindows)
+#endif
+ save->crtc2_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+ int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+ /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+ int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+ Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+ save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
+ }
+ }
+ else {
+ int offset = y * info->CurrentLayout.displayWidth + x;
+ switch (info->CurrentLayout.pixel_code) {
+ case 15:
+ case 16: offset *= 2; break;
+ case 24: offset *= 3; break;
+ case 32: offset *= 4; break;
+ }
+ Base += offset;
+ }
+
+ Base &= ~7; /* 3 lower bits are always 0 */
+
+#ifdef XF86DRI
+ if (info->directRenderingInited) {
+ /* note cannot use pScrn->pScreen since this is unitialized when called from
+ RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+ /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+ *** pageflipping!
+ ***/
+ pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+ /* can't get at sarea in a semi-sane way? */
+ pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+ pSAREAPriv->crtc2_base = Base;
+
+ if (pSAREAPriv->pfCurrentPage == 1) {
+ Base += info->backOffset - info->frontOffset;
+ }
+ }
+#endif
+ save->crtc2_offset = Base;
+
+ /* We must set SURFACE_CNTL properly on the second screen too */
+ save->surface_cntl = 0;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* We must set both apertures as they can be both used to map the entire
+ * video memory. -BenH.
+ */
+ switch (pScrn->bitsPerPixel) {
+ case 16:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
+ break;
+
+ case 32:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
+ break;
+ }
+#endif
+
+ if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */
+ save->rs480_unk_e34 = 0x2749D000; /* AMD really should */
+ save->rs480_unk_e38 = 0x29ca71dc; /* release docs */
+ save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */
+ }
+
+ return TRUE;
+}
+
+
+/* Compute n/d with rounding */
+static int RADEONDiv(int n, int d)
+{
+ return (n + (d / 2)) / d;
+}
+
+/* Define PLL registers for requested video mode */
+static void
+RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
+ RADEONSavePtr save, RADEONPLLPtr pll,
+ double dot_clock)
+{
+ unsigned long freq = dot_clock * 100;
+
+ struct {
+ int divider;
+ int bitvalue;
+ } *post_div, post_divs[] = {
+ /* From RAGE 128 VR/RAGE 128 GL Register
+ * Reference Manual (Technical Reference
+ * Manual P/N RRG-G04100-C Rev. 0.04), page
+ * 3-17 (PLL_DIV_[3:0]).
+ */
+ { 1, 0 }, /* VCLK_SRC */
+ { 2, 1 }, /* VCLK_SRC/2 */
+ { 4, 2 }, /* VCLK_SRC/4 */
+ { 8, 3 }, /* VCLK_SRC/8 */
+ { 3, 4 }, /* VCLK_SRC/3 */
+ { 16, 5 }, /* VCLK_SRC/16 */
+ { 6, 6 }, /* VCLK_SRC/6 */
+ { 12, 7 }, /* VCLK_SRC/12 */
+ { 0, 0 }
+ };
+
+ if (info->UseBiosDividers) {
+ save->ppll_ref_div = info->RefDivider;
+ save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16);
+ save->htotal_cntl = 0;
+ return;
+ }
+
+ if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
+ if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
+
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ save->pll_output_freq = post_div->divider * freq;
+
+ if (save->pll_output_freq >= pll->min_pll_freq
+ && save->pll_output_freq <= pll->max_pll_freq) break;
+ }
+
+ if (!post_div->divider) {
+ save->pll_output_freq = freq;
+ post_div = &post_divs[0];
+ }
+
+ save->dot_clock_freq = freq;
+ save->feedback_div = RADEONDiv(pll->reference_div
+ * save->pll_output_freq,
+ pll->reference_freq);
+ save->post_div = post_div->divider;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "dc=%ld, of=%ld, fd=%d, pd=%d\n",
+ save->dot_clock_freq,
+ save->pll_output_freq,
+ save->feedback_div,
+ save->post_div);
+
+ 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 */
+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 {
+ int divider;
+ int bitvalue;
+ } *post_div, post_divs[] = {
+ /* From RAGE 128 VR/RAGE 128 GL Register
+ * Reference Manual (Technical Reference
+ * Manual P/N RRG-G04100-C Rev. 0.04), page
+ * 3-17 (PLL_DIV_[3:0]).
+ */
+ { 1, 0 }, /* VCLK_SRC */
+ { 2, 1 }, /* VCLK_SRC/2 */
+ { 4, 2 }, /* VCLK_SRC/4 */
+ { 8, 3 }, /* VCLK_SRC/8 */
+ { 3, 4 }, /* VCLK_SRC/3 */
+ { 6, 6 }, /* VCLK_SRC/6 */
+ { 12, 7 }, /* VCLK_SRC/12 */
+ { 0, 0 }
+ };
+
+ if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
+ if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
+
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ /* Odd post divider value don't work properly on the second digital
+ * output
+ */
+ if (no_odd_postdiv && (post_div->divider & 1))
+ continue;
+ save->pll_output_freq_2 = post_div->divider * freq;
+ if (save->pll_output_freq_2 >= pll->min_pll_freq
+ && save->pll_output_freq_2 <= pll->max_pll_freq) break;
+ }
+
+ if (!post_div->divider) {
+ save->pll_output_freq_2 = freq;
+ post_div = &post_divs[0];
+ }
+
+ save->dot_clock_freq_2 = freq;
+ save->feedback_div_2 = RADEONDiv(pll->reference_div
+ * save->pll_output_freq_2,
+ pll->reference_freq);
+ save->post_div_2 = post_div->divider;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "dc=%ld, of=%ld, fd=%d, pd=%d\n",
+ save->dot_clock_freq_2,
+ save->pll_output_freq_2,
+ save->feedback_div_2,
+ save->post_div_2);
+
+ save->p2pll_ref_div = pll->reference_div;
+ 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);
+
+}
+
static void
radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode, int x, int y)
@@ -121,7 +741,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONMonitorType montype;
+ RADEONMonitorType montype = MT_NONE;
int i = 0;
double dot_clock = 0;
@@ -198,7 +818,6 @@ radeon_crtc_mode_commit(xf86CrtcPtr crtc)
void radeon_crtc_load_lut(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
@@ -219,10 +838,7 @@ static void
radeon_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green,
CARD16 *blue, int size)
{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
- RADEONInfoPtr info = RADEONPTR(pScrn);
int i;
for (i = 0; i < 256; i++) {
@@ -239,9 +855,8 @@ radeon_crtc_lock(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
-#ifdef XF86DRI
- Bool CPStarted = info->CPStarted;
+#ifdef XF86DRI
if (info->CPStarted && pScrn->pScreen) {
DRILock(pScrn->pScreen, 0);
if (info->accelOn)
@@ -322,7 +937,7 @@ radeon_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
unsigned long rotate_pitch;
unsigned long rotate_offset;
- int align = KB(4), size;
+ int align = 4096, size;
int cpp = pScrn->bitsPerPixel / 8;
rotate_pitch = pScrn->displayWidth * cpp;
@@ -382,7 +997,6 @@ static PixmapPtr
radeon_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
{
ScrnInfoPtr pScrn = crtc->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned long rotate_pitch;
PixmapPtr rotate_pixmap;
int cpp = pScrn->bitsPerPixel / 8;
@@ -599,8 +1213,7 @@ RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox)
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
RADEONInfoPtr info = RADEONPTR(pScrn);
int c;
- int highx = 0, highy = 0;
- int crtc_num;
+ int crtc_num = 0;
for (c = 0; c < xf86_config->num_crtc; c++)
{
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index b3f7691..98f4560 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -59,14 +59,6 @@
/* X and server generic header files */
#include "xf86.h"
-/* Mono ARGB cursor colours (premultiplied). */
-static CARD32 mono_cursor_color[] = {
- 0x00000000, /* White, fully transparent. */
- 0x00000000, /* Black, fully transparent. */
- 0xffffffff, /* White, fully opaque. */
- 0xff000000, /* Black, fully opaque. */
-};
-
#define CURSOR_WIDTH 64
#define CURSOR_HEIGHT 64
@@ -131,44 +123,6 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crtc)
}
-/* Set cursor foreground and background colors */
-static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- CARD32 *pixels = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
- int pixel, i;
- CURSOR_SWAPPING_DECL_MMIO
-
- RADEONCTRACE(("RADEONSetCursorColors\n"));
-
-#ifdef ARGB_CURSOR
- /* Don't recolour cursors set with SetCursorARGB. */
- if (info->cursor_argb)
- return;
-#endif
-
- fg |= 0xff000000;
- bg |= 0xff000000;
-
- /* Don't recolour the image if we don't have to. */
- if (fg == info->cursor_fg && bg == info->cursor_bg)
- return;
-
- CURSOR_SWAPPING_START();
-
- /* Note: We assume that the pixels are either fully opaque or fully
- * transparent, so we won't premultiply them, and we can just
- * check for non-zero pixel values; those are either fg or bg
- */
- for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++)
- if ((pixel = *pixels))
- *pixels = (pixel == info->cursor_fg) ? fg : bg;
-
- CURSOR_SWAPPING_END();
- info->cursor_fg = fg;
- info->cursor_bg = bg;
-}
-
void
radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
{
@@ -262,14 +216,13 @@ void
radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
{
ScrnInfoPtr pScrn = crtc->scrn;
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
- int crtc_id = radeon_crtc->crtc_id;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 *d = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
+#if 0
int x, y, w, h;
CARD32 *i;
+#endif
RADEONCTRACE(("RADEONLoadCursorARGB\n"));
@@ -313,7 +266,6 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
- xf86CursorInfoPtr cursor;
int width;
int width_bytes;
int height;
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 0442b9a..18d8a01 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -49,28 +49,6 @@
extern int getRADEONEntityIndex(void);
-static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
-{
- {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_UNKNOW*/
- {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_LEGACY*/
- {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/
- {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/
- {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/
- {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/
- {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/
- {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/
- {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/
- {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/
- {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
- {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/
- {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/
- {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/
- {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV380*/
- {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R420*/
- {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
- {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
-};
-
static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
{
0x00000000, /* unknown */
@@ -93,68 +71,6 @@ static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
0x00780000, /* rs400 */ /* FIXME: just values from rv380 used... */
};
-static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
-{
- ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned long val;
- unsigned char *RADEONMMIO = info->MMIO;
-
- /* Get the result */
-
- if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
- val = INREG(b->DriverPrivate.uval+4);
- *Clock = (val & (1<<13)) != 0;
- *data = (val & (1<<12)) != 0;
- } else {
- val = INREG(b->DriverPrivate.uval);
- *Clock = (val & RADEON_GPIO_Y_1) != 0;
- *data = (val & RADEON_GPIO_Y_0) != 0;
- }
-}
-
-static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
-{
- ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned long val;
- unsigned char *RADEONMMIO = info->MMIO;
-
- if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
- val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<12) | (1<<13));
- val |= (Clock ? 0:(1<<13));
- val |= (data ? 0:(1<<12));
- OUTREG(b->DriverPrivate.uval, val);
- } else {
- val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
- val |= (Clock ? 0:RADEON_GPIO_EN_1);
- val |= (data ? 0:RADEON_GPIO_EN_0);
- OUTREG(b->DriverPrivate.uval, val);
- }
- /* read back to improve reliability on some cards. */
- val = INREG(b->DriverPrivate.uval);
-}
-
-Bool RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
-{
- I2CBusPtr pI2CBus;
-
- pI2CBus = xf86CreateI2CBusRec();
- if (!pI2CBus) return FALSE;
-
- pI2CBus->BusName = name;
- pI2CBus->scrnIndex = pScrn->scrnIndex;
- pI2CBus->I2CPutBits = RADEONI2CPutBits;
- pI2CBus->I2CGetBits = RADEONI2CGetBits;
- pI2CBus->AcknTimeout = 5;
- pI2CBus->DriverPrivate.uval = i2c_reg;
-
- if (!xf86I2CBusInit(pI2CBus)) return FALSE;
-
- *bus_ptr = pI2CBus;
- return TRUE;
-}
-
void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
{
MonPtr mon = pScrn->monitor;
@@ -243,590 +159,6 @@ void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
}
}
-RADEONMonitorType
-RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int bConnected = 0;
-
- /* the monitor either wasn't connected or it is a non-DDC CRT.
- * try to probe it
- */
- if(IsCrtDac) {
- unsigned long ulOrigVCLK_ECP_CNTL;
- unsigned long ulOrigDAC_CNTL;
- unsigned long ulOrigDAC_MACRO_CNTL;
- unsigned long ulOrigDAC_EXT_CNTL;
- unsigned long ulOrigCRTC_EXT_CNTL;
- unsigned long ulData;
- unsigned long ulMask;
-
- ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
- ulData = ulOrigVCLK_ECP_CNTL;
- ulData &= ~(RADEON_PIXCLK_ALWAYS_ONb
- | RADEON_PIXCLK_DAC_ALWAYS_ONb);
- ulMask = ~(RADEON_PIXCLK_ALWAYS_ONb
- |RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
- ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
- ulData = ulOrigCRTC_EXT_CNTL;
- ulData |= RADEON_CRTC_CRT_ON;
- OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
-
- ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
- ulData = ulOrigDAC_EXT_CNTL;
- ulData &= ~RADEON_DAC_FORCE_DATA_MASK;
- ulData |= (RADEON_DAC_FORCE_BLANK_OFF_EN
- |RADEON_DAC_FORCE_DATA_EN
- |RADEON_DAC_FORCE_DATA_SEL_MASK);
- if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
- (info->ChipFamily == CHIP_FAMILY_RV280))
- ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
- else
- ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
-
- OUTREG(RADEON_DAC_EXT_CNTL, ulData);
-
- /* turn on power so testing can go through */
- ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
- ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
- OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
-
- ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
- ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
- /* Enable comparators and set DAC range to PS2 (VGA) output level */
- ulData = ulOrigDAC_CNTL;
- ulData |= RADEON_DAC_CMP_EN;
- ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
- ulData |= 0x2;
- OUTREG(RADEON_DAC_CNTL, ulData);
-
- /* Settle down */
- usleep(10000);
-
- /* Read comparators */
- ulData = INREG(RADEON_DAC_CNTL);
- bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
-
- /* Restore things */
- ulData = ulOrigVCLK_ECP_CNTL;
- ulMask = 0xFFFFFFFFL;
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
- OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL );
- OUTREG(RADEON_DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
- OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
-
- if (!bConnected) {
- /* Power DAC down if CRT is not connected */
- ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
- ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
- ulData = INREG(RADEON_DAC_CNTL);
- ulData |= RADEON_DAC_PDWN;
- OUTREG(RADEON_DAC_CNTL, ulData);
- }
- } else { /* TV DAC */
-
- /* This doesn't seem to work reliably (maybe worse on some OEM cards),
- for now we always return false. If one wants to connected a
- non-DDC monitor on the DVI port when CRT port is also connected,
- he will need to explicitly tell the driver in the config file
- with Option MonitorLayout.
- */
- bConnected = FALSE;
-
-#if 0
- if (info->ChipFamily == CHIP_FAMILY_R200) {
- unsigned long ulOrigGPIO_MONID;
- unsigned long ulOrigFP2_GEN_CNTL;
- unsigned long ulOrigDISP_OUTPUT_CNTL;
- unsigned long ulOrigCRTC2_GEN_CNTL;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
- unsigned long ulOrigCRTC2_H_TOTAL_DISP;
- unsigned long ulOrigCRTC2_V_TOTAL_DISP;
- unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
- unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
- unsigned long ulData, i;
-
- ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
- ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
- ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
- ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
- ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
- ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
- ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
- ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
- ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
- ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
-
- ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
- ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
- ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
- ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-
- ulData = INREG(RADEON_GPIO_MONID);
- ulData &= ~RADEON_GPIO_A_0;
- OUTREG(RADEON_GPIO_MONID, ulData);
-
- OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
-
- OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
-
- OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
-
- for (i = 0; i < 200; i++) {
- ulData = INREG(RADEON_GPIO_MONID);
- bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
- if (!bConnected) break;
-
- usleep(1000);
- }
-
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
- OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
- OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
- OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
- OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
- } else {
- unsigned long ulOrigPIXCLKSDATA;
- unsigned long ulOrigTV_MASTER_CNTL;
- unsigned long ulOrigTV_DAC_CNTL;
- unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
- unsigned long ulOrigDAC_CNTL2;
- unsigned long ulData;
- unsigned long ulMask;
-
- ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-
- ulData = ulOrigPIXCLKSDATA;
- ulData &= ~(RADEON_PIX2CLK_ALWAYS_ONb
- | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
- ulMask = ~(RADEON_PIX2CLK_ALWAYS_ONb
- | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
- ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
- ulData = ulOrigTV_MASTER_CNTL;
- ulData &= ~RADEON_TVCLK_ALWAYS_ONb;
- OUTREG(RADEON_TV_MASTER_CNTL, ulData);
-
- ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
- ulData = ulOrigDAC_CNTL2;
- ulData &= ~RADEON_DAC2_DAC2_CLK_SEL;
- OUTREG(RADEON_DAC_CNTL2, ulData);
-
- ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
-
- ulData = 0x00880213;
- OUTREG(RADEON_TV_DAC_CNTL, ulData);
-
- ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-
- ulData = (RADEON_Y_RED_EN
- | RADEON_C_GRN_EN
- | RADEON_CMP_BLU_EN
- | RADEON_RED_MX_FORCE_DAC_DATA
- | RADEON_GRN_MX_FORCE_DAC_DATA
- | RADEON_BLU_MX_FORCE_DAC_DATA);
- if (IS_R300_VARIANT)
- ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
- else
- ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
-
- usleep(10000);
-
- ulData = INREG(RADEON_TV_DAC_CNTL);
- bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
-
- ulData = ulOrigPIXCLKSDATA;
- ulMask = 0xFFFFFFFFL;
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
- OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
- OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
- OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
- }
-#endif
- return MT_UNKNOWN;
- }
-
- return(bConnected ? MT_CRT : MT_NONE);
-}
-
-
-RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- unsigned long DDCReg;
- RADEONMonitorType MonType = MT_NONE;
- xf86MonPtr* MonInfo = &output->MonInfo;
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- RADEONDDCType DDCType = radeon_output->DDCType;
- int i, j;
-
- DDCReg = radeon_output->DDCReg;
-
- /* Read and output monitor info using DDC2 over I2C bus */
- if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK)) {
- OUTREG(DDCReg, INREG(DDCReg) &
- (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
-
- /* For some old monitors (like Compaq Presario FP500), we need
- * following process to initialize/stop DDC
- */
- OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
- for (j = 0; j < 3; j++) {
- OUTREG(DDCReg,
- INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
- usleep(13000);
-
- OUTREG(DDCReg,
- INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
- for (i = 0; i < 10; i++) {
- usleep(15000);
- if (INREG(DDCReg) & RADEON_GPIO_Y_1)
- break;
- }
- if (i == 10) continue;
-
- usleep(15000);
-
- OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
- usleep(15000);
-
- OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
- usleep(15000);
- OUTREG(DDCReg,
- INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
- usleep(15000);
- *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
-
- OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
- OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
- usleep(15000);
- OUTREG(DDCReg,
- INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
- for (i = 0; i < 5; i++) {
- usleep(15000);
- if (INREG(DDCReg) & RADEON_GPIO_Y_1)
- break;
- }
- usleep(15000);
- OUTREG(DDCReg,
- INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
- usleep(15000);
-
- OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
- OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
- usleep(15000);
- if(*MonInfo) break;
- }
- } else if (radeon_output->pI2CBus && info->ddc2 && DDCReg == RADEON_LCD_GPIO_MASK) {
- *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
- } else {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
- MonType = MT_NONE;
- }
-
- OUTREG(DDCReg, INREG(DDCReg) &
- ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
-
- if (*MonInfo) {
- if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
- (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
- MonType = MT_LCD;
- } else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
- (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D)) {
- MonType = MT_DFP;
- } else if ((*MonInfo)->rawData[0x14] & 0x80) { /* if it's digital */
- MonType = MT_DFP;
- } else {
- MonType = MT_CRT;
- }
- } else MonType = MT_NONE;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "DDC Type: %d, Detected Monitor Type: %d\n", DDCType, MonType);
-
- return MonType;
-}
-
-void RADEONGetPanelInfoFromReg (xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
- CARD32 fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
-
- radeon_output->PanelPwrDly = 200;
- if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
- radeon_output->PanelYRes = (fp_vert_stretch>>12) + 1;
- } else {
- radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
- }
- if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
- radeon_output->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;
- } else {
- radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
- }
-
- if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) {
- radeon_output->PanelXRes = 640;
- radeon_output->PanelYRes = 480;
- }
-
- // move this to crtc function
- if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
- CARD32 ppll_div_sel, ppll_val;
-
- ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
- RADEONPllErrataAfterIndex(info);
- ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
- if ((ppll_val & 0x000707ff) == 0x1bb)
- goto noprobe;
- info->FeedbackDivider = ppll_val & 0x7ff;
- info->PostDivider = (ppll_val >> 16) & 0x7;
- info->RefDivider = info->pll.reference_div;
- info->UseBiosDividers = TRUE;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Existing panel PLL dividers will be used.\n");
- }
- noprobe:
-
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Panel size %dx%d is derived, this may not be correct.\n"
- "If not, use PanelSize option to overwrite this setting\n",
- radeon_output->PanelXRes, radeon_output->PanelYRes);
-}
-
-
-/* BIOS may not have right panel size, we search through all supported
- * DDC modes looking for the maximum panel size.
- */
-void RADEONUpdatePanelSize(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- int j;
- /* XXX: fixme */
- xf86MonPtr ddc = pScrn->monitor->DDC;
- DisplayModePtr p;
-
- // crtc should handle?
- if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
- return;
-
- /* Go thru detailed timing table first */
- for (j = 0; j < 4; j++) {
- if (ddc->det_mon[j].type == 0) {
- struct detailed_timings *d_timings =
- &ddc->det_mon[j].section.d_timings;
- int match = 0;
-
- /* If we didn't get a panel clock or guessed one, try to match the
- * mode with the panel size. We do that because we _need_ a panel
- * clock, or ValidateFPModes will fail, even when UseBiosDividers
- * is set.
- */
- if (radeon_output->DotClock == 0 &&
- radeon_output->PanelXRes == d_timings->h_active &&
- radeon_output->PanelYRes == d_timings->v_active)
- match = 1;
-
- /* If we don't have a BIOS provided panel data with fixed dividers,
- * check for a larger panel size
- */
- if (radeon_output->PanelXRes < d_timings->h_active &&
- radeon_output->PanelYRes < d_timings->v_active &&
- !info->UseBiosDividers)
- match = 1;
-
- if (match) {
- radeon_output->PanelXRes = d_timings->h_active;
- radeon_output->PanelYRes = d_timings->v_active;
- radeon_output->DotClock = d_timings->clock / 1000;
- radeon_output->HOverPlus = d_timings->h_sync_off;
- radeon_output->HSyncWidth = d_timings->h_sync_width;
- radeon_output->HBlank = d_timings->h_blanking;
- radeon_output->VOverPlus = d_timings->v_sync_off;
- radeon_output->VSyncWidth = d_timings->v_sync_width;
- radeon_output->VBlank = d_timings->v_blanking;
- radeon_output->Flags = (d_timings->interlaced ? V_INTERLACE : 0);
- switch (d_timings->misc) {
- case 0: radeon_output->Flags |= V_NHSYNC | V_NVSYNC; break;
- case 1: radeon_output->Flags |= V_PHSYNC | V_NVSYNC; break;
- case 2: radeon_output->Flags |= V_NHSYNC | V_PVSYNC; break;
- case 3: radeon_output->Flags |= V_PHSYNC | V_PVSYNC; break;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
- radeon_output->PanelXRes, radeon_output->PanelYRes);
- }
- }
- }
-
- if (info->UseBiosDividers && radeon_output->DotClock != 0)
- return;
-
- /* Search thru standard VESA modes from EDID */
- for (j = 0; j < 8; j++) {
- if ((radeon_output->PanelXRes < ddc->timings2[j].hsize) &&
- (radeon_output->PanelYRes < ddc->timings2[j].vsize)) {
- for (p = pScrn->monitor->Modes; p; p = p->next) {
- if ((ddc->timings2[j].hsize == p->HDisplay) &&
- (ddc->timings2[j].vsize == p->VDisplay)) {
- float refresh =
- (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-
- if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
- /* Is this good enough? */
- radeon_output->PanelXRes = ddc->timings2[j].hsize;
- radeon_output->PanelYRes = ddc->timings2[j].vsize;
- radeon_output->HBlank = p->HTotal - p->HDisplay;
- radeon_output->HOverPlus = p->HSyncStart - p->HDisplay;
- radeon_output->HSyncWidth = p->HSyncEnd - p->HSyncStart;
- radeon_output->VBlank = p->VTotal - p->VDisplay;
- radeon_output->VOverPlus = p->VSyncStart - p->VDisplay;
- radeon_output->VSyncWidth = p->VSyncEnd - p->VSyncStart;
- radeon_output->DotClock = p->Clock;
- radeon_output->Flags = p->Flags;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
- radeon_output->PanelXRes, radeon_output->PanelYRes);
- }
- }
- }
- }
- }
-}
-
-Bool RADEONGetLVDSInfo (xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- char* s;
-
- if (!RADEONGetLVDSInfoFromBIOS(output))
- RADEONGetPanelInfoFromReg(output);
-
- if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
- radeon_output->PanelPwrDly = 200;
- if (sscanf (s, "%dx%d", &radeon_output->PanelXRes, &radeon_output->PanelYRes) != 2) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
- RADEONGetPanelInfoFromReg(output);
- }
- }
-
- /* The panel size we collected from BIOS may not be the
- * maximum size supported by the panel. If not, we update
- * it now. These will be used if no matching mode can be
- * found from EDID data.
- */
- RADEONUpdatePanelSize(output);
-
- if (radeon_output->DotClock == 0) {
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- DisplayModePtr tmp_mode = NULL;
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "No valid timing info from BIOS.\n");
- /* No timing information for the native mode,
- use whatever specified in the Modeline.
- If no Modeline specified, we'll just pick
- the VESA mode at 60Hz refresh rate which
- is likely to be the best for a flat panel.
- */
- tmp_mode = pScrn->monitor->Modes;
- while(tmp_mode) {
- if ((tmp_mode->HDisplay == radeon_output->PanelXRes) &&
- (tmp_mode->VDisplay == radeon_output->PanelYRes)) {
-
- float refresh =
- (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;
- if ((abs(60.0 - refresh) < 1.0) ||
- (tmp_mode->type == 0)) {
- radeon_output->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay;
- radeon_output->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay;
- radeon_output->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
- radeon_output->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay;
- radeon_output->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay;
- radeon_output->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
- radeon_output->DotClock = tmp_mode->Clock;
- radeon_output->Flags = 0;
- break;
- }
- }
- tmp_mode = tmp_mode->next;
- }
- if ((radeon_output->DotClock == 0) && !output->MonInfo) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Panel size is not correctly detected.\n"
- "Please try to use PanelSize option for correct settings.\n");
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-void RADEONGetTMDSInfo(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- int i;
-
- for (i=0; i<4; i++) {
- radeon_output->tmds_pll[i].value = 0;
- radeon_output->tmds_pll[i].freq = 0;
- }
-
- if (RADEONGetTMDSInfoFromBIOS(output)) return;
-
- for (i=0; i<4; i++) {
- radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
- radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
- }
-}
-
void RADEONGetTVDacAdjInfo(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
@@ -1400,11 +732,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_b
void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
DisplayModePtr mode1, mode2;
- RADEONInfoPtr info2 = NULL;
- xf86CrtcPtr crtc;
int pixel_bytes2 = 0;
mode1 = info->CurrentLayout.mode;
@@ -1432,10 +761,7 @@ void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
void RADEONBlank(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86OutputPtr output;
xf86CrtcPtr crtc;
int o, c;
@@ -1455,10 +781,7 @@ void RADEONBlank(ScrnInfoPtr pScrn)
void RADEONUnblank(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86OutputPtr output;
xf86CrtcPtr crtc;
int o, c;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b399736..925b8ee 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -93,6 +93,7 @@
#include "xf86_ansic.h" /* For xf86getsecs() */
#include "xf86_OSproc.h"
#include "xf86RAC.h"
+#include "xf86RandR12.h"
#include "xf86Resources.h"
#include "xf86cmap.h"
#include "vbe.h"
@@ -429,6 +430,7 @@ struct RADEONInt10Save {
static Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
+#if 0
static Bool
RADEONCreateScreenResources (ScreenPtr pScreen)
{
@@ -444,6 +446,7 @@ RADEONCreateScreenResources (ScreenPtr pScreen)
return TRUE;
}
+#endif
RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
{
@@ -538,8 +541,6 @@ static Bool RADEONGetRec(ScrnInfoPtr pScrn)
/* Free our private RADEONInfoRec */
static void RADEONFreeRec(ScrnInfoPtr pScrn)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
if (!pScrn || !pScrn->driverPrivate) return;
xfree(pScrn->driverPrivate);
pScrn->driverPrivate = NULL;
@@ -2488,7 +2489,6 @@ static Bool RADEONPreInitXv(ScrnInfoPtr pScrn)
static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
@@ -2827,7 +2827,6 @@ fail:
vgaHWFreeHWRec(pScrn);
#endif
- fail2:
if(info->MMIO) RADEONUnmapMMIO(pScrn);
info->MMIO = NULL;
@@ -2842,11 +2841,9 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors,
int *indices, LOCO *colors, VisualPtr pVisual)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
int index, j;
- unsigned char r, g, b;
CARD16 lut_r[256], lut_g[256], lut_b[256];
int c;
@@ -4032,7 +4029,6 @@ void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
info->ChipFamily != CHIP_FAMILY_R200 &&
!IS_R300_VARIANT) {
CARD32 tmp;
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
tmp = INREG(RADEON_DAC_CNTL2);
OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
@@ -4622,7 +4618,6 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
void
RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86CrtcPtr crtc = pRADEONEnt->pCrtc[crtc_num];
@@ -4640,11 +4635,7 @@ RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num)
/* Write out state to define a new video mode */
void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONCrtcPrivatePtr pCRTC1 = pRADEONEnt->Controller[0];
- RADEONCrtcPrivatePtr pCRTC2 = pRADEONEnt->Controller[1];
- xf86OutputPtr output;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONRestoreMode(%p)\n", restore);
@@ -4924,8 +4915,6 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
/* Save state that defines current video mode */
static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONSaveMode(%p)\n", save);
@@ -5070,914 +5059,6 @@ void RADEONRestore(ScrnInfoPtr pScrn)
#endif
}
-/* Define common registers for requested video mode */
-void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
-{
- save->ovr_clr = 0;
- save->ovr_wid_left_right = 0;
- save->ovr_wid_top_bottom = 0;
- save->ov0_scale_cntl = 0;
- save->subpic_cntl = 0;
- save->viph_control = 0;
- save->i2c_cntl_1 = 0;
- save->rbbm_soft_reset = 0;
- save->cap0_trig_cntl = 0;
- save->cap1_trig_cntl = 0;
- save->bus_cntl = info->BusCntl;
- /*
- * If bursts are enabled, turn on discards
- * Radeon doesn't have write bursts
- */
- if (save->bus_cntl & (RADEON_BUS_READ_BURST))
- save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
-}
-
-/* XXX: fix me */
-static void RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- if (info->ChipFamily == CHIP_FAMILY_R420 ||
- info->ChipFamily == CHIP_FAMILY_RV410) {
- save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
- ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- R420_TV_DAC_DACADJ_MASK |
- R420_TV_DAC_RDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_TVENABLE);
- } else {
- save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
- ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- RADEON_TV_DAC_DACADJ_MASK |
- RADEON_TV_DAC_RDACPD |
- RADEON_TV_DAC_GDACPD |
- RADEON_TV_DAC_GDACPD);
- }
- /* FIXME: doesn't make sense, this just replaces the previous value... */
- save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
- RADEON_TV_DAC_NHOLD |
- RADEON_TV_DAC_STD_PS2);
- // info->tv_dac_adj);
-}
-
-static void RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- int i;
- CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff;
-
- for (i=0; i<4; i++) {
- if (radeon_output->tmds_pll[i].freq == 0) break;
- if ((CARD32)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
- tmp = radeon_output->tmds_pll[i].value ;
- break;
- }
- }
-
- if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
- if (tmp & 0xfff00000)
- save->tmds_pll_cntl = tmp;
- else {
- save->tmds_pll_cntl = info->SavedReg.tmds_pll_cntl & 0xfff00000;
- save->tmds_pll_cntl |= tmp;
- }
- } else save->tmds_pll_cntl = tmp;
-
- save->tmds_transmitter_cntl = info->SavedReg.tmds_transmitter_cntl &
- ~(RADEON_TMDS_TRANSMITTER_PLLRST);
-
- if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
- save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
- else /* weird, RV chips got this bit reversed? */
- save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
-
- save->fp_gen_cntl = info->SavedReg.fp_gen_cntl |
- (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
- RADEON_FP_CRTC_DONT_SHADOW_HEND );
-
- save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-
- if (pScrn->rgbBits == 8)
- save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
- else
- save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
-
-
- if (IsPrimary) {
- if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
- save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
- if (mode->Flags & RADEON_USE_RMX)
- save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
- else
- save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
- } else
- save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
- } else {
- if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
- save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
- save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
- } else
- save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
- }
-
-}
-
-static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
-
- if (pScrn->rgbBits == 8)
- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
- RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
- else
- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
- ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
-
- save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
-
- if (IsPrimary) {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_EN |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- if (mode->Flags & RADEON_USE_RMX)
- save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
- } else {
- save->fp2_gen_cntl &= ~(RADEON_FP2_SRC_SEL_CRTC2 |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- }
- } else {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
- } else {
- save->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR);
- save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
- }
- }
-
-}
-
-static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl;
- save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
- save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
-
- if (IsPrimary)
- save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
- else
- save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
-
-}
-
-static void RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- int xres = mode->HDisplay;
- int yres = mode->VDisplay;
- float Hratio, Vratio;
-
- if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
- Hratio = 1.0;
- Vratio = 1.0;
- } else {
- if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
- if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
-
- Hratio = (float)xres/(float)radeon_output->PanelXRes;
- Vratio = (float)yres/(float)radeon_output->PanelYRes;
- }
-
- save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
- RADEON_VERT_STRETCH_RESERVED;
- save->fp_horz_stretch = info->SavedReg.fp_horz_stretch &
- (RADEON_HORZ_FP_LOOP_STRETCH |
- RADEON_HORZ_AUTO_RATIO_INC);
-
- if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
- save->fp_horz_stretch |= ((xres/8-1)<<16);
- } else {
- save->fp_horz_stretch |= ((((unsigned long)(Hratio * RADEON_HORZ_STRETCH_RATIO_MAX +
- 0.5)) & RADEON_HORZ_STRETCH_RATIO_MASK) |
- RADEON_HORZ_STRETCH_BLEND |
- RADEON_HORZ_STRETCH_ENABLE |
- ((radeon_output->PanelXRes/8-1)<<16));
- }
-
- if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
- save->fp_vert_stretch |= ((yres-1)<<12);
- } else {
- save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX +
- 0.5)) & RADEON_VERT_STRETCH_RATIO_MASK) |
- RADEON_VERT_STRETCH_ENABLE |
- RADEON_VERT_STRETCH_BLEND |
- ((radeon_output->PanelYRes-1)<<12));
- }
-
-}
-
-static void RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if (IsPrimary) {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_DAC_SOURCE_MASK;
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
- }
- } else {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_DAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
- }
- }
- save->dac_cntl = (RADEON_DAC_MASK_ALL
- | RADEON_DAC_VGA_ADR_EN
- | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
-}
-
-static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- /*0x0028023;*/
- RADEONInitTvDacCntl(pScrn, save);
-
- if (IsPrimary) {
- /*save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl | RADEON_CRTC2_CRT2_ON;*/
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- if (IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_TVDAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
- } else if (info->ChipFamily == CHIP_FAMILY_R200) {
- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
- ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- /*save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
- (RADEON_FP2_ON |
- RADEON_FP2_BLANK_EN |
- RADEON_FP2_DVO_EN);*/
- } else {
- save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL;
- }
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- if (IS_R300_VARIANT) {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- save->disp_output_cntl = info->SavedReg.disp_output_cntl &
- ~RADEON_DISP_TVDAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
- } else if (info->ChipFamily == CHIP_FAMILY_R200) {
- save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
- ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- save->fp2_gen_cntl |= (R200_FP2_SOURCE_SEL_CRTC2 /*|
- RADEON_FP2_BLANK_EN |
- RADEON_FP2_ON |
- RADEON_FP2_DVO_EN*/);
- /*save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
- save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;*/
- } else {
- save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
- save->disp_hw_debug = info->SavedReg.disp_hw_debug &
- ~RADEON_CRT2_DISP1_SEL;
- }
- }
-}
-
-void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, xf86OutputPtr output, int crtc_num)
-{
- Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- if (radeon_output->MonType == MT_CRT) {
- if (radeon_output->DACType == DAC_PRIMARY) {
- RADEONInitDACRegisters(output, save, mode, IsPrimary);
- } else {
- RADEONInitDAC2Registers(output, save, mode, IsPrimary);
- }
- } else if (radeon_output->MonType == MT_LCD) {
- if (crtc_num == 0)
- RADEONInitRMXRegisters(output, save, mode);
- RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
- } else if (radeon_output->MonType == MT_DFP) {
- if (crtc_num == 0)
- RADEONInitRMXRegisters(output, save, mode);
- if (radeon_output->TMDSType == TMDS_INT) {
- RADEONInitFPRegisters(output, save, mode, IsPrimary);
- } else {
- RADEONInitFP2Registers(output, save, mode, IsPrimary);
- }
- }
-}
-
-/* Define CRTC registers for requested video mode */
-Bool RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
- DisplayModePtr mode, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
- //RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int format;
- int hsync_start;
- int hsync_wid;
- int vsync_wid;
- int i, Base;
-#ifdef XF86DRI
- RADEONSAREAPrivPtr pSAREAPriv;
- XF86DRISAREAPtr pSAREA;
-#endif
-
- switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; break;
- case 8: format = 2; break;
- case 15: format = 3; break; /* 555 */
- case 16: format = 4; break; /* 565 */
- case 24: format = 5; break; /* RGB */
- case 32: format = 6; break; /* xRGB */
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unsupported pixel depth (%d)\n",
- info->CurrentLayout.bitsPerPixel);
- return FALSE;
- }
-
- save->bios_4_scratch = info->SavedReg.bios_4_scratch;
- save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
- | RADEON_CRTC_EN
- | (format << 8)
- | ((mode->Flags & V_DBLSCAN)
- ? RADEON_CRTC_DBL_SCAN_EN
- : 0)
- | ((mode->Flags & V_CSYNC)
- ? RADEON_CRTC_CSYNC_EN
- : 0)
- | ((mode->Flags & V_INTERLACE)
- ? RADEON_CRTC_INTERLACE_EN
- : 0));
-
- save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
- RADEON_CRTC_VSYNC_DIS |
- RADEON_CRTC_HSYNC_DIS |
- RADEON_CRTC_DISPLAY_DIS);
-
- save->surface_cntl = 0;
- save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
- save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* We must set both apertures as they can be both used to map the entire
- * video memory. -BenH.
- */
- switch (pScrn->bitsPerPixel) {
- case 16:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
- break;
-
- case 32:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
- break;
- }
-#endif
-
- save->crtc_more_cntl = 0;
- if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
- (info->ChipFamily == CHIP_FAMILY_RS200)) {
- /* This is to workaround the asic bug for RMX, some versions
- of BIOS dosen't have this register initialized correctly.
- */
- save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
- }
-
- save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
- | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
- << 16));
-
- hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
- if (!hsync_wid) hsync_wid = 1;
- if (hsync_wid > 0x3f) hsync_wid = 0x3f;
- hsync_start = mode->CrtcHSyncStart - 8;
-
- save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
- | (hsync_wid << 16)
- | ((mode->Flags & V_NHSYNC)
- ? RADEON_CRTC_H_SYNC_POL
- : 0));
-
- /* This works for double scan mode. */
- save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
- | ((mode->CrtcVDisplay - 1) << 16));
-
- vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
- if (!vsync_wid) vsync_wid = 1;
- if (vsync_wid > 0x1f) vsync_wid = 0x1f;
-
- save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
- | (vsync_wid << 16)
- | ((mode->Flags & V_NVSYNC)
- ? RADEON_CRTC_V_SYNC_POL
- : 0));
-
- save->crtc_offset = pScrn->fbOffset;
- if (info->tilingEnabled) {
- if (IS_R300_VARIANT)
- save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
- }
- else {
- if (IS_R300_VARIANT)
- save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
- }
-
- save->crtc_pitch = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
- ((pScrn->bitsPerPixel * 8) -1)) /
- (pScrn->bitsPerPixel * 8));
- save->crtc_pitch |= save->crtc_pitch << 16;
-
- save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
- save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
- save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
- save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
-
- Base = pScrn->fbOffset;
-
- if (info->tilingEnabled) {
- if (IS_R300_VARIANT) {
- /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
- * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
- * Makes tiling MUCH easier.
- */
- save->crtc_tile_x0_y0 = x | (y << 16);
- Base &= ~0x7ff;
- } else {
- /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
- drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
- flickering when scrolling vertically in a virtual screen, possibly because crtc will
- pick up the new offset value at the end of each scanline, but the new offset_cntl value
- only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
- OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
- save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL) & ~0xf;
-#if 0
- /* try to get rid of flickering when scrolling at least for 2d */
-#ifdef XF86DRI
- if (!info->have3DWindows)
-#endif
- save->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
-#endif
-
- int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
- /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
- int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
- Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
- save->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
- }
- }
- else {
- int offset = y * info->CurrentLayout.displayWidth + x;
- switch (info->CurrentLayout.pixel_code) {
- case 15:
- case 16: offset *= 2; break;
- case 24: offset *= 3; break;
- case 32: offset *= 4; break;
- }
- Base += offset;
- }
-
- Base &= ~7; /* 3 lower bits are always 0 */
-
-
-#ifdef XF86DRI
- if (info->directRenderingInited) {
- /* note cannot use pScrn->pScreen since this is unitialized when called from
- RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
- /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
- *** pageflipping!
- ***/
- pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
- /* can't get at sarea in a semi-sane way? */
- pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
-
- pSAREA->frame.x = (Base / info->CurrentLayout.pixel_bytes)
- % info->CurrentLayout.displayWidth;
- pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
- / info->CurrentLayout.displayWidth;
- pSAREA->frame.width = pScrn->frameX1 - x + 1;
- pSAREA->frame.height = pScrn->frameY1 - y + 1;
-
- if (pSAREAPriv->pfCurrentPage == 1) {
- Base += info->backOffset - info->frontOffset;
- }
- }
-#endif
- save->crtc_offset = Base;
-
-
- if (info->IsDellServer) {
- save->dac2_cntl = info->SavedReg.dac2_cntl;
- save->tv_dac_cntl = info->SavedReg.tv_dac_cntl;
- save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl;
- save->disp_hw_debug = info->SavedReg.disp_hw_debug;
-
- save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
- save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
-
- /* For CRT on DAC2, don't turn it on if BIOS didn't
- enable it, even it's detected.
- */
- save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
- save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
- save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
- }
-
- return TRUE;
-}
-
-/* Define CRTC2 registers for requested video mode */
-Bool RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
- DisplayModePtr mode, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
- //RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int format;
- int hsync_start;
- int hsync_wid;
- int vsync_wid;
- int i, Base;
-#ifdef XF86DRI
- RADEONSAREAPrivPtr pSAREAPriv;
- XF86DRISAREAPtr pSAREA;
-#endif
-
- switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; break;
- case 8: format = 2; break;
- case 15: format = 3; break; /* 555 */
- case 16: format = 4; break; /* 565 */
- case 24: format = 5; break; /* RGB */
- case 32: format = 6; break; /* xRGB */
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unsupported pixel depth (%d)\n",
- info->CurrentLayout.bitsPerPixel);
- return FALSE;
- }
-
- save->crtc2_h_total_disp =
- ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
- | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
-
- hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
- if (!hsync_wid) hsync_wid = 1;
- if (hsync_wid > 0x3f) hsync_wid = 0x3f;
- hsync_start = mode->CrtcHSyncStart - 8;
-
- save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
- | (hsync_wid << 16)
- | ((mode->Flags & V_NHSYNC)
- ? RADEON_CRTC_H_SYNC_POL
- : 0));
-
- /* This works for double scan mode. */
- save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
- | ((mode->CrtcVDisplay - 1) << 16));
-
- vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
- if (!vsync_wid) vsync_wid = 1;
- if (vsync_wid > 0x1f) vsync_wid = 0x1f;
-
- save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
- | (vsync_wid << 16)
- | ((mode->Flags & V_NVSYNC)
- ? RADEON_CRTC2_V_SYNC_POL
- : 0));
-
- /* It seems all fancy options apart from pflip can be safely disabled
- */
- save->crtc2_offset = pScrn->fbOffset;
- save->crtc2_offset_cntl &= RADEON_CRTC_OFFSET_FLIP_CNTL;
- if (info->tilingEnabled) {
- if (IS_R300_VARIANT)
- save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
- }
- else {
- if (IS_R300_VARIANT)
- save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
- }
-
- save->crtc2_pitch = ((info->CurrentLayout.displayWidth * pScrn->bitsPerPixel) +
- ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
- save->crtc2_pitch |= save->crtc2_pitch << 16;
-
- save->crtc2_gen_cntl = (RADEON_CRTC2_EN
- | (format << 8)
- | RADEON_CRTC2_VSYNC_DIS
- | RADEON_CRTC2_HSYNC_DIS
- | RADEON_CRTC2_DISP_DIS
- | ((mode->Flags & V_DBLSCAN)
- ? RADEON_CRTC2_DBL_SCAN_EN
- : 0)
- | ((mode->Flags & V_CSYNC)
- ? RADEON_CRTC2_CSYNC_EN
- : 0)
- | ((mode->Flags & V_INTERLACE)
- ? RADEON_CRTC2_INTERLACE_EN
- : 0));
-
- save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl;
- save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
-
- save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
- save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
-
- Base = pScrn->fbOffset;
-
- if (info->tilingEnabled) {
- if (IS_R300_VARIANT) {
- /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
- * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
- * Makes tiling MUCH easier.
- */
- save->crtc2_tile_x0_y0 = x | (y << 16);
- Base &= ~0x7ff;
- } else {
- /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
- drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
- flickering when scrolling vertically in a virtual screen, possibly because crtc will
- pick up the new offset value at the end of each scanline, but the new offset_cntl value
- only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
- OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
- save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL) & ~0xf;
-#if 0
- /* try to get rid of flickering when scrolling at least for 2d */
-#ifdef XF86DRI
- if (!info->have3DWindows)
-#endif
- save->crtc2_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
-#endif
-
- int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
- /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
- int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
- Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
- save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
- }
- }
- else {
- int offset = y * info->CurrentLayout.displayWidth + x;
- switch (info->CurrentLayout.pixel_code) {
- case 15:
- case 16: offset *= 2; break;
- case 24: offset *= 3; break;
- case 32: offset *= 4; break;
- }
- Base += offset;
- }
-
- Base &= ~7; /* 3 lower bits are always 0 */
-
-#ifdef XF86DRI
- if (info->directRenderingInited) {
- /* note cannot use pScrn->pScreen since this is unitialized when called from
- RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
- /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
- *** pageflipping!
- ***/
- pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
- /* can't get at sarea in a semi-sane way? */
- pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
-
- pSAREAPriv->crtc2_base = Base;
-
- if (pSAREAPriv->pfCurrentPage == 1) {
- Base += info->backOffset - info->frontOffset;
- }
- }
-#endif
- save->crtc2_offset = Base;
-
- /* We must set SURFACE_CNTL properly on the second screen too */
- save->surface_cntl = 0;
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* We must set both apertures as they can be both used to map the entire
- * video memory. -BenH.
- */
- switch (pScrn->bitsPerPixel) {
- case 16:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
- break;
-
- case 32:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
- break;
- }
-#endif
-
- if (info->ChipFamily == CHIP_FAMILY_RS400) {
- save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */
- save->rs480_unk_e34 = 0x2749D000; /* AMD really should */
- save->rs480_unk_e38 = 0x29ca71dc; /* release docs */
- save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */
- }
-
- return TRUE;
-}
-
-
-/* Define PLL registers for requested video mode */
-void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
- RADEONSavePtr save, RADEONPLLPtr pll,
- double dot_clock)
-{
- unsigned long freq = dot_clock * 100;
-
- struct {
- int divider;
- int bitvalue;
- } *post_div, post_divs[] = {
- /* From RAGE 128 VR/RAGE 128 GL Register
- * Reference Manual (Technical Reference
- * Manual P/N RRG-G04100-C Rev. 0.04), page
- * 3-17 (PLL_DIV_[3:0]).
- */
- { 1, 0 }, /* VCLK_SRC */
- { 2, 1 }, /* VCLK_SRC/2 */
- { 4, 2 }, /* VCLK_SRC/4 */
- { 8, 3 }, /* VCLK_SRC/8 */
- { 3, 4 }, /* VCLK_SRC/3 */
- { 16, 5 }, /* VCLK_SRC/16 */
- { 6, 6 }, /* VCLK_SRC/6 */
- { 12, 7 }, /* VCLK_SRC/12 */
- { 0, 0 }
- };
-
- if (info->UseBiosDividers) {
- save->ppll_ref_div = info->RefDivider;
- save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16);
- save->htotal_cntl = 0;
- return;
- }
-
- if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
- if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
-
- for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
- save->pll_output_freq = post_div->divider * freq;
-
- if (save->pll_output_freq >= pll->min_pll_freq
- && save->pll_output_freq <= pll->max_pll_freq) break;
- }
-
- if (!post_div->divider) {
- save->pll_output_freq = freq;
- post_div = &post_divs[0];
- }
-
- save->dot_clock_freq = freq;
- save->feedback_div = RADEONDiv(pll->reference_div
- * save->pll_output_freq,
- pll->reference_freq);
- save->post_div = post_div->divider;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "dc=%ld, of=%ld, fd=%d, pd=%d\n",
- save->dot_clock_freq,
- save->pll_output_freq,
- save->feedback_div,
- save->post_div);
-
- 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 */
-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 {
- int divider;
- int bitvalue;
- } *post_div, post_divs[] = {
- /* From RAGE 128 VR/RAGE 128 GL Register
- * Reference Manual (Technical Reference
- * Manual P/N RRG-G04100-C Rev. 0.04), page
- * 3-17 (PLL_DIV_[3:0]).
- */
- { 1, 0 }, /* VCLK_SRC */
- { 2, 1 }, /* VCLK_SRC/2 */
- { 4, 2 }, /* VCLK_SRC/4 */
- { 8, 3 }, /* VCLK_SRC/8 */
- { 3, 4 }, /* VCLK_SRC/3 */
- { 6, 6 }, /* VCLK_SRC/6 */
- { 12, 7 }, /* VCLK_SRC/12 */
- { 0, 0 }
- };
-
- if (freq > pll->max_pll_freq) freq = pll->max_pll_freq;
- if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
-
- for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
- /* Odd post divider value don't work properly on the second digital
- * output
- */
- if (no_odd_postdiv && (post_div->divider & 1))
- continue;
- save->pll_output_freq_2 = post_div->divider * freq;
- if (save->pll_output_freq_2 >= pll->min_pll_freq
- && save->pll_output_freq_2 <= pll->max_pll_freq) break;
- }
-
- if (!post_div->divider) {
- save->pll_output_freq_2 = freq;
- post_div = &post_divs[0];
- }
-
- save->dot_clock_freq_2 = freq;
- save->feedback_div_2 = RADEONDiv(pll->reference_div
- * save->pll_output_freq_2,
- pll->reference_freq);
- save->post_div_2 = post_div->divider;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "dc=%ld, of=%ld, fd=%d, pd=%d\n",
- save->dot_clock_freq_2,
- save->pll_output_freq_2,
- save->feedback_div_2,
- save->post_div_2);
-
- save->p2pll_ref_div = pll->reference_div;
- 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
/* Define initial palette for requested video mode. This doesn't do
* anything for XFree86 4.0.
@@ -6327,7 +5408,6 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
for (i = 0; i < xf86_config->num_crtc; i++)
{
xf86CrtcPtr crtc = xf86_config->crtc[i];
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
/* Mark that we'll need to re-set the mode for sure */
memset(&crtc->mode, 0, sizeof(crtc->mode));
if (!crtc->desiredMode.CrtcHDisplay) {
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index bc069ea..a7503a5 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -82,7 +82,6 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
DisplayModePtr new = NULL;
char stmp[32];
@@ -130,7 +129,6 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList)
{
ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
DisplayModePtr last = NULL;
DisplayModePtr new = NULL;
@@ -265,12 +263,8 @@ DisplayModePtr
RADEONProbeOutputModes(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
DisplayModePtr mode;
- DisplayModePtr test;
xf86MonPtr edid_mon;
DisplayModePtr modes = NULL;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 8ac43b2..99b6544 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -124,13 +124,33 @@ const char *OutputType[10] = {
"Composite",
};
+static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
+{
+ {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_UNKNOW*/
+ {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_LEGACY*/
+ {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RADEON*/
+ {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV100*/
+ {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS100*/
+ {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV200*/
+ {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS200*/
+ {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R200*/
+ {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV250*/
+ {{0, 0}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS300*/
+ {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
+ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R300*/
+ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R350*/
+ {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV350*/
+ {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV380*/
+ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R420*/
+ {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
+ {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
+};
+
static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
void RADEONPrintPortMap(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
RADEONOutputPrivatePtr radeon_output;
xf86OutputPtr output;
@@ -155,13 +175,356 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
}
+static RADEONMonitorType
+RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ unsigned long DDCReg;
+ RADEONMonitorType MonType = MT_NONE;
+ xf86MonPtr* MonInfo = &output->MonInfo;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONDDCType DDCType = radeon_output->DDCType;
+ int i, j;
+
+ DDCReg = radeon_output->DDCReg;
+
+ /* Read and output monitor info using DDC2 over I2C bus */
+ if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK)) {
+ OUTREG(DDCReg, INREG(DDCReg) &
+ (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
+
+ /* For some old monitors (like Compaq Presario FP500), we need
+ * following process to initialize/stop DDC
+ */
+ OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+ for (j = 0; j < 3; j++) {
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+ usleep(13000);
+
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+ for (i = 0; i < 10; i++) {
+ usleep(15000);
+ if (INREG(DDCReg) & RADEON_GPIO_Y_1)
+ break;
+ }
+ if (i == 10) continue;
+
+ usleep(15000);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+ usleep(15000);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+ usleep(15000);
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+ usleep(15000);
+ *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+ usleep(15000);
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+ for (i = 0; i < 5; i++) {
+ usleep(15000);
+ if (INREG(DDCReg) & RADEON_GPIO_Y_1)
+ break;
+ }
+ usleep(15000);
+ OUTREG(DDCReg,
+ INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+ usleep(15000);
+
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+ OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+ usleep(15000);
+ if(*MonInfo) break;
+ }
+ } else if (radeon_output->pI2CBus && info->ddc2 && DDCReg == RADEON_LCD_GPIO_MASK) {
+ *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
+ MonType = MT_NONE;
+ }
+
+ OUTREG(DDCReg, INREG(DDCReg) &
+ ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+
+ if (*MonInfo) {
+ if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
+ (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
+ MonType = MT_LCD;
+ } else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+ (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D)) {
+ MonType = MT_DFP;
+ } else if ((*MonInfo)->rawData[0x14] & 0x80) { /* if it's digital */
+ MonType = MT_DFP;
+ } else {
+ MonType = MT_CRT;
+ }
+ } else MonType = MT_NONE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "DDC Type: %d, Detected Monitor Type: %d\n", DDCType, MonType);
+
+ return MonType;
+}
+
+static RADEONMonitorType
+RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ int bConnected = 0;
+
+ /* the monitor either wasn't connected or it is a non-DDC CRT.
+ * try to probe it
+ */
+ if(IsCrtDac) {
+ unsigned long ulOrigVCLK_ECP_CNTL;
+ unsigned long ulOrigDAC_CNTL;
+ unsigned long ulOrigDAC_MACRO_CNTL;
+ unsigned long ulOrigDAC_EXT_CNTL;
+ unsigned long ulOrigCRTC_EXT_CNTL;
+ unsigned long ulData;
+ unsigned long ulMask;
+
+ ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+ ulData = ulOrigVCLK_ECP_CNTL;
+ ulData &= ~(RADEON_PIXCLK_ALWAYS_ONb
+ | RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ ulMask = ~(RADEON_PIXCLK_ALWAYS_ONb
+ |RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+ ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
+ ulData = ulOrigCRTC_EXT_CNTL;
+ ulData |= RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
+
+ ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
+ ulData = ulOrigDAC_EXT_CNTL;
+ ulData &= ~RADEON_DAC_FORCE_DATA_MASK;
+ ulData |= (RADEON_DAC_FORCE_BLANK_OFF_EN
+ |RADEON_DAC_FORCE_DATA_EN
+ |RADEON_DAC_FORCE_DATA_SEL_MASK);
+ if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
+ (info->ChipFamily == CHIP_FAMILY_RV280))
+ ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+ else
+ ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, ulData);
+
+ /* turn on power so testing can go through */
+ ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
+ ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
+ OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
+
+ ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+ ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+ /* Enable comparators and set DAC range to PS2 (VGA) output level */
+ ulData = ulOrigDAC_CNTL;
+ ulData |= RADEON_DAC_CMP_EN;
+ ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
+ ulData |= 0x2;
+ OUTREG(RADEON_DAC_CNTL, ulData);
+
+ /* Settle down */
+ usleep(10000);
+
+ /* Read comparators */
+ ulData = INREG(RADEON_DAC_CNTL);
+ bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
+
+ /* Restore things */
+ ulData = ulOrigVCLK_ECP_CNTL;
+ ulMask = 0xFFFFFFFFL;
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+ OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL );
+ OUTREG(RADEON_DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
+ OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
+
+ if (!bConnected) {
+ /* Power DAC down if CRT is not connected */
+ ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+ ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+ ulData = INREG(RADEON_DAC_CNTL);
+ ulData |= RADEON_DAC_PDWN;
+ OUTREG(RADEON_DAC_CNTL, ulData);
+ }
+ } else { /* TV DAC */
+
+ /* This doesn't seem to work reliably (maybe worse on some OEM cards),
+ for now we always return false. If one wants to connected a
+ non-DDC monitor on the DVI port when CRT port is also connected,
+ he will need to explicitly tell the driver in the config file
+ with Option MonitorLayout.
+ */
+ bConnected = FALSE;
+
+#if 0
+ if (info->ChipFamily == CHIP_FAMILY_R200) {
+ unsigned long ulOrigGPIO_MONID;
+ unsigned long ulOrigFP2_GEN_CNTL;
+ unsigned long ulOrigDISP_OUTPUT_CNTL;
+ unsigned long ulOrigCRTC2_GEN_CNTL;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
+ unsigned long ulOrigCRTC2_H_TOTAL_DISP;
+ unsigned long ulOrigCRTC2_V_TOTAL_DISP;
+ unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
+ unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
+ unsigned long ulData, i;
+
+ ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
+ ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
+ ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
+ ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
+ ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+ ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+ ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+ ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+ ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+ ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+
+ ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+ ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+ ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+ ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ ulData = INREG(RADEON_GPIO_MONID);
+ ulData &= ~RADEON_GPIO_A_0;
+ OUTREG(RADEON_GPIO_MONID, ulData);
+
+ OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
+
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+ for (i = 0; i < 200; i++) {
+ ulData = INREG(RADEON_GPIO_MONID);
+ bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
+ if (!bConnected) break;
+
+ usleep(1000);
+ }
+
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
+ OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
+ OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
+ } else {
+ unsigned long ulOrigPIXCLKSDATA;
+ unsigned long ulOrigTV_MASTER_CNTL;
+ unsigned long ulOrigTV_DAC_CNTL;
+ unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
+ unsigned long ulOrigDAC_CNTL2;
+ unsigned long ulData;
+ unsigned long ulMask;
+
+ ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+
+ ulData = ulOrigPIXCLKSDATA;
+ ulData &= ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ ulMask = ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+ ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
+ ulData = ulOrigTV_MASTER_CNTL;
+ ulData &= ~RADEON_TVCLK_ALWAYS_ONb;
+ OUTREG(RADEON_TV_MASTER_CNTL, ulData);
+
+ ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
+ ulData = ulOrigDAC_CNTL2;
+ ulData &= ~RADEON_DAC2_DAC2_CLK_SEL;
+ OUTREG(RADEON_DAC_CNTL2, ulData);
+
+ ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
+
+ ulData = 0x00880213;
+ OUTREG(RADEON_TV_DAC_CNTL, ulData);
+
+ ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+ ulData = (RADEON_Y_RED_EN
+ | RADEON_C_GRN_EN
+ | RADEON_CMP_BLU_EN
+ | RADEON_RED_MX_FORCE_DAC_DATA
+ | RADEON_GRN_MX_FORCE_DAC_DATA
+ | RADEON_BLU_MX_FORCE_DAC_DATA);
+ if (IS_R300_VARIANT)
+ ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+ else
+ ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
+
+ usleep(10000);
+
+ ulData = INREG(RADEON_TV_DAC_CNTL);
+ bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
+
+ ulData = ulOrigPIXCLKSDATA;
+ ulMask = 0xFFFFFFFFL;
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
+ OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
+ OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
+ }
+#endif
+ return MT_UNKNOWN;
+ }
+
+ return(bConnected ? MT_CRT : MT_NONE);
+}
+
/* Primary Head (DVI or Laptop Int. panel)*/
/* A ddc capable display connected on DVI port */
/* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/
void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
if (radeon_output->MonType == MT_UNKNOWN) {
@@ -212,8 +575,6 @@ static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr
static void
radeon_dpms(xf86OutputPtr output, int mode)
{
- ScrnInfoPtr pScrn = output->scrn;
-
switch(mode) {
case DPMSModeOn:
RADEONEnableDisplay(output, TRUE);
@@ -241,10 +602,7 @@ radeon_restore(xf86OutputPtr restore)
static int
radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
- DisplayModePtr m;
if (radeon_output->type != OUTPUT_LVDS)
return MODE_OK;
@@ -293,6 +651,317 @@ radeon_mode_prepare(xf86OutputPtr output)
{
}
+static void RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int i;
+ CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff;
+
+ for (i=0; i<4; i++) {
+ if (radeon_output->tmds_pll[i].freq == 0) break;
+ if ((CARD32)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
+ tmp = radeon_output->tmds_pll[i].value ;
+ break;
+ }
+ }
+
+ if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
+ if (tmp & 0xfff00000)
+ save->tmds_pll_cntl = tmp;
+ else {
+ save->tmds_pll_cntl = info->SavedReg.tmds_pll_cntl & 0xfff00000;
+ save->tmds_pll_cntl |= tmp;
+ }
+ } else save->tmds_pll_cntl = tmp;
+
+ save->tmds_transmitter_cntl = info->SavedReg.tmds_transmitter_cntl &
+ ~(RADEON_TMDS_TRANSMITTER_PLLRST);
+
+ if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
+ save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
+ else /* weird, RV chips got this bit reversed? */
+ save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
+
+ save->fp_gen_cntl = info->SavedReg.fp_gen_cntl |
+ (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
+ RADEON_FP_CRTC_DONT_SHADOW_HEND );
+
+ save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+
+ if (pScrn->rgbBits == 8)
+ save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
+ else
+ save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
+
+
+ if (IsPrimary) {
+ if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
+ save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+ if (mode->Flags & RADEON_USE_RMX)
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
+ else
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
+ } else
+ save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
+ } else {
+ if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
+ save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
+ } else
+ save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
+ }
+
+}
+
+static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+
+ if (pScrn->rgbBits == 8)
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
+ RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
+ else
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+ ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
+
+ save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+
+ if (IsPrimary) {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_EN |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ if (mode->Flags & RADEON_USE_RMX)
+ save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
+ } else {
+ save->fp2_gen_cntl &= ~(RADEON_FP2_SRC_SEL_CRTC2 |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ }
+ } else {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+ } else {
+ save->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR);
+ save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
+ }
+ }
+
+}
+
+static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl;
+ save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
+ save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
+
+ if (IsPrimary)
+ save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
+ else
+ save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
+
+}
+
+static void RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int xres = mode->HDisplay;
+ int yres = mode->VDisplay;
+ float Hratio, Vratio;
+
+ if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
+ Hratio = 1.0;
+ Vratio = 1.0;
+ } else {
+ if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
+ if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
+
+ Hratio = (float)xres/(float)radeon_output->PanelXRes;
+ Vratio = (float)yres/(float)radeon_output->PanelYRes;
+ }
+
+ save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
+ RADEON_VERT_STRETCH_RESERVED;
+ save->fp_horz_stretch = info->SavedReg.fp_horz_stretch &
+ (RADEON_HORZ_FP_LOOP_STRETCH |
+ RADEON_HORZ_AUTO_RATIO_INC);
+
+ if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
+ save->fp_horz_stretch |= ((xres/8-1)<<16);
+ } else {
+ save->fp_horz_stretch |= ((((unsigned long)(Hratio * RADEON_HORZ_STRETCH_RATIO_MAX +
+ 0.5)) & RADEON_HORZ_STRETCH_RATIO_MASK) |
+ RADEON_HORZ_STRETCH_BLEND |
+ RADEON_HORZ_STRETCH_ENABLE |
+ ((radeon_output->PanelXRes/8-1)<<16));
+ }
+
+ if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
+ save->fp_vert_stretch |= ((yres-1)<<12);
+ } else {
+ save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX +
+ 0.5)) & RADEON_VERT_STRETCH_RATIO_MASK) |
+ RADEON_VERT_STRETCH_ENABLE |
+ RADEON_VERT_STRETCH_BLEND |
+ ((radeon_output->PanelYRes-1)<<12));
+ }
+
+}
+
+static void RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (IsPrimary) {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_DAC_SOURCE_MASK;
+ } else {
+ save->dac2_cntl = info->SavedReg.dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
+ }
+ } else {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_DAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
+ } else {
+ save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
+ }
+ }
+ save->dac_cntl = (RADEON_DAC_MASK_ALL
+ | RADEON_DAC_VGA_ADR_EN
+ | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
+}
+
+/* XXX: fix me */
+static void
+RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ if (info->ChipFamily == CHIP_FAMILY_R420 ||
+ info->ChipFamily == CHIP_FAMILY_RV410) {
+ save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
+ ~(RADEON_TV_DAC_STD_MASK |
+ RADEON_TV_DAC_BGADJ_MASK |
+ R420_TV_DAC_DACADJ_MASK |
+ R420_TV_DAC_RDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_TVENABLE);
+ } else {
+ save->tv_dac_cntl = info->SavedReg.tv_dac_cntl &
+ ~(RADEON_TV_DAC_STD_MASK |
+ RADEON_TV_DAC_BGADJ_MASK |
+ RADEON_TV_DAC_DACADJ_MASK |
+ RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD |
+ RADEON_TV_DAC_GDACPD);
+ }
+ /* FIXME: doesn't make sense, this just replaces the previous value... */
+ save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_DAC_STD_PS2);
+ // info->tv_dac_adj);
+}
+
+static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ /*0x0028023;*/
+ RADEONInitTvDacCntl(pScrn, save);
+
+ if (IsPrimary) {
+ /*save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl | RADEON_CRTC2_CRT2_ON;*/
+ save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+ if (IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
+ } else if (info->ChipFamily == CHIP_FAMILY_R200) {
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+ ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ /*save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
+ (RADEON_FP2_ON |
+ RADEON_FP2_BLANK_EN |
+ RADEON_FP2_DVO_EN);*/
+ } else {
+ save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL;
+ }
+ } else {
+ save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+ if (IS_R300_VARIANT) {
+ save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+ save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+ ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+ } else if (info->ChipFamily == CHIP_FAMILY_R200) {
+ save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+ ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ save->fp2_gen_cntl |= (R200_FP2_SOURCE_SEL_CRTC2 /*|
+ RADEON_FP2_BLANK_EN |
+ RADEON_FP2_ON |
+ RADEON_FP2_DVO_EN*/);
+ /*save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
+ save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;*/
+ } else {
+ save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+ save->disp_hw_debug = info->SavedReg.disp_hw_debug &
+ ~RADEON_CRT2_DISP1_SEL;
+ }
+ }
+}
+
+static void
+RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output,
+ int crtc_num)
+{
+ Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ RADEONInitDACRegisters(output, save, mode, IsPrimary);
+ } else {
+ RADEONInitDAC2Registers(output, save, mode, IsPrimary);
+ }
+ } else if (radeon_output->MonType == MT_LCD) {
+ if (crtc_num == 0)
+ RADEONInitRMXRegisters(output, save, mode);
+ RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (crtc_num == 0)
+ RADEONInitRMXRegisters(output, save, mode);
+ if (radeon_output->TMDSType == TMDS_INT) {
+ RADEONInitFPRegisters(output, save, mode, IsPrimary);
+ } else {
+ RADEONInitFP2Registers(output, save, mode, IsPrimary);
+ }
+ }
+}
+
static void
radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
@@ -336,7 +1005,6 @@ radeon_detect(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
radeon_output->MonType = MT_UNKNOWN;
@@ -394,13 +1062,12 @@ radeon_destroy (xf86OutputPtr output)
static void
radeon_set_backlight_level(xf86OutputPtr output, int level)
{
+#if 0
ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
unsigned char * RADEONMMIO = info->MMIO;
CARD32 lvds_gen_cntl;
-#if 0
lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL);
lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_LEVEL_MASK;
@@ -508,7 +1175,6 @@ static Bool
radeon_set_property(xf86OutputPtr output, Atom property,
RRPropertyValuePtr value)
{
- ScrnInfoPtr pScrn = output->scrn;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
INT32 val;
@@ -613,6 +1279,315 @@ void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output
radeon_output->type = output;
}
+static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
+{
+ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned long val;
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ /* Get the result */
+
+ if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
+ val = INREG(b->DriverPrivate.uval+4);
+ *Clock = (val & (1<<13)) != 0;
+ *data = (val & (1<<12)) != 0;
+ } else {
+ val = INREG(b->DriverPrivate.uval);
+ *Clock = (val & RADEON_GPIO_Y_1) != 0;
+ *data = (val & RADEON_GPIO_Y_0) != 0;
+ }
+}
+
+static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
+{
+ ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned long val;
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
+ val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<12) | (1<<13));
+ val |= (Clock ? 0:(1<<13));
+ val |= (data ? 0:(1<<12));
+ OUTREG(b->DriverPrivate.uval, val);
+ } else {
+ val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
+ val |= (Clock ? 0:RADEON_GPIO_EN_1);
+ val |= (data ? 0:RADEON_GPIO_EN_0);
+ OUTREG(b->DriverPrivate.uval, val);
+ }
+ /* read back to improve reliability on some cards. */
+ val = INREG(b->DriverPrivate.uval);
+}
+
+static Bool
+RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
+{
+ I2CBusPtr pI2CBus;
+
+ pI2CBus = xf86CreateI2CBusRec();
+ if (!pI2CBus) return FALSE;
+
+ pI2CBus->BusName = name;
+ pI2CBus->scrnIndex = pScrn->scrnIndex;
+ pI2CBus->I2CPutBits = RADEONI2CPutBits;
+ pI2CBus->I2CGetBits = RADEONI2CGetBits;
+ pI2CBus->AcknTimeout = 5;
+ pI2CBus->DriverPrivate.uval = i2c_reg;
+
+ if (!xf86I2CBusInit(pI2CBus)) return FALSE;
+
+ *bus_ptr = pI2CBus;
+ return TRUE;
+}
+
+static void
+RADEONGetPanelInfoFromReg (xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
+ CARD32 fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
+
+ radeon_output->PanelPwrDly = 200;
+ if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
+ radeon_output->PanelYRes = (fp_vert_stretch>>12) + 1;
+ } else {
+ radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
+ }
+ if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
+ radeon_output->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;
+ } else {
+ radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
+ }
+
+ if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) {
+ radeon_output->PanelXRes = 640;
+ radeon_output->PanelYRes = 480;
+ }
+
+ // move this to crtc function
+ if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
+ CARD32 ppll_div_sel, ppll_val;
+
+ ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
+ RADEONPllErrataAfterIndex(info);
+ ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
+ if ((ppll_val & 0x000707ff) == 0x1bb)
+ goto noprobe;
+ info->FeedbackDivider = ppll_val & 0x7ff;
+ info->PostDivider = (ppll_val >> 16) & 0x7;
+ info->RefDivider = info->pll.reference_div;
+ info->UseBiosDividers = TRUE;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Existing panel PLL dividers will be used.\n");
+ }
+ noprobe:
+
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Panel size %dx%d is derived, this may not be correct.\n"
+ "If not, use PanelSize option to overwrite this setting\n",
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
+}
+
+/* BIOS may not have right panel size, we search through all supported
+ * DDC modes looking for the maximum panel size.
+ */
+static void
+RADEONUpdatePanelSize(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int j;
+ /* XXX: fixme */
+ xf86MonPtr ddc = pScrn->monitor->DDC;
+ DisplayModePtr p;
+
+ // crtc should handle?
+ if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
+ return;
+
+ /* Go thru detailed timing table first */
+ for (j = 0; j < 4; j++) {
+ if (ddc->det_mon[j].type == 0) {
+ struct detailed_timings *d_timings =
+ &ddc->det_mon[j].section.d_timings;
+ int match = 0;
+
+ /* If we didn't get a panel clock or guessed one, try to match the
+ * mode with the panel size. We do that because we _need_ a panel
+ * clock, or ValidateFPModes will fail, even when UseBiosDividers
+ * is set.
+ */
+ if (radeon_output->DotClock == 0 &&
+ radeon_output->PanelXRes == d_timings->h_active &&
+ radeon_output->PanelYRes == d_timings->v_active)
+ match = 1;
+
+ /* If we don't have a BIOS provided panel data with fixed dividers,
+ * check for a larger panel size
+ */
+ if (radeon_output->PanelXRes < d_timings->h_active &&
+ radeon_output->PanelYRes < d_timings->v_active &&
+ !info->UseBiosDividers)
+ match = 1;
+
+ if (match) {
+ radeon_output->PanelXRes = d_timings->h_active;
+ radeon_output->PanelYRes = d_timings->v_active;
+ radeon_output->DotClock = d_timings->clock / 1000;
+ radeon_output->HOverPlus = d_timings->h_sync_off;
+ radeon_output->HSyncWidth = d_timings->h_sync_width;
+ radeon_output->HBlank = d_timings->h_blanking;
+ radeon_output->VOverPlus = d_timings->v_sync_off;
+ radeon_output->VSyncWidth = d_timings->v_sync_width;
+ radeon_output->VBlank = d_timings->v_blanking;
+ radeon_output->Flags = (d_timings->interlaced ? V_INTERLACE : 0);
+ switch (d_timings->misc) {
+ case 0: radeon_output->Flags |= V_NHSYNC | V_NVSYNC; break;
+ case 1: radeon_output->Flags |= V_PHSYNC | V_NVSYNC; break;
+ case 2: radeon_output->Flags |= V_NHSYNC | V_PVSYNC; break;
+ case 3: radeon_output->Flags |= V_PHSYNC | V_PVSYNC; break;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
+ }
+ }
+ }
+
+ if (info->UseBiosDividers && radeon_output->DotClock != 0)
+ return;
+
+ /* Search thru standard VESA modes from EDID */
+ for (j = 0; j < 8; j++) {
+ if ((radeon_output->PanelXRes < ddc->timings2[j].hsize) &&
+ (radeon_output->PanelYRes < ddc->timings2[j].vsize)) {
+ for (p = pScrn->monitor->Modes; p; p = p->next) {
+ if ((ddc->timings2[j].hsize == p->HDisplay) &&
+ (ddc->timings2[j].vsize == p->VDisplay)) {
+ float refresh =
+ (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
+
+ if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
+ /* Is this good enough? */
+ radeon_output->PanelXRes = ddc->timings2[j].hsize;
+ radeon_output->PanelYRes = ddc->timings2[j].vsize;
+ radeon_output->HBlank = p->HTotal - p->HDisplay;
+ radeon_output->HOverPlus = p->HSyncStart - p->HDisplay;
+ radeon_output->HSyncWidth = p->HSyncEnd - p->HSyncStart;
+ radeon_output->VBlank = p->VTotal - p->VDisplay;
+ radeon_output->VOverPlus = p->VSyncStart - p->VDisplay;
+ radeon_output->VSyncWidth = p->VSyncEnd - p->VSyncStart;
+ radeon_output->DotClock = p->Clock;
+ radeon_output->Flags = p->Flags;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
+ radeon_output->PanelXRes, radeon_output->PanelYRes);
+ }
+ }
+ }
+ }
+ }
+}
+
+static Bool
+RADEONGetLVDSInfo (xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ char* s;
+
+ if (!RADEONGetLVDSInfoFromBIOS(output))
+ RADEONGetPanelInfoFromReg(output);
+
+ if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
+ radeon_output->PanelPwrDly = 200;
+ if (sscanf (s, "%dx%d", &radeon_output->PanelXRes, &radeon_output->PanelYRes) != 2) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
+ RADEONGetPanelInfoFromReg(output);
+ }
+ }
+
+ /* The panel size we collected from BIOS may not be the
+ * maximum size supported by the panel. If not, we update
+ * it now. These will be used if no matching mode can be
+ * found from EDID data.
+ */
+ RADEONUpdatePanelSize(output);
+
+ if (radeon_output->DotClock == 0) {
+ DisplayModePtr tmp_mode = NULL;
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "No valid timing info from BIOS.\n");
+ /* No timing information for the native mode,
+ use whatever specified in the Modeline.
+ If no Modeline specified, we'll just pick
+ the VESA mode at 60Hz refresh rate which
+ is likely to be the best for a flat panel.
+ */
+ tmp_mode = pScrn->monitor->Modes;
+ while(tmp_mode) {
+ if ((tmp_mode->HDisplay == radeon_output->PanelXRes) &&
+ (tmp_mode->VDisplay == radeon_output->PanelYRes)) {
+
+ float refresh =
+ (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;
+ if ((abs(60.0 - refresh) < 1.0) ||
+ (tmp_mode->type == 0)) {
+ radeon_output->HBlank = tmp_mode->HTotal - tmp_mode->HDisplay;
+ radeon_output->HOverPlus = tmp_mode->HSyncStart - tmp_mode->HDisplay;
+ radeon_output->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
+ radeon_output->VBlank = tmp_mode->VTotal - tmp_mode->VDisplay;
+ radeon_output->VOverPlus = tmp_mode->VSyncStart - tmp_mode->VDisplay;
+ radeon_output->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
+ radeon_output->DotClock = tmp_mode->Clock;
+ radeon_output->Flags = 0;
+ break;
+ }
+ }
+
+ tmp_mode = tmp_mode->next;
+
+ if (tmp_mode == pScrn->monitor->Modes)
+ break;
+ }
+ if ((radeon_output->DotClock == 0) && !output->MonInfo) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Panel size is not correctly detected.\n"
+ "Please try to use PanelSize option for correct settings.\n");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+RADEONGetTMDSInfo(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int i;
+
+ for (i=0; i<4; i++) {
+ radeon_output->tmds_pll[i].value = 0;
+ radeon_output->tmds_pll[i].freq = 0;
+ }
+
+ if (RADEONGetTMDSInfoFromBIOS(output)) return;
+
+ for (i=0; i<4; i++) {
+ radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
+ radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+ }
+}
+
void RADEONInitConnector(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
@@ -662,7 +1637,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86OutputPtr output;
char *optstr;
- int i = 0, second = 0, max_mt = 5;
+ int i = 0;
/* We first get the information about all connectors from BIOS.
@@ -731,8 +1706,10 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
}
/* parse connector table option */
- if (optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE)) {
- if (sscanf(optstr, "%d,%d,%d,%d,%d,%d,%d,%d",
+ optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE);
+
+ if (optstr) {
+ if (sscanf(optstr, "%u,%d,%d,%u,%u,%d,%d,%u",
&info->BiosConnector[0].DDCType,
&info->BiosConnector[0].DACType,
&info->BiosConnector[0].TMDSType,
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 5510d7b..d389e11 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2422,7 +2422,6 @@ RADEONDisplayVideo(
int y_off;
CARD32 scaler_src;
CARD32 dot_clock;
- DisplayModePtr overlay_mode;
int is_rgb;
int is_planar;
int i;