diff mbox

drm/radeon: Fix Asus M2A-VM HDMI EDID error flooding problem

Message ID 1309946963-6409-1-git-send-email-reimth@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Thomas Reim July 6, 2011, 10:09 a.m. UTC
From: Thomas Reim <rdratlos@yahoo.co.uk>

    Some integrated ATI Radeon chipset implementations
    with add-on HDMI card (e. g. Asus M2A-VM HDMI) indicate the availability
    of a DDC even when the add-on card is not plugged in or HDMI is disabled
    in BIOS setup. In this case, drm_get_edid() and drm_edid_block_valid()
    periodically dump data and kernel errors into system log files and onto
    terminals. For these chipsets DDC probing is extended by a check for a
    correct EDID header. Only in case a valid EDID header is also found, the
    (HDMI) connector will be used by the Radeon driver. This prevents the
    kernel driver from useless flooding of logs and terminal sessions with
    EDID dumps and error messages.
    This patch adds a flag 'requires_extended_probe' to the radeon_connector
    structure. In function radeon_connector_needs_extended_probe() this flag
    can be set on a chipset family/vendor/connector type specific basis.
    In addition, function drm_edid_header_is_valid() has been added for EDID
    header check and function radeon_ddc_probe() has been adapted to perform
    extended DDC probing if required by the connector's flag.

    Tested for kernel 2.35, 2.38 and 3.0 on Asus M2A-VM HDMI board

Signed-off-by: Thomas Reim <rdratlos@yahoo.co.uk>
---
 drivers/gpu/drm/drm_edid.c                 |   24 +++++++++++----
 drivers/gpu/drm/radeon/radeon_connectors.c |   45 ++++++++++++++++++++++++++--
 drivers/gpu/drm/radeon/radeon_device.c     |    7 ++++-
 drivers/gpu/drm/radeon/radeon_display.c    |    9 +++++
 drivers/gpu/drm/radeon/radeon_i2c.c        |   32 +++++++++++++++-----
 drivers/gpu/drm/radeon/radeon_mode.h       |    6 +++-
 include/drm/drm_crtc.h                     |    1 +
 7 files changed, 105 insertions(+), 19 deletions(-)

Comments

Thomas Reim July 6, 2011, 12:26 p.m. UTC | #1
Here are the kernel logs with and without the patch for better
visualisation of the changes:

1. dmesg after applying the patch:

[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.0-3-generic (root@Mark-Aurel) (gcc
version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ) #5 SMP Wed Jul 6 01:54:25
CEST 2011 (Ubuntu 3.0-3.5-generic 3.0.0-rc5)
...
[    6.980082] [drm] Initialized drm 1.1.0 20060810
[    8.353140] [drm] radeon defaulting to kernel modesetting.
[    8.353147] [drm] radeon kernel modesetting enabled.
[    8.423983] radeon 0000:01:05.0: PCI INT A -> GSI 18 (level, low) ->
IRQ 18
[    8.424296] [drm] initializing kernel modesetting (RS690
0x1002:0x791E 0x1043:0x826D).
[    8.424323] [drm] register mmio base: 0xFDCF0000
[    8.424326] [drm] register mmio size: 65536
[    8.424667] ATOM BIOS: ATI
[    8.424697] radeon 0000:01:05.0: VRAM: 128M 0x0000000038000000 -
0x000000003FFFFFFF (128M used)
[    8.424702] radeon 0000:01:05.0: GTT: 512M 0x0000000040000000 -
0x000000005FFFFFFF
[    8.424722] [drm] Supports vblank timestamp caching Rev 1
(10.10.2010).
[    8.424724] [drm] Driver supports precise vblank timestamp query.
[    8.424738] [drm] radeon: irq initialized.
[    8.424833] [drm] Detected VRAM RAM=128M, BAR=128M
[    8.424839] [drm] RAM width 128bits DDR
[    8.429082] [TTM] Zone  kernel: Available graphics memory: 412360
kiB.
[    8.429087] [TTM] Initializing pool allocator.
[    8.429119] [drm] radeon: 128M of VRAM memory ready
[    8.429121] [drm] radeon: 512M of GTT memory ready.
[    8.429149] [drm] GART: num cpu pages 131072, num gpu pages 131072
[    8.433650] [drm] radeon: 1 quad pipes, 1 z pipes initialized.
[    8.450393] radeon 0000:01:05.0: WB enabled
[    8.452791] [drm] Loading RS690/RS740 Microcode
[    9.139696] [drm] radeon: ring at 0x0000000040001000
[    9.139718] [drm] ring test succeeded in 1 usecs
[    9.139884] [drm] radeon: ib pool ready.
[    9.139978] [drm] ib test succeeded in 0 usecs
[    9.140324] [drm] Radeon Display Connectors
[    9.140327] [drm] Connector 0:
[    9.140329] [drm]   VGA
[    9.140332] [drm]   DDC: 0x7e50 0x7e40 0x7e54 0x7e44 0x7e58 0x7e48
0x7e5c 0x7e4c
[    9.140334] [drm]   Encoders:
[    9.140336] [drm]     CRT1: INTERNAL_KLDSCP_DAC1
[    9.140338] [drm] Connector 1:
[    9.140340] [drm]   S-video
[    9.140341] [drm]   Encoders:
[    9.140343] [drm]     TV1: INTERNAL_KLDSCP_DAC1
[    9.140344] [drm] Connector 2:
[    9.140346] [drm]   HDMI-A
[    9.140347] [drm]   HPD2
[    9.140350] [drm]   DDC: 0x7e40 0x7e60 0x7e44 0x7e64 0x7e48 0x7e68
0x7e4c 0x7e6c
[    9.140352] [drm]   Encoders:
[    9.140354] [drm]     DFP2: INTERNAL_DDI
[    9.140356] [drm] Connector 3:
[    9.140357] [drm]   DVI-D
[    9.140360] [drm]   DDC: 0x7e40 0x7e50 0x7e44 0x7e54 0x7e48 0x7e58
0x7e4c 0x7e5c
[    9.140362] [drm]   Encoders:
[    9.140364] [drm]     DFP3: INTERNAL_LVTM1
[    9.200505] [drm] Radeon display connector VGA-1: No monitor
connected or invalid EDID
[    9.536899] Raw EDID:
[    9.536907] <3>00 00 00 00 00 01 00 00 00 00 00 00 00 00 00
00  ................
[    9.536911] <3>00 00 00 00 3f 00 00 00 00 00 00 00 00 00 00
00  ....?...........
[    9.536914] <3>00 00 03 00 00 00 00 00 00 00 00 00 00 7f 00
00  ................
[    9.536917] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[    9.536920] <3>00 00 00 00 00 00 00 3f 00 00 00 00 00 00 00
00  .......?........
[    9.536922] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[    9.536925] <3>ff 00 00 00 00 00 00 00 00 00 00 00 00 0f 1f
00  ................
[    9.536928] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[    9.536930] 
[    9.865805] Raw EDID:
[    9.865813] <3>00 00 00 00 01 00 00 00 00 00 00 00 00 00 ff
00  ................
[    9.865816] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 1f 00
00  ................
[    9.865819] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[    9.865822] <3>00 00 00 00 00 00 00 07 00 00 00 00 00 00 00
00  ................
[    9.865825] <3>00 00 03 00 00 00 00 00 00 00 ff 00 00 00 00
00  ................
[    9.865828] <3>00 03 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[    9.865831] <3>00 00 1f 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[    9.865833] <3>00 00 00 00 00 00 00 00 00 00 07 00 00 00 00
00  ................
[    9.865836] 
[   10.211426] Raw EDID:
[   10.211436] <3>00 00 00 00 00 00 00 03 00 00 00 ff 00 00 00
00  ................
[   10.211439] <3>00 00 00 00 00 00 00 03 00 00 00 00 00 00 00
00  ................
[   10.211442] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   10.211445] <3>7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   10.211448] <3>00 00 00 00 00 00 3f 00 00 00 00 ff 00 00 00
00  ......?.........
[   10.211451] <3>00 00 00 00 00 00 00 00 00 00 00 00 3f 00 00
00  ............?...
[   10.211454] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   10.211457] <3>00 3f 00 00 00 00 00 00 00 00 00 00 00 00 ff
00  .?..............
[   10.211459] 
[   10.407265] Raw EDID:
[   10.407274] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   10.407277] <3>00 00 00 ff 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   10.407280] <3>00 00 00 ff 00 7f 00 00 00 00 00 00 00 00 00
00  ................
[   10.407283] <3>00 00 00 00 00 00 ff 00 00 00 00 00 00 00 00
00  ................
[   10.407286] <3>00 00 00 00 00 00 00 00 00 00 00 7f 00 00 00
00  ................
[   10.407289] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   10.407309] <3>00 0f 00 00 00 00 00 00 00 00 01 00 00 00 00
00  ................
[   10.407312] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 3f 00
00  .............?..
[   10.407314] 
[   10.407320] radeon 0000:01:05.0: HDMI-A-1: EDID block 0 invalid.
[   10.407324] [drm] Radeon display connector HDMI-A-1: No monitor
connected or invalid EDID
[   10.601868] [drm] Radeon display connector DVI-D-1: Found valid EDID
[   11.200051] [drm] fb mappable at 0xF0040000
[   11.200056] [drm] vram apper at 0xF0000000
[   11.200059] [drm] size 5242880
[   11.200061] [drm] fb depth is 24
[   11.200062] [drm]    pitch is 5120
[   11.201974] drm: registered panic notifier
[   11.202110] [drm] Initialized radeon 2.10.0 20080528 for 0000:01:05.0
on minor 0

