Bug 31339

Summary: HP/Compaq 8510w HDMI port only works when booted with monitor attached
Product: xorg Reporter: Tyson Whitehead <twhitehead>
Component: Driver/RadeonAssignee: xf86-video-ati maintainers <xorg-driver-ati>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: linville
Version: 7.5 (2009.10)   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
See Also: https://bugzilla.kernel.org/show_bug.cgi?id=23752
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
Register dump pre-suspension (display working fine)
none
Register dump post-suspension (display no longer working)
none
Picture of DVI display prior to suspend
none
Picture of DVI display after suspend and resume (when it is not black)
none
Dump of dmesg log post-suspension (display no longer working)
none
Xorg log post-suspension (display no longer working)
none
Diff of pre- and post-suspend constant registers
none
fix
none
Patch to correct (likely) typo in indexing in atom bios data walking code
none
Dump of xrandr showing incorrect activation of DVI-0 after patches
none
Patch to always reset validity entries in reused router structure instead of just for connectors with attached router objects
none
Patch to add (likely) missing complements in masking operations used to update DDC and clock/data mux
none
The prior patches all rolled into one and signed off none

Description Tyson Whitehead 2010-11-02 13:52:51 UTC
I have a HP/Compaq 8501w with a "ATI Technologies Inc M76 [Radeon Mobility HD2600
Series]" graphics card.  It has a HDMI port on the side of it which I use to plug in my DVI monitor via a HDMI to DVI cable.

With the closure of 18564 (thanks again very much for that), everything works great with a patched 2.6.36 kernel as long as I plug in the monitor before booting the machine and don't suspend.

If I plug it in and enable it after booting the machine or suspend and resume, then the output on the DVI display flickers between a very unstable image (snow with mixed up colors) and a black screen.

This is not a regression, this has always happened as far as I recall.  Before KMS, I was able to get things working again by switching to a console, doing "vbetool post" while the DVI display was plugged in, and then switching back again.  If I do this with KMS, things get very confused.

The problem sounds pretty much identical to 10418, except that it is not a Mac.

Thanks!  -Tyson
Comment 1 Tyson Whitehead 2010-11-02 13:55:17 UTC
Created attachment 39993 [details]
Register dump pre-suspension (display working fine)

A dump of the registers using radeontool after booting up with display attached.  At this point it is working fine.
Comment 2 Tyson Whitehead 2010-11-02 14:02:40 UTC
Created attachment 39994 [details]
Register dump post-suspension (display no longer working)

Register dump using radeontool after having booted up with display attached (was working fine) and then suspend and resumed (now no longer working fine).
Comment 3 Tyson Whitehead 2010-11-02 14:28:42 UTC
Created attachment 39997 [details]
Picture of DVI display prior to suspend
Comment 4 Tyson Whitehead 2010-11-02 14:29:53 UTC
Created attachment 39998 [details]
Picture of DVI display after suspend and resume (when it is not black)
Comment 5 Tyson Whitehead 2010-11-02 14:32:23 UTC
Created attachment 39999 [details]
Dump of dmesg log post-suspension (display no longer working)

Dump of dmesg log after having booted up with display attached (was working fine) and then suspend and resumed (now no longer working fine).
Comment 6 Tyson Whitehead 2010-11-02 14:35:03 UTC
Created attachment 40000 [details]
Xorg log post-suspension (display no longer working)

Xorg log after having booted up with display attached (was working fine) and then suspend and resumed (now no longer working fine).
Comment 7 Tyson Whitehead 2010-11-02 18:42:57 UTC
Created attachment 40002 [details]
Diff of pre- and post-suspend constant registers

Result of diffing the output of

- booting up with DVI display attached (and working fine),
- doing 100 dumps of the registers between 0x6000-0x8000 after Xorg starts,
- filtering out any registers that do not remain constant

and

- suspending and resuming (display no longer working fine),
- doing 100 dumps of the registers between 0x6000-0x8000 after Xorg starts,
- filtering out any registers that do not remain constant

attached.

Nothing stands out to me here looking these up the RV630 register reference.  It pretty much just looks like some memory map addresses have changed and some of the I2C control register have been (mostly) just reset to defaults.

I would be happy to query the I2C buses as well if there are some instructions somewhere on how to do that.

Thanks!  -Tyson
Comment 8 Alex Deucher 2010-11-02 18:54:42 UTC
I see the problem.  Your laptop uses an i2c gpio mux that toggles one i2c line between the HDMI and DVI ports and also appears to use a mux to toggles the data/clock lines between the two ports.  I implemented support for the i2c mux in 2.6.36 (http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=26b5bc986423cf3887e09188cb662ed651c5374d), but it appears your laptop uses the clock/data mux as well.  I'll try and whip up a patch soon.
Comment 9 Alex Deucher 2010-11-02 19:31:57 UTC
Created attachment 40003 [details] [review]
fix

This patch should fix it.
Comment 10 Tyson Whitehead 2010-11-03 09:29:06 UTC
Created attachment 40015 [details] [review]
Patch to correct (likely) typo in indexing in atom bios data walking code

Hi Alex,

I gave your patch a try.  It didn't work as it, but I'm pretty sure that is because of an index typo in the atom bios router object walking code.  I'm attaching a patch to fix this.

With this patch, and some additional dump code in the atom bios data walking code, I get the following in my dmesg log

[   25.805592] [drm] Connector Object 0: (id,num,type) = (05,1,3)
[   25.805595] [drm]   Graph Object 0: (id,num,type) = (15,1,2)
[   25.805650] [drm] Connector Object 1: (id,num,type) = (0c,1,3)
[   25.805652] [drm]   Graph Object 0: (id,num,type) = (13,2,2)
[   25.805677] [drm]   Graph Object 1: (id,num,type) = (01,1,4)
[   25.805679] [drm]     Router Object 0: (id) = (4101)
[   25.805681] [drm]       Atom I2C Record: (info,addr) = (76,41)
[   25.805683] [drm]       DDC Path Selector: (type,pin,state) = (2,6,2)
[   25.805685] [drm]       Data Clock Patch Selector: (type,pin,state) = (2,1,0)
[   25.805734] [drm] Connector Object 2: (id,num,type) = (04,1,3)
[   25.805736] [drm]   Graph Object 0: (id,num,type) = (13,1,2)
[   25.805759] [drm]   Graph Object 1: (id,num,type) = (01,1,4)
[   25.805761] [drm]     Router Object 0: (id) = (4101)
[   25.805763] [drm]       Atom I2C Record: (info,addr) = (02,41)
[   25.805765] [drm]       DDC Path Selector: (type,pin,state) = (2,6,4)
[   25.805767] [drm]       Data Clock Patch Selector: (type,pin,state) = (2,1,1)
[   25.805813] [drm] Connector Object 3: (id,num,type) = (0e,1,3)
[   25.805815] [drm]   Graph Object 0: (id,num,type) = (0f,1,2)
[   25.805882] [drm] Connector Object 4: (id,num,type) = (0f,1,3)
[   25.805884] [drm]   Graph Object 0: (id,num,type) = (16,1,2)
[   25.805952] [drm] Connector Object 5: (id,num,type) = (0f,1,3)
[   25.805954] [drm] Radeon Display Connectors
[   25.805956] [drm] Connector 0:
[   25.805957] [drm]   VGA
[   25.805959] [drm]   DDC: 0x7e40 0x7e40 0x7e44 0x7e44 0x7e48 0x7e48 0x7e4c 0x7e4c
[   25.805961] [drm]   Encoders:
[   25.805962] [drm]     CRT1: INTERNAL_KLDSCP_DAC1
[   25.805964] [drm] Connector 1:
[   25.805965] [drm]   HDMI-A
[   25.805966] [drm]   HPD2
[   25.805968] [drm]   DDC: 0x7e50 0x7e50 0x7e54 0x7e54 0x7e58 0x7e58 0x7e5c 0x7e5c
[   25.805970] [drm]   DDC Router 0x6/0x2
[   25.805972] [drm]   Clock/Data Router 0x1/0x0
[   25.805973] [drm]   Encoders:
[   25.805974] [drm]     DFP1: INTERNAL_KLDSCP_TMDS1
[   25.805976] [drm] Connector 2:
[   25.805977] [drm]   DVI-D
[   25.805978] [drm]   HPD1
[   25.805980] [drm]   DDC: 0x7e50 0x7e50 0x7e54 0x7e54 0x7e58 0x7e58 0x7e5c 0x7e5c
[   25.805982] [drm]   DDC Router 0x6/0x4
[   25.805984] [drm]   Clock/Data Router 0x1/0x1
[   25.805985] [drm]   Encoders:
[   25.805986] [drm]     DFP2: INTERNAL_KLDSCP_TMDS1
[   25.805988] [drm] Connector 3:
[   25.805989] [drm]   LVDS
[   25.805991] [drm]   DDC: 0xac0 0xac0 0xac4 0xac4 0xac8 0xac8 0xacc 0xacc
[   25.805993] [drm]   DDC Router 0x6/0x4
[   25.805994] [drm]   Clock/Data Router 0x1/0x1
[   25.805996] [drm]   Encoders:
[   25.805997] [drm]     LCD1: INTERNAL_LVTM1
[   25.805999] [drm] Connector 4:
[   25.806000] [drm]   DIN
[   25.806001] [drm]   Encoders:
[   25.806002] [drm]     TV1: INTERNAL_KLDSCP_DAC2

