aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Deucher2013-04-10 08:58:42 -0500
committerGreg Kroah-Hartman2013-05-11 15:54:05 -0500
commit609326a6060f71626cab7b4bc02b419e42c11f8d (patch)
treeb4c6f8561a9428874af7e3db9051e6f9765a02b2
parent415c4bfb8b5e2a6bdc98f1038d87d2f6393bb216 (diff)
downloadkernel-omap-609326a6060f71626cab7b4bc02b419e42c11f8d.tar.gz
kernel-omap-609326a6060f71626cab7b4bc02b419e42c11f8d.tar.xz
kernel-omap-609326a6060f71626cab7b4bc02b419e42c11f8d.zip
drm/radeon: properly lock disp in mc_stop/resume for evergreen+
commit 968c01664ccbe0e46c19a1af662c4c266a904203 upstream. Need to wait for the new addresses to take affect before re-enabling the MC. Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c47
-rw-r--r--drivers/gpu/drm/radeon/evergreen_reg.h2
2 files changed, 45 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 4157c33516af..82d855f9a013 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1354,18 +1354,14 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
1354 if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) { 1354 if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
1355 radeon_wait_for_vblank(rdev, i); 1355 radeon_wait_for_vblank(rdev, i);
1356 tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; 1356 tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
1357 WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
1358 WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); 1357 WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
1359 WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
1360 } 1358 }
1361 } else { 1359 } else {
1362 tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); 1360 tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
1363 if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) { 1361 if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
1364 radeon_wait_for_vblank(rdev, i); 1362 radeon_wait_for_vblank(rdev, i);
1365 tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; 1363 tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
1366 WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
1367 WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); 1364 WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
1368 WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
1369 } 1365 }
1370 } 1366 }
1371 /* wait for the next frame */ 1367 /* wait for the next frame */
@@ -1392,6 +1388,22 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
1392 } 1388 }
1393 /* wait for the MC to settle */ 1389 /* wait for the MC to settle */
1394 udelay(100); 1390 udelay(100);
1391
1392 /* lock double buffered regs */
1393 for (i = 0; i < rdev->num_crtc; i++) {
1394 if (save->crtc_enabled[i]) {
1395 tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
1396 if (!(tmp & EVERGREEN_GRPH_UPDATE_LOCK)) {
1397 tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
1398 WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
1399 }
1400 tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
1401 if (!(tmp & 1)) {
1402 tmp |= 1;
1403 WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
1404 }
1405 }
1406 }
1395} 1407}
1396 1408
1397void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) 1409void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1413,6 +1425,33 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s
1413 WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); 1425 WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
1414 WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); 1426 WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
1415 1427
1428 /* unlock regs and wait for update */
1429 for (i = 0; i < rdev->num_crtc; i++) {
1430 if (save->crtc_enabled[i]) {
1431 tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]);
1432 if ((tmp & 0x3) != 0) {
1433 tmp &= ~0x3;
1434 WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
1435 }
1436 tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
1437 if (tmp & EVERGREEN_GRPH_UPDATE_LOCK) {
1438 tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
1439 WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
1440 }
1441 tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
1442 if (tmp & 1) {
1443 tmp &= ~1;
1444 WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
1445 }
1446 for (j = 0; j < rdev->usec_timeout; j++) {
1447 tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
1448 if ((tmp & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) == 0)
1449 break;
1450 udelay(1);
1451 }
1452 }
1453 }
1454
1416 /* unblackout the MC */ 1455 /* unblackout the MC */
1417 tmp = RREG32(MC_SHARED_BLACKOUT_CNTL); 1456 tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
1418 tmp &= ~BLACKOUT_MODE_MASK; 1457 tmp &= ~BLACKOUT_MODE_MASK;
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h
index 034f4c22e5db..3e9773aea7fe 100644
--- a/drivers/gpu/drm/radeon/evergreen_reg.h
+++ b/drivers/gpu/drm/radeon/evergreen_reg.h
@@ -225,6 +225,8 @@
225#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 225#define EVERGREEN_CRTC_STATUS_POSITION 0x6e90
226#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8 226#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8
227#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 227#define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4
228#define EVERGREEN_MASTER_UPDATE_LOCK 0x6ef4
229#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8
228 230
229#define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 231#define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0
230#define EVERGREEN_DC_GPIO_HPD_A 0x64b4 232#define EVERGREEN_DC_GPIO_HPD_A 0x64b4