staticint
getMNP_single(struct nvkm_subdev *subdev, struct nvbios_pll *info, int clk, int *pN, int *pM, int *pP)
{ /* Find M, N and P for a single stage PLL * *Notethatsomebioses(NV3x)havelookuptablesofprecomputedMNP *values,butwe'retoolazytousethoseatm * *"clk"parameterinkHz *returnscalculatedclock
*/ struct nvkm_bios *bios = subdev->device->bios; int minvco = info->vco1.min_freq, maxvco = info->vco1.max_freq; int minM = info->vco1.min_m, maxM = info->vco1.max_m; int minN = info->vco1.min_n, maxN = info->vco1.max_n; int minU = info->vco1.min_inputfreq; int maxU = info->vco1.max_inputfreq; int minP = info->min_p; int maxP = info->max_p_usable; int crystal = info->refclk; int M, N, thisP, P; int clkP, calcclk; int delta, bestdelta = INT_MAX; int bestclk = 0;
/* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */ /* possibly correlated with introduction of 27MHz crystal */ if (bios->version.major < 0x60) { int cv = bios->version.chip; if (cv < 0x17 || cv == 0x1a || cv == 0x20) { if (clk > 250000)
maxM = 6; if (clk > 340000)
maxM = 2;
} elseif (cv < 0x40) { if (clk > 150000)
maxM = 6; if (clk > 200000)
maxM = 4; if (clk > 340000)
maxM = 2;
}
}
if (clkP < minvco) continue; if (clkP > maxvco) return bestclk;
for (M = minM; M <= maxM; M++) { if (crystal/M < minU) return bestclk; if (crystal/M > maxU) continue;
/* add crystal/2 to round better */
N = (clkP * M + crystal/2) / crystal;
if (N < minN) continue; if (N > maxN) break;
/* more rounding additions */
calcclk = ((N * crystal + P/2) / P + M/2) / M;
delta = abs(calcclk - clk); /* we do an exhaustive search rather than terminating *onanoptimalitycondition...
*/ if (delta < bestdelta) {
bestdelta = delta;
bestclk = calcclk;
*pN = N;
*pM = M;
*pP = thisP; if (delta == 0) /* except this one */ return bestclk;
}
}
}
return bestclk;
}
staticint
getMNP_double(struct nvkm_subdev *subdev, struct nvbios_pll *info, int clk, int *pN1, int *pM1, int *pN2, int *pM2, int *pP)
{ /* Find M, N and P for a two stage PLL * *Notethatsomebioses(NV30+)havelookuptablesofprecomputedMNP *values,butwe'retoolazytousethoseatm * *"clk"parameterinkHz *returnscalculatedclock
*/ int chip_version = subdev->device->bios->version.chip; int minvco1 = info->vco1.min_freq, maxvco1 = info->vco1.max_freq; int minvco2 = info->vco2.min_freq, maxvco2 = info->vco2.max_freq; int minU1 = info->vco1.min_inputfreq, minU2 = info->vco2.min_inputfreq; int maxU1 = info->vco1.max_inputfreq, maxU2 = info->vco2.max_inputfreq; int minM1 = info->vco1.min_m, maxM1 = info->vco1.max_m; int minN1 = info->vco1.min_n, maxN1 = info->vco1.max_n; int minM2 = info->vco2.min_m, maxM2 = info->vco2.max_m; int minN2 = info->vco2.min_n, maxN2 = info->vco2.max_n; int maxlog2P = info->max_p_usable; int crystal = info->refclk; bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2); int M1, N1, M2, N2, log2P; int clkP, calcclk1, calcclk2, calcclkout; int delta, bestdelta = INT_MAX; int bestclk = 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.