Comment # 35
on bug 69675
from Pierre Ossman
(In reply to comment #28) > Created attachment 88450 [details] [review] [review] > use fractional fb div on DCE4+ > > Does this patch help? This should allow the pll value to more closely match > the actual requested clock. Nope. Still glitches around 9 minutes. The calculations in the table are off though, so I'm not surprised. With corrected values it works fine. I also changed the algorithm to be able to calculate these values properly: static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { /* 32kHz 44.1kHz 48kHz */ /* Clock N CTS N CTS N CTS */ { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */ { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */ { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */ { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */ { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */ { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */ { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */ { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */ { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */ { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */ }; /* * calculate CTS and N values if they are not found in the table */ static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) { int n, cts; unsigned long div, mul; /* Safe, but overly large values */ n = 128 * freq; cts = clock * 1000; /* Smallest valid fraction */ div = gcd(n, cts); n /= div; cts /= div; /* * The optimal N is 128*freq/1000. Calculate the closest larger * value that doesn't truncate any bits. */ mul = ((128*freq/1000) + (n-1))/n; n *= mul; cts *= mul; *N = n; *CTS = cts; DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n", *N, *CTS, freq); } struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock) { struct radeon_hdmi_acr res; u8 i; /* Precalculated values for common clocks */ for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) { if (r600_hdmi_predefined_acr[i].clock == clock) { return r600_hdmi_predefined_acr[i]; } } /* And odd clocks get manually calculated */ r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000); r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100); r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000); return res; } Two notes here: 1. The 25175 clock at 44.1 kHz is out of spec. There are no correct values to make it in spec. So either change the clock, rely on hw calculated values, or hope that sinks tolerate the large N. 2. None the N values for 44100 listed in the HDMI spec are optimal. Not sure why, so I haven't changed them except where needed.
You are receiving this mail because:
- You are the assignee for the bug.
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel