From mboxrd@z Thu Jan 1 00:00:00 1970 From: bugzilla-daemon@freedesktop.org Subject: [Bug 56139] [bisected] kernel 3.7.0-rc1 breaks 6950 (CAYMAN) Date: Fri, 26 Oct 2012 03:17:36 +0000 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1891648748==" Return-path: Received: from culpepper.freedesktop.org (unknown [131.252.210.165]) by gabe.freedesktop.org (Postfix) with ESMTP id 5FB3BA0AE8 for ; Thu, 25 Oct 2012 20:17:36 -0700 (PDT) In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org Errors-To: dri-devel-bounces+sf-dri-devel=m.gmane.org@lists.freedesktop.org To: dri-devel@lists.freedesktop.org List-Id: dri-devel@lists.freedesktop.org --===============1891648748== Content-Type: multipart/alternative; boundary="1351221456.aD6aBc0.26372"; charset="us-ascii" --1351221456.aD6aBc0.26372 Date: Fri, 26 Oct 2012 03:17:36 +0000 MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" https://bugs.freedesktop.org/show_bug.cgi?id=56139 --- Comment #4 from Alexandre Demers --- 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: You are the assignee for the bug. --1351221456.aD6aBc0.26372 Date: Fri, 26 Oct 2012 03:17:36 +0000 MIME-Version: 1.0 Content-Type: text/html; charset="UTF-8"

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:
  • You are the assignee for the bug.
--1351221456.aD6aBc0.26372-- --===============1891648748== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel --===============1891648748==--