and the display comes up properly on plugin after start and resume.  Without it the router object is ignored as it doesn't have the same index as the associated graph object, and the display does not come up properly on plugin after start or resume unless I manually write the i2c registers using i2cset.

Unfortunately, this patch also seems to result in detection confusion between the HDMI and DVI port.  The monitor is listed as being plugged into both ports again (as detailed in comment 21 and 22 of 18564), and the system defaults to trying to turn on the DVI one, which doesn't work.

I then have to manually turn off the DVI one with "xrandr --output DVI-0 --off" and on the HDMI on "xrandr --output HDMI-0 --auto" in order to get my display.  All in all, I'm pretty excited though.  This seems to be getting very close.

Cheers!  -Tyson
Comment 11 Tyson Whitehead 2010-11-03 09:36:01 UTC
Created attachment 40017 [details]
Dump of xrandr showing incorrect activation of DVI-0 after patches

The "xrandr --verbose" dump following booting up with the patched 2.6.36 kernel (both patches in this report and the last one in 18564) and the the DVI monitor plugged in via the HDMI port.

Nothing is plugged into the DVI port (I don't even have the docking bay that exposes it), but you can see how the system lists the monitor under both HDMI-0 and DVI-0 and has tried to activate it under DVI-0.

To properly activate it, I have to turn off DVI-0 and on HDMI-0 manually using xrandr (dump is called pre-switch because I haven't done this yet at this point).
Comment 12 Alex Deucher 2010-11-03 21:33:35 UTC
(In reply to comment #10)

> I gave your patch a try.  It didn't work as it, but I'm pretty sure that is
> because of an index typo in the atom bios router object walking code.  I'm
> attaching a patch to fix this.

Good catch.

> [   25.805988] [drm] Connector 3:
> [   25.805989] [drm]   LVDS
> [   25.805991] [drm]   DDC: 0xac0 0xac0 0xac4 0xac4 0xac8 0xac8 0xacc 0xacc
> [   25.805993] [drm]   DDC Router 0x6/0x4
> [   25.805994] [drm]   Clock/Data Router 0x1/0x1

                         ^^^^^^^^^^^^^^^^^^^^^^^^^
I think I see the problem.  The LVDS port is getting a router assigned to it when it doesn't have a router object in the object table.  Not quite sure how that's happening, but I suspect it's messing up the line toggling.  Unfortunately, I won't have access to my dev box until next week.
Comment 13 Tyson Whitehead 2010-11-04 09:24:45 UTC
Created attachment 40045 [details] [review]
Patch to always reset validity entries in reused router structure instead of just for connectors with attached router objects

Hey Alex,

It didn't seem like it should be too hard to figure out where that router was being picked up for the LVDS port, so I had a look through the code and came up with the above patch.

With this patch, the connector information looks correct now

[   15.666376] [drm] Connector Object 0: (id,num,type) = (05,1,3)
[   15.666379] [drm]   Graph Object 0: (id,num,type) = (15,1,2)
[   15.666434] [drm] Connector Object 1: (id,num,type) = (0c,1,3)
[   15.666437] [drm]   Graph Object 0: (id,num,type) = (13,2,2)
[   15.666464] [drm]   Graph Object 1: (id,num,type) = (01,1,4)
[   15.666466] [drm]     Router Object 0: (id) = (4101)
[   15.666468] [drm]       Atom I2C Record: (addr) = (41)
[   15.666469] [drm]       DDC Path Selector: (type,pin,state) = (2,6,2)
[   15.666471] [drm]       Data Clock Patch Selector: (type,pin,state) = (2,1,0)
[   15.666522] [drm] Connector Object 2: (id,num,type) = (04,1,3)
[   15.666524] [drm]   Graph Object 0: (id,num,type) = (13,1,2)
[   15.666547] [drm]   Graph Object 1: (id,num,type) = (01,1,4)
[   15.666549] [drm]     Router Object 0: (id) = (4101)
[   15.666551] [drm]       Atom I2C Record: (addr) = (41)
[   15.666553] [drm]       DDC Path Selector: (type,pin,state) = (2,6,4)
[   15.666555] [drm]       Data Clock Patch Selector: (type,pin,state) = (2,1,1)
[   15.666601] [drm] Connector Object 3: (id,num,type) = (0e,1,3)
[   15.666603] [drm]   Graph Object 0: (id,num,type) = (0f,1,2)
[   15.666669] [drm] Connector Object 4: (id,num,type) = (0f,1,3)
[   15.666671] [drm]   Graph Object 0: (id,num,type) = (16,1,2)
[   15.666738] [drm] Connector Object 5: (id,num,type) = (0f,1,3)
[   15.666741] [drm] Radeon Display Connectors
[   15.666742] [drm] Connector 0:
[   15.666744] [drm]   VGA
[   15.666746] [drm]   DDC: 0x7e40 0x7e40 0x7e44 0x7e44 0x7e48 0x7e48 0x7e4c 0x7e4c
[   15.666748] [drm]   Encoders:
[   15.666749] [drm]     CRT1: INTERNAL_KLDSCP_DAC1
[   15.666751] [drm] Connector 1:
[   15.666752] [drm]   HDMI-A
[   15.666753] [drm]   HPD2
[   15.666755] [drm]   DDC: 0x7e50 0x7e50 0x7e54 0x7e54 0x7e58 0x7e58 0x7e5c 0x7e5c
[   15.666757] [drm]   DDC Router 0x6/0x2
[   15.666758] [drm]   Clock/Data Router 0x1/0x0
[   15.666760] [drm]   Encoders:
[   15.666761] [drm]     DFP1: INTERNAL_KLDSCP_TMDS1
[   15.666763] [drm] Connector 2:
[   15.666764] [drm]   DVI-D
[   15.666765] [drm]   HPD1
[   15.666767] [drm]   DDC: 0x7e50 0x7e50 0x7e54 0x7e54 0x7e58 0x7e58 0x7e5c 0x7e5c
[   15.666769] [drm]   DDC Router 0x6/0x4
[   15.666770] [drm]   Clock/Data Router 0x1/0x1
[   15.666772] [drm]   Encoders:
[   15.666773] [drm]     DFP2: INTERNAL_KLDSCP_TMDS1
[   15.666774] [drm] Connector 3:
[   15.666776] [drm]   LVDS
[   15.666778] [drm]   DDC: 0xac0 0xac0 0xac4 0xac4 0xac8 0xac8 0xacc 0xacc
[   15.666779] [drm]   Encoders:
[   15.666781] [drm]     LCD1: INTERNAL_LVTM1
[   15.666782] [drm] Connector 4:
[   15.666783] [drm]   DIN
[   15.666784] [drm]   Encoders:
[   15.666786] [drm]     TV1: INTERNAL_KLDSCP_DAC2

Unfortunately though, even with this patch, I'm still getting that weired cross over of the HDMI onto the DVI (that is, the monitor attached to the HDMI port is still listed under both HDMI-0 and DVI-0, and enabled by default on the DVI-0).

Cheers!  -Tyson
Comment 14 Tyson Whitehead 2010-11-05 11:43:10 UTC
Created attachment 40073 [details] [review]
Patch to add (likely) missing complements in masking operations used to update DDC and clock/data mux

Hey Alex,

It seemed that this must be related to the DDC mux, so I had a quick look through the code I2C mux code.  The masking operations seemed suspect as they effectively did either

val &= 0x06  (ddc_mux_control_pin)
val |= 0x04  (ddc_mux_state)

or

val &= 0x06  (ddc_mux_control_pin)
val |= 0x02  (ddc_mux_state)

That really seemed like it should be

val &= 0xf9  (~ddc_mux_control_pin)
val |= 0x04  (ddc_mux_state)

or

val &= 0xf9  (~ddc_mux_control_pin)
val |= 0x02  (ddc_mux_state)

so I switched the masking to use the complements, and everything works now!

Thanks again for all your hard work on this.  It's great to finally have open source drivers for a state-of-the-art video card.

Cheers!  -Tyson
Comment 15 Alex Deucher 2010-11-06 09:25:50 UTC
Another good catch.  Thanks!  Can you attach a combined patch of all of your fixes and add your signed off by?  I'll send them to Dave next week.
Comment 16 Tyson Whitehead 2010-11-07 20:42:57 UTC
Created attachment 40110 [details] [review]
The prior patches all rolled into one and signed off

Hi Alex,

Thanks again for the quick turn around on this stuff.  I tried to keep the description along the lines of your prior ones.  Hopefully it isn't too wordy.

Let me know if there is anything else I can do to help.

Thanks!  -Tyson
Comment 17 Alex Deucher 2010-11-08 08:09:42 UTC
I've sent the patches to Dave.
Comment 18 John W. Linville 2010-11-25 07:41:26 UTC
https://bugzilla.kernel.org/show_bug.cgi?id=23752

Any chance for a fix that doesn't break anything else? :-)

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.