diff options
author | Michel Dänzer <michel@tungstengraphics.com> | 2007-05-30 18:56:53 +0200 |
---|---|---|
committer | Michel Dänzer <michel@tungstengraphics.com> | 2007-05-30 20:25:39 +0200 |
commit | 0e0946e0aa2527794e07473199e851bbfbc47cb1 (patch) | |
tree | 53ded2d6d1f83947d66535541c3cc8565b2c0fc5 | |
parent | 31c1be420d5277dd15505bd73e6144827a0580cd (diff) |
radeon: Lots of warning fixes.
Move code where it's used, remove unused variables, etc.
-rw-r--r-- | src/radeon.h | 22 | ||||
-rw-r--r-- | src/radeon_bios.c | 2 | ||||
-rw-r--r-- | src/radeon_crtc.c | 635 | ||||
-rw-r--r-- | src/radeon_cursor.c | 52 | ||||
-rw-r--r-- | src/radeon_display.c | 677 | ||||
-rw-r--r-- | src/radeon_driver.c | 926 | ||||
-rw-r--r-- | src/radeon_modes.c | 6 | ||||
-rw-r--r-- | src/radeon_output.c | 1007 | ||||
-rw-r--r-- | src/radeon_video.c | 1 |
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; |