? Makefile ? benh-all.patch ? bioshotkeys.diff ? crtc_to_output.patch ? fp2fix.diff ? mspll_probe.diff ? r128-vgaaccess.diff ? r128.4x.html ? r128._man ? r128dualhead.diff ? radeon-agp8x.diff ? radeon.4x.html ? radeon._man ? radeon_tiling_ddx7.diff ? radeon_tiling_ddx9.diff ? radeonmem.diff ? roland-mergedfb-fix.diff ? xorg_radeon_monitor_fixes.diff Index: radeon.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v retrieving revision 1.17 diff -u -r1.17 radeon.h --- radeon.h 26 Jan 2005 18:23:40 -0000 1.17 +++ radeon.h 19 Feb 2005 23:00:28 -0000 @@ -312,6 +312,7 @@ RADEONMonitorType DisplayType; /* Monitor connected on */ RADEONDDCType DDCType; RADEONConnectorType ConnectorType; + RADEONTmdsType TMDSType; /* int/ext TMDS */ Bool HasCRTC2; /* All cards except original Radeon */ Bool IsMobility; /* Mobile chips for laptops */ Bool IsIGP; /* IGP chips */ @@ -610,6 +611,7 @@ int CRT1frameY1; RADEONMonitorType MergeType; RADEONDDCType MergeDDCType; + RADEONTmdsType MergeTMDSType; void (*PointerMoved)(int index, int x, int y); /* pseudo xinerama support for mergedfb */ int maxCRT1_X1, maxCRT1_X2, maxCRT1_Y1, maxCRT1_Y2; Index: radeon_driver.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v retrieving revision 1.42 diff -u -r1.42 radeon_driver.c --- radeon_driver.c 18 Feb 2005 19:55:35 -0000 1.42 +++ radeon_driver.c 19 Feb 2005 23:00:33 -0000 @@ -1677,7 +1677,7 @@ { "NONE", "Internal", - "External" + "External" }; const char *DDCTypeName[5] = @@ -1686,7 +1686,7 @@ "MONID", "DVI_DDC", "VGA_DDC", - "CRT2_DDC" + "CRT2_DDC" }; const char *DACTypeName[3] = @@ -1726,6 +1726,7 @@ if(info->IsSecondary) { info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType2; + info->TMDSType = pRADEONEnt->PortInfo[1].TMDSType; if(info->DisplayType == MT_NONE) return FALSE; return TRUE; } @@ -1901,6 +1902,17 @@ pRADEONEnt->PortInfo[0].MonInfo = NULL; } + /* some thinkpads and powerbooks use lvds and internal tmds + * at the same time. --AGD + */ + + if ((pRADEONEnt->PortInfo[0].MonType == MT_LCD) && + (pRADEONEnt->PortInfo[1].MonType == MT_DFP)) { + pRADEONEnt->PortInfo[1].DDCType = DDC_DVI; + pRADEONEnt->PortInfo[0].DDCType = DDC_MONID; + pRADEONEnt->PortInfo[1].TMDSType = TMDS_INT; + } + if (!ignore_edid) { if ((pRADEONEnt->PortInfo[0].MonType > MT_NONE) && (pRADEONEnt->PortInfo[0].MonType < MT_STV)) @@ -2018,14 +2030,18 @@ } info->DisplayType = pRADEONEnt->MonType1; + info->TMDSType = pRADEONEnt->PortInfo[0].TMDSType; pRADEONEnt->ReversedDAC = FALSE; info->OverlayOnCRTC2 = FALSE; info->MergeType = MT_NONE; + info->MergeTMDSType = TMDS_UNKNOWN; if (pRADEONEnt->MonType2 != MT_NONE) { if(!pRADEONEnt->HasSecondary) { info->MergeType = pRADEONEnt->MonType2; } + info->MergeTMDSType = pRADEONEnt->PortInfo[1].TMDSType; + if (pRADEONEnt->PortInfo[1].DACType == DAC_TVDAC) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Reversed DAC decteced\n"); pRADEONEnt->ReversedDAC = TRUE; @@ -5621,34 +5637,59 @@ OUTREG(RADEON_CRTC2_PITCH, restore->crtc2_pitch); OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl); - if ((info->DisplayType == MT_DFP && info->IsSecondary) || - info->MergeType == MT_DFP) { - OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp2_h_sync_strt_wid); - OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp2_v_sync_strt_wid); - OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl); - } #if 0 /* Hack for restoring text mode -- fixed elsewhere */ usleep(100000); #endif } -/* Write flat panel registers */ -static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +/* Write external tmds registers */ +static void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, + RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp2_h_sync_strt_wid); + OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp2_v_sync_strt_wid); + OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl); +} + +/* Write RMX registers */ +static void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch); + OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); + +} + +static void RADEONRestoreCommonFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - unsigned long tmp; OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp); OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp); OUTREG(RADEON_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid); OUTREG(RADEON_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid); + OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); + +} + +/* Write flat panel registers */ +static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONRestoreCommonFPRegisters(pScrn, restore); + OUTREG(RADEON_TMDS_PLL_CNTL, restore->tmds_pll_cntl); OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl); - OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch); - OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch); - OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); + /* old AIW Radeon has some BIOS initialization problem * with display buffer underflow, only occurs to DFP @@ -5657,46 +5698,63 @@ OUTREG(RADEON_GRPH_BUFFER_CNTL, INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000); + if (!info->IsSecondary) + RADEONRestoreRMXRegisters(pScrn, restore); + +} + +/* Write LVDS registers */ +static void RADEONRestoreLCDRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + unsigned long tmp; + unsigned long tmpPixclksCntl; + + RADEONRestoreCommonFPRegisters(pScrn, restore); + if (info->IsMobility) { OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch); OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch); OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch); } - if (info->DisplayType != MT_DFP) { - unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); + tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL); - if (info->IsMobility || info->IsIGP) { - /* Asic bug, when turning off LVDS_ON, we have to make sure - RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off - */ - if (!(restore->lvds_gen_cntl & RADEON_LVDS_ON)) { - OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); - } + if (info->IsMobility || info->IsIGP) { + /* Asic bug, when turning off LVDS_ON, we have to make sure + RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off + */ + if (!(restore->lvds_gen_cntl & RADEON_LVDS_ON)) { + OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb); } + } - tmp = INREG(RADEON_LVDS_GEN_CNTL); - if ((tmp & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) == - (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON))) { + tmp = INREG(RADEON_LVDS_GEN_CNTL); + if ((tmp & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) == + (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON))) { + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); + } else { + if (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) { + usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); } else { - if (restore->lvds_gen_cntl & (RADEON_LVDS_ON | RADEON_LVDS_BLON)) { - usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); - OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); - } else { - OUTREG(RADEON_LVDS_GEN_CNTL, - restore->lvds_gen_cntl | RADEON_LVDS_BLON); - usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); - OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); - } + OUTREG(RADEON_LVDS_GEN_CNTL, + restore->lvds_gen_cntl | RADEON_LVDS_BLON); + usleep(RADEONPTR(pScrn)->PanelPwrDly * 1000); + OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl); } + } - if (info->IsMobility || info->IsIGP) { - if (!(restore->lvds_gen_cntl & RADEON_LVDS_ON)) { - OUTPLL(RADEON_PIXCLKS_CNTL, tmpPixclksCntl); - } + if (info->IsMobility || info->IsIGP) { + if (!(restore->lvds_gen_cntl & RADEON_LVDS_ON)) { + OUTPLL(RADEON_PIXCLKS_CNTL, tmpPixclksCntl); } } + + if (!info->IsSecondary) + RADEONRestoreRMXRegisters(pScrn, restore); + } static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn) @@ -6117,6 +6175,13 @@ if (!pRADEONEnt->RestorePrimary && !info->IsSwitching) RADEONRestoreCommonRegisters(pScrn, restore); RADEONRestoreCrtc2Registers(pScrn, restore); + if (info->DisplayType == MT_DFP) { + if (info->TMDSType == TMDS_EXT) + RADEONRestoreFP2Registers(pScrn, restore); + else + RADEONRestoreFPRegisters(pScrn, restore); + } else if (info->DisplayType == MT_LCD) + RADEONRestoreLCDRegisters(pScrn, restore); RADEONRestorePLL2Registers(pScrn, restore); if(info->IsSwitching) return; @@ -6127,7 +6192,13 @@ pRADEONEnt->RestorePrimary = FALSE; RADEONRestoreCrtcRegisters(pScrn, &restore0); - RADEONRestoreFPRegisters(pScrn, &restore0); + if (pRADEONEnt->MonType1 == MT_DFP) { + if (pRADEONEnt->PortInfo[0].TMDSType == TMDS_EXT) + RADEONRestoreFP2Registers(pScrn, &restore0); + else + RADEONRestoreFPRegisters(pScrn, &restore0); + } else if (pRADEONEnt->MonType1 == MT_LCD) + RADEONRestoreLCDRegisters(pScrn, &restore0); RADEONRestorePLLRegisters(pScrn, &restore0); pRADEONEnt->IsSecondaryRestored = FALSE; } @@ -6137,6 +6208,13 @@ if (info->MergedFB) { RADEONRestoreCrtc2Registers(pScrn, restore); + if (info->MergeType == MT_DFP) { + if (info->MergeTMDSType == TMDS_EXT) + RADEONRestoreFP2Registers(pScrn, restore); + else + RADEONRestoreFPRegisters(pScrn, restore); + } else if (info->MergeType == MT_LCD) + RADEONRestoreLCDRegisters(pScrn, restore); RADEONRestorePLL2Registers(pScrn, restore); } @@ -6145,7 +6223,13 @@ pRADEONEnt->IsSecondaryRestored = FALSE; RADEONRestoreCrtcRegisters(pScrn, restore); - RADEONRestoreFPRegisters(pScrn, restore); + if (info->DisplayType == MT_DFP) { + if (info->TMDSType == TMDS_EXT) + RADEONRestoreFP2Registers(pScrn, restore); + else + RADEONRestoreFPRegisters(pScrn, restore); + } else if (info->DisplayType == MT_LCD) + RADEONRestoreLCDRegisters(pScrn, restore); RADEONRestorePLLRegisters(pScrn, restore); } else { memcpy(&restore0, restore, sizeof(restore0)); @@ -6229,8 +6313,19 @@ } } +/* Read RMX registers */ +static void RADEONSaveRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + save->fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH); + save->fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH); + +} + /* Read flat panel registers */ -static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +static void RADEONSaveCommonFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; @@ -6239,21 +6334,48 @@ save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP); save->fp_gen_cntl = INREG(RADEON_FP_GEN_CNTL); save->fp_h_sync_strt_wid = INREG(RADEON_FP_H_SYNC_STRT_WID); - save->fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH); save->fp_v_sync_strt_wid = INREG(RADEON_FP_V_SYNC_STRT_WID); - save->fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH); - save->lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); - save->lvds_pll_cntl = INREG(RADEON_LVDS_PLL_CNTL); + +} + +/* Read flat panel registers */ +static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONSaveCommonFPRegisters(pScrn, save); + save->tmds_pll_cntl = INREG(RADEON_TMDS_PLL_CNTL); save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL); - save->bios_4_scratch = INREG(RADEON_BIOS_4_SCRATCH); - save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH); - save->bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH); if (info->ChipFamily == CHIP_FAMILY_RV280) { /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ save->tmds_pll_cntl ^= (1 << 22); } + + if (!info->IsSecondary) + RADEONSaveRMXRegisters(pScrn, save); + +} + +/* Read LCD registers */ +static void RADEONSaveLCDRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + + RADEONSaveCommonFPRegisters(pScrn, save); + + save->lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL); + save->lvds_pll_cntl = INREG(RADEON_LVDS_PLL_CNTL); + save->bios_4_scratch = INREG(RADEON_BIOS_4_SCRATCH); + save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH); + save->bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH); + + if (!info->IsSecondary) + RADEONSaveRMXRegisters(pScrn, save); + } /* Read CRTC2 registers */ @@ -6275,10 +6397,18 @@ save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL); save->crtc2_pitch = INREG(RADEON_CRTC2_PITCH); + save->disp2_merge_cntl = INREG(RADEON_DISP2_MERGE_CNTL); +} + +/* Read external tmds registers */ +static void RADEONSaveFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + save->fp2_h_sync_strt_wid = INREG (RADEON_FP_H2_SYNC_STRT_WID); save->fp2_v_sync_strt_wid = INREG (RADEON_FP_V2_SYNC_STRT_WID); save->fp2_gen_cntl = INREG (RADEON_FP2_GEN_CNTL); - save->disp2_merge_cntl = INREG(RADEON_DISP2_MERGE_CNTL); } /* Read PLL registers */ @@ -6348,11 +6478,24 @@ } else { RADEONSavePLLRegisters(pScrn, save); RADEONSaveCrtcRegisters(pScrn, save); - RADEONSaveFPRegisters(pScrn, save); + if (info->DisplayType == MT_DFP) { + if (info->TMDSType == TMDS_EXT) + RADEONSaveFP2Registers(pScrn, save); + else + RADEONSaveFPRegisters(pScrn, save); + } else if (info->DisplayType == MT_LCD) + RADEONSaveLCDRegisters(pScrn, save); if (info->MergedFB) { RADEONSaveCrtc2Registers(pScrn, save); RADEONSavePLL2Registers(pScrn, save); + if (info->MergeType == MT_DFP) { + if (info->MergeTMDSType == TMDS_EXT) + RADEONSaveFP2Registers(pScrn, save); + else + RADEONSaveFPRegisters(pScrn, save); + } else if (info->MergeType == MT_LCD) + RADEONSaveLCDRegisters(pScrn, save); } /* RADEONSavePalette(pScrn, save); */ } @@ -6991,6 +7134,31 @@ save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16)); } + /* If the FP registers have been initialized before for a panel, + * but the primary port is a CRT, we need to reinitialize + * FP registers in order for CRT to work properly + */ +#if 0 + if ((info->DisplayType != MT_DFP) && (info->DisplayType != MT_LCD)) { + save->fp_crtc_h_total_disp = orig->fp_crtc_h_total_disp; + save->fp_crtc_v_total_disp = orig->fp_crtc_v_total_disp; + save->fp_gen_cntl = 0; + save->fp_h_sync_strt_wid = orig->fp_h_sync_strt_wid; + save->fp_v_sync_strt_wid = orig->fp_v_sync_strt_wid; + save->tmds_pll_cntl = orig->tmds_pll_cntl; + save->tmds_transmitter_cntl= orig->tmds_transmitter_cntl; + + save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); + + save->lvds_gen_cntl = orig->lvds_gen_cntl; + save->lvds_pll_cntl = orig->lvds_pll_cntl; + + save->lvds_gen_cntl |= ( RADEON_LVDS_DISPLAY_DIS | (1 << 23)); + save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON | RADEON_LVDS_ON); + + } +#endif + RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n", save->crtc_pitch, pScrn->virtualX, info->CurrentLayout.displayWidth)); @@ -7036,6 +7204,11 @@ ? RADEON_CRTC2_INTERLACE_EN : 0)); + if ((info->DisplayType == MT_DFP) || + (info->DisplayType == MT_LCD)) { + save->crtc2_gen_cntl = (RADEON_CRTC2_EN | (format << 8)); + } + /* Turn CRT on in case the first head is a DFP */ save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON; save->dac2_cntl = info->SavedReg.dac2_cntl; @@ -7141,32 +7314,6 @@ save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl; save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN); - if ((info->DisplayType == MT_DFP && info->IsSecondary) || - info->MergeType == MT_DFP) { - save->crtc2_gen_cntl = (RADEON_CRTC2_EN | (format << 8)); - save->fp2_h_sync_strt_wid = save->crtc2_h_sync_strt_wid; - save->fp2_v_sync_strt_wid = save->crtc2_v_sync_strt_wid; - save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl | RADEON_FP2_ON; - save->fp2_gen_cntl &= ~(RADEON_FP2_BLANK_EN); - - 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 | - RADEON_FP2_DVO_EN); - } else { - save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_MASK; - save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; - } - - if (pScrn->rgbBits == 8) - save->fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format */ - else - save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format */ - - } /* We must set SURFACE_CNTL properly on the second screen too */ save->surface_cntl = 0; @@ -7192,8 +7339,59 @@ return TRUE; } -/* Define CRTC registers for requested video mode */ -static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, +/* Define external tmds registers for requested video mode */ +static void RADEONInitFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr orig, + RADEONSavePtr save, DisplayModePtr mode, + RADEONInfoPtr info) +{ + + save->fp2_h_sync_strt_wid = save->crtc2_h_sync_strt_wid; + save->fp2_v_sync_strt_wid = save->crtc2_v_sync_strt_wid; + save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl | RADEON_FP2_ON; + save->fp2_gen_cntl &= ~(RADEON_FP2_BLANK_EN); + + + if (info->MergedFB) { + if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) { + save->fp2_gen_cntl &= ~(R200_FP2_SOURCE_SEL_MASK | + RADEON_FP2_DVO_RATE_SEL_SDR); + + if (info->MergeTMDSType == TMDS_EXT) + save->fp2_gen_cntl |= (R200_FP2_SOURCE_SEL_CRTC2 | + RADEON_FP2_DVO_EN); + else + save->fp2_gen_cntl |= RADEON_FP2_DVO_EN; + } else { + save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_MASK; + if (info->MergeTMDSType == TMDS_EXT) + save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; + } + } 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); + + if (info->IsSecondary) + save->fp2_gen_cntl |= (R200_FP2_SOURCE_SEL_CRTC2 | + RADEON_FP2_DVO_EN); + else + save->fp2_gen_cntl |= RADEON_FP2_DVO_EN; + } else { + save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_MASK; + if (info->IsSecondary) + save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2; + } + } + + if (pScrn->rgbBits == 8) + save->fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format */ + else + save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format */ + +} + +/* Define RMX registers for requested video mode */ +static void RADEONInitRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, RADEONSavePtr save, DisplayModePtr mode, RADEONInfoPtr info) { @@ -7201,28 +7399,9 @@ int yres = mode->VDisplay; float Hratio, Vratio; - /* If the FP registers have been initialized before for a panel, - * but the primary port is a CRT, we need to reinitialize - * FP registers in order for CRT to work properly - */ - if ((info->DisplayType != MT_DFP) && (info->DisplayType != MT_LCD)) { - save->fp_crtc_h_total_disp = orig->fp_crtc_h_total_disp; - save->fp_crtc_v_total_disp = orig->fp_crtc_v_total_disp; - save->fp_gen_cntl = 0; - save->fp_h_sync_strt_wid = orig->fp_h_sync_strt_wid; save->fp_horz_stretch = 0; - save->fp_v_sync_strt_wid = orig->fp_v_sync_strt_wid; save->fp_vert_stretch = 0; - save->lvds_gen_cntl = orig->lvds_gen_cntl; - save->lvds_pll_cntl = orig->lvds_pll_cntl; - save->tmds_pll_cntl = orig->tmds_pll_cntl; - save->tmds_transmitter_cntl= orig->tmds_transmitter_cntl; - - save->lvds_gen_cntl |= ( RADEON_LVDS_DISPLAY_DIS | (1 << 23)); - save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON | RADEON_LVDS_ON); - save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - return; } @@ -7283,6 +7462,13 @@ } +} + +/* fp_gen_cntl and others are shared */ +static void RADEONInitCommonFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, + RADEONSavePtr save, DisplayModePtr mode, + RADEONInfoPtr info) +{ save->fp_gen_cntl = (orig->fp_gen_cntl & (CARD32) ~(RADEON_FP_SEL_CRTC2 | RADEON_FP_RMX_HVSYNC_CONTROL_EN | @@ -7295,52 +7481,75 @@ save->fp_gen_cntl |= (RADEON_FP_CRTC_DONT_SHADOW_VPAR | RADEON_FP_CRTC_DONT_SHADOW_HEND ); + 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 0 + 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; +#endif + save->fp_crtc_h_total_disp = save->crtc_h_total_disp; + save->fp_crtc_v_total_disp = save->crtc_v_total_disp; + save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; + save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; - 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; +} - save->lvds_gen_cntl = orig->lvds_gen_cntl; - save->lvds_pll_cntl = orig->lvds_pll_cntl; +/* Define CRTC registers for requested video mode */ +static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, + RADEONSavePtr save, DisplayModePtr mode, + RADEONInfoPtr info) +{ - info->PanelOff = FALSE; - /* This option is used to force the ONLY DEVICE in XFConfig to use - * CRT port, instead of default DVI port. - */ - if (xf86ReturnOptValBool(info->Options, OPTION_PANEL_OFF, FALSE)) { - info->PanelOff = TRUE; + RADEONInitCommonFPRegisters(pScrn, orig, save, mode, info); + + if (info->MergedFB) { + if (IS_R300_VARIANT || + (info->ChipFamily == CHIP_FAMILY_R200)) { + save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; + if (info->MergeTMDSType == TMDS_INT) { + save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2; + } else { + 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 { + if (info->MergeTMDSType == TMDS_INT) + save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2; + 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; + if (info->IsSecondary) { + save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2; + } else { + 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 { + if (info->IsSecondary) + save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2; + else + save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1; + } } save->tmds_pll_cntl = orig->tmds_pll_cntl; save->tmds_transmitter_cntl= orig->tmds_transmitter_cntl; if (info->PanelOff && info->MergedFB) { - info->OverlayOnCRTC2 = TRUE; - if (info->DisplayType == MT_LCD) { - /* Turning off LVDS_ON seems to make panel white blooming. - * For now we just turn off display data ??? - */ - save->lvds_gen_cntl |= (RADEON_LVDS_DISPLAY_DIS); - save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON | RADEON_LVDS_ON); - - } else if (info->DisplayType == MT_DFP) save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); } else { - if (info->DisplayType == MT_LCD) { - - save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); - save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); - - } else if (info->DisplayType == MT_DFP) { int i; CARD32 tmp = orig->tmds_pll_cntl & 0xfffff; for (i=0; i<4; i++) { @@ -7370,7 +7579,56 @@ save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN); save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); - } + + } + + /* only crtc1 has RMX */ + if (!info->IsSecondary) { + if (mode->Flags & RADEON_USE_RMX) + RADEONInitRMXRegisters(pScrn, orig, save, mode, info); + } + +} + +/* Define CRTC registers for requested video mode */ +static void RADEONInitLCDRegisters(ScrnInfoPtr pScrn, RADEONSavePtr orig, + RADEONSavePtr save, DisplayModePtr mode, + RADEONInfoPtr info) +{ + + RADEONInitCommonFPRegisters(pScrn, orig, save, mode, info); + + save->lvds_gen_cntl = orig->lvds_gen_cntl; + save->lvds_pll_cntl = orig->lvds_pll_cntl; + + /* apparently the crtc select bit is actually LVDS_PLL_CNTL.LVDS_SRC_SEL + * for r300 and up. Unforunately, I don't have the hardware or + * the register reference to verify this. I'm not sure what bit(s) + * in LVDS_PLL_CNTL LVDS_SRC_SEL would be. + */ + if (info->IsSecondary) + save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2; + else + save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2; + + info->PanelOff = FALSE; + /* This option is used to force the ONLY DEVICE in XFConfig to use + * CRT port, instead of default DVI port. + */ + if (xf86ReturnOptValBool(info->Options, OPTION_PANEL_OFF, FALSE)) { + info->PanelOff = TRUE; + } + + if (info->PanelOff && info->MergedFB) { + info->OverlayOnCRTC2 = TRUE; + /* Turning off LVDS_ON seems to make panel white blooming. + * For now we just turn off display data ??? + */ + save->lvds_gen_cntl |= (RADEON_LVDS_DISPLAY_DIS); + save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON | RADEON_LVDS_ON); + } else { + save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON); +/* save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);*/ } info->BiosHotkeys = FALSE; @@ -7388,7 +7646,7 @@ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn); /* To work correctly with laptop hotkeys. - * Since there is no machnism for accessing ACPI evnets + * Since there is no machnism for accessing ACPI events * and the driver currently doesn't know how to validate * a mode dynamically, we have to tell BIOS don't do * display switching after X has started. @@ -7429,10 +7687,12 @@ } - save->fp_crtc_h_total_disp = save->crtc_h_total_disp; - save->fp_crtc_v_total_disp = save->crtc_v_total_disp; - save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid; - save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid; + /* only crtc1 has RMX */ + if (!info->IsSecondary) { + if (mode->Flags & RADEON_USE_RMX) + RADEONInitRMXRegisters(pScrn, orig, save, mode, info); + } + } /* Define PLL registers for requested video mode */ @@ -7670,18 +7930,39 @@ /* make RMX work for mergedfb modes on the LCD */ if (info->MergedFB) { - if ((info->MergeType == MT_LCD) || (info->MergeType == MT_DFP)) { - /* I suppose crtc2 could drive the FP as well... */ - RADEONInitFPRegisters(pScrn, &info->SavedReg, save, + if (info->MergeType == MT_DFP) { + if (info->MergeTMDSType == TMDS_EXT) + RADEONInitFP2Registers(pScrn, &info->SavedReg, save, ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, info); - } - else { - RADEONInitFPRegisters(pScrn, &info->SavedReg, save, + else + RADEONInitFPRegisters(pScrn, &info->SavedReg, save, + ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, info); + } else if (info->MergeType == MT_LCD) + RADEONInitLCDRegisters(pScrn, &info->SavedReg, save, + ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, info); + + if (info->DisplayType == MT_DFP) { + if (info->TMDSType == TMDS_EXT) + RADEONInitFP2Registers(pScrn, &info->SavedReg, save, ((RADEONMergedDisplayModePtr)mode->Private)->CRT1, info); - } + else + RADEONInitFPRegisters(pScrn, &info->SavedReg, save, + ((RADEONMergedDisplayModePtr)mode->Private)->CRT1, info); + } else if (info->DisplayType == MT_LCD) + RADEONInitLCDRegisters(pScrn, &info->SavedReg, save, + ((RADEONMergedDisplayModePtr)mode->Private)->CRT1, info); + } else { - RADEONInitFPRegisters(pScrn, &info->SavedReg, save, mode, info); + if (info->DisplayType == MT_DFP) { + if (info->TMDSType == TMDS_EXT) + RADEONInitFP2Registers(pScrn, &info->SavedReg, save, + ((RADEONMergedDisplayModePtr)mode->Private)->CRT1, info); + else + RADEONInitFPRegisters(pScrn, &info->SavedReg, save, + ((RADEONMergedDisplayModePtr)mode->Private)->CRT1, info); + } else if (info->DisplayType == MT_LCD) + RADEONInitLCDRegisters(pScrn, &info->SavedReg, save, mode, info); } RADEONTRACE(("RADEONInit returns %p\n", save)); @@ -8299,25 +8580,46 @@ if (PowerManagementMode == DPMSModeOn) { if (info->IsSecondary) { if (info->DisplayType == MT_DFP) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN); + if (info->TMDSType == TMDS_EXT) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, + RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN); + } + } else { + OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), + ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); } } else if (info->DisplayType == MT_CRT) { RADEONDacPowerSet(pScrn, TRUE, !pRADEONEnt->ReversedDAC); } } else { if ((info->MergedFB) && (info->MergeType == MT_DFP)) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN); + if (info->MergeTMDSType == TMDS_EXT) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, + RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN); + } + } else { + OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), + ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); } } if (info->DisplayType == MT_DFP) { - OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), + if (info->TMDSType == TMDS_EXT) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, + RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN); + } + } else { + OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN), ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); + } } else if (info->DisplayType == MT_LCD) { OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON); @@ -8338,24 +8640,40 @@ (PowerManagementMode == DPMSModeStandby)) { if (info->IsSecondary) { if (info->DisplayType == MT_DFP) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN); + if (info->TMDSType == TMDS_EXT) { + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN); + } + } else { + OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); } } else if (info->DisplayType == MT_CRT) { RADEONDacPowerSet(pScrn, FALSE, !pRADEONEnt->ReversedDAC); } } else { if ((info->MergedFB) && (info->MergeType == MT_DFP)) { - OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); - if (info->ChipFamily >= CHIP_FAMILY_R200) { - OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN); + if (info->MergeTMDSType == TMDS_EXT) { + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN); + } + } else { + OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); } } if (info->DisplayType == MT_DFP) { - OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); + if (info->TMDSType == TMDS_EXT) { + OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN); + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON); + if (info->ChipFamily >= CHIP_FAMILY_R200) { + OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN); + } + } else { + OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN)); + } } else if (info->DisplayType == MT_LCD) { unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);