> From: Thomas Reim <rdratlos@yahoo.co.uk>
> 
>     Some integrated ATI Radeon chipset implementations
>     with add-on HDMI card (e. g. Asus M2A-VM HDMI) indicate the availability
>     of a DDC even when the add-on card is not plugged in or HDMI is disabled
>     in BIOS setup. In this case, drm_get_edid() and drm_edid_block_valid()
>     periodically dump data and kernel errors into system log files and onto
>     terminals. For these chipsets DDC probing is extended by a check for a
>     correct EDID header. Only in case a valid EDID header is also found, the
>     (HDMI) connector will be used by the Radeon driver. This prevents the
>     kernel driver from useless flooding of logs and terminal sessions with
>     EDID dumps and error messages.
>     This patch adds a flag 'requires_extended_probe' to the radeon_connector
>     structure. In function radeon_connector_needs_extended_probe() this flag
>     can be set on a chipset family/vendor/connector type specific basis.
>     In addition, function drm_edid_header_is_valid() has been added for EDID
>     header check and function radeon_ddc_probe() has been adapted to perform
>     extended DDC probing if required by the connector's flag.
> 
>     Tested for kernel 2.35, 2.38 and 3.0 on Asus M2A-VM HDMI board
> 
> Signed-off-by: Thomas Reim <rdratlos@yahoo.co.uk>


2. dmesg without patch:

[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Linux version 3.0.0-rc3-radeonfix (root@Mark-Aurel) (gcc
version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5) ) #1 SMP Tue Jun 21
10:29:44 CEST 2011
[    0.000000] Command line:
BOOT_IMAGE=/boot/vmlinuz-3.0.0-rc3-radeonfix
root=UUID=0cc18590-dcbb-43ba-867a-0a3b3b6a9b56 ro quiet splash
vt.handoff=7
.
.
.
[   13.590728] [drm] Initialized drm 1.1.0 20060810
[   14.923157] [drm] radeon defaulting to kernel modesetting.
[   14.923163] [drm] radeon kernel modesetting enabled.
[   14.931891] radeon 0000:01:05.0: PCI INT A -> GSI 18 (level, low) ->
IRQ 18
[   14.932445] [drm] initializing kernel modesetting (RS690
0x1002:0x791E).
[   14.932475] [drm] register mmio base: 0xFDCF0000
[   14.932478] [drm] register mmio size: 65536
[   14.932817] ATOM BIOS: ATI
[   14.932845] radeon 0000:01:05.0: VRAM: 128M 0x0000000038000000 -
0x000000003FFFFFFF (128M used)
[   14.932849] radeon 0000:01:05.0: GTT: 512M 0x0000000040000000 -
0x000000005FFFFFFF
[   14.932884] [drm] Supports vblank timestamp caching Rev 1
(10.10.2010).
[   14.932887] [drm] Driver supports precise vblank timestamp query.
[   14.932902] [drm] radeon: irq initialized.
[   14.932994] [drm] Detected VRAM RAM=128M, BAR=128M
[   14.932998] [drm] RAM width 128bits DDR
[   14.933165] [TTM] Zone  kernel: Available graphics memory: 445354
kiB.
[   14.933168] [TTM] Initializing pool allocator.
[   14.933200] [drm] radeon: 128M of VRAM memory ready
[   14.933203] [drm] radeon: 512M of GTT memory ready.
[   14.933284] [drm] GART: num cpu pages 131072, num gpu pages 131072
[   14.938106] [drm] radeon: 1 quad pipes, 1 z pipes initialized.
[   14.981418] radeon 0000:01:05.0: WB enabled
[   14.982168] [drm] Loading RS690/RS740 Microcode
[   15.030767] [drm] radeon: ring at 0x0000000040001000
[   15.030789] [drm] ring test succeeded in 1 usecs
[   15.030950] [drm] radeon: ib pool ready.
[   15.031038] [drm] ib test succeeded in 0 usecs
[   15.031047] failed to evaluate ATIF got AE_BAD_PARAMETER
[   15.031332] [drm] Radeon Display Connectors
[   15.031335] [drm] Connector 0:
[   15.031337] [drm]   VGA
[   15.031340] [drm]   DDC: 0x7e50 0x7e40 0x7e54 0x7e44 0x7e58 0x7e48
0x7e5c 0x7e4c
[   15.031342] [drm]   Encoders:
[   15.031344] [drm]     CRT1: INTERNAL_KLDSCP_DAC1
[   15.031346] [drm] Connector 1:
[   15.031348] [drm]   S-video
[   15.031349] [drm]   Encoders:
[   15.031351] [drm]     TV1: INTERNAL_KLDSCP_DAC1
[   15.031353] [drm] Connector 2:
[   15.031355] [drm]   HDMI-A
[   15.031356] [drm]   HPD2
[   15.031359] [drm]   DDC: 0x7e40 0x7e60 0x7e44 0x7e64 0x7e48 0x7e68
0x7e4c 0x7e6c
[   15.031361] [drm]   Encoders:
[   15.031363] [drm]     DFP2: INTERNAL_DDI
[   15.031365] [drm] Connector 3:
[   15.031367] [drm]   DVI-D
[   15.031369] [drm]   DDC: 0x7e40 0x7e50 0x7e44 0x7e54 0x7e48 0x7e58
0x7e4c 0x7e5c
[   15.031371] [drm]   Encoders:
[   15.031373] [drm]     DFP3: INTERNAL_LVTM1
[   15.461821] Raw EDID:
[   15.461865] <3>00 00 00 00 00 00 00 00 00 00 00 00 07 00 00
00  ................
[   15.461869] <3>00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
00  ................
[   15.461872] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f  ...............?
[   15.461875] <3>0f 1f 3f 1f 3f 7f 00 00 00 00 00 00 00 00 00
00  ..?.?...........
[   15.461877] <3>00 00 00 00 00 00 00 ff 00 00 00 00 00 00 00
00  ................
[   15.461880] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f  ...............?
[   15.461883] <3>03 1f 00 00 00 00 00 00 00 00 3f 00 00 00 0f
00  ..........?.....
[   15.461886] <3>00 00 00 00 00 00 00 00 00 00 0f 07 00 3f 00
00  .............?..
[   15.461888] 
[   15.822495] Raw EDID:
[   15.822539] <3>00 03 00 00 00 00 00 00 00 3f 00 00 00 00 00
00  .........?......
[   15.822542] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   15.822545] <3>00 0f 00 00 00 00 00 00 00 00 00 00 00 3f 00
00  .............?..
[   15.822548] <3>0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   15.822551] <3>00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
00  ................
[   15.822553] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 07
00  ................
[   15.822556] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   15.822559] <3>00 00 00 00 00 00 00 00 7f 00 ff 00 00 00 00
00  ................
[   15.822561] 
[   15.861945] EXT4-fs (sda3): re-mounted. Opts: errors=remount-ro
[   16.193649] Raw EDID:
[   16.193692] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   16.193696] <3>00 00 00 00 1f 00 00 00 00 00 03 00 00 00 00
00  ................
[   16.193699] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   16.193702] <3>00 00 00 00 00 ff 00 00 00 00 00 00 00 00 00
00  ................
[   16.193705] <3>00 00 00 00 00 00 00 00 00 00 00 7f 00 00 00
00  ................
[   16.193707] <3>00 00 00 7f 00 00 00 3f 00 00 00 00 00 07 3f
00  .......?......?.
[   16.193710] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   16.193713] <3>00 03 00 00 07 1f 00 00 00 00 00 00 00 00 00
00  ................
[   16.193715] 
[   16.499673] Raw EDID:
[   16.499717] <3>00 07 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   16.499720] <3>00 00 00 00 00 00 00 00 01 00 00 00 00 00 00
00  ................
[   16.499723] <3>00 00 00 00 00 00 00 00 00 00 00 00 03 00 00
00  ................
[   16.499726] <3>00 00 00 00 03 00 00 07 00 00 00 00 00 00 00
00  ................
[   16.499729] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   16.499732] <3>00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   16.499734] <3>00 00 00 00 00 00 00 00 00 00 00 3f 00 00 01
00  ...........?....
[   16.499737] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   16.499739] 
[   16.499778] radeon 0000:01:05.0: HDMI-A-1: EDID block 0 invalid.
[   17.585964] Raw EDID:
[   17.586008] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 7f
00  ................
[   17.586012] <3>00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00
00  ................
[   17.586015] <3>00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   17.586017] <3>00 00 00 00 00 00 00 00 00 00 00 3f 00 00 00
00  ...........?....
[   17.586020] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
00  ................
[   17.586023] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   17.586026] <3>00 00 00 00 00 00 00 00 00 7f 00 00 00 00 00
00  ................
[   17.586028] <3>00 00 00 00 00 3f 00 00 00 00 00 00 00 00 00
00  .....?..........
[   17.586030] 
[   17.886217] Raw EDID:
[   17.886260] <3>00 00 00 00 00 00 00 7f 00 00 00 00 00 00 00
00  ................
[   17.886263] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   17.886266] <3>00 0f 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   17.886269] <3>00 00 00 00 00 00 00 00 00 00 00 01 00 00 00
00  ................
[   17.886271] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   17.886274] <3>00 00 00 00 00 0f 00 00 00 00 00 00 00 00 00
00  ................
[   17.886277] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01  ................
[   17.886279] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   17.886282] 
[   18.203072] Raw EDID:
[   18.203117] <3>00 00 00 00 00 00 0f 00 00 00 00 00 00 00 00
00  ................
[   18.203120] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.203123] <3>01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.203126] <3>00 00 00 00 00 00 00 00 00 00 00 7f 00 00 00
00  ................
[   18.203129] <3>00 00 00 0f 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.203131] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
00  ................
[   18.203134] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.203137] <3>00 00 00 00 00 00 00 00 7f 00 00 00 00 00 00
00  ................
[   18.203139] 
[   18.493769] Raw EDID:
[   18.493812] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 01
00  ................
[   18.493815] <3>00 00 00 00 00 00 00 00 00 00 00 00 1f 00 00
00  ................
[   18.493818] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.493821] <3>00 00 00 00 00 00 03 00 00 00 00 00 00 00 00
00  ................
[   18.493823] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.493826] <3>00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.493829] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   18.493832] <3>00 00 00 00 00 00 3f 00 00 00 00 00 00 00 00
00  ......?.........
[   18.493834] 
[   18.493872] radeon 0000:01:05.0: HDMI-A-1: EDID block 0 invalid.
[   18.493877] [drm:radeon_dvi_detect] *ERROR* HDMI-A-1: probed a
monitor but no|invalid EDID
[   18.900024] [drm] fb mappable at 0xF0040000
[   18.900029] [drm] vram apper at 0xF0000000
[   18.900031] [drm] size 5242880
[   18.900033] [drm] fb depth is 24
[   18.900034] [drm]    pitch is 5120
[   18.982054] drm: registered panic notifier
[   19.040041] [drm] Initialized radeon 2.10.0 20080528 for 0000:01:05.0
on minor 0
.
.
.
[   20.064119] Raw EDID:
[   20.064168] <3>00 00 00 00 00 00 00 00 00 00 07 00 00 00 00
00  ................
[   20.064171] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1f  ................
[   20.064174] <3>00 00 00 00 00 00 00 1f 00 00 00 00 00 00 00
00  ................
[   20.064177] <3>00 00 00 00 00 00 3f 00 00 00 00 00 00 00 00
00  ......?.........
[   20.064180] <3>00 00 00 00 03 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.064182] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 1f 00
00  ................
[   20.064185] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.064188] <3>00 00 00 00 00 07 00 00 00 00 00 00 00 00 00
00  ................
[   20.064190] 
[   20.257421] Raw EDID:
[   20.257471] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.257474] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.257477] <3>00 00 7f 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.257479] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.257482] <3>07 00 00 00 00 00 00 00 00 00 00 07 00 00 00
00  ................
[   20.257485] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.257487] <3>00 00 00 00 00 01 00 00 00 00 00 00 03 00 00
00  ................
[   20.257490] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.257492] 
[   20.465811] Raw EDID:
[   20.465860] <3>00 00 00 3f 00 00 00 00 00 00 00 07 00 00 00
00  ...?............
[   20.465863] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.465866] <3>00 00 7f 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.465869] <3>00 00 00 00 00 00 00 00 00 00 00 00 1f 00 00
00  ................
[   20.465872] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.465874] <3>00 00 00 00 00 00 07 00 00 00 00 00 00 00 00
00  ................
[   20.465877] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.465880] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.465882] 
[   20.665976] Raw EDID:
[   20.666026] <3>00 00 00 00 00 00 00 0f 00 00 00 00 00 00 00
00  ................
[   20.666029] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.666032] <3>00 07 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.666034] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.666037] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.666040] <3>00 00 00 00 00 00 3f 00 00 00 00 00 00 00 00
00  ......?.........
[   20.666043] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.666045] <3>0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.666047] 
[   20.666076] radeon 0000:01:05.0: HDMI-A-1: EDID block 0 invalid.
[   20.666081] [drm:radeon_dvi_detect] *ERROR* HDMI-A-1: probed a
monitor but no|invalid EDID
[   20.900353] Raw EDID:
[   20.900399] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.900402] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.900405] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.900408] <3>07 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.900411] <3>00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
00  ................
[   20.900413] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   20.900416] <3>00 00 00 00 00 7f 00 00 00 00 00 00 00 00 00
00  ................
[   20.900419] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1f  ................
[   20.900421] 
[   21.102164] Raw EDID:
[   21.102209] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.102212] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f
00  ................
[   21.102215] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.102217] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.102220] <3>00 00 00 00 00 00 7f 00 00 00 00 00 00 00 00
00  ................
[   21.102223] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.102226] <3>1f 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.102228] <3>00 00 00 00 00 00 00 00 00 00 07 00 00 00 00
00  ................
[   21.102230] 
[   21.303189] Raw EDID:
[   21.303234] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.303237] <3>00 7f 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.303240] <3>00 00 00 00 00 00 00 00 00 00 00 1f 00 00 00
00  ................
[   21.303243] <3>00 00 00 00 00 0f 00 00 00 00 00 00 00 00 00
00  ................
[   21.303245] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
03  ................
[   21.303248] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.303251] <3>00 00 00 00 00 00 00 00 00 00 ff 00 00 00 00
00  ................
[   21.303254] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.303256] 
[   21.488194] Raw EDID:
[   21.488248] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f
00  ................
[   21.488251] <3>00 00 00 07 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.488254] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.488256] <3>00 00 00 00 00 00 3f 00 00 00 00 00 00 00 00
00  ......?.........
[   21.488259] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.488262] <3>0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.488265] <3>00 00 00 00 00 00 00 00 00 00 03 00 00 00 00
00  ................
[   21.488267] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   21.488269] 
[   21.488300] radeon 0000:01:05.0: HDMI-A-1: EDID block 0 invalid.
[   21.488305] [drm:radeon_dvi_detect] *ERROR* HDMI-A-1: probed a
monitor but no|invalid EDID
[   21.625439] r8169 0000:03:05.0: eth1: link up
[   23.012406] Raw EDID:
[   23.012414] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
00  ................
[   23.012417] <3>00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
00  ................
[   23.012420] <3>00 00 00 00 00 00 00 00 00 01 00 00 00 00 00
00  ................
[   23.012423] <3>00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
00  ................
[   23.012426] <3>00 00 00 00 00 1f 00 00 00 00 00 00 00 00 00
00  ................
[   23.012428] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
03  ................
[   23.012431] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.012434] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.012436] 
[   23.165127] Raw EDID:
[   23.165135] <3>00 00 00 00 7f 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.165138] <3>00 00 0f 00 00 00 00 00 00 00 00 00 00 00 1f
00  ................
[   23.165141] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.165144] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.165147] <3>00 00 00 00 00 00 00 7f 00 00 00 00 00 00 00
00  ................
[   23.165149] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.165152] <3>00 1f 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.165155] <3>00 00 03 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.165157] 
[   23.315132] Raw EDID:
[   23.315139] <3>00 00 00 00 00 00 00 00 00 0f 00 00 00 00 00
00  ................
[   23.315142] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.315145] <3>00 00 7f 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.315148] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.315151] <3>07 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.315153] <3>00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
00  ................
[   23.315156] <3>00 00 00 00 00 00 00 00 01 00 00 00 00 00 00
00  ................
[   23.315159] <3>00 00 03 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.315161] 
[   23.477121] Raw EDID:
[   23.477129] <3>00 00 00 00 00 00 00 00 00 0f 00 00 00 00 00
00  ................
[   23.477132] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.477135] <3>00 00 00 00 00 ff 00 00 00 00 00 00 00 00 00
00  ................
[   23.477138] <3>00 00 00 00 00 00 00 00 00 3f 00 00 00 00 00
00  .........?......
[   23.477140] <3>00 00 00 0f 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.477143] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 01 00
00  ................
[   23.477146] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 7f
00  ................
[   23.477149] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.477151] 
[   23.477156] radeon 0000:01:05.0: HDMI-A-1: EDID block 0 invalid.
[   23.477161] [drm:radeon_dvi_detect] *ERROR* HDMI-A-1: probed a
monitor but no|invalid EDID
[   23.650366] Raw EDID:
[   23.650374] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.650377] <3>00 00 3f 00 00 00 00 00 00 00 00 00 0f 00 00
00  ..?.............
[   23.650380] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.650383] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01  ................
[   23.650385] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.650388] <3>00 00 00 00 00 ff 00 00 00 00 00 00 00 00 00
00  ................
[   23.650391] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.650394] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
3f  ...............?
[   23.650396] 
[   23.792015] Raw EDID:
[   23.792022] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.792025] <3>00 00 00 00 00 00 ff 00 00 00 00 00 00 00 00
00  ................
[   23.792028] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.792031] <3>00 00 00 00 00 00 00 00 00 3f 00 00 00 00 00
00  .........?......
[   23.792034] <3>00 00 00 00 00 00 1f 00 00 00 00 00 00 00 00
00  ................
[   23.792036] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.792039] <3>00 1f 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.792042] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.792044] 
[   23.930039] Raw EDID:
[   23.930047] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.930050] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.930053] <3>00 00 3f 00 03 00 00 00 00 00 00 00 00 00 00
00  ..?.............
[   23.930056] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.930058] <3>00 00 00 1f 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.930061] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.930064] <3>00 00 00 00 00 01 00 00 00 00 00 00 00 00 00
00  ................
[   23.930066] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   23.930069] 
[   24.108740] Raw EDID:
[   24.108748] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   24.108752] <3>00 00 00 00 00 00 00 ff 00 00 00 00 00 00 00
00  ................
[   24.108754] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   24.108757] <3>00 1f 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   24.108760] <3>00 00 00 00 00 00 00 00 00 00 00 03 00 00 00
00  ................
[   24.108763] <3>00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00  ................
[   24.108765] <3>00 00 00 00 00 00 1f 00 00 00 00 00 00 00 ff
00  ................
[   24.108768] <3>00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
00  ................
[   24.108770] 
[   24.108775] radeon 0000:01:05.0: HDMI-A-1: EDID block 0 invalid.
[   24.108780] [drm:radeon_dvi_detect] *ERROR* HDMI-A-1: probed a
monitor but no|invalid EDID
...

