[Intel-gfx] [PATCH v5] drm/i915: pass ELD to HDMI/DP audio driver

Takashi Iwai tiwai at suse.de
Thu Nov 10 14:01:39 CET 2011


At Thu, 10 Nov 2011 13:39:00 +0100,
Christopher White wrote:
> 
> On 11/10/11 12:53 PM, Takashi Iwai wrote:
> > At Thu, 10 Nov 2011 12:50:11 +0100,
> > Christopher White wrote:
> >> On 11/10/11 12:22 PM, Takashi Iwai wrote:
> >>> At Thu, 10 Nov 2011 12:00:53 +0100,
> >>> Christopher White wrote:
> >>>> On 11/10/11 9:55 AM, Christopher White wrote:
> >>>>> On 11/10/11 8:55 AM, Wu Fengguang wrote:
> >>>>>> On Thu, Nov 10, 2011 at 03:33:50PM +0800, Wu Fengguang wrote:
> >>>>>>> Wow I reproduced the bug and got a very interesting dmesg:
> >>>>>>>
> >>>>>>> gfx =>           [ 4561.287980] [drm:intel_write_eld], ELD on
> >>>>>>> [CONNECTOR:12:HDMI-A-2], [ENCODER:11:TMDS-11]
> >>>>>>> gfx =>           [ 4561.291730] [drm:ironlake_write_eld], ELD on pipe B
> >>>>>>> gfx =>           [ 4561.293804] [drm:ironlake_write_eld], Audio
> >>>>>>> directed to unknown port
> >>>>>>> gfx =>           [ 4561.295273] [drm:ironlake_write_eld],
> >>>>>>>          alsa =>    [ 4561.295486] HDMI hot plug event: Codec=3 Pin=6
> >>>>>>> Presence_Detect=1 ELD_Valid=0
> >>>>>>>          alsa =>    [ 4561.295564] HDMI status: Codec=3 Pin=6
> >>>>>>> Presence_Detect=1 ELD_Valid=0
> >>>>>>> gfx =>           [ 4561.300020] ELD size 13
> >>>>>>>          alsa =>    [ 4561.300697] HDMI hot plug event: Codec=3 Pin=6
> >>>>>>> Presence_Detect=1 ELD_Valid=1
> >>>>>>>          alsa =>    [ 4561.303322] HDMI status: Codec=3 Pin=6
> >>>>>>> Presence_Detect=1 ELD_Valid=1
> >>>>>>>          alsa =>    [ 4561.311120] ALSA hda_eld.c:259 HDMI: Unknown ELD
> >>>>>>> version 0
> >>>>>>>
> >>>>>>> Hey the two parts are interleaved!
> >>>>>>>
> >>>>>>> But still it should work all fine, since the gfx driver does
> >>>>>>>
> >>>>>>>            set ELD_Valid = 0
> >>>>>>>            write ELD
> >>>>>>>            set ELD_Valid = 1
> >>>>>>>
> >>>>>>> So the audio driver would read the correct ELD unless the ELD content
> >>>>>>> and flag writes are somehow _reordered_ underneath. Or the ELD content
> >>>>>>> writes take some time to take effect?
> >>>>>> Just confirmed that adding 1s delay can fix it!
> >>>>>>
> >>>>>> New dmesg is:
> >>>>>>
> >>>>>> [   48.564923] [drm:drm_crtc_helper_set_mode], [ENCODER:11:TMDS-11]
> >>>>>> set [MODE:34:]
> >>>>>> [   48.567481] [drm:intel_hdmi_mode_set], Enabling HDMI audio on pipe B
> >>>>>> [   48.568975] [drm:intel_write_eld], ELD on [CONNECTOR:12:HDMI-A-2],
> >>>>>> [ENCODER:11:TMDS-11]
> >>>>>> [   48.571728] [drm:ironlake_write_eld], ELD on pipe B
> >>>>>> [   48.572882] [drm:ironlake_write_eld], Audio directed to unknown port
> >>>>>> [   48.575252] [drm:ironlake_write_eld],
> >>>>>> [   48.575400] HDMI hot plug event: Codec=3 Pin=6 Presence_Detect=1
> >>>>>> ELD_Valid=0
> >>>>>> [   48.575487] HDMI status: Codec=3 Pin=6 Presence_Detect=1 ELD_Valid=0
> >>>>>> [   48.580116] ELD size 13
> >>>>>> [   48.580795] HDMI hot plug event: Codec=3 Pin=6 Presence_Detect=1
> >>>>>> ELD_Valid=1
> >>>>>> [   48.583340] HDMI status: Codec=3 Pin=6 Presence_Detect=1 ELD_Valid=1
> >>>>>> [   48.632514] [drm:intel_wait_for_vblank], vblank wait timed out
> >>>>>> [   48.685322] [drm:intel_wait_for_vblank], vblank wait timed out
> >>>>>> [   48.687438] [drm:ironlake_update_wm], FIFO watermarks For pipe A -
> >>>>>> plane 5, cursor: 6
> >>>>>> [   48.687438] [drm:ironlake_update_wm], FIFO watermarks For pipe A -
> >>>>>> plane 5, cursor: 6
> >>>>>> [   48.690106] [drm:ironlake_update_wm], FIFO watermarks For pipe B -
> >>>>>> plane 42, cursor: 6
> >>>>>> [   48.745204] [drm:intel_wait_for_vblank], vblank wait timed out
> >>>>>> [   48.798035] [drm:intel_wait_for_vblank], vblank wait timed out
> >>>>>> [   48.799633] [drm:ironlake_fdi_link_train], FDI_RX_IIR 0x100
> >>>>>> [   48.802686] [drm:ironlake_fdi_link_train], FDI train 1 done.
> >>>>>> [   48.805103] [drm:ironlake_fdi_link_train], FDI_RX_IIR 0x600
> >>>>>> [   48.807246] [drm:ironlake_fdi_link_train], FDI train 2 done.
> >>>>>> [   48.809426] [drm:ironlake_fdi_link_train], FDI train done
> >>>>>> [   48.813960] [drm:intel_update_fbc],
> >>>>>> [   48.814782] [drm:drm_crtc_helper_set_config], Setting connector
> >>>>>> DPMS state to on
> >>>>>> [   48.818093] [drm:drm_crtc_helper_set_config],
> >>>>>> [CONNECTOR:12:HDMI-A-2] set DPMS on
> >>>>>> [   48.828633] [drm:intel_prepare_page_flip], preparing flip with no
> >>>>>> unpin work?
> >>>>>> [   49.618962] HDMI: detected monitor RX-V1800 at connection type HDMI
> >>>>>> [   49.621013] HDMI: available speakers: FL/FR LFE FC RL/RR RC RLC/RRC
> >>>>>> [   49.622304] HDMI: supports coding type LPCM: channels = 2, rates =
> >>>>>> 32000 44100 48000 96000 176400 192000 384000, bits = 16 20 24
> >>>>>> [   49.625069] HDMI: supports coding type LPCM: channels = 8, rates =
> >>>>>> 32000 44100 48000 96000 176400 192000 384000, bits = 16 20 24
> >>>>>> [   49.628535] HDMI: supports coding type AC-3: channels = 6, rates =
> >>>>>> 32000 44100 48000, max bitrate = 640000
> >>>>>> [   49.630810] HDMI: supports coding type DTS: channels = 7, rates =
> >>>>>> 32000 44100 48000 96000 176400, max bitrate = 1536000
> >>>>>> [   49.633148] HDMI: supports coding type DSD (One Bit Audio):
> >>>>>> channels = 6, rates = 44100
> >>>>>> [   49.635039] HDMI: supports coding type E-AC-3/DD+ (Dolby Digital
> >>>>>> Plus): channels = 8, rates = 44100 48000
> >>>>>> [   49.637130] HDMI: supports coding type MLP (Dolby TrueHD):
> >>>>>> channels = 8, rates = 48000 176400 384000
> >>>>>> [   49.639172] HDMI: supports coding type DTS-HD: channels = 8, rates
> >>>>>> = 48000 176400 384000
> >>>>>>
> >>>>>> Thanks,
> >>>>>> Fengguang
> >>>>> Wow, you were able to reproduce it! That's the best news ever. I will
> >>>>> be applying this patch and rebuilding now to see what happens. So it
> >>>>> was some sort of timing issue after all.
> >>>>>
> >>>>> Expect me to reply within 1h, but rebuild takes some time.
> >>>> I still had the old build directory and only had to rebuild one module
> >>>> which only took 5 minutes. The rest of the delay was me doing an hour of
> >>>> tests as well as being on a 45 minute phone call. Anyway, now the result:
> >>>>
> >>>> Success!
> >>>>
> >>>> So we know it's a timing issue somewhere. Wow, real progress and near a
> >>>> solution. Finally! The big question now is what causes the audio driver
> >>>> to read the ELD while it is empty, and why the 1 second delay fixes it.
> >>>>
> >>>> Look at speakertest.txt here. It's beautiful. ;-) Playing digital
> >>>> multichannel sound over the HDMI PCH bus, and I can hear every channel
> >>>> in their proper location on my speaker system. It's beautiful. I've
> >>>> waited for this moment since building this Linux HTPC back in April. ;-)
> >>>> (I'm an astonishingly patient man hehe).
> >>>>
> >>>> Now as for why we needed a 1 second delay, any ideas? Could it be that
> >>>> the audio driver was reading the ELD while it wasn't written to the
> >>>> register yet?
> >>> Maybe not necessarily 1 second.  It could do some loop with a small
> >>> delay until it reads zero-size?  Or if it really can take long time
> >>> like 1 second, it'd be better to be a work to self-reschdule to do in
> >>> background, as it's called at the probing time and at each unsol
> >>> event.  Since radeon sends really zero-byte ELD when a DVI monitor
> >>> without audio is connected, stalling one second there is no good
> >>> choice.
> >>>
> >>> Hopefully this delay would fix the zero-size problem we are currently
> >>> working around in an ugly way (the comment mentions about ASUS P5E-VM
> >>> HDMI board), too.
> >>>
> >>>
> >>> thanks,
> >>>
> >>> Takashi
> >> Well yes obviously the 1 second delay is a temporary workaround until
> >> the real cause is found. Something like what you suggested should be the
> >> final fix; a real loop that proceeds only when the data is ready (with a
> >> 1 second or so maximum loop time, to avoid infinite loop if data never
> >> becomes ready).
> >>
> >> I don't think a background schedule would work, because the data needs
> >> to be available at boot BEFORE the audio layer loads. Otherwise ALSA
> >> (for example) would load while no data had yet been read into the ELD
> >> registers. If a background schedule is used, then GREAT care must be
> >> taken to make sure it finishes before the audio layer launches.
> > In theory, the delayed probe and notification can be handled just like
> > a hotplug case.  We have still no notification framework (especially
> > in PulseAudio) yet, though :)
> >
> >
> > thanks,
> >
> > Takashi
> Yep that is the main risk of a delayed event - a possible inability to 
> re-configure the audio layer.
> 
> I think ALSA *might* be able to re-detect audio devices and settings 
> after the initial boot, because I know there is a MANUAL "alsa 
> force-reload" command.

