|
@@ -1241,116 +1241,103 @@ void evergreen_agp_enable(struct radeon_device *rdev)
|
|
|
|
|
|
void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
|
|
|
{
|
|
|
+ u32 crtc_enabled, tmp, frame_count, blackout;
|
|
|
+ int i, j;
|
|
|
+
|
|
|
save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
|
|
|
save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
|
|
|
|
|
|
- /* Stop all video */
|
|
|
+ /* disable VGA render */
|
|
|
WREG32(VGA_RENDER_CONTROL, 0);
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1);
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1);
|
|
|
- if (rdev->num_crtc >= 4) {
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
|
|
|
- }
|
|
|
- if (rdev->num_crtc >= 6) {
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1);
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1);
|
|
|
- }
|
|
|
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
|
|
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
|
|
- if (rdev->num_crtc >= 4) {
|
|
|
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
|
|
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
|
|
- }
|
|
|
- if (rdev->num_crtc >= 6) {
|
|
|
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
|
|
- WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
|
|
- }
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
|
|
|
- if (rdev->num_crtc >= 4) {
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
|
|
|
- }
|
|
|
- if (rdev->num_crtc >= 6) {
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
|
|
|
- WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
|
|
|
+ /* blank the display controllers */
|
|
|
+ for (i = 0; i < rdev->num_crtc; i++) {
|
|
|
+ crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN;
|
|
|
+ if (crtc_enabled) {
|
|
|
+ save->crtc_enabled[i] = true;
|
|
|
+ if (ASIC_IS_DCE6(rdev)) {
|
|
|
+ tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
|
|
|
+ if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
|
|
|
+ radeon_wait_for_vblank(rdev, i);
|
|
|
+ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
|
|
|
+ WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
|
|
|
+ if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
|
|
|
+ radeon_wait_for_vblank(rdev, i);
|
|
|
+ tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
|
|
|
+ WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* wait for the next frame */
|
|
|
+ frame_count = radeon_get_vblank_counter(rdev, i);
|
|
|
+ for (j = 0; j < rdev->usec_timeout; j++) {
|
|
|
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
|
|
|
+ break;
|
|
|
+ udelay(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- WREG32(D1VGA_CONTROL, 0);
|
|
|
- WREG32(D2VGA_CONTROL, 0);
|
|
|
- if (rdev->num_crtc >= 4) {
|
|
|
- WREG32(EVERGREEN_D3VGA_CONTROL, 0);
|
|
|
- WREG32(EVERGREEN_D4VGA_CONTROL, 0);
|
|
|
- }
|
|
|
- if (rdev->num_crtc >= 6) {
|
|
|
- WREG32(EVERGREEN_D5VGA_CONTROL, 0);
|
|
|
- WREG32(EVERGREEN_D6VGA_CONTROL, 0);
|
|
|
+ radeon_mc_wait_for_idle(rdev);
|
|
|
+
|
|
|
+ blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
|
|
|
+ if ((blackout & BLACKOUT_MODE_MASK) != 1) {
|
|
|
+ /* Block CPU access */
|
|
|
+ WREG32(BIF_FB_EN, 0);
|
|
|
+ /* blackout the MC */
|
|
|
+ blackout &= ~BLACKOUT_MODE_MASK;
|
|
|
+ WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
|
|
|
{
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC0_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC0_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
-
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
-
|
|
|
- if (rdev->num_crtc >= 4) {
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
-
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
- }
|
|
|
- if (rdev->num_crtc >= 6) {
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET,
|
|
|
- upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET,
|
|
|
- (u32)rdev->mc.vram_start);
|
|
|
+ u32 tmp, frame_count;
|
|
|
+ int i, j;
|
|
|
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
|
|
+ /* update crtc base addresses */
|
|
|
+ for (i = 0; i < rdev->num_crtc; i++) {
|
|
|
+ WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
|
|
|
upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
|
|
+ WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
|
|
|
upper_32_bits(rdev->mc.vram_start));
|
|
|
- WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
|
|
+ WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
|
|
|
(u32)rdev->mc.vram_start);
|
|
|
- WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET,
|
|
|
+ WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
|
|
|
(u32)rdev->mc.vram_start);
|
|
|
}
|
|
|
-
|
|
|
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
|
|
|
WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
|
|
|
- /* Unlock host access */
|
|
|
+
|
|
|
+ /* unblackout the MC */
|
|
|
+ tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
|
|
|
+ tmp &= ~BLACKOUT_MODE_MASK;
|
|
|
+ WREG32(MC_SHARED_BLACKOUT_CNTL, tmp);
|
|
|
+ /* allow CPU access */
|
|
|
+ WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
|
|
|
+
|
|
|
+ for (i = 0; i < rdev->num_crtc; i++) {
|
|
|
+ if (save->crtc_enabled) {
|
|
|
+ if (ASIC_IS_DCE6(rdev)) {
|
|
|
+ tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
|
|
|
+ tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
|
|
|
+ WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
|
|
|
+ } else {
|
|
|
+ tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
|
|
|
+ tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
|
|
|
+ WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
|
|
|
+ }
|
|
|
+ /* wait for the next frame */
|
|
|
+ frame_count = radeon_get_vblank_counter(rdev, i);
|
|
|
+ for (j = 0; j < rdev->usec_timeout; j++) {
|
|
|
+ if (radeon_get_vblank_counter(rdev, i) != frame_count)
|
|
|
+ break;
|
|
|
+ udelay(1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /* Unlock vga access */
|
|
|
WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
|
|
|
mdelay(1);
|
|
|
WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
|