[Bug 97442] [HSW HDMI] Audio with 44.1 khz not working when 1920x1080p screen refreshrate > 30hz

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Sat Sep 10 05:50:59 UTC 2016


https://bugs.freedesktop.org/show_bug.cgi?id=97442

--- Comment #25 from Mark Wilczynski <Mark_Wilczynski at hotmail.com> ---
>From the HDMI spec, we know that the audio frequency is determined via
regeneration from the TMDS clock using the N and CTS constants.

The formula is: 128 * fS = fTMDS_clock * N / CTS

N is restricted to:

128 * fS / 1500Hz ≤ N ≤ 128 * fS / 300Hz

We need to pass correct N and CTS values to the display via audio clock
regeneration packets.  Tracing through the driver code I found that it never
actually sets N or CTS anywhere.  The AUD_CONFIG register always stays with the
default N value of 0x7FA6 for HDMI.  The code only changes the "Pixel Clock
HDMI" value of the AUD_CONFIG register depending on pixel clock (max allowed
value 148.5 Mhz).  I assume this means that under typical conditions, the N and
CTS values are automatically computed by some hardware.  Since I can't see the
actual N/CTS values sent to the sink device, I can only assume that they are
wrong or out-of-range when pixel-clock != TMDS clock.  This only happens when
running in deep-color modes like 36-bit color because TMDS is now 1.5x
pixel_clock.

I fixed the missing 44.1 kHz audio on my TV by forcing specific N values into
the AUD_CONFIG register when running in deep-color 1920x1080p modes over HDMI. 
Since I don't know what CTS value is being sent, I had to play around with the
N values to find ones that worked well for my TV.  I ended up needing a
different N for 148.352 and 148.5 pixel clock modes.  See the first attached
patch for intel_audio.c

The second bug with deep-color modes was skipping video frames as a result of
the vertical refresh rate not matching the requested modeline pixel clock. 
When requesting 148.352, the WRPLL_CTL register which holds the TMDS clock
frequency was being set to 0xB01C0411.  When you decode the bits, and apply the
formula from the docs ( TMDS Frequency = (Reference Frequency / Reference
Divider) * (Feedback Divider / Post Divider)), you end up with:

(2700/17 * 100) * (28/4) * 2 = 222352.9411764706 port clock.

Dividing by 1.5 to convert from 12-bit to 8-bit pixels, the pixel clock ends up
being 148235.2941176471

The actual vertical refresh rate ends up being: 148235.2941176471 * 1000 /
(2200 * 1125 total pixels per frame) = 59.8930481283422 Hz.

59.89 is exactly the incorrect refresh rate I measured in one of my earlier
posts.  It should be 59.940.  The reason this happens is because there is not
enough precision in the 148352 number that is passed as an integer throughout
the driver code.  The actual number should be 148351.6483516484.  This
round-off error is magnified in deep color modes because of the 1.5x scaling to
222528.  The correctly scaled TMDS clock should be 222525.  The function which
computes clock multipliers and dividers has some presets for common/exact
clocks like 222525 but not for 222528.  It ends up searching through various
combinations of dividers and comes up with those n,r,p (28,17,4) values which
produce 222352 TMDS clock.

I ended up fixing this bug by patching intel_hdmi.c so that it replaces the
truncated port clock with the full precision value of 222525.  This ends up
producing n,r,p values of 150,91,4.  With those values inside WRPLL_CTL
register, I get perfect 59.94005994005994 refresh rate.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
You are the QA Contact for the bug.
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/intel-gfx-bugs/attachments/20160910/ff638d84/attachment.html>


More information about the intel-gfx-bugs mailing list