drivers/video/fbdev/kyro/STG4000InitDevice.c

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/kyro/STG4000InitDevice.c

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/kyro/STG4000InitDevice.c
Extension
.c
Size
9785 bytes
Lines
324
Domain
Driver Families
Bucket
drivers/video
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

while (R <= STG4K3_PLL_MAX_R) {
			/* estimate required feedback multiplier */
			ulTmp = R * (ulScaleClockReq << OD);

			/* F = ClkRequired * R * (2^OD) / Fref */
			F = (u32)(ulTmp / (refClock >> STG4K3_PLL_SCALER));

			/* compensate for accuracy */
			if (F > STG4K3_PLL_MIN_F)
				F--;


			/*
			 * We should be close to our target frequency (if it's
			 * achievable with current OD & R) let's iterate
			 * through F for best fit
			 */
			while ((F >= STG4K3_PLL_MIN_F) &&
			       (F <= STG4K3_PLL_MAX_F)) {
				/* Calc VCO at full accuracy */
				ulVCO = refClock / R;
				ulVCO = F * ulVCO;

				/*
				 * Check it's within restricted VCO range
				 * unless of course the desired frequency is
				 * above the restricted range, then test
				 * against VCO limit
				 */
				if ((ulVCO >= STG4K3_PLL_MINR_VCO) &&
				    ((ulVCO <= STG4K3_PLL_MAXR_VCO) ||
				     ((coreClock > STG4K3_PLL_MAXR_VCO)
				      && (ulVCO <= STG4K3_PLL_MAX_VCO)))) {
					ulTmp = (ulVCO >> OD);	/* Clock = VCO / (2^OD) */

					/* Is this clock good enough? */
					if ((ulTmp >= ulMinClock)
					    && (ulTmp <= ulMaxClock)) {
						ulPhaseScore = (((refClock / R) - (refClock / STG4K3_PLL_MAX_R))) / ((refClock - (refClock / STG4K3_PLL_MAX_R)) >> 10);

						ulVcoScore = ((ulVCO - STG4K3_PLL_MINR_VCO)) / ((STG4K3_PLL_MAXR_VCO - STG4K3_PLL_MINR_VCO) >> 10);
						ulScore = ulPhaseScore + ulVcoScore;

						if (!ulBestScore) {
							ulBestOD = OD;
							ulBestF = F;
							ulBestR = R;
							ulBestClk = ulTmp;
							ulBestScore =
							    ulScore;
						}
						/* is this better, ( aim for highest Score) */
			/*--------------------------------------------------------------------------
                             Here we want to use a scoring system which will take account of both the
                            value at the phase comparater and the VCO output
                             to do this we will use a cumulative score between the two
                          The way this ends up is that we choose the first value in the loop anyway
                          but we shall keep this code in case new restrictions come into play
                          --------------------------------------------------------------------------*/
						if ((ulScore >= ulBestScore) && (OD > 0)) {
							ulBestOD = OD;
							ulBestF = F;
							ulBestR = R;
							ulBestClk = ulTmp;
							ulBestScore =
							    ulScore;
						}
					}
				}
				F++;
			}
			R++;
		}
	}

	/*
	   did we find anything?
	   Then return RFOD
	 */
	if (ulBestScore) {
		*ROut = ulBestR;
		*FOut = ulBestF;

		if ((ulBestOD == 2) || (ulBestOD == 3)) {
			*POut = 3;
		} else
			*POut = ulBestOD;

	}

Annotation

Implementation Notes