[Bug,96789] Black screen with R9 290 and Apple Cinema Display 23"
diff mbox

Message ID bug-96789-502@http.bugs.freedesktop.org/
State New
Headers show

Commit Message

bugzilla-daemon@freedesktop.org July 2, 2016, 9:57 p.m. UTC
https://bugs.freedesktop.org/show_bug.cgi?id=96789

            Bug ID: 96789
           Summary: Black screen with R9 290 and Apple Cinema Display 23"
           Product: DRI
           Version: unspecified
          Hardware: x86-64 (AMD64)
                OS: Linux (All)
            Status: NEW
          Severity: normal
          Priority: medium
         Component: DRM/Radeon
          Assignee: dri-devel@lists.freedesktop.org
          Reporter: benh@kernel.crashing.org

With Radeon (any recent distro version including upstream 4.7-rc5), my Apple
Cinema Display 23" gives a black screen when radeon loads.

The monitor is a fairly old DVI LCD 1920x1200x60. It has a fixed timing, ie, no
scaler. It used to work with earlier versions of radeons but I haven't used it
on a Linux machine for a couple of hears at least.

It works using the agd5f's current amdgpu, but not upstream which doesn't
support the HAWAII. I isolated the difference that makes it work to the PPLL
setting. This one liner fixes it:

        *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max);

Here's a log of the working vs. non-working versions of the calculations in
radeon_compute_pll_avivo(). Note that when I did these, I also changed
radeon's max_feedback_div to match amdgpu's value of 0xfff instead of 0x7ff in
current radeon, though that didn't impact the results.

[    3.471131] fb_div_min/max=4/4095 pll_flags=400
[    3.471132] by 10 ! fb_div_min/max=40/40950
[    3.471133] ref_div_min=2 (from 0/2)
[    3.471133] ref_div_max=1023 (from 0/1023)
[    3.471134] vco_min/max=600000/1200000
[    3.471134] post_div_min/max=4/7
[    3.471135] initial nom=153970, den=2700
[    3.471136] reduced nom=15397, den=270
[    3.471136] - trying post_div 4, ref_div_max=32
[    3.471137]   tentative ref_div=32m, fb_div=7299
[    3.471137]   adjusted ref_div=32m, fb_div=7299
[    3.471138] diff=7, diff_best=-1
[    3.471138] - trying post_div 5, ref_div_max=25
[    3.471139]   tentative ref_div=25m, fb_div=7128
[    3.471139]   adjusted ref_div=25m, fb_div=7128
[    3.471139] diff=6, diff_best=7
[    3.471140] - trying post_div 6, ref_div_max=21
[    3.471140]   tentative ref_div=21m, fb_div=7185
[    3.471141]   adjusted ref_div=21m, fb_div=7185
[    3.471141] diff=6, diff_best=6
[    3.471141] - trying post_div 7, ref_div_max=18
[    3.471142]   tentative ref_div=18m, fb_div=7185
[    3.471142]   adjusted ref_div=18m, fb_div=7185
[    3.471150] diff=6, diff_best=6
[    3.471150] post_div_best=7
[    3.471151] - trying post_div 7, ref_div_max=18
[    3.471151]   tentative ref_div=18m, fb_div=7185
[    3.471152]   adjusted ref_div=18m, fb_div=7185
[    3.471153] [drm:amdgpu_pll_compute] 153970 - 153960, pll dividers - fb:
239.5 ref: 6, post 7

Now this is with radeon *NOTE: I have bumped the max fb div to the same as AMD
GPU when taking that trace but that had no effect:

[    4.718126] fb_div_min/max=4/4095 pll_flags=410
[    4.718126] by 10 ! fb_div_min/max=40/40950
[    4.718127] ref_div_min=2 (from 0/2)
[    4.718128] ref_div_max=1023 (from 0/1023)
[    4.718128] vco_min/max=600000/1200000
[    4.718129] post_div_min/max=4/7
[    4.718129] initial nom=153970, den=2700
[    4.718130] reduced nom=15397, den=270
[    4.718130] - trying post_div 4, ref_div_max=25
[    4.718131]   tentative ref_div=25m, fb_div=5703
[    4.718131]   adjusted ref_div=25m, fb_div=5703
[    4.718132] diff=11, diff_best=-1
[    4.718133] - trying post_div 5, ref_div_max=20
[    4.718133]   tentative ref_div=20m, fb_div=5703
[    4.718133]   adjusted ref_div=20m, fb_div=5703
[    4.718134] diff=11, diff_best=11
[    4.718134] - trying post_div 6, ref_div_max=16
[    4.718135]   tentative ref_div=16m, fb_div=5474
[    4.718135]   adjusted ref_div=16m, fb_div=5474
[    4.718136] diff=14, diff_best=11
[    4.718136] - trying post_div 7, ref_div_max=14
[    4.718136]   tentative ref_div=14m, fb_div=5589
[    4.718137]   adjusted ref_div=14m, fb_div=5589
[    4.718137] diff=12, diff_best=11
[    4.718138] post_div_best=5
[    4.718138] - trying post_div 5, ref_div_max=20
[    4.718139]   tentative ref_div=20m, fb_div=5703
[    4.718139]   adjusted ref_div=20m, fb_div=5703
[    4.718141] [drm:radeon_compute_pll_avivo] 153970 - 153980, pll dividers -
fb: 570.3 ref: 20, post 5

The modeline is:

Modeline 55:"1920x1200" 60 153970 1920 1968 2000 2080 1200 1203 1209 1235 0x48
0x9

And is consistent between the 2 drivers (different mode number but same
values).

Comments

bugzilla-daemon@freedesktop.org July 5, 2016, 9:08 a.m. UTC | #1
https://bugs.freedesktop.org/show_bug.cgi?id=96789

--- Comment #1 from Christian K├Ânig <deathsimple@vodafone.de> ---
Well that is a rather special case. The monitor needs a very precise timing to
work reliable and even with the higher ref/post dividers we don't hit it
completely correct.

Not sure what to do here, cause raising the limit will certainly break others
again.
bugzilla-daemon@freedesktop.org July 5, 2016, 9:29 a.m. UTC | #2
https://bugs.freedesktop.org/show_bug.cgi?id=96789

--- Comment #2 from Benjamin Herrenschmidt <benh@kernel.crashing.org> ---
Will it ? I mean, it works with every other driver under the sun ;-) Do you
have ways to know what AMD windows driver picks ? That could be a reasonable
choice for the Linux one...

Patch
diff mbox

--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -953,7 +953,7 @@  static void avivo_get_fb_ref_div(unsigned nom, unsigned
den, unsigned post_div,
                                 unsigned *fb_div, unsigned *ref_div)
 {
        /* limit reference * post divider to a maximum */
-       ref_div_max = max(min(100 / post_div, ref_div_max), 1u);
+       ref_div_max = max(min(128 / post_div, ref_div_max), 1u);

        /* get matching reference and feedback divider */