Lines Matching refs:pll

10 #include "pll.h"
71 pll_limit_probe(pll_info* pll)
99 pll->referenceFreq
103 pll->pllOutMin
107 pll->pllOutMin
112 pll->pllOutMax
117 pll->lcdPllOutMin
121 if (pll->lcdPllOutMin == 0)
122 pll->lcdPllOutMin = pll->pllOutMin;
124 pll->lcdPllOutMax
128 if (pll->lcdPllOutMax == 0)
129 pll->lcdPllOutMax = pll->pllOutMax;
132 pll->lcdPllOutMin = pll->pllOutMin;
133 pll->lcdPllOutMax = pll->pllOutMax;
136 if (pll->pllOutMin == 0) {
137 pll->pllOutMin = 64800 * 10;
141 pll->minPostDiv = POST_DIV_MIN;
142 pll->maxPostDiv = POST_DIV_LIMIT;
143 pll->minRefDiv = REF_DIV_MIN;
144 pll->maxRefDiv = REF_DIV_LIMIT;
145 pll->minFeedbackDiv = FB_DIV_MIN;
146 pll->maxFeedbackDiv = FB_DIV_LIMIT;
148 pll->pllInMin = B_LENDIAN_TO_HOST_INT16(
150 pll->pllInMax = B_LENDIAN_TO_HOST_INT16(
155 "pllInMax: %" B_PRIu32 "\n", __func__, pll->referenceFreq,
156 pll->pllOutMin, pll->pllOutMax, pll->pllInMin, pll->pllInMax);
163 pll_ppll_ss_probe(pll_info* pll, uint32 ssID)
174 pll->ssEnabled = false;
188 pll->ssPercentage = B_LENDIAN_TO_HOST_INT16(
190 pll->ssType = ss_info->asSS_Info[i].ucSpreadSpectrumType;
191 pll->ssStep = ss_info->asSS_Info[i].ucSS_Step;
192 pll->ssDelay = ss_info->asSS_Info[i].ucSS_Delay;
193 pll->ssRange = ss_info->asSS_Info[i].ucSS_Range;
194 pll->ssReferenceDiv
196 pll->ssEnabled = true;
201 pll->ssEnabled = false;
207 pll_asic_ss_probe(pll_info* pll, uint32 ssID)
218 pll->ssEnabled = false;
244 if (pll->pixelClock / 10 > B_LENDIAN_TO_HOST_INT32(
250 pll->ssPercentage = B_LENDIAN_TO_HOST_INT16(
254 pll->ssType
256 pll->ssRate = B_LENDIAN_TO_HOST_INT16(
258 pll->ssPercentageDiv = 100;
259 pll->ssEnabled = true;
273 if (pll->pixelClock / 10 > B_LENDIAN_TO_HOST_INT32(
279 pll->ssPercentage = B_LENDIAN_TO_HOST_INT16(
284 pll->ssType
286 pll->ssRate = B_LENDIAN_TO_HOST_INT16(
288 pll->ssPercentageDiv = 100;
289 pll->ssEnabled = true;
303 if (pll->pixelClock / 10 > B_LENDIAN_TO_HOST_INT32(
309 pll->ssPercentage = B_LENDIAN_TO_HOST_INT16(
313 pll->ssType
315 pll->ssRate = B_LENDIAN_TO_HOST_INT16(
320 pll->ssPercentageDiv = 1000;
322 pll->ssPercentageDiv = 100;
326 pll->ssRate /= 100;
328 pll->ssEnabled = true;
334 pll->ssEnabled = false;
339 pll->ssEnabled = false;
345 pll_compute_post_divider(pll_info* pll)
347 if ((pll->flags & PLL_USE_POST_DIV) != 0) {
353 if ((pll->flags & PLL_PREFER_MINM_OVER_MAXP) != 0) {
354 if ((pll->flags & PLL_IS_LCD) != 0)
355 vco = pll->lcdPllOutMin;
357 vco = pll->pllOutMax;
359 if ((pll->flags & PLL_IS_LCD) != 0)
360 vco = pll->lcdPllOutMax;
362 vco = pll->pllOutMin;
367 uint32 postDivider = vco / pll->adjustedClock;
368 uint32 tmp = vco % pll->adjustedClock;
370 if ((pll->flags & PLL_PREFER_MINM_OVER_MAXP) != 0) {
378 if (postDivider > pll->maxPostDiv)
379 postDivider = pll->maxPostDiv;
380 else if (postDivider < pll->minPostDiv)
381 postDivider = pll->minPostDiv;
383 pll->postDiv = postDivider;
393 pll_compute(pll_info* pll)
397 pll_compute_post_divider(pll);
399 const uint32 targetClock = pll->adjustedClock;
401 pll->feedbackDiv = 0;
402 pll->feedbackDivFrac = 0;
404 if ((pll->flags & PLL_USE_REF_DIV) != 0) {
408 pll->referenceDiv = pll->minRefDiv;
411 if ((pll->flags & PLL_USE_FRAC_FB_DIV) != 0) {
414 const uint32 numerator = pll->postDiv * pll->referenceDiv
416 pll->feedbackDiv = numerator / pll->referenceFreq;
417 pll->feedbackDivFrac = numerator % pll->referenceFreq;
419 if (pll->feedbackDiv > pll->maxFeedbackDiv)
420 pll->feedbackDiv = pll->maxFeedbackDiv;
421 else if (pll->feedbackDiv < pll->minFeedbackDiv)
422 pll->feedbackDiv = pll->minFeedbackDiv;
425 pll->feedbackDivFrac
426 = (100 * pll->feedbackDivFrac) / pll->referenceFreq;
429 if (pll->feedbackDivFrac >= 5) {
430 pll->feedbackDivFrac -= 5;
431 pll->feedbackDivFrac /= 10;
432 pll->feedbackDivFrac++;
434 if (pll->feedbackDivFrac >= 10) {
435 pll->feedbackDiv++;
436 pll->feedbackDivFrac = 0;
441 while (pll->referenceDiv <= pll->maxRefDiv) {
443 uint32 retroEncabulator = pll->postDiv * pll->referenceDiv;
446 pll->feedbackDiv = retroEncabulator / pll->referenceFreq;
447 pll->feedbackDivFrac
448 = retroEncabulator % pll->referenceFreq;
450 if (pll->feedbackDiv > pll->maxFeedbackDiv)
451 pll->feedbackDiv = pll->maxFeedbackDiv;
452 else if (pll->feedbackDiv < pll->minFeedbackDiv)
453 pll->feedbackDiv = pll->minFeedbackDiv;
455 if (pll->feedbackDivFrac >= (pll->referenceFreq / 2))
456 pll->feedbackDiv++;
458 pll->feedbackDivFrac = 0;
460 if (pll->referenceDiv == 0
461 || pll->postDiv == 0
465 __func__, pll->referenceDiv);
467 __func__, pll->postDiv);
472 uint32 tmp = (pll->referenceFreq * pll->feedbackDiv)
473 / (pll->postDiv * pll->referenceDiv);
477 pll->referenceDiv++;
481 pll->referenceDiv++;
485 if (pll->referenceDiv == 0 || pll->postDiv == 0) {
492 = ((pll->referenceFreq * pll->feedbackDiv * 10)
493 + (pll->referenceFreq * pll->feedbackDivFrac))
494 / (pll->referenceDiv * pll->postDiv * 10);
499 "referenceDivider: %" B_PRIu32 "\n", __func__, pll->referenceFreq,
500 pll->referenceDiv);
502 "feedbackDividerFrac: %" B_PRIu32 "\n", __func__, pll->feedbackDiv,
503 pll->feedbackDivFrac);
504 TRACE("%s: postDivider: %" B_PRIu32 "\n", __func__, pll->postDiv);
506 if (pll->adjustedClock != calculatedClock) {
508 __func__, pll->adjustedClock, calculatedClock);
509 pll->pixelClock = calculatedClock;
513 if (info.dceMajor >= 4 && pll->ssEnabled) {
514 if (pll->ssPercentageDiv == 0) {
518 pll->ssEnabled = false;
521 uint32 amount = ((pll->feedbackDiv * 10) + pll->feedbackDivFrac);
522 amount *= pll->ssPercentage;
523 amount /= pll->ssPercentageDiv * 100;
524 pll->ssAmount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
525 pll->ssAmount |= ((amount - (amount / 10))
529 if ((pll->ssType & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD) != 0)
531 pll->ssStep = (centerSpreadMultiplier * amount * pll->referenceDiv
532 * (pll->ssRate * 2048)) / (125 * 25 * pll->referenceFreq / 100);
540 pll_setup_flags(pll_info* pll, uint8 crtcID)
549 crtcID, pll->id);
551 if (dceVersion >= 302 && pll->pixelClock > 200000)
552 pll->flags |= PLL_PREFER_HIGH_FB_DIV;
554 pll->flags |= PLL_PREFER_LOW_REF_DIV;
557 pll->flags |= PLL_PREFER_MINM_OVER_MAXP;
560 pll->flags |= PLL_IS_LCD;
564 pll->ssPercentage);
565 if (pll->ssPercentage > 0) {
566 if (pll->ssReferenceDiv > 0) {
569 __func__, pll->referenceDiv, pll->ssReferenceDiv);
570 pll->flags |= PLL_USE_REF_DIV;
571 pll->referenceDiv = pll->ssReferenceDiv;
574 pll->flags |= PLL_USE_FRAC_FB_DIV;
580 pll->flags |= PLL_PREFER_CLOSEST_LOWER;
584 pll->flags |= PLL_USE_FRAC_FB_DIV;
590 * pll_adjust - Ask AtomBIOS if it wants to make adjustments to our pll
595 pll_adjust(pll_info* pll, display_mode* mode, uint8 crtcID)
599 uint32 pixelClock = pll->pixelClock;
610 pll->adjustedClock = pll->pixelClock;
646 if (pll->ssPercentage > 0) {
653 pll->adjustedClock
655 pll->adjustedClock *= 10;
663 if (pll->ssPercentage > 0) {
704 pll->adjustedClock = B_LENDIAN_TO_HOST_INT32(
706 pll->adjustedClock *= 10;
710 pll->flags |= PLL_USE_FRAC_FB_DIV;
711 pll->flags |= PLL_USE_REF_DIV;
712 pll->referenceDiv = args.v3.sOutput.ucRefDiv;
715 pll->flags |= PLL_USE_FRAC_FB_DIV;
716 pll->flags |= PLL_USE_POST_DIV;
717 pll->postDiv = args.v3.sOutput.ucPostDiv;
734 pixelClock, pll->adjustedClock);
741 * pll_set - Calculate and set a pll on the crtc provided based on the mode.
750 pll_info* pll = &gConnector[connectorIndex]->encoder.pll;
753 pll->ssEnabled = false;
755 pll->pixelClock = mode->timing.pixel_clock;
760 pll->ssPercentage = 0;
761 pll->ssType = 0;
762 pll->ssStep = 0;
763 pll->ssDelay = 0;
764 pll->ssRange = 0;
765 pll->ssReferenceDiv = 0;
771 pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_DP);
774 pll_ppll_ss_probe(pll, ATOM_DP_SS_ID2);
775 if (!pll->ssEnabled)
776 pll_ppll_ss_probe(pll, ATOM_DP_SS_ID1);
778 pll_ppll_ss_probe(pll, ATOM_DP_SS_ID1);
783 pll_asic_ss_probe(pll, gInfo->lvdsSpreadSpectrumID);
785 pll_ppll_ss_probe(pll, gInfo->lvdsSpreadSpectrumID);
789 pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_TMDS);
793 pll_asic_ss_probe(pll, ASIC_INTERNAL_SS_ON_HDMI);
797 pll_setup_flags(pll, crtcID);
799 pll_adjust(pll, mode, crtcID);
801 pll_compute(pll);
833 = B_HOST_TO_LENDIAN_INT16(pll->pixelClock / 10);
834 args.v1.usRefDiv = B_HOST_TO_LENDIAN_INT16(pll->referenceDiv);
835 args.v1.usFbDiv = B_HOST_TO_LENDIAN_INT16(pll->feedbackDiv);
836 args.v1.ucFracFbDiv = pll->feedbackDivFrac;
837 args.v1.ucPostDiv = pll->postDiv;
838 args.v1.ucPpll = pll->id;
844 = B_HOST_TO_LENDIAN_INT16(pll->pixelClock / 10);
845 args.v2.usRefDiv = B_HOST_TO_LENDIAN_INT16(pll->referenceDiv);
846 args.v2.usFbDiv = B_HOST_TO_LENDIAN_INT16(pll->feedbackDiv);
847 args.v2.ucFracFbDiv = pll->feedbackDivFrac;
848 args.v2.ucPostDiv = pll->postDiv;
849 args.v2.ucPpll = pll->id;
855 = B_HOST_TO_LENDIAN_INT16(pll->pixelClock / 10);
856 args.v3.usRefDiv = B_HOST_TO_LENDIAN_INT16(pll->referenceDiv);
857 args.v3.usFbDiv = B_HOST_TO_LENDIAN_INT16(pll->feedbackDiv);
858 args.v3.ucFracFbDiv = pll->feedbackDivFrac;
859 args.v3.ucPostDiv = pll->postDiv;
860 args.v3.ucPpll = pll->id;
861 args.v3.ucMiscInfo = (pll->id << 2);
862 if (pll->ssPercentage > 0
863 && (pll->ssType & ATOM_EXTERNAL_SS_MASK) != 0) {
873 = B_HOST_TO_LENDIAN_INT16(pll->pixelClock / 10);
874 args.v5.ucRefDiv = pll->referenceDiv;
875 args.v5.usFbDiv = B_HOST_TO_LENDIAN_INT16(pll->feedbackDiv);
877 = B_HOST_TO_LENDIAN_INT32(pll->feedbackDivFrac * 100000);
878 args.v5.ucPostDiv = pll->postDiv;
880 if (pll->ssPercentage > 0
881 && (pll->ssType & ATOM_EXTERNAL_SS_MASK) != 0) {
903 args.v5.ucPpll = pll->id;
907 = B_HOST_TO_LENDIAN_INT32(crtcID << 24 | pll->pixelClock / 10);
908 args.v6.ucRefDiv = pll->referenceDiv;
909 args.v6.usFbDiv = B_HOST_TO_LENDIAN_INT16(pll->feedbackDiv);
911 = B_HOST_TO_LENDIAN_INT32(pll->feedbackDivFrac * 100000);
912 args.v6.ucPostDiv = pll->postDiv;
914 if (pll->ssPercentage > 0
915 && (pll->ssType & ATOM_EXTERNAL_SS_MASK) != 0) {
938 args.v6.ucPpll = pll->id;
942 = B_HOST_TO_LENDIAN_INT32(pll->pixelClock / 10);
945 && pll->pixelClock > 165000) {
973 args.v7.ucPpll = pll->id;
982 __func__, pll->pixelClock, mode->timing.pixel_clock);
986 if (pll->ssEnabled)
987 display_crtc_ss(pll, ATOM_ENABLE);
989 display_crtc_ss(pll, ATOM_DISABLE);
996 * pll_set_external - Sets external default pll via SetPixelClock
1003 TRACE("%s: set external pll clock to %" B_PRIu32 "\n", __func__, clock);
1068 * pll_set_dce - Sets external default pll via DCE Clock Allocation
1076 TRACE("%s: set external pll clock to %" B_PRIu32 "\n", __func__, clock);
1122 * pll_external_init - Sets external default pll to sane value
1140 // Create our own pseudo pll
1141 pll_info pll;
1142 pll.pixelClock = gInfo->displayClockFrequency;
1144 pll_asic_ss_probe(&pll, ASIC_INTERNAL_SS_ON_DCPLL);
1145 if (pll.ssEnabled)
1146 display_crtc_ss(&pll, ATOM_DISABLE);
1147 pll_set_external(pll.pixelClock);
1148 if (pll.ssEnabled)
1149 display_crtc_ss(&pll, ATOM_ENABLE);
1165 pll_info* pll = &gConnector[id]->encoder.pll;
1166 if (pll->id != ATOM_PPLL_INVALID)
1167 pllMask |= (1 << pll->id);
1185 pll_info* pll = &gConnector[id]->encoder.pll;
1186 if (pll->id == pllID)
1206 pll_info* pll = &gConnector[id]->encoder.pll;
1207 return pll->id;
1250 pll_info* pll = &gConnector[connectorIndex]->encoder.pll;
1257 pll->id = ATOM_PPLL_INVALID;
1262 pll->id = ATOM_PPLL2;
1269 pll->id = ATOM_PPLL_INVALID;
1276 pll->id = pll_shared_dp();
1277 if (pll->id != ATOM_PPLL_INVALID)
1281 pll->id = ATOM_PPLL0;
1284 pll->id = ATOM_DCPLL;
1290 pll->id = pll_next_available();
1295 pll->id = ATOM_PPLL1;