summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <agd5f@yahoo.com>2005-03-24 06:45:52 +0000
committerAlex Deucher <agd5f@yahoo.com>2005-03-24 06:45:52 +0000
commit5be4bf9000bdf58584a10a6b8e285d0f173304fa (patch)
tree0a381b6b148ccc1576947c599de6ebe0cc3e3db5
parent34af3da80304a13b6407dcc0f4db54d6c8bb7a41 (diff)
- radeon PLL access errata workarounds (Benjamin Herrenschmidt, acked by
Hui Yu)
-rw-r--r--src/radeon.h11
-rw-r--r--src/radeon_accel.c8
-rw-r--r--src/radeon_bios.c2
-rw-r--r--src/radeon_cursor.c2
-rw-r--r--src/radeon_dri.c2
-rw-r--r--src/radeon_driver.c153
-rw-r--r--src/radeon_macros.h50
-rw-r--r--src/radeon_mergedfb.c2
-rw-r--r--src/radeon_mm_i2c.c2
-rw-r--r--src/radeon_video.c12
-rw-r--r--src/radeon_vip.c2
11 files changed, 156 insertions, 90 deletions
diff --git a/src/radeon.h b/src/radeon.h
index b6fd8ce3..02d742f0 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -277,6 +277,16 @@ typedef enum {
(info->ChipFamily == CHIP_FAMILY_RV380) || \
(info->ChipFamily == CHIP_FAMILY_R420))
+/*
+ * Errata workarounds
+ */
+typedef enum {
+ CHIP_ERRATA_R300_CG = 0x00000001,
+ CHIP_ERRATA_PLL_DUMMYREADS = 0x00000002,
+ CHIP_ERRATA_PLL_DELAY = 0x00000004
+} RADEONErrata;
+
+
typedef struct {
CARD32 freq;
@@ -289,6 +299,7 @@ typedef struct {
PCITAG PciTag;
int Chipset;
RADEONChipFamily ChipFamily;
+ RADEONErrata ChipErrata;
Bool FBDev;
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index e2f479d3..355cf5c7 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -72,9 +72,9 @@
/* Driver data structures */
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
-#include "radeon_reg.h"
#include "radeon_version.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -196,7 +196,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
RADEONEngineFlush(pScrn);
clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
- if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+ RADEONPllErrataAfterIndex(info);
#if 0 /* taken care of by new PM code */
/* Some ASICs have bugs with dynamic-on feature, which are
@@ -274,8 +274,8 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
- OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
- if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+ RADEONPllErrataAfterIndex(info);
+ OUTPLL(pScrn, RADEON_MCLK_CNTL, mclk_cntl);
}
/* Restore the acceleration hardware to its previous state */
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 37a3e269..d9f20a71 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -30,9 +30,9 @@
#include "xf86_OSproc.h"
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
-#include "radeon_reg.h"
#include "vbe.h"
/* Read the Video BIOS block and the FP registers (if applicable). */
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index fba00f3a..102d3b0b 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -46,8 +46,8 @@
/* Driver data structures */
#include "radeon.h"
-#include "radeon_macros.h"
#include "radeon_reg.h"
+#include "radeon_macros.h"
#include "radeon_mergedfb.h"
/* X and server generic header files */
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 1bf3ed7d..88dda361 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -38,9 +38,9 @@
/* Driver data structures */
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_dri.h"
-#include "radeon_reg.h"
#include "radeon_version.h"
/* X and server generic header files */
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 247ee49f..22c800b6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -64,9 +64,9 @@
/* Driver data structures */
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
-#include "radeon_reg.h"
#include "radeon_version.h"
#include "radeon_mergedfb.h"
@@ -712,24 +712,7 @@ static Bool RADEONUnmapMem(ScrnInfoPtr pScrn)
return TRUE;
}
-/* This function is required to workaround a hardware bug in some (all?)
- * revisions of the R300. This workaround should be called after every
- * CLOCK_CNTL_INDEX register access. If not, register reads afterward
- * may not be correct.
- */
-void R300CGWorkaround(ScrnInfoPtr pScrn) {
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 save, tmp;
-
- save = INREG(RADEON_CLOCK_CNTL_INDEX);
- tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
- OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp);
- tmp = INREG(RADEON_CLOCK_CNTL_DATA);
- OUTREG(RADEON_CLOCK_CNTL_INDEX, save);
-}
-
-/* Read PLL information */
+/* Read PLL register */
unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -737,12 +720,27 @@ unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr)
CARD32 data;
OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);
+ RADEONPllErrataAfterIndex(info);
data = INREG(RADEON_CLOCK_CNTL_DATA);
- if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+ RADEONPllErrataAfterData(info);
return data;
}
+/* Write PLL information */
+unsigned RADEONOUTPLL(ScrnInfoPtr pScrn, int addr, CARD32 data)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) |
+ RADEON_PLL_WR_EN));
+ RADEONPllErrataAfterIndex(info);
+ OUTREG(RADEON_CLOCK_CNTL_DATA, data);
+ RADEONPllErrataAfterData(info);
+}
+
+
#if 0
/* Read PAL information (only used for debugging) */
static int RADEONINPAL(int idx)
@@ -1287,8 +1285,8 @@ static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
break;
}
- OUTREG(RADEON_CLOCK_CNTL_INDEX, 1);
- ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_DATA + 1) & 0x3;
+ ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
+ RADEONPllErrataAfterIndex(info);
n = (INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
m = (INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff);
@@ -1441,15 +1439,15 @@ static void RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn)
if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
CARD32 ppll_div_sel, ppll_val;
- OUTREG(RADEON_CLOCK_CNTL_INDEX, 1);
- ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_DATA + 1) & 0x3;
- ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
+ 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;
+ 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");
@@ -2549,10 +2547,22 @@ static Bool RADEONPreInitConfig(ScrnInfoPtr pScrn)
/* Some production boards of m6 will return 0 if it's 8 MB */
if (pScrn->videoRam == 0) pScrn->videoRam = 8192;
- info->R300CGWorkaround =
- (info->ChipFamily == CHIP_FAMILY_R300 &&
- (INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
- == RADEON_CFG_ATI_REV_A11);
+ /* Check chip errata */
+ info->ChipErrata = 0;
+
+ if (info->ChipFamily == CHIP_FAMILY_R300 &&
+ (INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
+ == RADEON_CFG_ATI_REV_A11)
+ info->ChipErrata |= CHIP_ERRATA_R300_CG;
+
+ if (info->ChipFamily == CHIP_FAMILY_RV200 ||
+ info->ChipFamily == CHIP_FAMILY_RS200)
+ info->ChipErrata |= CHIP_ERRATA_PLL_DUMMYREADS;
+
+ if (info->ChipFamily == CHIP_FAMILY_RV100 ||
+ info->ChipFamily == CHIP_FAMILY_RS100 ||
+ info->ChipFamily == CHIP_FAMILY_RS200)
+ info->ChipErrata |= CHIP_ERRATA_PLL_DELAY;
info->MemCntl = INREG(RADEON_SDRAM_MODE_REG);
info->BusCntl = INREG(RADEON_BUS_CNTL);
@@ -5695,7 +5705,7 @@ static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
if (info->IsMobility || info->IsIGP) {
if (!(restore->lvds_gen_cntl & RADEON_LVDS_ON)) {
- OUTPLL(RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
}
}
}
@@ -5768,8 +5778,14 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
By doing this we can avoid the blanking problem with some panels.
*/
if ((restore->ppll_ref_div == (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
- (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) & (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK))))
- return;
+ (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) &
+ (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
+ OUTREGP(RADEON_CLOCK_CNTL_INDEX,
+ RADEON_PLL_DIV_SEL,
+ ~(RADEON_PLL_DIV_SEL));
+ RADEONPllErrataAfterIndex(info);
+ return;
+ }
}
OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
@@ -5788,6 +5804,7 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
OUTREGP(RADEON_CLOCK_CNTL_INDEX,
RADEON_PLL_DIV_SEL,
~(RADEON_PLL_DIV_SEL));
+ RADEONPllErrataAfterIndex(info);
if (IS_R300_VARIANT ||
(info->ChipFamily == CHIP_FAMILY_RS300)) {
@@ -5821,7 +5838,7 @@ static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
RADEONPLLWriteUpdate(pScrn);
RADEONPLLWaitForReadUpdateComplete(pScrn);
- OUTPLL(RADEON_HTOTAL_CNTL, restore->htotal_cntl);
+ OUTPLL(pScrn, RADEON_HTOTAL_CNTL, restore->htotal_cntl);
OUTPLLP(pScrn, RADEON_PPLL_CNTL,
0,
@@ -5883,7 +5900,7 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
RADEONPLL2WriteUpdate(pScrn);
RADEONPLL2WaitForReadUpdateComplete(pScrn);
- OUTPLL(RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
+ OUTPLL(pScrn, RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
OUTPLLP(pScrn, RADEON_P2PLL_CNTL,
0,
@@ -6396,7 +6413,7 @@ static void RADEONSave(ScrnInfoPtr pScrn)
save->dp_datatype = INREG(RADEON_DP_DATATYPE);
save->rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
- if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+ RADEONPllErrataAfterIndex(info);
}
RADEONSaveMode(pScrn, save);
@@ -6425,7 +6442,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
RADEONBlank(pScrn);
OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
- if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+ RADEONPllErrataAfterIndex(info);
OUTREG(RADEON_RBBM_SOFT_RESET, restore->rbbm_soft_reset);
OUTREG(RADEON_DP_DATATYPE, restore->dp_datatype);
OUTREG(RADEON_GRPH_BUFFER_CNTL, restore->grph_buffer_cntl);
@@ -8375,7 +8392,7 @@ static void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
~(RADEON_LVDS_BLON | RADEON_LVDS_ON));
if (info->IsMobility || info->IsIGP) {
- OUTPLL(RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
}
} else if (info->DisplayType == MT_CRT) {
if ((pRADEONEnt->HasSecondary) || info->MergedFB) {
@@ -8596,14 +8613,14 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
RADEON_SCLK_FORCE_RE | RADEON_SCLK_FORCE_PB |
RADEON_SCLK_FORCE_TAM | RADEON_SCLK_FORCE_TDM |
RADEON_SCLK_FORCE_RB);
- OUTPLL(RADEON_SCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
} else if (info->ChipFamily == CHIP_FAMILY_RV350) {
/* for RV350/M10, no delays are required. */
tmp = INPLL(pScrn, R300_SCLK_CNTL2);
tmp |= (R300_SCLK_FORCE_TCL |
R300_SCLK_FORCE_GA |
R300_SCLK_FORCE_CBA);
- OUTPLL(R300_SCLK_CNTL2, tmp);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
@@ -8614,11 +8631,11 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
R300_SCLK_FORCE_PX | R300_SCLK_FORCE_TX |
R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
- OUTPLL(RADEON_SCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
tmp |= RADEON_SCLK_MORE_FORCEON;
- OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
tmp |= (RADEON_FORCEON_MCLKA |
@@ -8626,13 +8643,13 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
RADEON_FORCEON_YCLKA |
RADEON_FORCEON_YCLKB |
RADEON_FORCEON_MC);
- OUTPLL(RADEON_MCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
RADEON_PIXCLK_DAC_ALWAYS_ONb |
R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF);
- OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb |
@@ -8649,7 +8666,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
R300_P2G2CLK_ALWAYS_ONb |
R300_P2G2CLK_ALWAYS_ONb |
R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
- OUTPLL(RADEON_PIXCLKS_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
} else {
tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
@@ -8686,7 +8703,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
tmp |= ( R300_SCLK_FORCE_TCL |
R300_SCLK_FORCE_GA |
R300_SCLK_FORCE_CBA);
- OUTPLL(R300_SCLK_CNTL2, tmp);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
usleep(16000);
}
@@ -8703,7 +8720,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
(info->ChipFamily == CHIP_FAMILY_RV280)) {
tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
tmp |= RADEON_SCLK_MORE_FORCEON;
- OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
usleep(16000);
}
@@ -8722,7 +8739,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb |
RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Disabled\n");
break;
@@ -8738,7 +8755,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE |
RADEON_SCLK_FORCE_PB | RADEON_SCLK_FORCE_TAM |
RADEON_SCLK_FORCE_TDM);
- OUTPLL (RADEON_SCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
} else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
(info->ChipFamily == CHIP_FAMILY_R350) ||
(info->ChipFamily == CHIP_FAMILY_RV350)) {
@@ -8750,7 +8767,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
tmp |= (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
R300_SCLK_GA_MAX_DYN_STOP_LAT |
R300_SCLK_CBA_MAX_DYN_STOP_LAT);
- OUTPLL(R300_SCLK_CNTL2, tmp);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP |
@@ -8762,17 +8779,17 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
R300_SCLK_FORCE_US | RADEON_SCLK_FORCE_TV_SCLK |
R300_SCLK_FORCE_SU | RADEON_SCLK_FORCE_OV0);
tmp |= RADEON_DYN_STOP_LAT_MASK;
- OUTPLL(RADEON_SCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
tmp &= ~RADEON_SCLK_MORE_FORCEON;
tmp |= RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
- OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
tmp |= (RADEON_PIX2CLK_ALWAYS_ONb |
@@ -8788,12 +8805,12 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
R300_PIXCLK_TVO_ALWAYS_ONb |
R300_P2G2CLK_ALWAYS_ONb |
R300_P2G2CLK_ALWAYS_ONb);
- OUTPLL(RADEON_PIXCLKS_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
tmp = INPLL(pScrn, RADEON_MCLK_MISC);
tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
RADEON_IO_MCLK_DYN_ENABLE);
- OUTPLL(RADEON_MCLK_MISC, tmp);
+ OUTPLL(pScrn, RADEON_MCLK_MISC, tmp);
tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
tmp |= (RADEON_FORCEON_MCLKA |
@@ -8822,19 +8839,19 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
}
}
- OUTPLL(RADEON_MCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
} else {
tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
tmp &= ~(R300_SCLK_FORCE_VAP);
tmp |= RADEON_SCLK_FORCE_CP;
- OUTPLL(RADEON_SCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
usleep(15000);
tmp = INPLL(pScrn, R300_SCLK_CNTL2);
tmp &= ~(R300_SCLK_FORCE_TCL |
R300_SCLK_FORCE_GA |
R300_SCLK_FORCE_CBA);
- OUTPLL(R300_SCLK_CNTL2, tmp);
+ OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
}
} else {
tmp = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL);
@@ -8845,12 +8862,12 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
tmp |= (RADEON_ENGIN_DYNCLK_MODE |
(0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
- OUTPLL(RADEON_CLK_PWRMGT_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_CLK_PWRMGT_CNTL, tmp);
usleep(15000);
tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL);
tmp |= RADEON_SCLK_DYN_START_CNTL;
- OUTPLL(RADEON_CLK_PIN_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_CLK_PIN_CNTL, tmp);
usleep(15000);
/* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200
@@ -8871,7 +8888,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
tmp |= RADEON_SCLK_FORCE_VIP;
}
- OUTPLL(RADEON_SCLK_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
if ((info->ChipFamily == CHIP_FAMILY_RV200) ||
(info->ChipFamily == CHIP_FAMILY_RV250) ||
@@ -8886,7 +8903,7 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
RADEON_CFG_ATI_REV_A13)) {
tmp |= RADEON_SCLK_MORE_FORCEON;
}
- OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
usleep(15000);
}
@@ -8911,14 +8928,14 @@ static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode)
RADEON_PIXCLK_LVDS_ALWAYS_ONb |
RADEON_PIXCLK_TMDS_ALWAYS_ONb);
- OUTPLL(RADEON_PIXCLKS_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
usleep(15000);
tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
usleep(15000);
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Enabled\n");
diff --git a/src/radeon_macros.h b/src/radeon_macros.h
index 71b90834..3d8aa13d 100644
--- a/src/radeon_macros.h
+++ b/src/radeon_macros.h
@@ -84,19 +84,14 @@ do { \
#define INPLL(pScrn, addr) RADEONINPLL(pScrn, addr)
-#define OUTPLL(addr, val) \
-do { \
- OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) | \
- RADEON_PLL_WR_EN)); \
- OUTREG(RADEON_CLOCK_CNTL_DATA, val); \
-} while (0)
+#define OUTPLL(pScrn, addr, val) RADEONOUTPLL(pScrn, addr, val)
#define OUTPLLP(pScrn, addr, val, mask) \
do { \
CARD32 tmp_ = INPLL(pScrn, addr); \
tmp_ &= (mask); \
tmp_ |= (val); \
- OUTPLL(addr, tmp_); \
+ OUTPLL(pScrn, addr, tmp_); \
} while (0)
#define OUTPAL_START(idx) \
@@ -138,5 +133,46 @@ do { \
} \
} while (0)
+static void RADEONPllErrataAfterIndex(RADEONInfoPtr info)
+{
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (!(info->ChipErrata & CHIP_ERRATA_PLL_DUMMYREADS))
+ return;
+
+ /* This workaround is necessary on rv200 and RS200 or PLL
+ * reads may return garbage (among others...)
+ */
+ (void)INREG(RADEON_CLOCK_CNTL_DATA);
+ (void)INREG(RADEON_CRTC_GEN_CNTL);
+}
+
+static void RADEONPllErrataAfterData(RADEONInfoPtr info)
+{
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ /* This workarounds is necessary on RV100, RS100 and RS200 chips
+ * or the chip could hang on a subsequent access
+ */
+ if (info->ChipErrata & CHIP_ERRATA_PLL_DELAY) {
+ /* we can't deal with posted writes here ... */
+ usleep(5000);
+ }
+
+ /* This function is required to workaround a hardware bug in some (all?)
+ * revisions of the R300. This workaround should be called after every
+ * CLOCK_CNTL_INDEX register access. If not, register reads afterward
+ * may not be correct.
+ */
+ if (info->ChipErrata & CHIP_ERRATA_R300_CG) {
+ CARD32 save, tmp;
+
+ save = INREG(RADEON_CLOCK_CNTL_INDEX);
+ tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
+ OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp);
+ tmp = INREG(RADEON_CLOCK_CNTL_DATA);
+ OUTREG(RADEON_CLOCK_CNTL_INDEX, save);
+ }
+}
#endif
diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 741edffe..809ac0d7 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -43,8 +43,8 @@
#include "radeon.h"
-#include "radeon_macros.h"
#include "radeon_reg.h"
+#include "radeon_macros.h"
#include "radeon_mergedfb.h"
/* psuedo xinerama support */
diff --git a/src/radeon_mm_i2c.c b/src/radeon_mm_i2c.c
index f6a36889..970cc1f0 100644
--- a/src/radeon_mm_i2c.c
+++ b/src/radeon_mm_i2c.c
@@ -1,7 +1,7 @@
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
-#include "radeon_reg.h"
#include "Xv.h"
#include "radeon_video.h"
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 00038247..cfc61195 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1,9 +1,9 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c,v 1.30 2003/11/10 18:22:18 tsi Exp $ */
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
-#include "radeon_reg.h"
#include "radeon_mergedfb.h"
#include "radeon_video.h"
@@ -1323,8 +1323,8 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dotclock is %g Mhz, setting ecp_div to %d\n", info->ModeReg.dot_clock_freq/100.0, pPriv->ecp_div);
#endif
- OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) &
- 0xfffffCff) | (pPriv->ecp_div << 8));
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) &
+ 0xfffffCff) | (pPriv->ecp_div << 8));
/* I suspect we may need a usleep after writing to the PLL. if you play a video too soon
after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
@@ -1336,7 +1336,8 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
(info->ChipFamily == CHIP_FAMILY_RS300)) {
/* Force the overlay clock on for integrated chips
*/
- OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
+ (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
}
/* overlay scaler line length differs for different revisions
@@ -2301,7 +2302,8 @@ RADEONDisplayVideo(
else
ecp_div = 1;
- OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
+ (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
/* I suspect we may need a usleep after writing to the PLL. if you play a video too soon
after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey
diff --git a/src/radeon_vip.c b/src/radeon_vip.c
index d1ac15f2..815a098d 100644
--- a/src/radeon_vip.c
+++ b/src/radeon_vip.c
@@ -1,7 +1,7 @@
#include "radeon.h"
+#include "radeon_reg.h"
#include "radeon_macros.h"
#include "radeon_probe.h"
-#include "radeon_reg.h"
#include "Xv.h"
#include "radeon_video.h"