<html>
    <head>
      <base href="https://bugs.freedesktop.org/" />
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - [bisected] kernel 3.7.0-rc1 breaks 6950 (CAYMAN)"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=56139#c4">Comment # 4</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - [bisected] kernel 3.7.0-rc1 breaks 6950 (CAYMAN)"
   href="https://bugs.freedesktop.org/show_bug.cgi?id=56139">bug 56139</a>
              from <span class="vcard"><a class="email" href="mailto:alexandre.f.demers@gmail.com" title="Alexandre Demers <alexandre.f.demers@gmail.com>"> <span class="fn">Alexandre Demers</span></a>
</span></b>
        <pre>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?</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>