summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/radeon_crtc.c54
-rw-r--r--src/radeon_driver.c114
-rw-r--r--src/radeon_output.c16
-rw-r--r--src/radeon_probe.h2
4 files changed, 172 insertions, 14 deletions
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index fd2c38cf..413bad4f 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -681,6 +681,10 @@ RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
int pixel_bytes1 = info->CurrentLayout.pixel_bytes;
int pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+ /* XXX fix me */
+ if (IS_DCE4_VARIANT)
+ return;
+
if (xf86_config->num_crtc == 2) {
if (xf86_config->crtc[1]->enabled &&
xf86_config->crtc[0]->enabled) {
@@ -713,6 +717,7 @@ Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
{
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
RADEONInfoPtr info = RADEONPTR(pScrn);
+ int i;
if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
radeon_crtc_funcs.shadow_create = radeon_crtc_shadow_create;
@@ -759,7 +764,10 @@ Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
pRADEONEnt->Controller[1]->crtc_id = 1;
- pRADEONEnt->Controller[1]->crtc_offset = AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
+ if (IS_DCE4_VARIANT)
+ pRADEONEnt->Controller[1]->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
+ else
+ pRADEONEnt->Controller[1]->crtc_offset = AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL;
pRADEONEnt->Controller[1]->initialized = FALSE;
if (info->allowColorTiling)
pRADEONEnt->Controller[1]->can_tile = 1;
@@ -767,6 +775,50 @@ Bool RADEONAllocateControllers(ScrnInfoPtr pScrn, int mask)
pRADEONEnt->Controller[1]->can_tile = 0;
}
+ /* 6 crtcs on DCE4 chips */
+ if (IS_DCE4_VARIANT && ((mask & 3) == 3)) {
+ for (i = 2; i < RADEON_MAX_CRTC; i++) {
+ pRADEONEnt->pCrtc[i] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+ if (!pRADEONEnt->pCrtc[i])
+ return FALSE;
+
+ pRADEONEnt->Controller[i] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
+ if (!pRADEONEnt->Controller[i])
+ {
+ xfree(pRADEONEnt->Controller[i]);
+ return FALSE;
+ }
+
+ pRADEONEnt->pCrtc[i]->driver_private = pRADEONEnt->Controller[i];
+ pRADEONEnt->Controller[i]->crtc_id = i;
+ switch (i) {
+ case 0:
+ pRADEONEnt->Controller[i]->crtc_offset = EVERGREEN_CRTC0_REGISTER_OFFSET;
+ break;
+ case 1:
+ pRADEONEnt->Controller[i]->crtc_offset = EVERGREEN_CRTC1_REGISTER_OFFSET;
+ break;
+ case 2:
+ pRADEONEnt->Controller[i]->crtc_offset = EVERGREEN_CRTC2_REGISTER_OFFSET;
+ break;
+ case 3:
+ pRADEONEnt->Controller[i]->crtc_offset = EVERGREEN_CRTC3_REGISTER_OFFSET;
+ break;
+ case 4:
+ pRADEONEnt->Controller[i]->crtc_offset = EVERGREEN_CRTC4_REGISTER_OFFSET;
+ break;
+ case 5:
+ pRADEONEnt->Controller[i]->crtc_offset = EVERGREEN_CRTC5_REGISTER_OFFSET;
+ break;
+ }
+ pRADEONEnt->Controller[i]->initialized = FALSE;
+ if (info->allowColorTiling)
+ pRADEONEnt->Controller[i]->can_tile = 1;
+ else
+ pRADEONEnt->Controller[i]->can_tile = 0;
+ }
+ }
+
return TRUE;
}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ae4993bc..859a7099 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -741,7 +741,12 @@ static Bool radeon_get_mc_idle(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- if (info->ChipFamily >= CHIP_FAMILY_R600) {
+ if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+ if (INREG(R600_SRBM_STATUS) & 0x1f00)
+ return FALSE;
+ else
+ return TRUE;
+ } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
if (INREG(R600_SRBM_STATUS) & 0x3f00)
return FALSE;
else
@@ -787,6 +792,7 @@ static void radeon_write_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, uint32_
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ /* evergreen is same as r7xx */
if (info->ChipFamily >= CHIP_FAMILY_RV770) {
if (mask & LOC_FB)
OUTREG(R700_MC_VM_FB_LOCATION, fb_loc);
@@ -837,6 +843,7 @@ static void radeon_read_mc_fb_agp_location(ScrnInfoPtr pScrn, int mask, uint32_t
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ /* evergreen is same as r7xx */
if (info->ChipFamily >= CHIP_FAMILY_RV770) {
if (mask & LOC_FB)
*fb_loc = INREG(R700_MC_VM_FB_LOCATION);
@@ -1389,7 +1396,12 @@ static void RADEONInitMemoryMap(ScrnInfoPtr pScrn)
/* We shouldn't use info->videoRam here which might have been clipped
* but the real video RAM instead
*/
- if (info->ChipFamily >= CHIP_FAMILY_R600) {
+ if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+ /* size in MB on evergreen */
+ /* XXX watch for overflow!!! */
+ mem_size = INREG(R600_CONFIG_MEMSIZE) * 1024 * 1024;
+ aper_size = INREG(R600_CONFIG_APER_SIZE) * 1024 * 1024;
+ } else if (info->ChipFamily >= CHIP_FAMILY_R600) {
mem_size = INREG(R600_CONFIG_MEMSIZE);
aper_size = INREG(R600_CONFIG_APER_SIZE);
} else {
@@ -1609,7 +1621,10 @@ static uint32_t RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
uint32_t aper_size;
unsigned char byte;
- if (info->ChipFamily >= CHIP_FAMILY_R600)
+ if (info->ChipFamily >= CHIP_FAMILY_CEDAR)
+ /* size in MB */
+ aper_size = INREG(R600_CONFIG_APER_SIZE) * 1024;
+ else if (info->ChipFamily >= CHIP_FAMILY_R600)
aper_size = INREG(R600_CONFIG_APER_SIZE) / 1024;
else
aper_size = INREG(RADEON_CONFIG_APER_SIZE) / 1024;
@@ -1671,7 +1686,7 @@ static uint32_t RADEONGetAccessibleVRAM(ScrnInfoPtr pScrn)
*/
if (INREG(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL)
return aper_size * 2;
-
+
return aper_size;
}
@@ -1692,7 +1707,11 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
OUTREG(RADEON_CONFIG_MEMSIZE, pScrn->videoRam * 1024);
} else {
- if (info->ChipFamily >= CHIP_FAMILY_R600)
+ if (info->ChipFamily >= CHIP_FAMILY_CEDAR)
+ /* R600_CONFIG_MEMSIZE is MB on evergreen */
+ /* XXX watch for overflow!!! */
+ pScrn->videoRam = INREG(R600_CONFIG_MEMSIZE) * 1024;
+ else if (info->ChipFamily >= CHIP_FAMILY_R600)
pScrn->videoRam = INREG(R600_CONFIG_MEMSIZE) / 1024;
else {
/* Read VRAM size from card */
@@ -2307,6 +2326,12 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
if (info->IsSecondary)
return FALSE;
+ if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "No DRI yet on Evergreen\n");
+ return FALSE;
+ }
+
if (info->Chipset == PCI_CHIP_RN50_515E ||
info->Chipset == PCI_CHIP_RN50_5969) {
if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) {
@@ -3834,8 +3859,75 @@ void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
" MC_AGP_LOCATION : 0x%08x\n",
(unsigned)restore->mc_agp_location);
- if (IS_AVIVO_VARIANT) {
+ if (IS_DCE4_VARIANT) {
+ if (mc_fb_loc != restore->mc_fb_location ||
+ mc_agp_loc != restore->mc_agp_location) {
+ uint32_t tmp;
+
+ //XXX
+ //RADEONWaitForIdleMMIO(pScrn);
+
+ /* disable VGA rendering core */
+ OUTREG(AVIVO_VGA_RENDER_CONTROL, INREG(AVIVO_VGA_RENDER_CONTROL) & ~AVIVO_VGA_VSTATUS_CNTL_MASK);
+ OUTREG(AVIVO_D1VGA_CONTROL, INREG(AVIVO_D1VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
+ OUTREG(AVIVO_D2VGA_CONTROL, INREG(AVIVO_D2VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
+ OUTREG(EVERGREEN_D3VGA_CONTROL, INREG(EVERGREEN_D3VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
+ OUTREG(EVERGREEN_D4VGA_CONTROL, INREG(EVERGREEN_D4VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
+ OUTREG(EVERGREEN_D5VGA_CONTROL, INREG(EVERGREEN_D5VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
+ OUTREG(EVERGREEN_D6VGA_CONTROL, INREG(EVERGREEN_D6VGA_CONTROL) & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
+ /* Stop display & memory access */
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
+ OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET);
+
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
+ OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET);
+
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
+ OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
+
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+ OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
+ OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
+
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+ OUTREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, tmp & ~EVERGREEN_CRTC_MASTER_EN);
+ tmp = INREG(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
+
+ usleep(10000);
+ timeout = 0;
+ while (!(radeon_get_mc_idle(pScrn))) {
+ if (++timeout > 1000000) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Timeout trying to update memory controller settings !\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "You will probably crash now ... \n");
+ /* Nothing we can do except maybe try to kill the server,
+ * let's wait 2 seconds to leave the above message a chance
+ * to maybe hit the disk and continue trying to setup despite
+ * the MC being non-idle
+ */
+ usleep(2000000);
+ }
+ usleep(10);
+ }
+
+ radeon_write_mc_fb_agp_location(pScrn, LOC_FB | LOC_AGP,
+ restore->mc_fb_location,
+ restore->mc_agp_location,
+ restore->mc_agp_location_hi);
+
+ OUTREG(R600_HDP_NONSURFACE_BASE, (restore->mc_fb_location << 16) & 0xff0000);
+
+ }
+ } else if (IS_AVIVO_VARIANT) {
if (mc_fb_loc != restore->mc_fb_location ||
mc_agp_loc != restore->mc_agp_location) {
uint32_t tmp;
@@ -5164,7 +5256,10 @@ static void RADEONSave(ScrnInfoPtr pScrn)
}
#endif
- if (IS_AVIVO_VARIANT) {
+ if (IS_DCE4_VARIANT) {
+ RADEONSaveMemMapRegisters(pScrn, save);
+ //XXX
+ } else if (IS_AVIVO_VARIANT) {
RADEONSaveMemMapRegisters(pScrn, save);
avivo_save(pScrn, save);
} else {
@@ -5214,7 +5309,10 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
RADEONBlank(pScrn);
- if (IS_AVIVO_VARIANT) {
+ if (IS_DCE4_VARIANT) {
+ RADEONRestoreMemMapRegisters(pScrn, restore);
+ //XXX
+ } else if (IS_AVIVO_VARIANT) {
RADEONRestoreMemMapRegisters(pScrn, restore);
avivo_restore(pScrn, restore);
} else {
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 3a18302a..3bc2f003 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -920,6 +920,10 @@ radeon_bios_output_crtc(xf86OutputPtr output)
xf86CrtcPtr crtc = output->crtc;
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ /* no need to update crtc routing scratch regs on DCE4 */
+ if (IS_DCE4_VARIANT)
+ return;
+
if (info->IsAtomBios) {
if (radeon_output->active_device & ATOM_DEVICE_TV1_SUPPORT) {
save->bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE;
@@ -2992,10 +2996,14 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
return FALSE;
}
output->driver_private = radeon_output;
- output->possible_crtcs = 1;
- /* crtc2 can drive LVDS, it just doesn't have RMX */
- if (!(radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)))
- output->possible_crtcs |= 2;
+ if (IS_DCE4_VARIANT) {
+ output->possible_crtcs = 0x3f;
+ } else {
+ output->possible_crtcs = 1;
+ /* crtc2 can drive LVDS, it just doesn't have RMX */
+ if (!(radeon_output->devices & (ATOM_DEVICE_LCD_SUPPORT)))
+ output->possible_crtcs |= 2;
+ }
/* we can clone the DACs, and probably TV-out,
but I'm not sure it's worth the trouble */
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 43cf31d2..f374ab08 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -52,7 +52,7 @@
extern DriverRec RADEON;
-#define RADEON_MAX_CRTC 2
+#define RADEON_MAX_CRTC 6
#define RADEON_MAX_BIOS_CONNECTOR 16
typedef enum