You don't have to do so much things.  The HDMI codec is there
statically, and the corresponding device is already created at boot
even the ELD probe is delayed.  What would change after the ELD probe
is the information of the PCM stream, i.e. the supported format,
channels, etc.

> I am pretty sure it doesn't run automatically 
> when the Intel driver detects a hotplug, though. That would require some 
> sort of notification between the Intel driver and ALSA which afaik 
> doesn't exist. Then there's also the problem that applications could 
> start using the audio layer in its bad state and won't like the 
> unexpected reconfigure.

Right, this has been discussed recently, and I'm already working on
it.  PA will have some support for jack-detection, and HDMI driver
will issue a jack-notification as well.

> This means that once the ALSA layer has loaded with a bad config, it's 
> stuck like that.

Then it falls back to the basic 2-ch stream, so usually not too
critical for "normal" users :)

> Therefore the biggest priority of the final solution 
> will be to ensure that all ELD data is ready *before* ALSA (or any other 
> audio layer) first queries it, so that the system boots into the proper 
> audio state right away.

No, the driver shouldn't be stuck at the boot time at all.
If ELD probe is pending, user-space can sync at the first open, for
example.  Remember that the device itself already.  Blocking in the
driver probe time is simply bad.

> We already know that it takes less than a second to have ELD ready from 
> the point that the ELD function has been entered, so a small loop with a 
> 1 second max execution time (to prevent infinite) could be good enough. 

The problem is, as mentioned, the case where the hardware really sends
zero-size ELD.  In this case, it stops until the defined time-out.

> It would be interesting to try such a loop along with a small counter, 
> and a 10ms or so wait between iterations, and then printing the number 
> of iterations to the debug log. That will show us how long the average 
> wait for valid ELD is.

This is the first step, indeed.


Takashi



More information about the Intel-gfx mailing list