Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1440 lines
47 KiB

  1. /**********************************************************
  2. * Copyright Cirrus Logic, 1997. All rights reserved.
  3. ***********************************************************
  4. *
  5. * 5465BW.C - Bandwidth functions for CL-GD5465
  6. *
  7. ***********************************************************
  8. *
  9. * Author: Rick Tillery
  10. * Date: 03/20/97
  11. *
  12. * Revision History:
  13. * -----------------
  14. * WHO WHEN WHAT/WHY/HOW
  15. * --- ---- ------------
  16. *
  17. ***********************************************************/
  18. #include "precomp.h"
  19. #if defined WINNT_VER35 // WINNT_VER35
  20. // If WinNT 3.5 skip all the source code
  21. #elif defined (NTDRIVER_546x)
  22. // If WinNT 4.0 and 5462/64 build skip all the source code
  23. #else
  24. #ifndef WINNT_VER40
  25. #include "5465BW.h"
  26. #endif
  27. /**********************************************************
  28. *
  29. * ScaleMultiply()
  30. *
  31. * Calculates product of two DWORD factors supplied. If the
  32. * result would overflow a DWORD, the larger of the two factors
  33. * is divided by 2 (shifted right) until the overflow will
  34. * not occur.
  35. *
  36. * Returns: Number of right shifts applied to the product.
  37. * Product of the factors shifted by the value above.
  38. *
  39. ***********************************************************
  40. * Author: Rick Tillery
  41. * Date: 11/18/95
  42. *
  43. * Revision History:
  44. * -----------------
  45. * WHO WHEN WHAT/WHY/HOW
  46. * --- ---- ------------
  47. *********************************************************/
  48. static int ScaleMultiply(DWORD dw1,
  49. DWORD dw2,
  50. LPDWORD pdwResult)
  51. {
  52. int iShift = 0; // Start with no shifts
  53. DWORD dwLimit;
  54. // ODS("ScaleMultiply() called.\n");
  55. // Either factor 0 will be a zero result and also cause a problem
  56. // in our divide below.
  57. if((0 == dw1) || (0 == dw2))
  58. {
  59. *pdwResult = 0;
  60. }
  61. else
  62. {
  63. // Determine which factor is larger
  64. if(dw1 > dw2)
  65. {
  66. // Determine largest number by with dw2 can be multiplied without
  67. // overflowing a DWORD.
  68. dwLimit = 0xFFFFFFFFul / dw2;
  69. // Shift dw1, keeping track of how many times, until it won't
  70. // overflow when multiplied by dw2.
  71. while(dw1 > dwLimit)
  72. {
  73. dw1 >>= 1;
  74. iShift++;
  75. }
  76. }
  77. else
  78. {
  79. // Determine largest number by with dw1 can be multiplied without
  80. // overflowing a DWORD.
  81. dwLimit = 0xFFFFFFFFul / dw1;
  82. // Shift dw2, keeping track of how many times, until it won't
  83. // overflow when multiplied by dw1.
  84. while(dw2 > dwLimit)
  85. {
  86. dw2 >>= 1;
  87. iShift++;
  88. }
  89. }
  90. // Calculate (scaled) product
  91. *pdwResult = dw1 * dw2;
  92. }
  93. // Return the number of shifts we had to use
  94. return(iShift);
  95. }
  96. /**********************************************************
  97. *
  98. * ChipCalcMCLK()
  99. *
  100. * Determines currently set memory clock (MCLK) based on
  101. * register values provided.
  102. *
  103. * Returns: Success and current MCLK in Hz.
  104. *
  105. ***********************************************************
  106. * Author: Rick Tillery
  107. * Date: 03/21/97
  108. *
  109. * Revision History:
  110. * -----------------
  111. * WHO WHEN WHAT/WHY/HOW
  112. * --- ---- ------------
  113. *********************************************************/
  114. BOOL ChipCalcMCLK(LPBWREGS pBWRegs,
  115. LPDWORD pdwMCLK)
  116. {
  117. BOOL fSuccess = FALSE;
  118. // We make the assumption that if the BCLK_Denom /4 is set, the reference
  119. // xtal is 27MHz. If it is not set, we assume the ref xtal is 14.31818MHz.
  120. // This means that 1/2 the 27MHz (13.5MHz) should not be used.
  121. DWORD dwRefXtal = (pBWRegs->BCLK_Denom & 0x02) ? (TVO_XTAL / 4) : REF_XTAL;
  122. ODS("ChipCalcMCLK() called.\n");
  123. *pdwMCLK = (dwRefXtal * (DWORD)pBWRegs->BCLK_Mult) >> 2;
  124. ODS("ChipCalcMCLK(): MCLK = %ld\n", *pdwMCLK);
  125. if(0 == *pdwMCLK)
  126. {
  127. ODS("ChipCalcMCLK(): Calculated invalid MCLK (0).\n");
  128. goto Error;
  129. }
  130. fSuccess = TRUE;
  131. Error:
  132. return(fSuccess);
  133. }
  134. /**********************************************************
  135. *
  136. * ChipCalcVCLK()
  137. *
  138. * Determines currently set pixel clock (VCLK) based on
  139. * register values provided.
  140. *
  141. * Returns: Success and current VCLK in Hz.
  142. *
  143. ***********************************************************
  144. * Author: Rick Tillery
  145. * Date: 11/18/95
  146. *
  147. * Revision History:
  148. * -----------------
  149. * WHO WHEN WHAT/WHY/HOW
  150. * --- ---- ------------
  151. *********************************************************/
  152. BOOL ChipCalcVCLK(LPBWREGS pBWRegs,
  153. LPDWORD pdwVCLK)
  154. {
  155. BOOL fSuccess = FALSE;
  156. BYTE bNum, bDenom;
  157. int iShift;
  158. // We make the assumption that if the BCLK_Denom /4 is set, the reference
  159. // xtal is 27MHz. If it is not set, we assume the ref xtal is 14.31818MHz.
  160. // This means that 1/2 the 27MHz (13.5MHz) should not be used.
  161. // Add 20000000ul to increas Bandwidth.
  162. DWORD dwRefXtal = (pBWRegs->BCLK_Denom & 0x02) ? (TVO_XTAL + 2000000ul) : REF_XTAL;
  163. ODS("ChipCalcVCLK() called dwRef= %ld\n",dwRefXtal);
  164. if(pBWRegs->VCLK3Num & 0x80)
  165. {
  166. fSuccess = ChipCalcMCLK(pBWRegs, pdwVCLK);
  167. goto Error;
  168. }
  169. /*
  170. * VCLK is normally based on one of 4 sets of numerator and
  171. * denominator pairs. However, the CL-GD5465 can only access
  172. * VCLK 3 through the MMI/O.
  173. */
  174. if((pBWRegs->MISCOutput & 0x0C) != 0x0C)
  175. {
  176. ODS("ChipCalcVCLK(): VCLK %d in use. MMI/O can only access VCLK 3.\n",
  177. (int)((pBWRegs->MISCOutput & 0x0C) >> 2));
  178. // goto Error;
  179. }
  180. bNum = pBWRegs->VCLK3Num & 0x7F;
  181. bDenom = (pBWRegs->VCLK3Denom & 0xFE) >> 1;
  182. if(pBWRegs->VCLK3Denom & 0x01)
  183. {
  184. // Apply post scalar
  185. bDenom <<= 1;
  186. }
  187. if(0 == bDenom)
  188. {
  189. ODS("ChipCalcVCLK(): Invalid VCLK denominator (0).\n");
  190. goto Error;
  191. }
  192. // Calculate actual VCLK frequency (Hz)
  193. iShift = ScaleMultiply(dwRefXtal, (DWORD)bNum, pdwVCLK);
  194. *pdwVCLK /= (DWORD)bDenom;
  195. *pdwVCLK >>= iShift;
  196. //Check PLL output Frequency
  197. iShift = ( pBWRegs->GfVdFormat >> 14 );
  198. *pdwVCLK >>= iShift;
  199. ODS("ChipCalcVCLK(): VCLK = %ld\n", *pdwVCLK);
  200. if(0 == *pdwVCLK)
  201. {
  202. ODS("ChipCalcVCLK(): Calculated invalid VCLK (0).\n");
  203. goto Error;
  204. }
  205. fSuccess = TRUE;
  206. Error:
  207. return(fSuccess);
  208. }
  209. /**********************************************************
  210. *
  211. * ChipIsEnoughBandwidth()
  212. *
  213. * Determines whether their is enough bandwidth for the video
  214. * configuration specified in the VIDCONFIG structure with
  215. * the system configuration specified in the BWREGS structure
  216. * and returns the values that need to be programmed into the
  217. * bandwidth related registers. The pProgRegs parameter
  218. * may be NULL to allow checking a configuration only. This
  219. * function gets the register values and passes them to
  220. * ChipCheckBW() to check the bandwidth.
  221. *
  222. *
  223. * Returns: BOOLean indicating whether there is sufficient
  224. * bandwidth for the configuration specified.
  225. * Values to program into bandwidth related registers
  226. * if the pProgRegs parameter is not NULL.
  227. *
  228. ***********************************************************
  229. * Author: Rick Tillery
  230. * Date: 03/20/97
  231. *
  232. * Revision History:
  233. * -----------------
  234. * WHO WHEN WHAT/WHY/HOW
  235. * --- ---- ------------
  236. *********************************************************/
  237. BOOL ChipIsEnoughBandwidth(LPPROGREGS pProgRegs,
  238. LPVIDCONFIG pConfig,
  239. LPBWREGS pBWRegs )
  240. {
  241. BOOL fSuccess = FALSE;
  242. DWORD dwMCLK, dwVCLK;
  243. DWORD dwDenom;
  244. int iNumShift, iDenomShift;
  245. DWORD dwGfxFetch, dwBLTFetch;
  246. DWORD dwGfxFill, dwBLTFill;
  247. DWORD dwMaxGfxThresh, dwMinGfxThresh;
  248. DWORD dwMaxVidThresh, dwMinVidThresh;
  249. DWORD dwHitLatency, dwRandom;
  250. BOOL f500MHZ,fConCurrent;
  251. DWORD dwTemp;
  252. BOOL f585MHZ = TRUE; //PDR#11521
  253. // There are some modes that have the same bandwidth parameters
  254. // like MCLK, VCLK, but have different dwScreenWidht. The bandwidth
  255. // related register settings have major differences for these mode.
  256. // For this reason, dwScreenWidth need to be passed for this function.
  257. DWORD dwScreenWidth;
  258. // ODS("ChipIsEnoughBandwidth() called.\n");
  259. if(!ChipCalcMCLK(pBWRegs, &dwMCLK))
  260. {
  261. ODS("ChipIsEnoughBandwidth(): Unable to calculate MCLK.\n");
  262. goto Error;
  263. }
  264. if(!ChipCalcVCLK(pBWRegs, &dwVCLK))
  265. {
  266. ODS("ChipIsEnoughBandwidth(): Unable to calculate VCLK.\n");
  267. goto Error;
  268. }
  269. if( dwMCLK > 70000000 )
  270. f500MHZ = FALSE;
  271. else
  272. f500MHZ = TRUE;
  273. if ((dwMCLK > 70000000) && ( dwMCLK < 72000000)) //PDR#11521
  274. f585MHZ = TRUE;
  275. else
  276. f585MHZ = FALSE;
  277. dwScreenWidth = (pBWRegs->CR1 + 1 ) << 3;
  278. if( pBWRegs->CR1E & 0x40 )
  279. dwScreenWidth += 0x1000;
  280. ODS("ChipIsEnoughBandwidth(): dwScreenWidth = %ld\n",dwScreenWidth);
  281. dwBLTFetch = (pBWRegs->Control2 & 0x0010) ? 256ul : 128ul;
  282. dwGfxFetch = (pBWRegs->DispThrsTiming & 0x0040) ? 256ul : 128ul;
  283. ODS("GraphicDepth%ld,VideoDepth=%ld",pConfig->uGfxDepth,pConfig->uSrcDepth);
  284. if(pBWRegs->RIFControl & 0xC000)
  285. {
  286. ODS("ChipIsEnoughBandwidth(): Concurrent RDRAM detected!\n");
  287. dwHitLatency = CONC_HIT_LATENCY;
  288. dwRandom = CONC_RANDOM;
  289. fConCurrent = TRUE;
  290. }
  291. else
  292. {
  293. ODS("ChipIsEnoughBandwidth(): Normal RDRAM detected.\n");
  294. dwHitLatency = NORM_HIT_LATENCY;
  295. dwRandom = NORM_RANDOM;
  296. fConCurrent = FALSE;
  297. }
  298. // Determine the number of MCLKs to transfer to the graphics FIFO.
  299. dwGfxFill = (dwGfxFetch * 8ul) / FIFOWIDTH;
  300. // And BLTer FIFO.
  301. dwBLTFill = (dwBLTFetch * 8ul) / FIFOWIDTH;
  302. //
  303. // Determine maximum graphics threshold
  304. //
  305. dwMaxGfxThresh = dwHitLatency + dwGfxFill + (GFXFIFOSIZE / 2ul) -10ul;
  306. // ( K * VCLK * GfxDepth ) GFXFIFOSIZE
  307. // INT( ------------------- ) + ----------- - 1
  308. // ( FIFOWIDTH * MCLK ) 2
  309. iNumShift = ScaleMultiply(dwMaxGfxThresh, dwVCLK, &dwMaxGfxThresh);
  310. iNumShift += ScaleMultiply(dwMaxGfxThresh, (DWORD)pConfig->uGfxDepth,
  311. &dwMaxGfxThresh);
  312. iDenomShift = ScaleMultiply(FIFOWIDTH, dwMCLK, &dwDenom);
  313. if(iNumShift > iDenomShift)
  314. {
  315. dwDenom >>= (iNumShift - iDenomShift);
  316. }
  317. else
  318. {
  319. dwMaxGfxThresh >>= (iDenomShift - iNumShift);
  320. }
  321. dwMaxGfxThresh /= dwDenom;
  322. dwMaxGfxThresh += (GFXFIFOSIZE / 2ul) - 1ul;
  323. if(dwMaxGfxThresh > GFXFIFOSIZE -1 )
  324. dwMaxGfxThresh = GFXFIFOSIZE -1;
  325. ODS("ChipIsEnoughBandwidth(): Max graphics thresh = %ld.\n", dwMaxGfxThresh);
  326. /*
  327. * Determine minimum graphics threshold
  328. */
  329. if(pConfig->dwFlags & VCFLG_DISP)
  330. {
  331. // Video enabled
  332. DWORD dwMinGfxThresh1, dwMinGfxThresh2;
  333. if(pConfig->dwFlags & VCFLG_420)
  334. {
  335. // 4:2:0
  336. dwMinGfxThresh1 = DISP_LATENCY + dwRandom + dwBLTFill
  337. + dwRandom - RIF_SAVINGS + dwBLTFill
  338. + dwRandom - RIF_SAVINGS + VID420FILL
  339. + dwRandom - RIF_SAVINGS + VID420FILL
  340. + dwRandom - RIF_SAVINGS + 1ul;
  341. dwMinGfxThresh2 = DISP_LATENCY + dwRandom + dwBLTFill
  342. + dwRandom - RIF_SAVINGS + dwBLTFill
  343. + dwRandom - RIF_SAVINGS + VID420FILL
  344. + dwRandom - RIF_SAVINGS + VID420FILL
  345. + dwRandom - RIF_SAVINGS + dwGfxFill
  346. + dwRandom - RIF_SAVINGS + dwBLTFill
  347. + dwRandom - RIF_SAVINGS + VID420FILL
  348. + dwRandom - RIF_SAVINGS + VID420FILL
  349. + dwRandom - RIF_SAVINGS + 1ul;
  350. }
  351. else
  352. {
  353. // 4:2:2, 5:5:5, 5:6:5, or X:8:8:8
  354. dwMinGfxThresh1 = DISP_LATENCY + dwRandom + dwBLTFill
  355. + dwRandom - RIF_SAVINGS + dwBLTFill
  356. + dwRandom - RIF_SAVINGS + VIDFILL
  357. + dwRandom - RIF_SAVINGS + 1ul;
  358. dwMinGfxThresh2 = DISP_LATENCY + dwRandom + dwBLTFill
  359. + dwRandom - RIF_SAVINGS + dwBLTFill
  360. + dwRandom - RIF_SAVINGS + VIDFILL
  361. + dwRandom - RIF_SAVINGS + dwGfxFill
  362. + dwRandom - RIF_SAVINGS + dwBLTFill
  363. + dwRandom - RIF_SAVINGS + VIDFILL
  364. + dwRandom - RIF_SAVINGS + 1ul;
  365. }
  366. //
  367. // Finish dwMinGfxThresh1
  368. //
  369. // ( K * VCLK * GfxDepth FIFOWIDTH * MCLK) - 1 )
  370. // INT( ------------------- + --------------------- ) + 1
  371. // ( FIFOWIDTH * MCLK FIFOWIDTH * MCLK )
  372. //
  373. iNumShift = ScaleMultiply(dwMinGfxThresh1, dwVCLK, &dwMinGfxThresh1);
  374. iNumShift += ScaleMultiply(dwMinGfxThresh1, (DWORD)pConfig->uGfxDepth,
  375. &dwMinGfxThresh1);
  376. iDenomShift = ScaleMultiply(FIFOWIDTH, dwMCLK, &dwDenom);
  377. if(iNumShift > iDenomShift)
  378. {
  379. dwDenom >>= (iNumShift - iDenomShift);
  380. }
  381. else
  382. {
  383. dwMinGfxThresh1 >>= (iDenomShift - iNumShift);
  384. }
  385. // Be sure rounding below doesn't overflow.
  386. while((dwMinGfxThresh1 + dwDenom - 1ul) < dwMinGfxThresh1)
  387. {
  388. dwMinGfxThresh1 >>= 1;
  389. dwDenom >>= 1;
  390. }
  391. // Round up
  392. dwMinGfxThresh1 += dwDenom - 1ul;
  393. dwMinGfxThresh1 /= dwDenom;
  394. dwMinGfxThresh1++; // Compensate for decrement by 2
  395. //
  396. // Finish dwMinGfxThresh2
  397. //
  398. // ( K * VCLK * GfxDepth (FIFOWIDTH * MCLK) - 1 ) GfxFetch * 8
  399. // INT( ------------------- + ---------------------- ) - ------------ + 1
  400. // ( FIFOWIDTH * MCLK FIFOWIDTH * MCLK ) FIFOWIDTH
  401. //
  402. iNumShift = ScaleMultiply(dwMinGfxThresh2, dwVCLK, &dwMinGfxThresh2);
  403. iNumShift += ScaleMultiply(dwMinGfxThresh2, (DWORD)pConfig->uGfxDepth,
  404. &dwMinGfxThresh2);
  405. iDenomShift = ScaleMultiply(FIFOWIDTH, dwMCLK, &dwDenom);
  406. if(iNumShift > iDenomShift)
  407. {
  408. dwDenom >>= (iNumShift - iDenomShift);
  409. }
  410. else
  411. {
  412. dwMinGfxThresh2 >>= (iDenomShift - iNumShift);
  413. }
  414. // Be sure rounding below doesn't overflow.
  415. while((dwMinGfxThresh2 + dwDenom - 1ul) < dwMinGfxThresh2)
  416. {
  417. dwMinGfxThresh2 >>= 1;
  418. dwDenom >>= 1;
  419. }
  420. // Round up
  421. dwMinGfxThresh2 += dwDenom - 1ul;
  422. dwMinGfxThresh2 /= dwDenom;
  423. // Adjust for second transfer
  424. dwMinGfxThresh2 -= ((dwGfxFetch * 8ul) / FIFOWIDTH);
  425. // Adjust for decrement by 2
  426. dwMinGfxThresh2++;
  427. if( fConCurrent)
  428. {
  429. if( f500MHZ)
  430. {
  431. if( (pConfig->uGfxDepth == 32) && ( dwVCLK >= 64982518ul ))
  432. {
  433. dwTemp = ( dwVCLK - 64982518ul) /1083333ul + 1ul;
  434. dwMinGfxThresh2 -= dwTemp;
  435. dwMinGfxThresh1 -= 10;
  436. }
  437. else if( (pConfig->uGfxDepth == 24) && (dwVCLK > 94500000ul))
  438. dwMinGfxThresh2 -=5; //Adjust again for 24 bit #xc
  439. }
  440. else //600MHZ
  441. {
  442. if( (pConfig->uGfxDepth == 16) && ( dwVCLK > 156000000ul))
  443. dwMinGfxThresh2 -= 4;
  444. else if( (pConfig->uGfxDepth == 24) && ( dwVCLK > 104000000ul))
  445. {
  446. dwMinGfxThresh2 -= (5ul+ 8ul * (dwVCLK - 104000000ul) / 17000000ul);
  447. }
  448. else if( (pConfig->uGfxDepth == 32) )
  449. {
  450. if( dwVCLK > 94000000ul)
  451. dwMinGfxThresh2 -= 16;
  452. if( dwVCLK > 70000000ul)
  453. dwMinGfxThresh2 -= 4;
  454. else
  455. dwMinGfxThresh2 +=6; //#PDR#11506 10x7x32bit could not
  456. //support YUV420.
  457. }
  458. }
  459. if( (pConfig->uGfxDepth == 8) && (dwVCLK > 18000000ul))
  460. dwMinGfxThresh2 += 6;
  461. }
  462. else //Normal RDRam
  463. {
  464. if( f500MHZ )
  465. {
  466. if( (pConfig->uGfxDepth == 32) && ( dwVCLK > 49500000ul ))
  467. {
  468. dwMinGfxThresh1 -= 4;
  469. dwMinGfxThresh2 -= (( dwVCLK - 49715909ul) / 726981ul + 3ul);
  470. }
  471. else if( (pConfig->uGfxDepth == 24) && ( dwVCLK > 60000000ul )
  472. && (dwVCLK < 95000000ul))
  473. {
  474. dwTemp= ((dwVCLK - 64982518ul) / 1135287ul + 3ul);
  475. dwMinGfxThresh2 -=dwTemp;
  476. dwMinGfxThresh1 -= 10;
  477. }
  478. }
  479. else //600MHZ case
  480. {
  481. if( (pConfig->uGfxDepth == 32) && ( dwVCLK > 49700000ul ))
  482. {
  483. dwTemp= ((dwVCLK - 49700000ul) / 1252185ul + 5ul);
  484. dwMinGfxThresh2 -= dwTemp;
  485. dwMinGfxThresh1 -= 4ul;
  486. }
  487. else if( (pConfig->uGfxDepth == 24) && ( dwVCLK > 60000000ul ))
  488. {
  489. dwTemp= ((dwVCLK - 64982518ul) / 2270575ul + 4ul);
  490. dwMinGfxThresh2 -=dwTemp;
  491. dwMinGfxThresh1 -= 8;
  492. }
  493. else if( pConfig->uGfxDepth == 16)
  494. {
  495. dwMinGfxThresh2 -= 4;
  496. }
  497. else if( pConfig->uGfxDepth == 8)
  498. {
  499. if(dwVCLK >170000000)
  500. dwMinGfxThresh1 += 10;
  501. else
  502. dwMinGfxThresh1 += 4;
  503. }
  504. }
  505. }
  506. ODS("ChipIsEnoughBandwidth(): Min graphics thresh1 2 = %ld,%ld.\n",
  507. dwMinGfxThresh1, dwMinGfxThresh2);
  508. // Adjust for unsigned overflow
  509. if(dwMinGfxThresh2 > GFXFIFOSIZE + 20ul)
  510. {
  511. dwMinGfxThresh2 = 0ul;
  512. }
  513. //
  514. // Whichever is higher should be the right one
  515. //
  516. dwMinGfxThresh = __max(dwMinGfxThresh1, dwMinGfxThresh2);
  517. }
  518. else
  519. {
  520. // No video enabled
  521. dwMinGfxThresh = DISP_LATENCY + dwRandom + dwBLTFill
  522. + dwRandom - RIF_SAVINGS + 1ul;
  523. // ( K * VCLK * GfxDepth (FIFOWIDTH * MCLK) - 1 )
  524. // INT( ------------------- + ---------------------- )
  525. // ( FIFOWIDTH * MCLK FIFOWIDTH * MCLK )
  526. iNumShift = ScaleMultiply(dwMinGfxThresh, dwVCLK, &dwMinGfxThresh);
  527. iNumShift += ScaleMultiply(dwMinGfxThresh, (DWORD)pConfig->uGfxDepth,
  528. &dwMinGfxThresh);
  529. iDenomShift = ScaleMultiply(FIFOWIDTH, dwMCLK, &dwDenom);
  530. if(iNumShift > iDenomShift)
  531. {
  532. dwDenom >>= (iNumShift - iDenomShift);
  533. }
  534. else
  535. {
  536. dwMinGfxThresh >>= (iDenomShift - iNumShift);
  537. }
  538. // Be sure rounding below doesn't overflow.
  539. while((dwMinGfxThresh + dwDenom - 1ul) < dwMinGfxThresh)
  540. {
  541. dwMinGfxThresh >>= 1;
  542. dwDenom >>= 1;
  543. }
  544. // Round up
  545. dwMinGfxThresh += dwDenom - 1ul;
  546. dwMinGfxThresh /= dwDenom;
  547. dwMinGfxThresh++; // Compensate for decrement by 2
  548. }
  549. ODS("ChipIsEnoughBandwidth(): Min graphics thresh = %ld.\n", dwMinGfxThresh);
  550. if(dwMaxGfxThresh < dwMinGfxThresh)
  551. {
  552. ODS("ChipIsEnoughBandwidth(): Minimum graphics threshold exceeds maximum.\n");
  553. goto Error;
  554. }
  555. if(pProgRegs)
  556. {
  557. pProgRegs->DispThrsTiming = (WORD)dwMinGfxThresh;
  558. }
  559. ODS("xfer=%x,cap=%x,src=%x,dsp=%x\n",pConfig->sizXfer.cx,pConfig->sizCap.cx,
  560. pConfig->sizSrc.cx,pConfig->sizDisp.cx);
  561. // Start-of-line check is only for capture
  562. if(pConfig->dwFlags & VCFLG_CAP)
  563. {
  564. DWORD dwNonCapMCLKs, dwCapMCLKs;
  565. // Do start-of-line check to be sure capture FIFO does not overflow.
  566. // First determine the number of MCLK cycles at the start of the line.
  567. // We'll compare this to the number of levels of the capture FIFO
  568. // filled during the same time to make sure the capture FIFO doesn't
  569. // overflow.
  570. // Start of line: BLT + HC + V + G + V + G
  571. dwNonCapMCLKs = dwRandom + dwBLTFill;
  572. // Hardware cursor is only necessary if it is on, however, since it can
  573. // be enabled or disabled, and VPM has no way of knowing when this
  574. // occurs, we must always assume it is on.
  575. dwNonCapMCLKs += dwRandom - RIF_SAVINGS + CURSORFILL;
  576. if(pConfig->dwFlags & VCFLG_DISP)
  577. {
  578. // Only one video fill is required, however if the video FIFO threshold
  579. // is greater than 1/2, the second fill will be done. Also, because of
  580. // the tiled architecture, even though the video might not be aligned,
  581. // the transfer will occur on a tile boundary. If the transfer of a
  582. // single tile cannot fulfill the FIFO request, the second fill will be
  583. // done. Since the pitch will vary, and the client can move the source
  584. // around, we must always assume that the second video FIFO fill will
  585. // be done.
  586. if(pConfig->dwFlags & VCFLG_420)
  587. {
  588. dwNonCapMCLKs += 4ul * (dwRandom - RIF_SAVINGS + VID420FILL);
  589. }
  590. else
  591. {
  592. dwNonCapMCLKs += 2ul * (dwRandom - RIF_SAVINGS + VIDFILL);
  593. }
  594. }
  595. // The graphics FIFO fill depends on the fetch size. We also assume that
  596. // the pitch is a multiple of the fetch width.
  597. dwNonCapMCLKs += dwRandom - RIF_SAVINGS + dwGfxFill;
  598. // The second graphics FIFO fill will be done if:
  599. // 1. The graphics is not aligned on a fetch boundary (panning).
  600. // 2. The FIFO threshold is over 1/2 the FIFO (the fill size).
  601. if((dwMinGfxThresh >= dwGfxFill) || (pConfig->dwFlags & VCFLG_PAN))
  602. {
  603. dwNonCapMCLKs += dwRandom - RIF_SAVINGS + dwGfxFill;
  604. }
  605. dwNonCapMCLKs += 3; // Magic number that seems to work for now.
  606. ODS("ChipIsEnoughBandwidth(): dwNonCapMCLKs = %ld\n", dwNonCapMCLKs);
  607. // sizXfer.cx * FIFOWIDTH * (CAPFIFOSIZE / 2) * dwMCLK
  608. // ---------------------------------------------------
  609. // dwXferRate * uCapDepth * sizCap.cx
  610. iNumShift = ScaleMultiply((DWORD)pConfig->sizXfer.cx, FIFOWIDTH,
  611. &dwCapMCLKs);
  612. iNumShift += ScaleMultiply(dwCapMCLKs, (CAPFIFOSIZE / 2), &dwCapMCLKs);
  613. iNumShift += ScaleMultiply(dwCapMCLKs, dwMCLK, &dwCapMCLKs);
  614. iDenomShift = ScaleMultiply(pConfig->dwXferRate, (DWORD)pConfig->uCapDepth,
  615. &dwDenom);
  616. iDenomShift += ScaleMultiply(dwDenom, (DWORD)pConfig->sizCap.cx, &dwDenom);
  617. if(iNumShift > iDenomShift)
  618. {
  619. dwDenom >>= (iNumShift - iDenomShift);
  620. }
  621. else
  622. {
  623. dwCapMCLKs >>= (iDenomShift - iNumShift);
  624. }
  625. dwCapMCLKs /= dwDenom;
  626. ODS("ChipIsEnoughBandwidth(): dwCapMCLKs = %ld\n", dwCapMCLKs);
  627. if(fConCurrent)
  628. {
  629. if( pConfig->uGfxDepth == 32)
  630. dwCapMCLKs -= 44; //adjust 32 bit
  631. }
  632. if(dwNonCapMCLKs > dwCapMCLKs)
  633. {
  634. ODS("ChipIsEnoughBandwidth(): Capture overflow at start of line.\n");
  635. goto Error;
  636. }
  637. }
  638. if(pConfig->dwFlags & VCFLG_DISP)
  639. {
  640. /*
  641. * Determine maximum video threshold
  642. */
  643. dwMaxVidThresh = dwHitLatency;
  644. if(pConfig->dwFlags & VCFLG_420)
  645. {
  646. dwMaxVidThresh += VID420FILL;
  647. if( !f500MHZ && fConCurrent )
  648. dwMaxVidThresh += 5;
  649. }
  650. else
  651. {
  652. dwMaxVidThresh += VIDFILL;
  653. }
  654. // ( K * VCLK * VidDepth * SrcWidth )
  655. // INT( ------------------------------ ) + VidFill (/ 2) - 1
  656. // ( FIFOWIDTH * MCLK * DispWidth ) ^non-4:2:0 only
  657. iNumShift = ScaleMultiply(dwMaxVidThresh, dwVCLK, &dwMaxVidThresh);
  658. iNumShift += ScaleMultiply(dwMaxVidThresh, (DWORD)pConfig->uSrcDepth,
  659. &dwMaxVidThresh);
  660. iNumShift += ScaleMultiply(dwMaxVidThresh, (DWORD)pConfig->sizSrc.cx,
  661. &dwMaxVidThresh);
  662. iDenomShift = ScaleMultiply(FIFOWIDTH, (DWORD)pConfig->sizDisp.cx, &dwDenom);
  663. iDenomShift += ScaleMultiply(dwDenom, dwMCLK, &dwDenom);
  664. if(iNumShift > iDenomShift)
  665. {
  666. dwDenom >>= (iNumShift - iDenomShift);
  667. }
  668. else
  669. {
  670. dwMaxVidThresh >>= (iDenomShift - iNumShift);
  671. }
  672. dwMaxVidThresh /= dwDenom;
  673. if(pConfig->dwFlags & VCFLG_420)
  674. {
  675. dwMaxVidThresh += VID420FILL;
  676. }
  677. else
  678. {
  679. dwMaxVidThresh += VIDFILL;
  680. // Threshold is programmed in DQWORDS for non-4:2:0
  681. dwMaxVidThresh /= 2ul;
  682. }
  683. dwMaxVidThresh--;
  684. ODS("ChipIsEnoughBandwidth(): Max video thresh = %ld.\n", dwMaxVidThresh);
  685. if( fConCurrent && f500MHZ && ( dwVCLK < 66000000ul))
  686. dwMaxVidThresh = __min(dwMaxVidThresh, 8);
  687. /*
  688. * Determine minimum video threshold
  689. */
  690. {
  691. DWORD dwMinVidThresh1, dwMinVidThresh2;
  692. if(pConfig->dwFlags & VCFLG_420)
  693. {
  694. // 4:2:0
  695. dwMinVidThresh1 = DISP_LATENCY + dwRandom + dwGfxFill
  696. + dwRandom - RIF_SAVINGS + VID420FILL
  697. + dwRandom - RIF_SAVINGS + 1;
  698. dwMinVidThresh2 = DISP_LATENCY + dwRandom + dwGfxFill
  699. + dwRandom - RIF_SAVINGS + VID420FILL
  700. + dwRandom - RIF_SAVINGS + VID420FILL
  701. + dwRandom - RIF_SAVINGS + VID420FILL
  702. + dwRandom - RIF_SAVINGS + 1;
  703. }
  704. else
  705. {
  706. // 4:2:2, 5:5:5, 5:6:5, or X:8:8:8
  707. dwMinVidThresh1 = DISP_LATENCY + dwRandom + dwGfxFill
  708. + dwRandom - RIF_SAVINGS + 2;
  709. dwMinVidThresh2 = DISP_LATENCY + dwRandom + dwGfxFill
  710. + dwRandom - RIF_SAVINGS + VIDFILL
  711. + 15ul //#xc
  712. // + 10ul
  713. + dwRandom - RIF_SAVINGS + dwGfxFill
  714. + dwRandom - RIF_SAVINGS + 2ul;
  715. if(fConCurrent)
  716. {
  717. if(f500MHZ )
  718. {
  719. if( (pConfig->uGfxDepth == 32) && ( dwVCLK > 60000000ul ))
  720. {
  721. if( dwVCLK > 94000000ul)
  722. dwMinVidThresh1 += 105;
  723. else if( dwVCLK > 74000000ul)
  724. dwMinVidThresh1 += 90;
  725. else
  726. dwMinVidThresh1 += 65;
  727. if(pConfig->dwFlags & VCFLG_CAP)
  728. {
  729. if(dwVCLK > 78000000ul)
  730. dwMinVidThresh1 += 260; //disable video
  731. else if( dwVCLK > 74000000ul)
  732. dwMinVidThresh1 += 70;
  733. }
  734. }
  735. else if( pConfig->uGfxDepth == 24)
  736. {
  737. if( dwVCLK > 94500000ul)
  738. {
  739. if(dwScreenWidth == 1024)
  740. dwMinVidThresh2 += 50ul;
  741. else
  742. dwMinVidThresh2 += 90ul;
  743. }
  744. else if( dwVCLK < 41000000ul)
  745. {
  746. dwMinVidThresh2 += 4;
  747. }
  748. else if(dwVCLK < 80000000ul)
  749. {
  750. if( (dwVCLK > 74000000ul) && (dwVCLK < 76000000ul))
  751. {
  752. dwMinVidThresh2 -= 1;
  753. }
  754. else
  755. dwMinVidThresh2 -= 8;
  756. dwMinVidThresh1 -= 4;
  757. }
  758. if(pConfig->dwFlags & VCFLG_CAP)
  759. if( dwVCLK > 94000000ul)
  760. {
  761. if((dwVCLK < 95000000ul) && ( dwGfxFetch == 256 ))
  762. dwMinVidThresh2 += 60;
  763. else
  764. dwMinVidThresh2 += 120;
  765. }
  766. }
  767. else if( (pConfig->uGfxDepth == 16) && ( dwVCLK > 60000000ul ))
  768. {
  769. if( dwVCLK < 94000000ul)
  770. {
  771. dwMinVidThresh2 -= 10;
  772. dwMinVidThresh1 -= 6;
  773. }
  774. else if( dwVCLK > 105000000ul)
  775. dwMinVidThresh2 += 50;
  776. }
  777. else if( (pConfig->uGfxDepth == 8) && ( dwVCLK > 60000000ul ))
  778. {
  779. if( dwVCLK > 216000000ul)
  780. {
  781. dwMinVidThresh2 += 50;
  782. dwMinVidThresh1 += 20;
  783. }
  784. else if( (dwVCLK < 95000000ul) && ( dwScreenWidth <= 1024))
  785. {
  786. dwMinVidThresh2 -= 12;
  787. dwMinVidThresh1 -= 10;
  788. dwMaxVidThresh = __min(dwMaxVidThresh, 9);
  789. }
  790. else if(dwVCLK < 109000000ul)
  791. {
  792. dwMinVidThresh2 += ( 14 - 4 * ( dwVCLK - 94000000ul ) / 14000000ul );
  793. dwMinVidThresh1 += 10;
  794. dwMaxVidThresh = __min(dwMaxVidThresh, 8);
  795. }
  796. else
  797. {
  798. dwMinVidThresh2 += 7;
  799. dwMinVidThresh1 += 4;
  800. }
  801. }
  802. }
  803. #if 1//PDR#11521
  804. else if (f585MHZ) //585MHZ
  805. {
  806. if( (pConfig->uGfxDepth == 8) && ( dwVCLK > 56000000ul))
  807. {
  808. if( dwVCLK > 200000000ul)
  809. {
  810. dwMaxVidThresh++;
  811. dwMinVidThresh1 += 7;
  812. dwMinVidThresh2 += 14;
  813. }
  814. else if( dwVCLK < 60000000ul)
  815. {
  816. dwMinVidThresh2 += 8;
  817. }
  818. else if( dwVCLK < 160000000ul)
  819. {
  820. dwMinVidThresh1 -=20;
  821. dwMinVidThresh2 -=10;
  822. }
  823. if(pConfig->dwFlags & VCFLG_CAP)
  824. {
  825. if( dwVCLK < 76000000ul)
  826. dwMinVidThresh2 +=8;
  827. else if( dwVCLK < 140000000ul)
  828. dwMinVidThresh2 +=25;
  829. else
  830. dwMinVidThresh2 +=32;
  831. }
  832. }
  833. else if( (pConfig->uGfxDepth == 16) && ( dwVCLK > 60000000ul))
  834. {
  835. if( dwVCLK > 157000000ul)
  836. {
  837. dwMinVidThresh1 += 27;
  838. dwMaxVidThresh ++;
  839. }
  840. if( dwVCLK > 125000000ul)
  841. {
  842. dwMinVidThresh1 += 40;
  843. }
  844. else if( dwVCLK > 107000000ul)
  845. {
  846. dwMinVidThresh1 += 34;
  847. }
  848. else
  849. if( dwVCLK > 74000000ul)
  850. {
  851. dwMinVidThresh1 += 18;
  852. }
  853. if( dwVCLK > 189000000ul) //PDR11521
  854. dwMaxVidThresh ++;
  855. if(pConfig->dwFlags & VCFLG_CAP)
  856. {
  857. if( dwVCLK > 74000000ul)
  858. dwMinVidThresh1 +=2;
  859. }
  860. }
  861. else if( pConfig->uGfxDepth == 24)
  862. {
  863. if( dwVCLK < 60000000ul)
  864. {
  865. dwMinVidThresh1 -= 8;
  866. dwMinVidThresh2 -= 16;
  867. }
  868. else if( dwVCLK > 107000000ul )
  869. dwMinVidThresh2 += 84;
  870. else if( (dwVCLK > 94000000ul) && (dwScreenWidth >= 1152))
  871. {
  872. dwMinVidThresh2 += 40;
  873. }
  874. if( dwVCLK > 126000000ul) //PDR11521
  875. dwMaxVidThresh ++;
  876. if(pConfig->dwFlags & VCFLG_CAP)
  877. {
  878. if( dwVCLK > 74000000ul)
  879. dwMinVidThresh2 +=12;
  880. }
  881. }
  882. else if(( pConfig->uGfxDepth == 32) && ( dwVCLK > 60000000ul))
  883. {
  884. if( dwVCLK > 74000000ul)
  885. {
  886. if( (dwVCLK > 77000000ul) && ( dwVCLK < 80000000ul))
  887. dwMinVidThresh2 += 120;
  888. else
  889. dwMinVidThresh2 += 83;
  890. }
  891. else
  892. dwMinVidThresh2 += 30;
  893. if( dwVCLK > 94000000ul) //PDR11521
  894. dwMaxVidThresh ++;
  895. if(pConfig->dwFlags & VCFLG_CAP)
  896. {
  897. if( dwVCLK > 94000000ul)
  898. dwMinVidThresh2 +=2;
  899. }
  900. }
  901. else if(( pConfig->uGfxDepth == 32) && ( dwVCLK > 49000000ul))
  902. {
  903. if(pConfig->dwFlags & VCFLG_CAP)
  904. dwMinVidThresh2 +=2;
  905. }
  906. }
  907. #endif
  908. else //600MZH concurrent
  909. {
  910. if( (pConfig->uGfxDepth == 8) && ( dwVCLK > 56000000ul))
  911. {
  912. if( dwVCLK > 200000000ul)
  913. {
  914. //PDR#11541 dwMaxVidThresh++;
  915. dwMinVidThresh1 += 7;
  916. dwMinVidThresh2 += 14;
  917. }
  918. else if( dwVCLK < 60000000ul)
  919. {
  920. dwMinVidThresh2 += 8;
  921. }
  922. else if( dwVCLK < 160000000ul)
  923. {
  924. dwMinVidThresh1 -=20;
  925. dwMinVidThresh2 -=10;
  926. }
  927. if(pConfig->dwFlags & VCFLG_CAP)
  928. {
  929. if( dwVCLK < 76000000ul)
  930. dwMinVidThresh2 +=8;
  931. else if( dwVCLK < 140000000ul)
  932. dwMinVidThresh2 +=25;
  933. else
  934. dwMinVidThresh2 +=32;
  935. }
  936. }
  937. else if( (pConfig->uGfxDepth == 16) && ( dwVCLK > 60000000ul))
  938. {
  939. if( dwVCLK > 157000000ul)
  940. {
  941. dwMinVidThresh1 += 27;
  942. //PDR#11541 dwMaxVidThresh ++;
  943. }
  944. if( dwVCLK > 125000000ul)
  945. {
  946. dwMinVidThresh1 += 40;
  947. }
  948. else if( dwVCLK > 107000000ul)
  949. {
  950. dwMinVidThresh1 += 34;
  951. }
  952. else
  953. if( dwVCLK > 74000000ul)
  954. {
  955. dwMinVidThresh1 += 18;
  956. }
  957. if(pConfig->dwFlags & VCFLG_CAP)
  958. {
  959. if( dwVCLK > 74000000ul)
  960. dwMinVidThresh1 +=2;
  961. }
  962. }
  963. else if( pConfig->uGfxDepth == 24)
  964. {
  965. if( dwVCLK < 60000000ul)
  966. {
  967. dwMinVidThresh1 -= 8;
  968. dwMinVidThresh2 -= 16;
  969. }
  970. else if( dwVCLK > 107000000ul )
  971. dwMinVidThresh2 += 84;
  972. else if( (dwVCLK > 94000000ul) && (dwScreenWidth >= 1152))
  973. {
  974. dwMinVidThresh2 += 40;
  975. }
  976. if(pConfig->dwFlags & VCFLG_CAP)
  977. {
  978. if( dwVCLK > 74000000ul)
  979. dwMinVidThresh2 +=12;
  980. }
  981. }
  982. else if(( pConfig->uGfxDepth == 32) && ( dwVCLK > 60000000ul))
  983. {
  984. if( dwVCLK > 74000000ul)
  985. {
  986. if( (dwVCLK > 77000000ul) && ( dwVCLK < 80000000ul))
  987. dwMinVidThresh2 += 120;
  988. else
  989. dwMinVidThresh2 += 83;
  990. }
  991. else
  992. dwMinVidThresh2 += 30;
  993. if(pConfig->dwFlags & VCFLG_CAP)
  994. {
  995. if( dwVCLK > 94000000ul)
  996. dwMinVidThresh2 +=2;
  997. }
  998. }
  999. else if(( pConfig->uGfxDepth == 32) && ( dwVCLK > 49000000ul))
  1000. {
  1001. if(pConfig->dwFlags & VCFLG_CAP)
  1002. dwMinVidThresh2 +=2;
  1003. }
  1004. }
  1005. }
  1006. else //Normal RDRam case
  1007. {
  1008. if(f500MHZ )
  1009. {
  1010. if( (pConfig->uGfxDepth == 32) && ( dwVCLK > 60000000ul ))
  1011. {
  1012. dwMinVidThresh1 += 75;
  1013. if(pConfig->dwFlags & VCFLG_CAP)
  1014. dwMinVidThresh1 +=20;
  1015. }
  1016. else if( (pConfig->uGfxDepth == 24) && ( dwVCLK > 7800000ul ))
  1017. {
  1018. dwMinVidThresh2 += 52;
  1019. if(pConfig->dwFlags & VCFLG_CAP)
  1020. {
  1021. dwMinVidThresh2 += 50;
  1022. }
  1023. }
  1024. else if(pConfig->uGfxDepth == 16)
  1025. {
  1026. if((dwVCLK > 36000000 ) && ( dwVCLK < 57000000))
  1027. {
  1028. dwMinVidThresh2 += 22 - ( dwVCLK - 36000000) * 3L /
  1029. 4000000;
  1030. }
  1031. else
  1032. {
  1033. dwMinVidThresh2 -= 18;
  1034. dwMinVidThresh1 -= 8;
  1035. }
  1036. if(pConfig->dwFlags & VCFLG_CAP)
  1037. {
  1038. dwMinVidThresh2 += 5;
  1039. }
  1040. }
  1041. else if((pConfig->uGfxDepth == 8) && ( dwVCLK > 36000000ul ))
  1042. {
  1043. if(dwVCLK > 160000000ul)
  1044. dwMinVidThresh2 -= 6;
  1045. else if( (dwVCLK > 94000000 ) && (dwVCLK < 109000000) && (dwScreenWidth == 1152))
  1046. {
  1047. dwMinVidThresh2 -= 2 + 4 * ( dwVCLK - 94000000 ) / 13500000;
  1048. }
  1049. else if( (dwVCLK < 109000000) && (dwScreenWidth == 1280))
  1050. {
  1051. dwMinVidThresh2 -= 5;
  1052. }
  1053. else if( dwVCLK > 60000000ul)
  1054. {
  1055. dwMinVidThresh2 -= 18;
  1056. if(pConfig->dwFlags & VCFLG_CAP)
  1057. {
  1058. dwMinVidThresh2 += 5;
  1059. }
  1060. }
  1061. else
  1062. dwMinVidThresh2 += 6;
  1063. dwMinVidThresh1 -= 8;
  1064. }
  1065. }
  1066. else //600 MHZ
  1067. {
  1068. if(pConfig->uGfxDepth == 32)
  1069. {
  1070. if( dwVCLK > 60000000ul )
  1071. {
  1072. dwTemp = ( dwVCLK - 60000000ul ) /300000ul + 38ul;
  1073. dwMinVidThresh1 += dwTemp;
  1074. }
  1075. if((pConfig->dwFlags & VCFLG_CAP) && (dwVCLK > 40000000ul))
  1076. {
  1077. if(dwVCLK > 94000000ul)
  1078. dwTemp = 120; //disable capture;
  1079. else
  1080. dwTemp = ( dwVCLK - 40006685ul) /1085905ul + 5;
  1081. dwMinVidThresh1 +=dwTemp;
  1082. }
  1083. }
  1084. else if( pConfig->uGfxDepth == 24)
  1085. {
  1086. if( dwVCLK < 50000000ul)
  1087. dwMinVidThresh2 -= 5;
  1088. else
  1089. dwMinVidThresh2 -= 18;
  1090. dwMinVidThresh1 -= 8;
  1091. if((pConfig->dwFlags & VCFLG_CAP) && (dwVCLK > 94000000ul))
  1092. dwMinVidThresh2 += 8;
  1093. }
  1094. else if(pConfig->uGfxDepth == 16)
  1095. {
  1096. if( (dwVCLK < 100000000ul ) && (dwVCLK > 66000000ul))
  1097. {
  1098. dwTemp = 31ul - (dwVCLK -60000000ul) / 1968750ul;
  1099. }
  1100. else if( dwVCLK <= 66000000ul) //after 1024X768 only adjust constantly
  1101. {
  1102. if( dwVCLK < 57000000ul)
  1103. {
  1104. dwTemp = 0ul;
  1105. dwMinVidThresh2 += 10ul;
  1106. }
  1107. else
  1108. dwTemp = 5ul;
  1109. }
  1110. if(dwVCLK > 100000000ul)
  1111. {
  1112. dwMinVidThresh2 += 40ul;
  1113. dwMinVidThresh1 += 20ul;
  1114. }
  1115. else
  1116. {
  1117. dwMinVidThresh2 -= dwTemp;
  1118. dwMinVidThresh1 -= 8ul;
  1119. }
  1120. }
  1121. else if(pConfig->uGfxDepth == 8)
  1122. {
  1123. if((dwVCLK > 94000000ul) && ( dwScreenWidth >=1152))
  1124. {
  1125. if(dwVCLK > 108000000ul)
  1126. dwMinVidThresh2 += 10;
  1127. else
  1128. dwMinVidThresh2 += 20;
  1129. dwMinVidThresh1 += 1;
  1130. }
  1131. else if( dwVCLK > 64000000ul )
  1132. {
  1133. if( dwVCLK > 70000000ul)
  1134. dwTemp = 25;
  1135. else
  1136. dwTemp = 5;
  1137. if(pConfig->dwFlags & VCFLG_CAP)
  1138. {
  1139. if(dwVCLK < 760000000ul )
  1140. dwTemp = 0;
  1141. else if(dwVCLK < 950000000ul)
  1142. dwTemp -= 10;
  1143. }
  1144. dwMinVidThresh2 -= dwTemp;
  1145. dwMinVidThresh1 -= 15;
  1146. }
  1147. }
  1148. }
  1149. }
  1150. }
  1151. //
  1152. // Finish dwMinVidThresh1
  1153. //
  1154. // ( K * VidDepth * SrcWidth * VCLK (FIFOWIDTH * DispWidth * MCLK) - 1 )
  1155. // INT( ------------------------------ + ---------------------------------- ) (/ 2) + 1
  1156. // ( FIFOWIDTH * DispWidth * MCLK FIFOWIDTH * DispWidth * MCLK )
  1157. iNumShift = ScaleMultiply(dwMinVidThresh1, (DWORD)pConfig->uSrcDepth,
  1158. &dwMinVidThresh1);
  1159. iNumShift += ScaleMultiply(dwMinVidThresh1, (DWORD)pConfig->sizSrc.cx,
  1160. &dwMinVidThresh1);
  1161. iNumShift += ScaleMultiply(dwMinVidThresh1, dwVCLK, &dwMinVidThresh1);
  1162. iDenomShift = ScaleMultiply(FIFOWIDTH, (DWORD)pConfig->sizDisp.cx,
  1163. &dwDenom);
  1164. iDenomShift += ScaleMultiply(dwDenom, dwMCLK, &dwDenom);
  1165. if(iNumShift > iDenomShift)
  1166. {
  1167. dwDenom >>= (iNumShift - iDenomShift);
  1168. }
  1169. else
  1170. {
  1171. dwMinVidThresh1 >>= (iDenomShift - iNumShift);
  1172. }
  1173. // Be sure rounding below doesn't overflow (it happened!)
  1174. while((dwMinVidThresh1 + dwDenom - 1ul) < dwMinVidThresh1)
  1175. {
  1176. dwMinVidThresh1 >>= 1;
  1177. dwDenom >>= 1;
  1178. }
  1179. dwMinVidThresh1 += dwDenom - 1ul;
  1180. dwMinVidThresh1 /= dwDenom;
  1181. if(!(pConfig->dwFlags & VCFLG_420))
  1182. {
  1183. // Threshold is programmed in DQWORDS for non-4:2:0
  1184. dwMinVidThresh1 /= 2ul;
  1185. }
  1186. dwMinVidThresh1++; // Adjust for -2 decrement of FIFO count done to
  1187. // synchronize MCLK with faster VCLK.
  1188. //
  1189. // Finish dwMinVidThresh2
  1190. //
  1191. // K * VidDepth * VidWidth * VCLK (FIFOWIDTH * DispWidth * MCLK) - 1
  1192. // ------------------------------ + ----------------------------------
  1193. // FIFOWIDTH * DispWidth * MCLK FIFOWIDTH * DispWidth * MCLK
  1194. //
  1195. // VIDFIFOSIZE
  1196. // - ----------- (/ 2) + 1
  1197. // 2 ^non-4:2:0 only
  1198. iNumShift = ScaleMultiply(dwMinVidThresh2, (DWORD)pConfig->uSrcDepth,
  1199. &dwMinVidThresh2);
  1200. iNumShift += ScaleMultiply(dwMinVidThresh2, (DWORD)pConfig->sizSrc.cx,
  1201. &dwMinVidThresh2);
  1202. iNumShift += ScaleMultiply(dwMinVidThresh2, dwVCLK, &dwMinVidThresh2);
  1203. iDenomShift = ScaleMultiply(FIFOWIDTH, (DWORD)pConfig->sizDisp.cx,
  1204. &dwDenom);
  1205. iDenomShift += ScaleMultiply(dwDenom, dwMCLK, &dwDenom);
  1206. if(iNumShift > iDenomShift)
  1207. {
  1208. dwDenom >>= (iNumShift - iDenomShift);
  1209. }
  1210. else
  1211. {
  1212. dwMinVidThresh2 >>= (iDenomShift - iNumShift);
  1213. }
  1214. // Be sure rounding below doesn't overflow (it happened!)
  1215. while((dwMinVidThresh2 + dwDenom - 1ul) < dwMinVidThresh2)
  1216. {
  1217. dwMinVidThresh2 >>= 1;
  1218. dwDenom >>= 1;
  1219. }
  1220. dwMinVidThresh2 += dwDenom - 1ul;
  1221. dwMinVidThresh2 /= dwDenom;
  1222. if(dwMinVidThresh2 > (VIDFIFOSIZE /2ul) )
  1223. dwMinVidThresh2 -= (VIDFIFOSIZE / 2ul);
  1224. else
  1225. dwMinVidThresh2 = 0;
  1226. if(!(pConfig->dwFlags & VCFLG_420))
  1227. {
  1228. // Threshold is programmed in DQWORDS for non-4:2:0
  1229. dwMinVidThresh2 /= 2ul;
  1230. }
  1231. dwMinVidThresh2++; // Adjust for -2 decrement of FIFO count done to
  1232. // synchronize MCLK with faster VCLK.
  1233. ODS("ChipIsEnoughBandwidth(): Min video thresh1 and 2 = %ld %ld.\n",
  1234. dwMinVidThresh1, dwMinVidThresh2);
  1235. if(dwMinVidThresh2 > VIDFIFOSIZE -1)
  1236. {
  1237. dwMinVidThresh2 = VIDFIFOSIZE -1;
  1238. }
  1239. //
  1240. // Whichever is higher should be the right one
  1241. //
  1242. dwMinVidThresh = __max(dwMinVidThresh1, dwMinVidThresh2);
  1243. }
  1244. ODS("ChipIsEnoughBandwidth(): Min video thresh = %ld.\n", dwMinVidThresh);
  1245. if(dwMaxVidThresh < dwMinVidThresh)
  1246. {
  1247. ODS("ChipIsEnoughBandwidth(): Minimum video threshold exceeds maximum.\n");
  1248. goto Error;
  1249. }
  1250. //I don't know why, but it need checked for capture. #xc
  1251. if((pConfig->dwFlags & VCFLG_CAP) && (dwMaxVidThresh > 8)
  1252. && ((pConfig->uGfxDepth != 8) || fConCurrent) && ( f500MHZ || !fConCurrent))
  1253. {
  1254. ODS("ChipIsEnoughBandwidth(): Video threshold exceeds non-aligned safe value.\n");
  1255. goto Error;
  1256. }
  1257. if(pProgRegs)
  1258. {
  1259. if((((pConfig->uGfxDepth == 8) && (dwVCLK > 60000000)) ||
  1260. ((pConfig->uGfxDepth != 8) && ( dwVCLK > 56000000)) ||
  1261. ( !f500MHZ && fConCurrent)) && !(pConfig->dwFlags & VCFLG_CAP))
  1262. pProgRegs->VW0_FIFO_THRSH = (WORD)dwMaxVidThresh;
  1263. else
  1264. pProgRegs->VW0_FIFO_THRSH = (WORD)__min( 8, dwMaxVidThresh);
  1265. ODS("ChipIsEnoughBandwidth(): thresh = %ld.\n", pProgRegs->VW0_FIFO_THRSH);
  1266. }
  1267. }
  1268. fSuccess = TRUE;
  1269. Error:
  1270. return(fSuccess);
  1271. }
  1272. #endif // WINNT_VER35
  1273. 
  1274.