Best regards

Thomas
Alex Deucher July 6, 2011, 3:39 p.m. UTC | #2
On Wed, Jul 6, 2011 at 6:09 AM,  <reimth@googlemail.com> wrote:
> From: Thomas Reim <rdratlos@yahoo.co.uk>
>
>    Some integrated ATI Radeon chipset implementations
>    with add-on HDMI card (e. g. Asus M2A-VM HDMI) indicate the availability
>    of a DDC even when the add-on card is not plugged in or HDMI is disabled
>    in BIOS setup. In this case, drm_get_edid() and drm_edid_block_valid()
>    periodically dump data and kernel errors into system log files and onto
>    terminals. For these chipsets DDC probing is extended by a check for a
>    correct EDID header. Only in case a valid EDID header is also found, the
>    (HDMI) connector will be used by the Radeon driver. This prevents the
>    kernel driver from useless flooding of logs and terminal sessions with
>    EDID dumps and error messages.
>    This patch adds a flag 'requires_extended_probe' to the radeon_connector
>    structure. In function radeon_connector_needs_extended_probe() this flag
>    can be set on a chipset family/vendor/connector type specific basis.
>    In addition, function drm_edid_header_is_valid() has been added for EDID
>    header check and function radeon_ddc_probe() has been adapted to perform
>    extended DDC probing if required by the connector's flag.
>
>    Tested for kernel 2.35, 2.38 and 3.0 on Asus M2A-VM HDMI board
>

