mirror of
https://github.com/tiagovignatti/intel-gpu-tools.git
synced 2025-06-13 02:46:23 +00:00
ddi_compute_wrpll: Rework the logic around r2 and n2 a bit
Let's not use the 2K variants of the frequencies it does not help in anything here and the explanations are hopefuly more understandable this way. On top of that, I noticed that we can just compute the desired min/max boundaries for r2 and n2, so use that instead of the two tests to discard out of range values. Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
This commit is contained in:
parent
bb1dfd5613
commit
4897ac41da
@ -12,14 +12,6 @@
|
|||||||
#define P_MAX 64
|
#define P_MAX 64
|
||||||
#define P_INC 2
|
#define P_INC 2
|
||||||
|
|
||||||
#define R2_MIN 5
|
|
||||||
#define R2_MAX 256
|
|
||||||
#define R2_INC 1
|
|
||||||
|
|
||||||
#define N2_MIN 5
|
|
||||||
#define N2_MAX 256
|
|
||||||
#define N2_INC 1
|
|
||||||
|
|
||||||
/* Constraints for PLL good behavior */
|
/* Constraints for PLL good behavior */
|
||||||
#define REF_MIN 48
|
#define REF_MIN 48
|
||||||
#define REF_MAX 400
|
#define REF_MAX 400
|
||||||
@ -189,33 +181,36 @@ wrpll_compute_rnp(int clock /* in Hz */,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ref * 2000 = LC_FREQ_2K / R, where Ref is the actual reference input
|
* Ref = LC_FREQ / R, where Ref is the actual reference input seen by
|
||||||
* seen by the WR PLL. In particular:
|
* the WR PLL.
|
||||||
* REF_MIN <= LC_FREQ_2K / (R * 2000) and
|
*
|
||||||
* REF_MAX >= LC_FREQ_2K / (R * 2000).
|
* We want R so that REF_MIN <= Ref <= REF_MAX.
|
||||||
* Eliminating fractions gives:
|
* Injecting R2 = 2 * R gives:
|
||||||
* 2000 * REF_MAX * R >= LC_FREQ_2K >= 2000 * R * REF_MIN, R2 = 2*R
|
* REF_MAX * r2 > LC_FREQ * 2 and
|
||||||
|
* REF_MIN * r2 < LC_FREQ * 2
|
||||||
|
*
|
||||||
|
* Which means the desired boundaries for r2 are:
|
||||||
|
* LC_FREQ * 2 / REF_MAX < r2 < LC_FREQ * 2 / REF_MIN
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
for (r2 = R2_MIN; r2 <= R2_MAX; r2 += R2_INC) {
|
for (r2 = LC_FREQ * 2 / REF_MAX + 1;
|
||||||
if (1000 * REF_MAX * r2 < LC_FREQ_2K)
|
r2 <= LC_FREQ * 2 / REF_MIN;
|
||||||
continue;
|
r2++) {
|
||||||
|
|
||||||
if (1000 * REF_MIN * r2 > LC_FREQ_2K)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VCO is N * Ref, that is: VCO = N * LC_FREQ_2K / (R * 2000).
|
* VCO = N * Ref, that is: VCO = N * LC_FREQ / R
|
||||||
*
|
*
|
||||||
* Once again, VCO_MAX >= N * LC_FREQ_2K / (R * 2000) >= VCO_MIN,
|
* Once again we want VCO_MIN <= VCO <= VCO_MAX.
|
||||||
* or: VCO_MAX * R * 2000 >= N * LC_FREQ_2K >= VCO_MIN * R * 2000,
|
* Injecting R2 = 2 * R and N2 = 2 * N, we get:
|
||||||
* where R2=2*R and N2=2*N
|
* VCO_MAX * r2 > n2 * LC_FREQ and
|
||||||
|
* VCO_MIN * r2 < n2 * LC_FREQ)
|
||||||
|
*
|
||||||
|
* Which means the desired boundaries for n2 are:
|
||||||
|
* VCO_MIN * r2 / LC_FREQ < n2 < VCO_MAX * r2 / LC_FREQ
|
||||||
*/
|
*/
|
||||||
for (n2 = N2_MIN; n2 <= N2_MAX; n2 += N2_INC) {
|
for (n2 = VCO_MIN * r2 / LC_FREQ + 1;
|
||||||
if (VCO_MAX * r2 * 2000 < n2 * LC_FREQ_2K)
|
n2 <= VCO_MAX * r2 / LC_FREQ;
|
||||||
continue;
|
n2++) {
|
||||||
|
|
||||||
if (VCO_MIN * r2 * 2000 > n2 * LC_FREQ_2K)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (p = P_MIN; p <= P_MAX; p += P_INC)
|
for (p = P_MIN; p <= P_MAX; p += P_INC)
|
||||||
wrpll_update_rnp(freq2k, budget,
|
wrpll_update_rnp(freq2k, budget,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user