summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/legacy_crtc.c252
-rw-r--r--src/radeon.h2
-rw-r--r--src/radeon_crtc.c38
-rw-r--r--src/radeon_reg.h15
4 files changed, 159 insertions, 148 deletions
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index 3df61a7a..e5561e87 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -1327,9 +1327,12 @@ radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore)
}
/* Calculate display buffer watermark to prevent buffer underflow */
-static void
-RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2)
+void
+RADEONInitDispBandwidthLegacy(ScrnInfoPtr pScrn,
+ DisplayModePtr mode1, int pixel_bytes1,
+ DisplayModePtr mode2, int pixel_bytes2)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
@@ -1352,10 +1355,10 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
float min_mem_eff = 0.8;
float sclk_eff, sclk_delay;
float mc_latency_mclk, mc_latency_sclk, cur_latency_mclk, cur_latency_sclk;
- float disp_latency, disp_latency_overhead, disp_drain_rate, disp_drain_rate2;
+ float disp_latency, disp_latency_overhead, disp_drain_rate = 0, disp_drain_rate2;
float pix_clk, pix_clk2; /* in MHz */
int cur_size = 16; /* in octawords */
- int critical_point, critical_point2;
+ int critical_point = 0, critical_point2;
int stop_req, max_stop_req;
float read_return_rate, time_disp1_drop_priority;
@@ -1366,11 +1369,10 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
*/
if ((info->DispPriority == 2) && IS_R300_VARIANT) {
uint32_t mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
- if (pRADEONEnt->pCrtc[1]->enabled) {
- mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
- } else {
- mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
- }
+ if (pRADEONEnt->pCrtc[1]->enabled)
+ mc_init_misc_lat_timer |= (1 << R300_MC_DISP1R_INIT_LAT_SHIFT); /* display 1 */
+ if (pRADEONEnt->pCrtc[0]->enabled)
+ mc_init_misc_lat_timer |= (1 << R300_MC_DISP0R_INIT_LAT_SHIFT); /* display 0 */
OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
}
@@ -1383,15 +1385,17 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
*/
mem_bw = info->mclk * (info->RamWidth / 8) * (info->IsDDR ? 2 : 1);
- pix_clk = mode1->Clock/1000.0;
- if (mode2)
+ pix_clk = 0;
+ pix_clk2 = 0;
+ peak_disp_bw = 0;
+ if (mode1) {
+ pix_clk = mode1->Clock/1000.0;
+ peak_disp_bw += (pix_clk * pixel_bytes1);
+ }
+ if (mode2) {
pix_clk2 = mode2->Clock/1000.0;
- else
- pix_clk2 = 0;
-
- peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes);
- if (pixel_bytes2)
- peak_disp_bw += (pix_clk2 * pixel_bytes2);
+ peak_disp_bw += (pix_clk2 * pixel_bytes2);
+ }
if (peak_disp_bw >= mem_bw * min_mem_eff) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -1399,20 +1403,6 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
"If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
}
- /* CRTC1
- Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
- GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
- */
- stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16;
-
- /* setup Max GRPH_STOP_REQ default value */
- if (IS_RV100_VARIANT)
- max_stop_req = 0x5c;
- else
- max_stop_req = 0x7c;
- if (stop_req > max_stop_req)
- stop_req = max_stop_req;
-
/* Get values from the EXT_MEM_CNTL register...converting its contents. */
temp = INREG(RADEON_MEM_TIMING_CNTL);
if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
@@ -1435,9 +1425,8 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
}
if (IS_R300_VARIANT) {
-
/* on the R300, Tcas is included in Trbs.
- */
+ */
temp = INREG(RADEON_MEM_CNTL);
data = (R300_MEM_NUM_CHANNELS_MASK & temp);
if (data == 1) {
@@ -1473,7 +1462,8 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
sclk_eff = info->sclk;
}
- /* Find the memory controller latency for the display client.
+ /*
+ Find the memory controller latency for the display client.
*/
if (IS_R300_VARIANT) {
/*not enough for R350 ???*/
@@ -1527,89 +1517,107 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
mc_latency_sclk = mc_latency_sclk + disp_latency_overhead + cur_latency_sclk;
disp_latency = MAX(mc_latency_mclk, mc_latency_sclk);
- /*
- Find the drain rate of the display buffer.
- */
- disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes);
- if (pixel_bytes2)
- disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
+ /* setup Max GRPH_STOP_REQ default value */
+ if (IS_RV100_VARIANT)
+ max_stop_req = 0x5c;
else
- disp_drain_rate2 = 0;
+ max_stop_req = 0x7c;
- /*
- Find the critical point of the display buffer.
- */
- critical_point= (uint32_t)(disp_drain_rate * disp_latency + 0.5);
+ if (mode1) {
+ /* CRTC1
+ Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
+ GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
+ */
+ stop_req = mode1->HDisplay * pixel_bytes1 / 16;
- /* ???? */
- /*
- temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT;
- if (critical_point < temp) critical_point = temp;
- */
- if (info->DispPriority == 2) {
- critical_point = 0;
- }
+ if (stop_req > max_stop_req)
+ stop_req = max_stop_req;
- /*
- The critical point should never be above max_stop_req-4. Setting
- GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
- */
- if (max_stop_req - critical_point < 4) critical_point = 0;
+ /*
+ Find the drain rate of the display buffer.
+ */
+ disp_drain_rate = pix_clk / (16.0/pixel_bytes1);
- if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) {
- /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/
- critical_point = 0x10;
- }
+ /*
+ Find the critical point of the display buffer.
+ */
+ critical_point= (uint32_t)(disp_drain_rate * disp_latency + 0.5);
- temp = info->SavedReg->grph_buffer_cntl;
- temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
- temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
- temp &= ~(RADEON_GRPH_START_REQ_MASK);
- if ((info->ChipFamily == CHIP_FAMILY_R350) &&
- (stop_req > 0x15)) {
- stop_req -= 0x10;
- }
- temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
+ /* ???? */
+ /*
+ temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT;
+ if (critical_point < temp) critical_point = temp;
+ */
+ if (info->DispPriority == 2) {
+ critical_point = 0;
+ }
- temp |= RADEON_GRPH_BUFFER_SIZE;
- temp &= ~(RADEON_GRPH_CRITICAL_CNTL |
- RADEON_GRPH_CRITICAL_AT_SOF |
- RADEON_GRPH_STOP_CNTL);
- /*
- Write the result into the register.
- */
- OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
- (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
+ /*
+ The critical point should never be above max_stop_req-4. Setting
+ GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
+ */
+ if (max_stop_req - critical_point < 4) critical_point = 0;
+
+ if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) {
+ /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/
+ critical_point = 0x10;
+ }
+
+ temp = info->SavedReg->grph_buffer_cntl;
+ temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
+ temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
+ temp &= ~(RADEON_GRPH_START_REQ_MASK);
+ if ((info->ChipFamily == CHIP_FAMILY_R350) &&
+ (stop_req > 0x15)) {
+ stop_req -= 0x10;
+ }
+ temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
+
+ temp |= RADEON_GRPH_BUFFER_SIZE;
+ temp &= ~(RADEON_GRPH_CRITICAL_CNTL |
+ RADEON_GRPH_CRITICAL_AT_SOF |
+ RADEON_GRPH_STOP_CNTL);
+ /*
+ Write the result into the register.
+ */
+ OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
+ (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
#if 0
- if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
- (info->ChipFamily == CHIP_FAMILY_RS480)) {
- /* attempt to program RS400 disp regs correctly ??? */
- temp = info->SavedReg->disp1_req_cntl1;
- temp &= ~(RS400_DISP1_START_REQ_LEVEL_MASK |
- RS400_DISP1_STOP_REQ_LEVEL_MASK);
- OUTREG(RS400_DISP1_REQ_CNTL1, (temp |
- (critical_point << RS400_DISP1_START_REQ_LEVEL_SHIFT) |
- (critical_point << RS400_DISP1_STOP_REQ_LEVEL_SHIFT)));
- temp = info->SavedReg->dmif_mem_cntl1;
- temp &= ~(RS400_DISP1_CRITICAL_POINT_START_MASK |
- RS400_DISP1_CRITICAL_POINT_STOP_MASK);
- OUTREG(RS400_DMIF_MEM_CNTL1, (temp |
- (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) |
- (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT)));
- }
+ if ((info->ChipFamily == CHIP_FAMILY_RS400) ||
+ (info->ChipFamily == CHIP_FAMILY_RS480)) {
+ /* attempt to program RS400 disp regs correctly ??? */
+ temp = info->SavedReg->disp1_req_cntl1;
+ temp &= ~(RS400_DISP1_START_REQ_LEVEL_MASK |
+ RS400_DISP1_STOP_REQ_LEVEL_MASK);
+ OUTREG(RS400_DISP1_REQ_CNTL1, (temp |
+ (critical_point << RS400_DISP1_START_REQ_LEVEL_SHIFT) |
+ (critical_point << RS400_DISP1_STOP_REQ_LEVEL_SHIFT)));
+ temp = info->SavedReg->dmif_mem_cntl1;
+ temp &= ~(RS400_DISP1_CRITICAL_POINT_START_MASK |
+ RS400_DISP1_CRITICAL_POINT_STOP_MASK);
+ OUTREG(RS400_DMIF_MEM_CNTL1, (temp |
+ (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) |
+ (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT)));
+ }
#endif
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "GRPH_BUFFER_CNTL from %x to %x\n",
- (unsigned int)info->SavedReg->grph_buffer_cntl,
- (unsigned int)INREG(RADEON_GRPH_BUFFER_CNTL));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "GRPH_BUFFER_CNTL from %x to %x\n",
+ (unsigned int)info->SavedReg->grph_buffer_cntl,
+ (unsigned int)INREG(RADEON_GRPH_BUFFER_CNTL));
+ }
if (mode2) {
stop_req = mode2->HDisplay * pixel_bytes2 / 16;
if (stop_req > max_stop_req) stop_req = max_stop_req;
+ /*
+ Find the drain rate of the display buffer.
+ */
+ disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
+
temp = info->SavedReg->grph2_buffer_cntl;
temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
@@ -1629,7 +1637,10 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
critical_point2 = 0;
else {
read_return_rate = MIN(info->sclk, info->mclk*(info->RamWidth*(info->IsDDR+1)/128));
- time_disp1_drop_priority = critical_point / (read_return_rate - disp_drain_rate);
+ if (mode1)
+ time_disp1_drop_priority = critical_point / (read_return_rate - disp_drain_rate);
+ else
+ time_disp1_drop_priority = 0;
critical_point2 = (uint32_t)((disp_latency + time_disp1_drop_priority +
disp_latency) * disp_drain_rate2 + 0.5);
@@ -1681,45 +1692,6 @@ RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2
}
void
-RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- DisplayModePtr mode1, mode2;
- int pixel_bytes2 = 0;
-
- if (info->IsPrimary || info->IsSecondary)
- mode1 = &xf86_config->crtc[0]->mode;
- else
- mode1 = info->CurrentLayout.mode;
- mode2 = NULL;
- pixel_bytes2 = info->CurrentLayout.pixel_bytes;
-
- if (xf86_config->num_crtc == 2) {
- pixel_bytes2 = 0;
- mode2 = NULL;
-
- if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
- pixel_bytes2 = info->CurrentLayout.pixel_bytes;
- mode1 = &xf86_config->crtc[0]->mode;
- mode2 = &xf86_config->crtc[1]->mode;
- } else if (xf86_config->crtc[0]->enabled) {
- mode1 = &xf86_config->crtc[0]->mode;
- } else if (xf86_config->crtc[1]->enabled) {
- mode1 = &xf86_config->crtc[1]->mode;
- } else
- return;
- } else {
- if (xf86_config->crtc[0]->enabled)
- mode1 = &xf86_config->crtc[0]->mode;
- else
- return;
- }
-
- RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
-}
-
-void
legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode, int x, int y)
{
diff --git a/src/radeon.h b/src/radeon.h
index 3f266de6..8f25fdf7 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -817,7 +817,6 @@ do { \
extern void legacy_crtc_dpms(xf86CrtcPtr crtc, int mode);
extern void legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode, int x, int y);
-extern void RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
extern void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
RADEONSavePtr restore);
extern void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
@@ -924,6 +923,7 @@ extern DisplayModePtr RADEONCrtcFindClosestMode(xf86CrtcPtr crtc,
DisplayModePtr pMode);
extern void RADEONUnblank(ScrnInfoPtr pScrn);
extern Bool RADEONSetTiling(ScrnInfoPtr pScrn);
+extern void RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
/* radeon_cursor.c */
extern Bool RADEONCursorInit(ScreenPtr pScreen);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index c63b6505..9e5f672b 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -58,6 +58,10 @@ extern void atombios_crtc_mode_set(xf86CrtcPtr crtc,
DisplayModePtr adjusted_mode,
int x, int y);
extern void atombios_crtc_dpms(xf86CrtcPtr crtc, int mode);
+extern void
+RADEONInitDispBandwidthLegacy(ScrnInfoPtr pScrn,
+ DisplayModePtr mode1, int pixel_bytes1,
+ DisplayModePtr mode2, int pixel_bytes2);
void
radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
@@ -567,6 +571,40 @@ static const xf86CrtcFuncsRec radeon_crtc_funcs = {
.destroy = NULL, /* XXX */
};
+void
+RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ DisplayModePtr mode1 = NULL, mode2 = NULL;
+ int pixel_bytes1 = info->CurrentLayout.pixel_bytes;
+ int pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+
+ if (xf86_config->num_crtc == 2) {
+ if (xf86_config->crtc[1]->enabled &&
+ xf86_config->crtc[0]->enabled) {
+ mode1 = &xf86_config->crtc[0]->mode;
+ mode2 = &xf86_config->crtc[1]->mode;
+ } else if (xf86_config->crtc[0]->enabled) {
+ mode1 = &xf86_config->crtc[0]->mode;
+ } else if (xf86_config->crtc[1]->enabled) {
+ mode2 = &xf86_config->crtc[1]->mode;
+ } else
+ return;
+ } else {
+ if (info->IsPrimary)
+ mode1 = &xf86_config->crtc[0]->mode;
+ else if (info->IsSecondary)
+ mode2 = &xf86_config->crtc[0]->mode;
+ else if (xf86_config->crtc[0]->enabled)
+ mode1 = &xf86_config->crtc[0]->mode;
+ else
+ return;
+ }
+
+ RADEONInitDispBandwidthLegacy(pScrn, mode1, pixel_bytes1, mode2, pixel_bytes2);
+}
+
Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
{
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index fbc724ad..b79dbd50 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -1032,6 +1032,8 @@
#define RADEON_OV0_BASE_ADDR 0x43c
#define RADEON_NB_TOM 0x15c
#define R300_MC_INIT_MISC_LAT_TIMER 0x180
+# define R300_MC_DISP0R_INIT_LAT_SHIFT 8
+# define R300_MC_DISP1R_INIT_LAT_SHIFT 12
#define RADEON_MCLK_CNTL 0x0012 /* PLL */
# define RADEON_FORCEON_MCLKA (1 << 16)
# define RADEON_FORCEON_MCLKB (1 << 17)
@@ -3431,12 +3433,12 @@
#define RS600_MC_STATUS 0x0
#define RS600_MC_STATUS_IDLE (1 << 0)
-#define AVIVO_MC_INDEX 0x0070
-#define R520_MC_STATUS 0x00
-#define R520_MC_STATUS_IDLE (1<<1)
-#define RV515_MC_STATUS 0x08
-#define RV515_MC_STATUS_IDLE (1<<4)
-#define AVIVO_MC_DATA 0x0074
+#define AVIVO_MC_INDEX 0x0070
+#define R520_MC_STATUS 0x00
+# define R520_MC_STATUS_IDLE (1 << 1)
+#define RV515_MC_STATUS 0x08
+# define RV515_MC_STATUS_IDLE (1 << 4)
+#define AVIVO_MC_DATA 0x0074
#define RV515_MC_FB_LOCATION 0x1
#define RV515_MC_AGP_LOCATION 0x2
@@ -3598,7 +3600,6 @@
#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4
#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8
-
#define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652c
#define AVIVO_D1MODE_VIEWPORT_START 0x6580
#define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584