Once it's ready, just add:
Cc: stable@kernel.org
to the commit message and it will go into the stable kernels as well.
Might want to mention the bug report in your commit message as well.
Just a couple comments below.  With those fixed:

Reviewed-by: Alex Deucher <alexdeucher@gmail.com>

> Signed-off-by: Thomas Reim <rdratlos@yahoo.co.uk>
> ---
>  drivers/gpu/drm/drm_edid.c                 |   24 +++++++++++----
>  drivers/gpu/drm/radeon/radeon_connectors.c |   45 ++++++++++++++++++++++++++--
>  drivers/gpu/drm/radeon/radeon_device.c     |    7 ++++-
>  drivers/gpu/drm/radeon/radeon_display.c    |    9 +++++
>  drivers/gpu/drm/radeon/radeon_i2c.c        |   32 +++++++++++++++-----
>  drivers/gpu/drm/radeon/radeon_mode.h       |    6 +++-
>  include/drm/drm_crtc.h                     |    1 +
>  7 files changed, 105 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index 0929219..1bbb85b 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -127,6 +127,23 @@ static const u8 edid_header[] = {
>        0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
>  };
>
> + /*
> + * Sanity check the header of the base EDID block.  Return 8 if the header
> + * is perfect, down to 0 if it's totally wrong.
> + */
> +int drm_edid_header_is_valid(const u8 *raw_edid)
> +{
> +       int i, score = 0;
> +
> +       for (i = 0; i < sizeof(edid_header); i++)
> +               if (raw_edid[i] == edid_header[i])
> +                       score++;
> +
> +       return score;
> +}
> +EXPORT_SYMBOL(drm_edid_header_is_valid);
> +
> +
>  /*
>  * Sanity check the EDID block (base or extension).  Return 0 if the block
>  * doesn't check out, or 1 if it's valid.
> @@ -139,12 +156,7 @@ drm_edid_block_valid(u8 *raw_edid)
>        struct edid *edid = (struct edid *)raw_edid;
>
>        if (raw_edid[0] == 0x00) {
> -               int score = 0;
> -
> -               for (i = 0; i < sizeof(edid_header); i++)
> -                       if (raw_edid[i] == edid_header[i])
> -                               score++;
> -
> +               int score = drm_edid_header_is_valid(raw_edid);
>                if (score == 8) ;
>                else if (score >= 6) {
>                        DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");

Might want to break this hunk out as a separate patch.

> diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
> index cbfca3a..2e70be2 100644
> --- a/drivers/gpu/drm/radeon/radeon_connectors.c
> +++ b/drivers/gpu/drm/radeon/radeon_connectors.c
> @@ -424,6 +424,36 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
>        return 0;
>  }
>
> +/*
> + * Some integrated ATI Radeon chipset implementations (e. g.
> + * Asus M2A-VM HDMI) may indicate the availability of a DDC,
> + * even when there's no monitor connected. For these connectors
> + * following DDC probe extension will be applied: check also for the
> + * availability of EDID with at least a correct EDID header. Only then,
> + * DDC is assumed to be available. This prevents drm_get_edid() and
> + * drm_edid_block_valid() from periodically dumping data and kernel
> + * errors into the logs and onto the terminal.
> + */
> +static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,
> +                                    uint32_t supported_device,
> +                                    int connector_type)
> +{
> +       /* Asus M2A-VM HDMI board sends data to i2c bus even,
> +        * if HDMI add-on card is not plugged in or HDMI is disabled in
> +        * BIOS. Valid DDC can only be assumed, if also a valid EDID header
> +        * can be retrieved via i2c bus during DDC probe */
> +       if ((dev->pdev->device == 0x791e) &&
> +           (dev->pdev->subsystem_vendor == 0x1043) &&
> +           (dev->pdev->subsystem_device == 0x826d)) {
> +               if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
> +                   (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
> +                       return true;
> +       }
> +
> +       /* Default: no EDID header probe required for DDC probing */
> +       return false;
> +}
> +
>  static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
>                                          struct drm_connector *connector)
>  {
> @@ -655,7 +685,8 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
>                ret = connector_status_disconnected;
>
>        if (radeon_connector->ddc_bus)
> -               dret = radeon_ddc_probe(radeon_connector);
> +               dret = radeon_ddc_probe(radeon_connector,
> +                                       radeon_connector->requires_extended_probe);
>        if (dret) {
>                if (radeon_connector->edid) {
>                        kfree(radeon_connector->edid);
> @@ -827,7 +858,8 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
>        bool dret = false;
>
>        if (radeon_connector->ddc_bus)
> -               dret = radeon_ddc_probe(radeon_connector);
> +               dret = radeon_ddc_probe(radeon_connector,
> +                                       radeon_connector->requires_extended_probe);
>        if (dret) {
>                if (radeon_connector->edid) {
>                        kfree(radeon_connector->edid);
> @@ -1245,7 +1277,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
>                                if (radeon_dp_getdpcd(radeon_connector))
>                                        ret = connector_status_connected;
>                        } else {
> -                               if (radeon_ddc_probe(radeon_connector))
> +                               if (radeon_ddc_probe(radeon_connector,
> +                                                    radeon_connector->requires_extended_probe))
>                                        ret = connector_status_connected;
>                        }
>                }
> @@ -1400,6 +1433,9 @@ radeon_add_atom_connector(struct drm_device *dev,
>        radeon_connector->shared_ddc = shared_ddc;
>        radeon_connector->connector_object_id = connector_object_id;
>        radeon_connector->hpd = *hpd;
> +       radeon_connector->requires_extended_probe =
> +               radeon_connector_needs_extended_probe(rdev, supported_device,
> +                                                       connector_type);
>        radeon_connector->router = *router;
>        if (router->ddc_valid || router->cd_valid) {
>                radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info);
> @@ -1746,6 +1782,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
>        radeon_connector->devices = supported_device;
>        radeon_connector->connector_object_id = connector_object_id;
>        radeon_connector->hpd = *hpd;
> +       radeon_connector->requires_extended_probe =
> +               radeon_connector_needs_extended_probe(rdev, supported_device,
> +                                                       connector_type);
>        switch (connector_type) {
>        case DRM_MODE_CONNECTOR_VGA:
>                drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
> diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
> index 7cfaa7e..cbdac3d 100644
> --- a/drivers/gpu/drm/radeon/radeon_device.c
> +++ b/drivers/gpu/drm/radeon/radeon_device.c
> @@ -704,8 +704,13 @@ int radeon_device_init(struct radeon_device *rdev,
>        rdev->gpu_lockup = false;
>        rdev->accel_working = false;
>
> -       DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
> +       if (pdev->subsystem_vendor == 0)
> +               DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
>                radeon_family_name[rdev->family], pdev->vendor, pdev->device);
> +       else
> +               DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n",
> +               radeon_family_name[rdev->family], pdev->vendor, pdev->device,
> +               pdev->subsystem_vendor, pdev->subsystem_device);
>

No need for the if block.  Just always print both the pci and
subsystem ids.  Also, I'd suggest making that a separate patch as it's
not related to the actual fix.


>        /* mutex initialization are all done here so we
>         * can recall function without having locking issues */
> diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
> index 292f73f..ed085ce 100644
> --- a/drivers/gpu/drm/radeon/radeon_display.c
> +++ b/drivers/gpu/drm/radeon/radeon_display.c
> @@ -777,8 +777,17 @@ static int radeon_ddc_dump(struct drm_connector *connector)
>        if (!radeon_connector->ddc_bus)
>                return -1;
>        edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
> +       /* Log EDID retrieval status here. In particular with regard to
> +        * connectors with requires_extended_probe flag set, that will prevent
> +        * function radeon_dvi_detect() to fetch EDID on this connector,
> +        * as long as there is no valid EDID header found */
>        if (edid) {
> +               DRM_INFO("Radeon display connector %s: Found valid EDID",
> +                               drm_get_connector_name(connector));
>                kfree(edid);
> +       } else {
> +               DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID",
> +                               drm_get_connector_name(connector));
>        }
>        return ret;
>  }
> diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
> index 781196d..6c111c1 100644
> --- a/drivers/gpu/drm/radeon/radeon_i2c.c
> +++ b/drivers/gpu/drm/radeon/radeon_i2c.c
> @@ -32,17 +32,17 @@
>  * radeon_ddc_probe
>  *
>  */
> -bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
> +bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe)
>  {
> -       u8 out_buf[] = { 0x0, 0x0};
> -       u8 buf[2];
> +       u8 out = 0x0;
> +       u8 buf[8];
>        int ret;
>        struct i2c_msg msgs[] = {
>                {
>                        .addr = 0x50,
>                        .flags = 0,
>                        .len = 1,
> -                       .buf = out_buf,
> +                       .buf = &out,
>                },
>                {
>                        .addr = 0x50,
> @@ -52,15 +52,31 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
>                }
>        };
>
> +       /* Read 8 bytes from i2c for extended probe of EDID header */
> +       if (requires_extended_probe)
> +               msgs[1].len = 8;
> +
>        /* on hw with routers, select right port */
>        if (radeon_connector->router.ddc_valid)
>                radeon_router_select_ddc_port(radeon_connector);
>
>        ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
> -       if (ret == 2)
> -               return true;
> -
> -       return false;
> +       if (ret != 2)
> +               /* Couldn't find an accessible DDC on this connector */
> +               return false;
> +       if (requires_extended_probe) {
> +               /* Probe also for valid EDID header
> +                * EDID header starts with:
> +                * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00.
> +                * Only the first 6 bytes must be valid as
> +                * drm_edid_block_valid() can fix the last 2 bytes */
> +               if (drm_edid_header_is_valid(buf) < 6) {
> +                       /* Couldn't find an accessible EDID on this
> +                        * connector */
> +                       return false;
> +               }
> +       }
> +       return true;
>  }
>
>  /* bit banging i2c */
> diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
> index 6df4e3c..d09031c 100644
> --- a/drivers/gpu/drm/radeon/radeon_mode.h
> +++ b/drivers/gpu/drm/radeon/radeon_mode.h
> @@ -438,6 +438,9 @@ struct radeon_connector {
>        struct radeon_i2c_chan *ddc_bus;
>        /* some systems have an hdmi and vga port with a shared ddc line */
>        bool shared_ddc;
> +       /* for some Radeon chip families we apply an additional EDID header
> +          check as part of the DDC probe */
> +       bool requires_extended_probe;
>        bool use_digital;
>        /* we need to mind the EDID between detect
>           and get modes due to analog/digital/tvencoder */
> @@ -514,7 +517,8 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
>                                u8 val);
>  extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
>  extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
> -extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
> +extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector,
> +                       bool requires_extended_probe);
>  extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
>
>  extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 33d12f8..0ec3687 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -802,6 +802,7 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
>  extern int drm_add_modes_noedid(struct drm_connector *connector,
>                                int hdisplay, int vdisplay);
>
> +extern int drm_edid_header_is_valid(const u8 *raw_edid);
>  extern bool drm_edid_is_valid(struct edid *edid);
>  struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
>                                           int hsize, int vsize, int fresh);
> --
> 1.7.1
>
>
Alex Deucher July 6, 2011, 3:42 p.m. UTC | #3
On Wed, Jul 6, 2011 at 11:39 AM, Alex Deucher <alexdeucher@gmail.com> wrote:
> On Wed, Jul 6, 2011 at 6:09 AM,  <reimth@googlemail.com> wrote:
>> From: Thomas Reim <rdratlos@yahoo.co.uk>
>>
>>    Some integrated ATI Radeon chipset implementations
>>    with add-on HDMI card (e. g. Asus M2A-VM HDMI) indicate the availability
>>    of a DDC even when the add-on card is not plugged in or HDMI is disabled
>>    in BIOS setup. In this case, drm_get_edid() and drm_edid_block_valid()
>>    periodically dump data and kernel errors into system log files and onto
>>    terminals. For these chipsets DDC probing is extended by a check for a
>>    correct EDID header. Only in case a valid EDID header is also found, the
>>    (HDMI) connector will be used by the Radeon driver. This prevents the
>>    kernel driver from useless flooding of logs and terminal sessions with
>>    EDID dumps and error messages.
>>    This patch adds a flag 'requires_extended_probe' to the radeon_connector
>>    structure. In function radeon_connector_needs_extended_probe() this flag
>>    can be set on a chipset family/vendor/connector type specific basis.
>>    In addition, function drm_edid_header_is_valid() has been added for EDID
>>    header check and function radeon_ddc_probe() has been adapted to perform
>>    extended DDC probing if required by the connector's flag.
>>
>>    Tested for kernel 2.35, 2.38 and 3.0 on Asus M2A-VM HDMI board
>>
>
> Once it's ready, just add:
> Cc: stable@kernel.org
> to the commit message and it will go into the stable kernels as well.
> Might want to mention the bug report in your commit message as well.
> Just a couple comments below.  With those fixed:
>
> Reviewed-by: Alex Deucher <alexdeucher@gmail.com>

