[Bug 56139] [bisected] kernel 3.7.0-rc1 breaks 6950 (CAYMAN)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Comment # 4 on bug 56139 from
First, I made a mistake last time I wrote: the evergreen_mc_resume() function
patch was fine. The bad code was in the evergreen_mc_stop() function. Sorry for
the wrong lead, I realized it today when I continued my tests.

Now, I split the evergreen_mc_stop() code in two parts. The following ran fine:
-    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);

and I was able to boot, stop, restart and suspend correctly.

However, when I applied:
void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save
*save)
 {
-    u32 blackout;
+    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);
+            }
+        }
     }

the bug appeared. So it seems blanking the display controllers with for(i = 0;
i < rdev->num_crtc; i++) is not equivalent to the code that it replaces. The
original code first wrote in the EVERGREEN_CRTC_UPDATE_LOCK registers, before
setting EVERGREEN_CRTC_CONTROL registers and writing again in the
EVERGREEN_CRTC_UPDATE_LOCK registers. On the other hand, the new code doesn't
write in the EVERGREEN_CRTC_UPDATE_LOCK neither before nor after setting
EVERGREEN_CRTC_CONTROL.

Could this be a clue?


You are receiving this mail because:
_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel

[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux