Source code of Windows XP (NT5)
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.

573 lines
16 KiB

  1. /*++
  2. Copyright (c) 1998 VIA Technologies, Inc. and Microsoft Corporation.
  3. Module Name:
  4. init.c
  5. Abstract:
  6. This module contains the initialization code for VIAAGP.SYS.
  7. Revision History:
  8. --*/
  9. #include "viaagp.h"
  10. ULONG AgpExtensionSize = sizeof(AGPVIA_EXTENSION);
  11. PAGP_FLUSH_PAGES AgpFlushPages = NULL; // not implemented
  12. VOID
  13. AgpTweak(
  14. VOID
  15. )
  16. /*++
  17. Routine Description:
  18. Check VIA rev and video device, then tweak config accordingly
  19. Parameters:
  20. None
  21. Return Value:
  22. None
  23. --*/
  24. {
  25. ULONG ulNB_ID, ulVGA_ID, ulNB_Rev=0xFFFFFFFF, ulNB_Version=0xFFFFFFFF;
  26. ULONG ulTmpPhysAddr;
  27. UCHAR bVMask, bVOrg;
  28. UCHAR i, bMaxItem=20;
  29. //----------------------------------------------------------------
  30. //Patch Mapping Table
  31. //----------------------------------------------------------------
  32. ULONG NBtable[11] =
  33. {
  34. //VT3054 VT3055 VT3062 VT3064 VT3056
  35. 0x059700FF, 0x0598000F, 0x0598101F, 0x0501000F, 0x0691000F,
  36. //VT3063 VT3073 VT3075 VT3085 VT3067
  37. 0x0691202F, 0x0691404F, 0x0691808F, 0x0691C0CF, 0x0601000F, 0xFFFFFFFF
  38. };
  39. ULONG NBVersion[11] =
  40. {
  41. 0x3054, 0x3055, 0x3062, 0x3064, 0x3056,
  42. 0x3063, 0x3073, 0x3075, 0x3085, 0x3067, 0xFFFFFFFF
  43. };
  44. #ifdef AGP_440
  45. DbgPrint("FineTune\n");
  46. #endif
  47. //----------------------------------------------------------------
  48. //Find the type of North Bridge (device id, revision #)
  49. //----------------------------------------------------------------
  50. //
  51. //Save back door value and close back door
  52. //
  53. ReadVIAConfig(&bVOrg, 0xFC, sizeof(bVOrg));
  54. bVMask=bVOrg & 0xFE;
  55. WriteVIAConfig(&bVMask, 0xFC, sizeof(bVMask));
  56. ReadVIAConfig(&ulNB_ID, 0x00, sizeof(ulNB_ID))
  57. ulNB_ID=ulNB_ID&0xFFFF0000;
  58. ReadVIAConfig(&ulNB_Rev, 0x08, sizeof(ulNB_Rev));
  59. ulNB_Rev=ulNB_Rev&0x000000FF;
  60. ulNB_ID=ulNB_ID | (ulNB_Rev<<8) | ulNB_Rev;
  61. WriteVIAConfig(&bVOrg, 0xFC, sizeof(bVOrg));
  62. //
  63. //Find the type of North Bridge from the predefined NBtable
  64. //
  65. for ( i=0; i<bMaxItem; i++ )
  66. {
  67. if ( (NBtable[i]&0xFFFF0000) == (ulNB_ID&0xFFFF0000) )
  68. {
  69. if ( ((NBtable[i]&0x0000FF00)<=(ulNB_ID&0x0000FF00)) && ((NBtable[i]&0x000000FF)>=(ulNB_ID&0x000000FF)) )
  70. {
  71. ulNB_Version=NBVersion[i];
  72. break;
  73. }
  74. }
  75. if ( NBtable[i]==0xFFFFFFFF )
  76. {
  77. break;
  78. }
  79. }
  80. //----------------------------------------------------------------
  81. // General Case for NB
  82. //----------------------------------------------------------------
  83. //
  84. //Stephen Add Start, If Socket 7's chipset, write 1 to Rx51 bit 6;
  85. //
  86. if ( (ulNB_ID & 0xFF000000) == 0x05000000) {
  87. ReadVIAConfig(&bVMask, 0x51, sizeof(bVMask));
  88. bVMask=bVMask|0x40;
  89. WriteVIAConfig(&bVMask, 0x51, sizeof(bVMask));
  90. }
  91. //
  92. // For the specific NB
  93. //
  94. switch(ulNB_Version)
  95. {
  96. case 0x3054:
  97. break;
  98. case 0x3055:
  99. // 51[7]=1, 51[6]=1, AC[2]=1
  100. if ( ulNB_Rev > 3 )
  101. {
  102. ReadVIAConfig(&bVMask, 0x51, sizeof(bVMask));
  103. bVMask=bVMask|0xC0;
  104. WriteVIAConfig(&bVMask, 0x51, sizeof(bVMask));
  105. ReadVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  106. bVMask=bVMask|0x04;
  107. WriteVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  108. }
  109. break;
  110. case 0x3056:
  111. // 69[1]=1, 69[0]=1, AC[2]=1, AC[5]=1
  112. ReadVIAConfig(&bVMask, 0x69, sizeof(bVMask));
  113. bVMask=bVMask|0x03;
  114. WriteVIAConfig(&bVMask, 0x69, sizeof(bVMask));
  115. ReadVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  116. bVMask=bVMask|0x24;
  117. WriteVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  118. break;
  119. case 0x3062:
  120. case 0x3063:
  121. case 0x3064:
  122. case 0x3073:
  123. case 0x3075:
  124. case 0x3085:
  125. case 0x3067:
  126. // AC[6]=1, AC[5]=1
  127. ReadVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  128. bVMask=bVMask|0x60;
  129. WriteVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  130. break;
  131. default:
  132. break;
  133. }
  134. //----------------------------------------------------------------
  135. //Find the type of AGP VGA Card (vender id, device id, revision #)
  136. //Bus 1, Device 0, Function 0
  137. //----------------------------------------------------------------
  138. ReadVGAConfig(&ulVGA_ID, 0x00, sizeof(ulVGA_ID));
  139. #ifdef AGP_440
  140. DbgPrint("\nPatch for ulNB_Version=%x (ulNB_ID=%x), ulVGA_ID=%x",ulNB_Version,ulNB_ID,ulVGA_ID);
  141. #endif
  142. //----------------------------------------------------------------
  143. //Patch the Compatibility between VGA Card and North Bridge
  144. //----------------------------------------------------------------
  145. //
  146. // Switch 1. For all cards of the same vender
  147. //
  148. switch(ulVGA_ID&0x0000FFFF)
  149. {
  150. //ATI
  151. case 0x00001002:
  152. switch(ulNB_Version)
  153. {
  154. case 0x3055:
  155. case 0x3054:
  156. case 0x3056:
  157. // P2P, 40[7]=0
  158. ReadP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  159. bVMask=bVMask&0x7F;
  160. WriteP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  161. break;
  162. }
  163. break;
  164. //3DLAB
  165. case 0x0000104C:
  166. if (ulNB_Version==0x3063)
  167. {
  168. // AC[1]=0
  169. ReadVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  170. bVMask=bVMask&0xFD;
  171. WriteVIAConfig(&bVMask, 0xAC, sizeof(bVMask));
  172. }
  173. break;
  174. }
  175. //
  176. // Switch 2. For the specific card
  177. //
  178. switch(ulVGA_ID)
  179. {
  180. //ATIRage128
  181. case 0x52461002:
  182. switch(ulNB_Version)
  183. {
  184. case 0x3056:
  185. // P2P, 40[7]=0
  186. ReadP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  187. bVMask=bVMask&0x7F;
  188. WriteP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  189. break;
  190. case 0x3063:
  191. if (ulNB_Rev == 6)
  192. {
  193. // P2P, 40[7]=1
  194. ReadP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  195. bVMask=bVMask|0x80;
  196. WriteP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  197. }
  198. else
  199. {
  200. // P2P, 40[7]=0
  201. ReadP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  202. bVMask=bVMask&0x7F;
  203. WriteP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  204. }
  205. break;
  206. }
  207. break;
  208. //TNT
  209. case 0x002010DE:
  210. switch(ulNB_Version)
  211. {
  212. case 0x3056:
  213. case 0x3063:
  214. case 0x3073:
  215. // P2P, 40[1]=0
  216. ReadP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  217. bVMask=bVMask&0xFD;
  218. WriteP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  219. // 70[2]=0
  220. ReadVIAConfig(&bVMask, 0x70, sizeof(bVMask));
  221. bVMask=bVMask&0xFB;
  222. WriteVIAConfig(&bVMask, 0x70, sizeof(bVMask));
  223. break;
  224. }
  225. break;
  226. //S33D
  227. case 0x8A225333:
  228. if (ulNB_Version==0x3063)
  229. if (ulNB_Rev==6)
  230. {
  231. // P2P, 40[7]=0
  232. ReadP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  233. bVMask=bVMask&0x7F;
  234. WriteP2PConfig(&bVMask, 0x40, sizeof(bVMask));
  235. }
  236. break;
  237. }
  238. }
  239. NTSTATUS
  240. AgpInitializeTarget(
  241. IN PVOID AgpExtension
  242. )
  243. /*++
  244. Routine Description:
  245. Entrypoint for target initialization. This is called first.
  246. Arguments:
  247. AgpExtension - Supplies the AGP extension
  248. Return Value:
  249. NTSTATUS
  250. --*/
  251. {
  252. ULONG VendorId = 0;
  253. PAGPVIA_EXTENSION Extension = AgpExtension;
  254. VIA_GATT_BASE GARTBASE_Config;
  255. //
  256. // Make sure we are really loaded only on a VIA chipset
  257. //
  258. ReadVIAConfig(&VendorId,0,sizeof(VendorId));
  259. VendorId &= 0x0000FFFF;
  260. ASSERT(VendorId == AGP_VIA_IDENTIFIER);
  261. if (VendorId != AGP_VIA_IDENTIFIER) {
  262. AGPLOG(AGP_CRITICAL,
  263. ("VIAAGP - AgpInitializeTarget called for platform %08lx which is not a VIA chipset!\n",
  264. VendorId));
  265. return(STATUS_UNSUCCESSFUL);
  266. }
  267. //
  268. // Initialize our chipset-specific extension
  269. //
  270. Extension->ApertureStart.QuadPart = 0;
  271. Extension->ApertureLength = 0;
  272. Extension->Gart = NULL;
  273. Extension->GartLength = 0;
  274. Extension->GlobalEnable = FALSE;
  275. Extension->PCIEnable = FALSE;
  276. Extension->GartPhysical.QuadPart = 0;
  277. Extension->SpecialTarget = 0;
  278. //
  279. // Check whether the chipset support Flush TLB or not
  280. // 88[2]=0, support FLUSH TLB
  281. //
  282. ReadVIAConfig(&GARTBASE_Config, GATTBASE_OFFSET, sizeof(GARTBASE_Config));
  283. if ( GARTBASE_Config.TLB_Timing == 0) {
  284. Extension->Cap_FlushTLB = TRUE;
  285. } else {
  286. Extension->Cap_FlushTLB = FALSE;
  287. }
  288. return(STATUS_SUCCESS);
  289. }
  290. NTSTATUS
  291. AgpInitializeMaster(
  292. IN PVOID AgpExtension,
  293. OUT ULONG *AgpCapabilities
  294. )
  295. /*++
  296. Routine Description:
  297. Entrypoint for master initialization. This is called after target initialization
  298. and should be used to initialize the AGP capabilities of both master and target.
  299. Arguments:
  300. AgpExtension - Supplies the AGP extension
  301. AgpCapabilities - Returns the capabilities of this AGP device.
  302. Return Value:
  303. STATUS_SUCCESS
  304. --*/
  305. {
  306. NTSTATUS Status;
  307. PCI_AGP_CAPABILITY MasterCap;
  308. PCI_AGP_CAPABILITY TargetCap;
  309. PAGPVIA_EXTENSION Extension = AgpExtension;
  310. ULONG SBAEnable;
  311. ULONG DataRate;
  312. ULONG FastWrite;
  313. ULONG FourGB;
  314. VIA_GART_TLB_CTRL AGPCTRL_Config;
  315. VIA_GATT_BASE GARTBASE_Config;
  316. VREF_REG VREF_Config;
  317. BOOLEAN ReverseInit;
  318. AGPMISC_REG AGPMISC_Config;
  319. #if DBG
  320. PCI_AGP_CAPABILITY CurrentCap;
  321. #endif
  322. //
  323. // Indicate that we can map memory through the GART aperture
  324. //
  325. *AgpCapabilities = AGP_CAPABILITIES_MAP_PHYSICAL;
  326. //
  327. // Get the master and target AGP capabilities
  328. //
  329. Status = AgpLibGetMasterCapability(AgpExtension, &MasterCap);
  330. if (!NT_SUCCESS(Status)) {
  331. AGPLOG(AGP_CRITICAL,
  332. ("AGPVIAInitializeDevice - AgpLibGetMasterCapability failed %08lx\n"));
  333. return(Status);
  334. }
  335. //
  336. // Some broken cards (Matrox Millenium II "AGP") report no valid
  337. // supported transfer rates. These are not really AGP cards. They
  338. // have an AGP Capabilities structure that reports no capabilities.
  339. //
  340. if (MasterCap.AGPStatus.Rate == 0) {
  341. AGPLOG(AGP_CRITICAL,
  342. ("AGP440InitializeDevice - AgpLibGetMasterCapability returned no valid transfer rate\n"));
  343. return(STATUS_INVALID_DEVICE_REQUEST);
  344. }
  345. Status = AgpLibGetPciDeviceCapability(0,0,&TargetCap);
  346. if (!NT_SUCCESS(Status)) {
  347. AGPLOG(AGP_CRITICAL,
  348. ("AGPVIAInitializeDevice - AgpLibGetPciDeviceCapability failed %08lx\n"));
  349. return(Status);
  350. }
  351. //
  352. // Determine the greatest common denominator for data rate.
  353. //
  354. DataRate = TargetCap.AGPStatus.Rate & MasterCap.AGPStatus.Rate;
  355. ASSERT(DataRate != 0);
  356. //
  357. // Select the highest common rate.
  358. //
  359. if (DataRate & PCI_AGP_RATE_4X) {
  360. DataRate = PCI_AGP_RATE_4X;
  361. } else if (DataRate & PCI_AGP_RATE_2X) {
  362. DataRate = PCI_AGP_RATE_2X;
  363. } else if (DataRate & PCI_AGP_RATE_1X) {
  364. DataRate = PCI_AGP_RATE_1X;
  365. //
  366. //Disable FW capability
  367. //
  368. TargetCap.AGPStatus.FastWrite = 0;
  369. ReadVIAConfig(&AGPMISC_Config, AGPMISC_OFFSET, sizeof(AGPMISC_Config));
  370. AGPMISC_Config.FW_Support = 0;
  371. WriteVIAConfig(&AGPMISC_Config, AGPMISC_OFFSET, sizeof(AGPMISC_Config));
  372. }
  373. //
  374. // Previously a call was made to change the rate (successfully),
  375. // use this rate again now
  376. //
  377. if (Extension->SpecialTarget & AGP_FLAG_SPECIAL_RESERVE) {
  378. DataRate = (ULONG)((Extension->SpecialTarget &
  379. AGP_FLAG_SPECIAL_RESERVE) >>
  380. AGP_FLAG_SET_RATE_SHIFT);
  381. }
  382. //
  383. // Set the VREF, RxB0[7].
  384. // 4x -> STB#
  385. // 1x, 2x -> AGPREF
  386. //
  387. ReadVIAConfig(&VREF_Config, VREF_OFFSET, sizeof(VREF_Config));
  388. if (DataRate == PCI_AGP_RATE_4X) {
  389. VREF_Config.VREF_Control = 0;
  390. } else {
  391. VREF_Config.VREF_Control = 1;
  392. }
  393. WriteVIAConfig(&VREF_Config, VREF_OFFSET, sizeof(VREF_Config));
  394. //
  395. // Enable SBA if both master and target support it.
  396. //
  397. SBAEnable = (TargetCap.AGPStatus.SideBandAddressing &
  398. MasterCap.AGPStatus.SideBandAddressing);
  399. //
  400. // Enable FastWrite if both master and target support it.
  401. //
  402. FastWrite = (TargetCap.AGPStatus.FastWrite & MasterCap.AGPStatus.FastWrite);
  403. //
  404. // Enable FourGB if both master and target support it.
  405. //
  406. FourGB = (TargetCap.AGPStatus.FourGB & MasterCap.AGPStatus.FourGB);
  407. //
  408. // Fine tune the Compatibility between VGA Card and North Bridge
  409. //
  410. AgpTweak();
  411. //
  412. // Enable the Master
  413. //
  414. ReverseInit =
  415. (Extension->SpecialTarget & AGP_FLAG_REVERSE_INITIALIZATION) ==
  416. AGP_FLAG_REVERSE_INITIALIZATION;
  417. if (ReverseInit) {
  418. MasterCap.AGPCommand.Rate = DataRate;
  419. MasterCap.AGPCommand.AGPEnable = 1;
  420. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  421. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  422. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  423. MasterCap.AGPCommand.FourGBEnable = FourGB;
  424. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  425. if (!NT_SUCCESS(Status)) {
  426. AGPLOG(AGP_CRITICAL,
  427. ("AGPVIAInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  428. &MasterCap,
  429. Status));
  430. }
  431. }
  432. //
  433. // Now enable the Target
  434. //
  435. TargetCap.AGPCommand.Rate = DataRate;
  436. TargetCap.AGPCommand.AGPEnable = 1;
  437. TargetCap.AGPCommand.SBAEnable = SBAEnable;
  438. TargetCap.AGPCommand.FastWriteEnable = FastWrite;
  439. TargetCap.AGPCommand.FourGBEnable = FourGB;
  440. Status = AgpLibSetPciDeviceCapability(0, 0, &TargetCap);
  441. if (!NT_SUCCESS(Status)) {
  442. AGPLOG(AGP_CRITICAL,
  443. ("AGPVIAInitializeDevice - AgpLibSetPciDeviceCapability %08lx for target failed %08lx\n",
  444. &TargetCap,
  445. Status));
  446. return(Status);
  447. }
  448. if (!ReverseInit) {
  449. MasterCap.AGPCommand.Rate = DataRate;
  450. MasterCap.AGPCommand.AGPEnable = 1;
  451. MasterCap.AGPCommand.SBAEnable = SBAEnable;
  452. MasterCap.AGPCommand.RequestQueueDepth = TargetCap.AGPStatus.RequestQueueDepthMaximum;
  453. MasterCap.AGPCommand.FastWriteEnable = FastWrite;
  454. MasterCap.AGPCommand.FourGBEnable = FourGB;
  455. Status = AgpLibSetMasterCapability(AgpExtension, &MasterCap);
  456. if (!NT_SUCCESS(Status)) {
  457. AGPLOG(AGP_CRITICAL,
  458. ("AGPVIAInitializeDevice - AgpLibSetMasterCapability %08lx failed %08lx\n",
  459. &MasterCap,
  460. Status));
  461. }
  462. }
  463. #if DBG
  464. //
  465. // Read them back, see if it worked
  466. //
  467. Status = AgpLibGetMasterCapability(AgpExtension, &CurrentCap);
  468. ASSERT(NT_SUCCESS(Status));
  469. //
  470. // If the target request queue depth is greater than the master will
  471. // allow, it will be trimmed. Loosen the assert to not require an
  472. // exact match.
  473. //
  474. ASSERT(CurrentCap.AGPCommand.RequestQueueDepth <= MasterCap.AGPCommand.RequestQueueDepth);
  475. CurrentCap.AGPCommand.RequestQueueDepth = MasterCap.AGPCommand.RequestQueueDepth;
  476. ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &MasterCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  477. Status = AgpLibGetPciDeviceCapability(0,0,&CurrentCap);
  478. ASSERT(NT_SUCCESS(Status));
  479. ASSERT(RtlEqualMemory(&CurrentCap.AGPCommand, &TargetCap.AGPCommand, sizeof(CurrentCap.AGPCommand)));
  480. #endif
  481. return(Status);
  482. }