We also may want to revert 4a9a8b71e12d41abb71c4e741bff524f016cfef4
once this patch goes in, otherwise we may remove the ddc bus
unnecessarily on some systems.

Alex
Thomas Reim July 6, 2011, 11:30 p.m. UTC | #4
From: Thomas Reim <rdratlos@yahoo.co.uk>

Dear Alex,

> > From: Thomas Reim <rdratlos@yahoo.co.uk>
> >
> >    Some integrated ATI Radeon chipset implementations
> >    with add-on HDMI card (e. g. Asus M2A-VM HDMI) indicate the availability
> >    of a DDC even when the add-on card is not plugged in or HDMI is disabled
> >    in BIOS setup. In this case, drm_get_edid() and drm_edid_block_valid()
> >    periodically dump data and kernel errors into system log files and onto
> >    terminals. For these chipsets DDC probing is extended by a check for a
> >    correct EDID header. Only in case a valid EDID header is also found, the
> >    (HDMI) connector will be used by the Radeon driver. This prevents the
> >    kernel driver from useless flooding of logs and terminal sessions with
> >    EDID dumps and error messages.
> >    This patch adds a flag 'requires_extended_probe' to the radeon_connector
> >    structure. In function radeon_connector_needs_extended_probe() this flag
> >    can be set on a chipset family/vendor/connector type specific basis.
> >    In addition, function drm_edid_header_is_valid() has been added for EDID
> >    header check and function radeon_ddc_probe() has been adapted to perform
> >    extended DDC probing if required by the connector's flag.
> >
> >    Tested for kernel 2.35, 2.38 and 3.0 on Asus M2A-VM HDMI board
> >
> 
> Once it's ready, just add:
> Cc: stable@kernel.org
> to the commit message and it will go into the stable kernels as well.
> Might want to mention the bug report in your commit message as well.
> Just a couple comments below.  With those fixed:
> 
> Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
> 
> > Signed-off-by: Thomas Reim <rdratlos@yahoo.co.uk>
> 
thank you for the review and your feedback. I've incorporated your comments as follows:

