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.

599 lines
15 KiB

  1. /*++
  2. Copyright (c) 1993 Weitek Corporation
  3. Module Name:
  4. wtkp90vl.c
  5. Abstract:
  6. This module contains OEM specific functions for the Weitek P9000
  7. VL evaluation 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 "vga.h"
  16. //
  17. // Default memory addresses for the P9 registers/frame buffer.
  18. //
  19. #define MemBase 0xC0000000
  20. //
  21. // Bit to write to the sequencer control register to enable/disable P9
  22. // video output.
  23. //
  24. #define P9_VIDEO_ENB 0x10
  25. //
  26. // Define the bit in the sequencer control register which determines
  27. // the sync polarities. For Weitek board, 1 = positive.
  28. //
  29. #define HSYNC_POL_MASK 0x20
  30. //
  31. // OEM specific static data.
  32. //
  33. //
  34. // List of valid base addresses for different Weitek based designs.
  35. //
  36. #define NUM_WTK_ADDRS 10
  37. ULONG ulWtkAddrRanges[] =
  38. {
  39. 0x4000000L,
  40. 0x8000000L,
  41. 0xD000000L,
  42. 0xE000000L,
  43. 0xF000000L,
  44. 0x80000000L,
  45. 0xC0000000L,
  46. 0xD0000000L,
  47. 0xE0000000L,
  48. 0xF0000000L
  49. };
  50. //
  51. // VLDefDACRegRange contains info about the memory/io space ranges
  52. // used by the DAC.
  53. //
  54. VIDEO_ACCESS_RANGE VLDefDACRegRange[] =
  55. {
  56. {
  57. 0x03C8, // Low address
  58. 0x00000000, // Hi address
  59. 0x01, // length
  60. 1, // Is range in i/o space?
  61. 1, // Range should be visible
  62. 1 // Range should be shareable
  63. },
  64. {
  65. 0x03C9, // Low address
  66. 0x00000000, // Hi address
  67. 0x01, // length
  68. 1, // Is range in i/o space?
  69. 1, // Range should be visible
  70. 1 // Range should be shareable
  71. },
  72. {
  73. 0x03C6, // Low address
  74. 0x00000000, // Hi address
  75. 0x01, // length
  76. 1, // Is range in i/o space?
  77. 1, // Range should be visible
  78. 1 // Range should be shareable
  79. },
  80. {
  81. 0x03C7, // Low address
  82. 0x00000000, // Hi address
  83. 0x01, // length
  84. 1, // Is range in i/o space?
  85. 1, // Range should be visible
  86. 1 // Range should be shareable
  87. },
  88. {
  89. 0x43C8, // Low address
  90. 0x00000000, // Hi address
  91. 0x01, // length
  92. 1, // Is range in i/o space?
  93. 1, // Range should be visible
  94. 1 // Range should be shareable
  95. },
  96. {
  97. 0x43C9, // Low address
  98. 0x00000000, // Hi address
  99. 0x01, // length
  100. 1, // Is range in i/o space?
  101. 1, // Range should be visible
  102. 1 // Range should be shareable
  103. },
  104. {
  105. 0x43C6, // Low address
  106. 0x00000000, // Hi address
  107. 0x01, // length
  108. 1, // Is range in i/o space?
  109. 1, // Range should be visible
  110. 1 // Range should be shareable
  111. },
  112. {
  113. 0x43C7, // Low address
  114. 0x00000000, // Hi address
  115. 0x01, // length
  116. 1, // Is range in i/o space?
  117. 1, // Range should be visible
  118. 1 // Range should be shareable
  119. },
  120. {
  121. 0x83C8, // Low address
  122. 0x00000000, // Hi address
  123. 0x01, // length
  124. 1, // Is range in i/o space?
  125. 1, // Range should be visible
  126. 1 // Range should be shareable
  127. },
  128. {
  129. 0x83C9, // Low address
  130. 0x00000000, // Hi address
  131. 0x01, // length
  132. 1, // Is range in i/o space?
  133. 1, // Range should be visible
  134. 1 // Range should be shareable
  135. },
  136. {
  137. 0x83C6, // Low address
  138. 0x00000000, // Hi address
  139. 0x01, // length
  140. 1, // Is range in i/o space?
  141. 1, // Range should be visible
  142. 1 // Range should be shareable
  143. },
  144. {
  145. 0x83C7, // Low address
  146. 0x00000000, // Hi address
  147. 0x01, // length
  148. 1, // Is range in i/o space?
  149. 1, // Range should be visible
  150. 1 // Range should be shareable
  151. },
  152. {
  153. 0xC3C8, // Low address
  154. 0x00000000, // Hi address
  155. 0x01, // length
  156. 1, // Is range in i/o space?
  157. 1, // Range should be visible
  158. 1 // Range should be shareable
  159. },
  160. {
  161. 0xC3C9, // Low address
  162. 0x00000000, // Hi address
  163. 0x01, // length
  164. 1, // Is range in i/o space?
  165. 1, // Range should be visible
  166. 1 // Range should be shareable
  167. },
  168. {
  169. 0xC3C6, // Low address
  170. 0x00000000, // Hi address
  171. 0x01, // length
  172. 1, // Is range in i/o space?
  173. 1, // Range should be visible
  174. 1 // Range should be shareable
  175. },
  176. {
  177. 0xC3C7, // Low address
  178. 0x00000000, // Hi address
  179. 0x01, // length
  180. 1, // Is range in i/o space?
  181. 1, // Range should be visible
  182. 1 // Range should be shareable
  183. }
  184. };
  185. BOOLEAN
  186. VLGetBaseAddr(
  187. PHW_DEVICE_EXTENSION HwDeviceExtension
  188. )
  189. /*++
  190. Routine Description:
  191. Perform board detection and if present return the P9000 base address.
  192. Arguments:
  193. HwDeviceExtension - Pointer to the miniport driver's device extension.
  194. Return Value:
  195. TRUE - Board found, P9 and Frame buffer address info was placed in
  196. the device extension.
  197. FALSE - Board not found.
  198. --*/
  199. {
  200. SHORT i;
  201. //
  202. // Only the viper p9000 works on the Siemens boxes
  203. //
  204. if_SIEMENS_VLB()
  205. {
  206. return FALSE;
  207. }
  208. if (HwDeviceExtension->P9PhysAddr.LowPart == 0)
  209. {
  210. //
  211. // The base address was not found in the registry, so copy the
  212. // default address into the device extension.
  213. //
  214. HwDeviceExtension->P9PhysAddr.LowPart = MemBase;
  215. }
  216. if (!VLP90CoprocDetect(HwDeviceExtension,
  217. HwDeviceExtension->P9PhysAddr.LowPart))
  218. {
  219. //
  220. // Scan all possible base addresses to see if the coprocessor is
  221. // present.
  222. //
  223. BOOLEAN bFound;
  224. bFound = FALSE;
  225. for (i = 0; i < NUM_WTK_ADDRS && !bFound; i++)
  226. {
  227. if (ulWtkAddrRanges[i] +
  228. HwDeviceExtension->P9CoprocInfo.CoprocRegOffset !=
  229. HwDeviceExtension->CoprocPhyAddr.LowPart)
  230. {
  231. if (VLP90CoprocDetect(HwDeviceExtension,
  232. ulWtkAddrRanges[i]))
  233. {
  234. HwDeviceExtension->P9PhysAddr.LowPart =
  235. ulWtkAddrRanges[i];
  236. bFound = TRUE;
  237. break;
  238. }
  239. }
  240. }
  241. if (!bFound)
  242. {
  243. return(FALSE);
  244. }
  245. }
  246. //
  247. // Copy the DAC register access ranges to the global access range
  248. // structure.
  249. //
  250. VideoPortMoveMemory(&DriverAccessRanges[NUM_DRIVER_ACCESS_RANGES],
  251. VLDefDACRegRange,
  252. HwDeviceExtension->Dac.cDacRegs *
  253. sizeof(VIDEO_ACCESS_RANGE));
  254. return(TRUE);
  255. }
  256. BOOLEAN
  257. VLP90CoprocDetect(
  258. PHW_DEVICE_EXTENSION HwDeviceExtension,
  259. ULONG ulCoprocPhyAddr
  260. )
  261. /*++
  262. Routine Description:
  263. Perform P9000 coprocessor detection.
  264. Arguments:
  265. HwDeviceExtension - Pointer to the miniport driver's device extension.
  266. ulCoprocPhyAddr - The physical base address used for detection.
  267. Return Values:
  268. TRUE - Coprocessor found.
  269. FALSE - Coprocessor not found.
  270. --*/
  271. {
  272. VIDEO_ACCESS_RANGE VLAccessRange;
  273. ULONG ulTestPat = 0xFFFFFFFF;
  274. ULONG ulTemp;
  275. //
  276. // Set up the access range so we can map the coprocessor address space.
  277. //
  278. VLAccessRange.RangeInIoSpace = FALSE;
  279. VLAccessRange.RangeVisible = TRUE;
  280. VLAccessRange.RangeShareable = TRUE;
  281. VLAccessRange.RangeStart.LowPart = ulCoprocPhyAddr +
  282. HwDeviceExtension->P9CoprocInfo.CoprocRegOffset;
  283. VLAccessRange.RangeStart.HighPart = 0;
  284. VLAccessRange.RangeLength = HwDeviceExtension->P9CoprocInfo.CoprocLength;
  285. //
  286. //
  287. // Check to see if another miniport driver has allocated any of the
  288. // coprocessor's address space.
  289. //
  290. if (VideoPortVerifyAccessRanges(HwDeviceExtension,
  291. 1L,
  292. &VLAccessRange) != NO_ERROR)
  293. {
  294. return(FALSE);
  295. }
  296. //
  297. // Get a virtual address for the coprocessor's address space.
  298. //
  299. if ((HwDeviceExtension->Coproc =
  300. VideoPortGetDeviceBase(HwDeviceExtension,
  301. VLAccessRange.RangeStart,
  302. VLAccessRange.RangeLength,
  303. VLAccessRange.RangeInIoSpace)) == 0)
  304. {
  305. return(FALSE);
  306. }
  307. //
  308. // Write a test value to the location of the coprocessor's clipping
  309. // window min register and attempt to read it back.
  310. //
  311. P9_WR_REG(WMIN, ulTestPat);
  312. ulTemp = P9_RD_REG(WMIN);
  313. VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->Coproc);
  314. //
  315. // The value read back from the clipping window min reg will have the
  316. // high order 3 bits of each word clear.
  317. //
  318. if (ulTemp == (ulTestPat & P9_COORD_MASK))
  319. {
  320. //
  321. // Coprocessor is present.
  322. //
  323. return(TRUE);
  324. }
  325. else
  326. {
  327. //
  328. // Coprocessor is absent.
  329. //
  330. return(FALSE);
  331. }
  332. }
  333. VOID
  334. VLSetMode(
  335. PHW_DEVICE_EXTENSION HwDeviceExtension
  336. )
  337. /*++
  338. Routine Description:
  339. This routine sets the video mode. Different OEM adapter implementations
  340. require that initialization operations be performed in a certain
  341. order. This routine uses the standard order which addresses most
  342. implementations (VL, Ajax, Weitek PCI, Tulip).
  343. Arguments:
  344. HwDeviceExtension - Pointer to the miniport driver's device extension.
  345. Return Value:
  346. None.
  347. --*/
  348. {
  349. //
  350. // Set the dot clock.
  351. //
  352. DevSetClock(HwDeviceExtension,
  353. (USHORT) HwDeviceExtension->VideoData.dotfreq1,
  354. FALSE,
  355. TRUE);
  356. //
  357. // If this mode uses the palette, clear it to all 0s.
  358. //
  359. if (P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.AttributeFlags
  360. && VIDEO_MODE_PALETTE_DRIVEN)
  361. {
  362. HwDeviceExtension->Dac.DACClearPalette(HwDeviceExtension);
  363. }
  364. //
  365. // Save the value in the VGA's Misc Output register.
  366. //
  367. HwDeviceExtension->MiscRegState = VGA_RD_REG(MISCIN);
  368. //
  369. // Initialize the DAC.
  370. //
  371. HwDeviceExtension->Dac.DACInit(HwDeviceExtension);
  372. //
  373. // Enable P9 video.
  374. //
  375. HwDeviceExtension->AdapterDesc.P9EnableVideo(HwDeviceExtension);
  376. }
  377. VOID
  378. VLEnableP9(
  379. PHW_DEVICE_EXTENSION HwDeviceExtension
  380. )
  381. /*++
  382. Routine Description:
  383. Perform the OEM specific tasks necessary to enable P9000 Video. These
  384. include memory mapping, setting the sync polarities, and enabling the
  385. P9000 video output.
  386. Arguments:
  387. HwDeviceExtension - Pointer to the miniport driver's device extension.
  388. Return Value:
  389. None.
  390. --*/
  391. {
  392. USHORT holdit;
  393. //
  394. // Select external frequency.
  395. //
  396. VGA_WR_REG(MISCOUT, VGA_RD_REG(MISCIN) | (MISCD | MISCC));
  397. //
  398. // If this is a Weitek VGA, unlock it.
  399. //
  400. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  401. {
  402. UnlockVGARegs(HwDeviceExtension);
  403. }
  404. VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
  405. holdit = VGA_RD_REG(SEQ_DATA_PORT);
  406. //
  407. // Set the sync polarity. First clear the sync polarity bits.
  408. //
  409. holdit &= ~HSYNC_POL_MASK;
  410. if (HwDeviceExtension->VideoData.hp == POSITIVE)
  411. {
  412. holdit |= HSYNC_POL_MASK;
  413. }
  414. holdit |= P9_VIDEO_ENB;
  415. VGA_WR_REG(SEQ_DATA_PORT, holdit);
  416. //
  417. // If this is a Weitek VGA, lock it.
  418. //
  419. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  420. {
  421. LockVGARegs(HwDeviceExtension);
  422. }
  423. return;
  424. }
  425. BOOLEAN
  426. VLDisableP9(
  427. PHW_DEVICE_EXTENSION HwDeviceExtension
  428. )
  429. /*++
  430. Routine Description:
  431. Arguments:
  432. HwDeviceExtension - Pointer to the miniport driver's device extension.
  433. pPal - Pointer to the array of pallete entries.
  434. StartIndex - Specifies the first pallete entry provided in pPal.
  435. Count - Number of palette entries in pPal
  436. Return Value:
  437. TRUE, indicating *no* int10 is needed to complete the switch
  438. --*/
  439. {
  440. USHORT holdit;
  441. //
  442. // If this is a Weitek VGA, unlock it.
  443. //
  444. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  445. {
  446. UnlockVGARegs(HwDeviceExtension);
  447. }
  448. VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
  449. holdit = VGA_RD_REG(SEQ_DATA_PORT);
  450. //
  451. // Disable P9000 video output.
  452. //
  453. holdit &= ~P9_VIDEO_ENB;
  454. VGA_WR_REG(SEQ_INDEX_PORT, SEQ_OUTCNTL_INDEX);
  455. VGA_WR_REG(SEQ_DATA_PORT, holdit);
  456. //
  457. // Restore clock select bits.
  458. //
  459. VGA_WR_REG(MISCOUT, HwDeviceExtension->MiscRegState);
  460. //
  461. // If this is a Weitek VGA, lock it.
  462. //
  463. if (HwDeviceExtension->AdapterDesc.bWtk5x86)
  464. {
  465. LockVGARegs(HwDeviceExtension);
  466. }
  467. return TRUE;
  468. }