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.

597 lines
12 KiB

  1. /*++
  2. Copyright (c) 1993 Weitek Corporation
  3. Module Name:
  4. viper.c
  5. Abstract:
  6. This module contains OEM specific functions for the Diamond Viper
  7. board.
  8. Environment:
  9. Kernel mode
  10. Revision History may be found at the end of this file.
  11. --*/
  12. #include "p9.h"
  13. #include "p9gbl.h"
  14. #include "p9000.h"
  15. #include "viper.h"
  16. #include "vga.h"
  17. #include "p9errlog.h"
  18. #define REJECT_ON_BIOS_VERSION 0
  19. //
  20. // OEM specific static data.
  21. //
  22. //
  23. // This structure is used to match the possible physical address
  24. // mappings with the value to be written to the sequencer control
  25. // register.
  26. typedef struct
  27. {
  28. PHYSICAL_ADDRESS BaseMemAddr;
  29. USHORT RegValue;
  30. } MEM_RANGE;
  31. MEM_RANGE ViperMemRange[] =
  32. {
  33. { 0x0A0000000, 0L, MEM_AXXX },
  34. { 0x080000000, 0L, MEM_8XXX },
  35. { 0x020000000, 0L, MEM_2XXX },
  36. { 0x01D000000, 0L, MEM_AXXX }
  37. };
  38. LONG NumMemRanges = sizeof(ViperMemRange) / sizeof(MEM_RANGE);
  39. #ifdef REJECT_ON_BIOS_VERSION
  40. /*++
  41. ** bRejectOnBiosVersion
  42. *
  43. * FILENAME: D:\nt351.nc\weitek\p9x\mini\viper.c
  44. *
  45. * PARAMETERS: PHW_DEVICE_EXTENSION HwDeviceExtension
  46. * PUCHAR pjBios linear address of the BIOS
  47. * ULONG ulBiosLength lengh of the BIOS
  48. *
  49. * DESCRIPTION: Scan the Bios,
  50. *
  51. * RETURNS: TRUE to reject supporting this card.
  52. * FALSE to support this card.
  53. *
  54. *
  55. --*/
  56. BOOLEAN
  57. bRejectOnBiosVersion(
  58. PHW_DEVICE_EXTENSION HwDeviceExtension,
  59. PUCHAR pjBiosAddr,
  60. ULONG ulBiosLength)
  61. {
  62. // Add the strings you want to detect for rejection to this array
  63. static PUCHAR aszBiosVersion[] = {
  64. "VIPER VLB Vers. 1",
  65. "VIPER VLB Vers. 2",
  66. NULL
  67. };
  68. LONG i;
  69. BOOLEAN bFound = FALSE;
  70. for (i = 0; aszBiosVersion[i] != 0; i++)
  71. {
  72. if (VideoPortScanRom(HwDeviceExtension,
  73. (PUCHAR) pjBiosAddr,
  74. VGA_BIOS_LEN,
  75. aszBiosVersion[i]))
  76. {
  77. bFound = TRUE;
  78. break;
  79. }
  80. }
  81. if (bFound == TRUE)
  82. {
  83. VideoPortLogError(HwDeviceExtension,
  84. NULL,
  85. P9_DOWN_LEVEL_BIOS,
  86. i);
  87. VideoDebugPrint((1, "P9X - Down Level Bios\n"));
  88. }
  89. // We will always boot, we'll just warn the user that bad things may happen
  90. return (FALSE);
  91. }
  92. #endif // REJECT_ON_BIOS_VERSION
  93. #define P9001_REV_ID 0x08
  94. BOOLEAN
  95. ViperGetBaseAddr(
  96. PHW_DEVICE_EXTENSION HwDeviceExtension
  97. )
  98. /*++
  99. Routine Description:
  100. Perform board detection and if present return the P9000 base address.
  101. Arguments:
  102. HwDeviceExtension - Pointer to the miniport driver's device extension.
  103. Return Value:
  104. TRUE - Board found, P9 and Frame buffer address info was placed in
  105. the device extension.
  106. FALSE - Board not found.
  107. --*/
  108. {
  109. VP_STATUS status;
  110. SHORT i;
  111. PUCHAR pucBiosAddr;
  112. BOOLEAN bValid = FALSE;
  113. ULONG ulTemp;
  114. VIDEO_ACCESS_RANGE BiosAccessRange =
  115. {
  116. VGA_BIOS_ADDR, // Low address
  117. 0x00000000, // Hi address
  118. VGA_BIOS_LEN, // length
  119. 0, // Is range in i/o space?
  120. 1, // Range should be visible
  121. 1 // Range should be shareable
  122. };
  123. if (HwDeviceExtension->MachineType == SIEMENS_P9100_VLB)
  124. return FALSE;
  125. //
  126. // More PnP goofing around: Try to detect a PCI card here. If successful,
  127. // fail finding a VLB Viper, since we won't support both a PCI and VLB
  128. // viper on the same machine as of NT5. We love PnP.
  129. //
  130. if (VideoPortGetBusData(HwDeviceExtension,
  131. PCIConfiguration,
  132. HwDeviceExtension->PciSlotNum,
  133. &ulTemp, //bogus name
  134. P9001_REV_ID,
  135. sizeof(ulTemp)))
  136. {
  137. VideoDebugPrint((1, "VPGetBusData succeeded???, line %d\n", __LINE__));
  138. return(FALSE);
  139. }
  140. //
  141. // Determine if a Viper card is installed by scanning the VGA BIOS ROM
  142. // memory space.
  143. //
  144. //
  145. // Map in the BIOS' memory space. If it can't be mapped,
  146. // return an error.
  147. //
  148. if (HwDeviceExtension->MachineType == SIEMENS)
  149. {
  150. BiosAccessRange.RangeStart.LowPart += 0x10000000L;
  151. }
  152. if (VideoPortVerifyAccessRanges(HwDeviceExtension,
  153. 1,
  154. &BiosAccessRange) != NO_ERROR)
  155. {
  156. return(FALSE);
  157. }
  158. if ((pucBiosAddr =
  159. VideoPortGetDeviceBase(HwDeviceExtension,
  160. BiosAccessRange.RangeStart,
  161. BiosAccessRange.RangeLength,
  162. FALSE)) == 0)
  163. {
  164. return(FALSE);
  165. }
  166. if (!VideoPortScanRom(HwDeviceExtension,
  167. pucBiosAddr,
  168. VGA_BIOS_LEN,
  169. VIPER_VL_ID_STR))
  170. {
  171. VideoPortFreeDeviceBase(HwDeviceExtension, pucBiosAddr);
  172. return(FALSE);
  173. }
  174. #ifdef REJECT_ON_BIOS_VERSION
  175. if (bRejectOnBiosVersion(HwDeviceExtension, pucBiosAddr, VGA_BIOS_LEN))
  176. return (FALSE);
  177. #endif // REJECT_ON_BIOS_VERSION
  178. VideoPortFreeDeviceBase(HwDeviceExtension, pucBiosAddr);
  179. //
  180. // For now, pretend we have a Weitek 5x86 VGA. Later we may call the
  181. // Viper BIOS to determine which type of BIOS is installed.
  182. //
  183. HwDeviceExtension->AdapterDesc.bWtk5x86 = TRUE;
  184. //
  185. // Copy the DAC register access ranges to the global access range
  186. // structure.
  187. //
  188. VideoPortMoveMemory(&DriverAccessRanges[NUM_DRIVER_ACCESS_RANGES],
  189. VLDefDACRegRange,
  190. HwDeviceExtension->Dac.cDacRegs *
  191. sizeof(VIDEO_ACCESS_RANGE));
  192. //
  193. // A value for the P9 base address may have beens found in the registry,
  194. // and it is now stored in the device extension. Ensure the address
  195. // value is valid for the Viper card. Then use it to compute
  196. // the starting address of the P9000 registers and frame buffer,
  197. // and store it in the device extension.
  198. //
  199. for (i = 0; i < NumMemRanges; i++)
  200. {
  201. if (HwDeviceExtension->P9PhysAddr.LowPart ==
  202. ViperMemRange[i].BaseMemAddr.LowPart)
  203. {
  204. bValid = TRUE;
  205. break;
  206. }
  207. }
  208. //
  209. // If the address value is invalid, or was not found in the registry,
  210. // use the default.
  211. //
  212. if (!bValid)
  213. {
  214. HwDeviceExtension->P9PhysAddr.LowPart = MemBase;
  215. }
  216. return(TRUE);
  217. }
  218. VOID
  219. ViperEnableP9(
  220. PHW_DEVICE_EXTENSION HwDeviceExtension
  221. )
  222. /*++
  223. Routine Description:
  224. Perform the OEM specific tasks necessary to enable the P9000. These
  225. include memory mapping, setting the sync polarities, and enabling the
  226. P9000 video output.
  227. Arguments:
  228. HwDeviceExtension - Pointer to the miniport driver's device extension.
  229. Return Value:
  230. None.
  231. --*/
  232. {
  233. USHORT holdit;
  234. //
  235. // Select external frequency.
  236. //
  237. VGA_WR_REG(MISCOUT, VGA_RD_REG(MISCIN) | (MISCD | MISCC));
  238. //
  239. // If this is a Weitek VGA, unlock it.
  240. //
  241. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  242. {
  243. UnlockVGARegs(HwDeviceExtension);
  244. }
  245. VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
  246. holdit = VGA_RD_REG(SEQ_DATA_PORT);
  247. //
  248. // Set the sync polarity. First clear the sync polarity bits.
  249. //
  250. holdit &= ~POL_MASK;
  251. //
  252. // Viper controls h and v sync polarities independently. Set the
  253. // vertical sync polarity.
  254. //
  255. if (HwDeviceExtension->VideoData.vp == POSITIVE)
  256. {
  257. holdit |= VSYNC_POL_MASK;
  258. }
  259. //
  260. // Disable VGA video output.
  261. //
  262. holdit &= VGA_VIDEO_DIS;
  263. if (HwDeviceExtension->VideoData.hp == POSITIVE)
  264. {
  265. holdit |= HSYNC_POL_MASK;
  266. }
  267. holdit |= P9_VIDEO_ENB;
  268. VGA_WR_REG(SEQ_DATA_PORT, holdit);
  269. //
  270. // If this is a Weitek VGA, lock it.
  271. //
  272. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  273. {
  274. LockVGARegs(HwDeviceExtension);
  275. }
  276. return;
  277. }
  278. BOOLEAN
  279. ViperDisableP9(
  280. PHW_DEVICE_EXTENSION HwDeviceExtension
  281. )
  282. /*++
  283. Routine Description:
  284. Arguments:
  285. HwDeviceExtension - Pointer to the miniport driver's device extension.
  286. pPal - Pointer to the array of pallete entries.
  287. StartIndex - Specifies the first pallete entry provided in pPal.
  288. Count - Number of palette entries in pPal
  289. Return Value:
  290. TRUE, indicating *no* int10 is needed to complete the switch
  291. --*/
  292. {
  293. USHORT holdit;
  294. //
  295. // If this is a Weitek VGA, unlock it.
  296. //
  297. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  298. {
  299. UnlockVGARegs(HwDeviceExtension);
  300. }
  301. VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
  302. holdit = VGA_RD_REG(SEQ_DATA_PORT);
  303. //
  304. // Disable P9000 video output.
  305. //
  306. holdit &= P9_VIDEO_DIS;
  307. //
  308. // VGA output enable is a seperate register bit for the Viper board.
  309. //
  310. holdit |= VGA_VIDEO_ENB;
  311. VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
  312. VGA_WR_REG(SEQ_DATA_PORT, holdit);
  313. //
  314. // Restore clock select bits.
  315. //
  316. VGA_WR_REG(MISCOUT, HwDeviceExtension->MiscRegState);
  317. //
  318. // If this is a Weitek VGA, lock it.
  319. //
  320. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  321. {
  322. LockVGARegs(HwDeviceExtension);
  323. }
  324. return TRUE;
  325. }
  326. BOOLEAN
  327. ViperEnableMem(
  328. PHW_DEVICE_EXTENSION HwDeviceExtension
  329. )
  330. /*++
  331. Routine Description:
  332. Enables the P9000 memory at the physical base address stored in the
  333. device extension.
  334. Arguments:
  335. HwDeviceExtension - Pointer to the miniport driver's device extension.
  336. Return Value:
  337. None.
  338. --*/
  339. {
  340. USHORT holdit;
  341. SHORT i;
  342. //
  343. // If this is a Weitek VGA, unlock it.
  344. //
  345. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  346. {
  347. UnlockVGARegs(HwDeviceExtension);
  348. }
  349. //
  350. // Read the contents of the sequencer memory address register.
  351. //
  352. VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
  353. holdit = VGA_RD_REG(SEQ_DATA_PORT);
  354. //
  355. // Clear out any address bits which are set.
  356. //
  357. holdit &= ADDR_SLCT_MASK;
  358. //
  359. // Map the P9000 to the address specified in the device extension.
  360. //
  361. for (i = 0; i < NumMemRanges; i++ )
  362. {
  363. if (ViperMemRange[i].BaseMemAddr.LowPart ==
  364. HwDeviceExtension->P9PhysAddr.LowPart)
  365. {
  366. holdit |= ViperMemRange[i].RegValue;
  367. break;
  368. }
  369. }
  370. VGA_WR_REG(SEQ_DATA_PORT, holdit);
  371. //
  372. // If this is a Weitek VGA, lock it.
  373. //
  374. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  375. {
  376. LockVGARegs(HwDeviceExtension);
  377. }
  378. return(TRUE);
  379. }
  380. VOID
  381. ViperSetMode(
  382. PHW_DEVICE_EXTENSION HwDeviceExtension
  383. )
  384. /*++
  385. Routine Description:
  386. This routine sets the video mode. Different OEM adapter implementations
  387. require that initialization operations be performed in a certain
  388. order. This routine uses the standard order which addresses most
  389. implementations (Viper VL and VIPER PCI).
  390. Arguments:
  391. HwDeviceExtension - Pointer to the miniport driver's device extension.
  392. Return Value:
  393. None.
  394. --*/
  395. {
  396. //
  397. // Save the value in the VGA's Misc Output register.
  398. //
  399. HwDeviceExtension->MiscRegState = VGA_RD_REG(MISCIN);
  400. //
  401. // Enable the Vipers Memory Map.
  402. //
  403. HwDeviceExtension->AdapterDesc.P9EnableMem(HwDeviceExtension);
  404. //
  405. // Enable P9000 video.
  406. //
  407. HwDeviceExtension->AdapterDesc.P9EnableVideo(HwDeviceExtension);
  408. //
  409. // Initialize the DAC.
  410. //
  411. HwDeviceExtension->Dac.DACInit(HwDeviceExtension);
  412. //
  413. // Set the dot clock.
  414. //
  415. DevSetClock(HwDeviceExtension,
  416. (USHORT) HwDeviceExtension->VideoData.dotfreq1,
  417. FALSE,
  418. TRUE);
  419. //
  420. // If this mode uses the palette, clear it to all 0s.
  421. //
  422. if (P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.AttributeFlags
  423. && VIDEO_MODE_PALETTE_DRIVEN)
  424. {
  425. HwDeviceExtension->Dac.DACClearPalette(HwDeviceExtension);
  426. }
  427. }