>  * Sanity check the EDID block (base or extension).  Return 0 if the block
> >  * doesn't check out, or 1 if it's valid.
> > @@ -139,12 +156,7 @@ drm_edid_block_valid(u8 *raw_edid)
> >        struct edid *edid = (struct edid *)raw_edid;
> >
> >        if (raw_edid[0] == 0x00) {
> > -               int score = 0;
> > -
> > -               for (i = 0; i < sizeof(edid_header); i++)
> > -                       if (raw_edid[i] == edid_header[i])
> > -                               score++;
> > -
> > +               int score = drm_edid_header_is_valid(raw_edid);
> >                if (score == 8) ;
> >                else if (score >= 6) {
> >                        DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
> 
> Might want to break this hunk out as a separate patch.

Done. Moved to [PATCH 1/3] drm: Separate EDID Header Check from EDID Block Check  

> --- a/drivers/gpu/drm/radeon/radeon_device.c
> > +++ b/drivers/gpu/drm/radeon/radeon_device.c
> > @@ -704,8 +704,13 @@ int radeon_device_init(struct radeon_device *rdev,
> >        rdev->gpu_lockup = false;
> >        rdev->accel_working = false;
> >
> > -       DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
> > +       if (pdev->subsystem_vendor == 0)
> > +               DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
> >                radeon_family_name[rdev->family], pdev->vendor, pdev->device);
> > +       else
> > +               DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n",
> > +               radeon_family_name[rdev->family], pdev->vendor, pdev->device,
> > +               pdev->subsystem_vendor, pdev->subsystem_device);
> >
> 
> No need for the if block.  Just always print both the pci and
> subsystem ids.  Also, I'd suggest making that a separate patch as it's
> not related to the actual fix.

Done. Moved to [PATCH 3/3] drm/radeon: Log Subsystem Vendor and Device Information.

The following mails will contain the three patches:
[PATCH 1/3] drm: Separate EDID Header Check from EDID Block Check
[PATCH 2/3] drm/radeon: Fix Asus M2A-VM HDMI EDID error flooding problem
[PATCH 3/3] drm/radeon: Log Subsystem Vendor and Device Information

[PATCH 2/3] requires [PATCH 1/3] (new function drm_edid_header_is_valid). [PATCH 3/3] 
is an add-on that helps people to identify also the subsystem vendor and device PCI ID 
of a Radeon chipset within the kernel log. So all information that is needed to include 
Radeon implementations other than Asus M2A-VM HDMI for extended DDC probing should now 
be available in dmesg. 

The patches were generated against revision 'Linux 3.0-rc6' in Linux kernel git repository.

Best regards

Thomas Reim


Thomas Reim (3):
  drm: Separate EDID Header Check from EDID Block Check
  drm/radeon: Fix Asus M2A-VM HDMI EDID error flooding problem
  drm/radeon: Log Subsystem Vendor and Device Information

 drivers/gpu/drm/drm_edid.c                 |   24 +++++++++++----
 drivers/gpu/drm/radeon/radeon_connectors.c |   45 ++++++++++++++++++++++++++--
 drivers/gpu/drm/radeon/radeon_device.c     |    5 ++-
 drivers/gpu/drm/radeon/radeon_display.c    |    9 +++++
 drivers/gpu/drm/radeon/radeon_i2c.c        |   32 +++++++++++++++-----
 drivers/gpu/drm/radeon/radeon_mode.h       |    6 +++-
 include/drm/drm_crtc.h                     |    1 +
 7 files changed, 102 insertions(+), 20 deletions(-)
diff mbox

Patch

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 0929219..1bbb85b 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -127,6 +127,23 @@  static const u8 edid_header[] = {
 	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
 };
 
+ /*
+ * Sanity check the header of the base EDID block.  Return 8 if the header
+ * is perfect, down to 0 if it's totally wrong.
+ */
+int drm_edid_header_is_valid(const u8 *raw_edid)
+{
+	int i, score = 0;
+
+	for (i = 0; i < sizeof(edid_header); i++)
+		if (raw_edid[i] == edid_header[i])
+			score++;
+
+	return score;
+}
+EXPORT_SYMBOL(drm_edid_header_is_valid);
+
+
 /*
  * Sanity check the EDID block (base or extension).  Return 0 if the block
  * doesn't check out, or 1 if it's valid.
@@ -139,12 +156,7 @@  drm_edid_block_valid(u8 *raw_edid)
 	struct edid *edid = (struct edid *)raw_edid;
 
 	if (raw_edid[0] == 0x00) {
-		int score = 0;
-
-		for (i = 0; i < sizeof(edid_header); i++)
-			if (raw_edid[i] == edid_header[i])
-				score++;
-
+		int score = drm_edid_header_is_valid(raw_edid);
 		if (score == 8) ;
 		else if (score >= 6) {
 			DRM_DEBUG("Fixing EDID header, your hardware may be failing\n");
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index cbfca3a..2e70be2 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -424,6 +424,36 @@  int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr
 	return 0;
 }
 
+/*
+ * Some integrated ATI Radeon chipset implementations (e. g.
+ * Asus M2A-VM HDMI) may indicate the availability of a DDC,
+ * even when there's no monitor connected. For these connectors
+ * following DDC probe extension will be applied: check also for the
+ * availability of EDID with at least a correct EDID header. Only then,
+ * DDC is assumed to be available. This prevents drm_get_edid() and
+ * drm_edid_block_valid() from periodically dumping data and kernel
+ * errors into the logs and onto the terminal.
+ */
+static bool radeon_connector_needs_extended_probe(struct radeon_device *dev,
+				     uint32_t supported_device,
+				     int connector_type)
+{
+	/* Asus M2A-VM HDMI board sends data to i2c bus even,
+	 * if HDMI add-on card is not plugged in or HDMI is disabled in
+	 * BIOS. Valid DDC can only be assumed, if also a valid EDID header
+	 * can be retrieved via i2c bus during DDC probe */
+	if ((dev->pdev->device == 0x791e) &&
+	    (dev->pdev->subsystem_vendor == 0x1043) &&
+	    (dev->pdev->subsystem_device == 0x826d)) {
+		if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
+		    (supported_device == ATOM_DEVICE_DFP2_SUPPORT))
+			return true;
+	}
+
+	/* Default: no EDID header probe required for DDC probing */
+	return false;
+}
+
 static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder,
 					  struct drm_connector *connector)
 {
@@ -655,7 +685,8 @@  radeon_vga_detect(struct drm_connector *connector, bool force)
 		ret = connector_status_disconnected;
 
 	if (radeon_connector->ddc_bus)
-		dret = radeon_ddc_probe(radeon_connector);
+		dret = radeon_ddc_probe(radeon_connector,
+					radeon_connector->requires_extended_probe);
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
@@ -827,7 +858,8 @@  radeon_dvi_detect(struct drm_connector *connector, bool force)
 	bool dret = false;
 
 	if (radeon_connector->ddc_bus)
-		dret = radeon_ddc_probe(radeon_connector);
+		dret = radeon_ddc_probe(radeon_connector,
+					radeon_connector->requires_extended_probe);
 	if (dret) {
 		if (radeon_connector->edid) {
 			kfree(radeon_connector->edid);
@@ -1245,7 +1277,8 @@  radeon_dp_detect(struct drm_connector *connector, bool force)
 				if (radeon_dp_getdpcd(radeon_connector))
 					ret = connector_status_connected;
 			} else {
-				if (radeon_ddc_probe(radeon_connector))
+				if (radeon_ddc_probe(radeon_connector,
+						     radeon_connector->requires_extended_probe))
 					ret = connector_status_connected;
 			}
 		}
@@ -1400,6 +1433,9 @@  radeon_add_atom_connector(struct drm_device *dev,
 	radeon_connector->shared_ddc = shared_ddc;
 	radeon_connector->connector_object_id = connector_object_id;
 	radeon_connector->hpd = *hpd;
+	radeon_connector->requires_extended_probe =
+		radeon_connector_needs_extended_probe(rdev, supported_device,
+							connector_type);
 	radeon_connector->router = *router;
 	if (router->ddc_valid || router->cd_valid) {
 		radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info);
@@ -1746,6 +1782,9 @@  radeon_add_legacy_connector(struct drm_device *dev,
 	radeon_connector->devices = supported_device;
 	radeon_connector->connector_object_id = connector_object_id;
 	radeon_connector->hpd = *hpd;
+	radeon_connector->requires_extended_probe =
+		radeon_connector_needs_extended_probe(rdev, supported_device,
+							connector_type);
 	switch (connector_type) {
 	case DRM_MODE_CONNECTOR_VGA:
 		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 7cfaa7e..cbdac3d 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -704,8 +704,13 @@  int radeon_device_init(struct radeon_device *rdev,
 	rdev->gpu_lockup = false;
 	rdev->accel_working = false;
 
-	DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
+	if (pdev->subsystem_vendor == 0)
+		DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n",
 		radeon_family_name[rdev->family], pdev->vendor, pdev->device);
+	else
+		DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n",
+		radeon_family_name[rdev->family], pdev->vendor, pdev->device,
+		pdev->subsystem_vendor, pdev->subsystem_device);
 
 	/* mutex initialization are all done here so we
 	 * can recall function without having locking issues */
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 292f73f..ed085ce 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -777,8 +777,17 @@  static int radeon_ddc_dump(struct drm_connector *connector)
 	if (!radeon_connector->ddc_bus)
 		return -1;
 	edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter);
+	/* Log EDID retrieval status here. In particular with regard to
+	 * connectors with requires_extended_probe flag set, that will prevent
+	 * function radeon_dvi_detect() to fetch EDID on this connector,
+	 * as long as there is no valid EDID header found */
 	if (edid) {
+		DRM_INFO("Radeon display connector %s: Found valid EDID",
+				drm_get_connector_name(connector));
 		kfree(edid);
+	} else {
+		DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID",
+				drm_get_connector_name(connector));
 	}
 	return ret;
 }
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index 781196d..6c111c1 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -32,17 +32,17 @@ 
  * radeon_ddc_probe
  *
  */
-bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
+bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe)
 {
-	u8 out_buf[] = { 0x0, 0x0};
-	u8 buf[2];
+	u8 out = 0x0;
+	u8 buf[8];
 	int ret;
 	struct i2c_msg msgs[] = {
 		{
 			.addr = 0x50,
 			.flags = 0,
 			.len = 1,
-			.buf = out_buf,
+			.buf = &out,
 		},
 		{
 			.addr = 0x50,
@@ -52,15 +52,31 @@  bool radeon_ddc_probe(struct radeon_connector *radeon_connector)
 		}
 	};
 
+	/* Read 8 bytes from i2c for extended probe of EDID header */
+	if (requires_extended_probe)
+		msgs[1].len = 8;
+
 	/* on hw with routers, select right port */
 	if (radeon_connector->router.ddc_valid)
 		radeon_router_select_ddc_port(radeon_connector);
 
 	ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
-	if (ret == 2)
-		return true;
-
-	return false;
+	if (ret != 2)
+		/* Couldn't find an accessible DDC on this connector */
+		return false;
+	if (requires_extended_probe) {
+		/* Probe also for valid EDID header
+		 * EDID header starts with:
+		 * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00.
+		 * Only the first 6 bytes must be valid as
+		 * drm_edid_block_valid() can fix the last 2 bytes */
+		if (drm_edid_header_is_valid(buf) < 6) {
+			/* Couldn't find an accessible EDID on this
+			 * connector */
+			return false;
+		}
+	}
+	return true;
 }
 
 /* bit banging i2c */
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 6df4e3c..d09031c 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -438,6 +438,9 @@  struct radeon_connector {
 	struct radeon_i2c_chan *ddc_bus;
 	/* some systems have an hdmi and vga port with a shared ddc line */
 	bool shared_ddc;
+	/* for some Radeon chip families we apply an additional EDID header
+	   check as part of the DDC probe */
+	bool requires_extended_probe;
 	bool use_digital;
 	/* we need to mind the EDID between detect
 	   and get modes due to analog/digital/tvencoder */
@@ -514,7 +517,8 @@  extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c,
 				u8 val);
 extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector);
 extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector);
-extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector);
+extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector,
+			bool requires_extended_probe);
 extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector);
 
 extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 33d12f8..0ec3687 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -802,6 +802,7 @@  extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
 extern int drm_add_modes_noedid(struct drm_connector *connector,
 				int hdisplay, int vdisplay);
 
+extern int drm_edid_header_is_valid(const u8 *raw_edid);
 extern bool drm_edid_is_valid(struct edid *edid);
 struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
 					   int hsize, int vsize, int fresh);