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.

1515 lines
46 KiB

  1. /***************************************************************************\
  2. *
  3. * ************************
  4. * * MINIPORT SAMPLE CODE *
  5. * ************************
  6. *
  7. * Module Name:
  8. *
  9. * perm3.h
  10. *
  11. * Abstract:
  12. *
  13. * This module contains the definitions for the Permedia3 miniport driver.
  14. *
  15. * Environment:
  16. *
  17. * Kernel mode
  18. *
  19. *
  20. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  21. * Copyright (c) 1995-2003 Microsoft Corporation. All Rights Reserved.
  22. *
  23. \***************************************************************************/
  24. //
  25. // This line will cause the DEFINE_GUID lines in i2cgpio.h actually do something
  26. //
  27. #define INITGUID
  28. #include "dderror.h"
  29. #include "devioctl.h"
  30. #include "miniport.h"
  31. #include "ntddvdeo.h"
  32. #include "video.h"
  33. #include "interupt.h"
  34. #define GAMMA_CORRECTION 1
  35. #define MASK_OUTFIFO_ERROR_INTERRUPT 1
  36. //
  37. // Define an assert macro for debugging
  38. //
  39. #if DBG
  40. #define PERM3_ASSERT(x, y) if (!(x)) { VideoDebugPrint((0, (y))); ASSERT(FALSE); }
  41. #else
  42. #define PERM3_ASSERT(x, y)
  43. #endif
  44. //
  45. // Include definitions for all supported RAMDACS
  46. //
  47. #include "p3rd.h"
  48. //
  49. // We use 'Int 10' to do mode switching on the x86.
  50. //
  51. #if defined(i386)
  52. #define INT10_MODE_SET 1
  53. #endif
  54. //
  55. // Default clock speed in Hz for the reference board. The actual speed
  56. // is looked up in the registry. Use this if no registry entry is found
  57. // or the registry entry is zero.
  58. //
  59. #define PERMEDIA3_DEFAULT_CLOCK_SPEED ( 80 * (1000*1000))
  60. #define PERMEDIA3_DEFAULT_CLOCK_SPEED_ALT ( 80 * (1000*1000))
  61. #define PERMEDIA3_MAX_CLOCK_SPEED (250 * (1000*1000))
  62. #define PERMEDIA3_DEFAULT_MCLK_SPEED ( 80 * (1000*1000))
  63. #define PERMEDIA3_DEFAULT_SCLK_SPEED ( 70 * (1000*1000))
  64. //
  65. // Maximum pixelclock values that the RAMDAC can handle (in 100's hz).
  66. //
  67. #define P3_MAX_PIXELCLOCK 2700000 // RAMDAC rated at 270 Mhz
  68. #define P4_REVB_MAX_PIXELCLOCK 3000000 // RAMDAC rated at 300 Mhz
  69. //
  70. // Maximum amount of video data per second, that the rasterizer
  71. // chip can send to the RAMDAC (limited by SDRAM/SGRAM throuput).
  72. //
  73. #define P3_MAX_PIXELDATA 15000000 // 1500 million bytes/sec (in 100's bytes)
  74. //
  75. // Base address numbers for the Perm3 PCI regions in which we're interested.
  76. // These are indexes into the AccessRanges array we get from probing the
  77. // device.
  78. //
  79. #define PCI_CTRL_BASE_INDEX 0
  80. #define PCI_LB_BASE_INDEX 1
  81. #define PCI_FB_BASE_INDEX 2
  82. #define ROM_MAPPED_LENGTH 0x10000
  83. #define VENDOR_ID_3DLABS 0x3D3D
  84. #define PERMEDIA3_ID 0x000A
  85. #define PERMEDIA4_ID 0x000C
  86. //
  87. // Capabilities flags
  88. //
  89. // These are private flags passed to the Permedia 3 display driver. They're
  90. // put in the high word of the 'AttributeFlags' field of the
  91. // 'VIDEO_MODE_INFORMATION' structure (found in 'ntddvdeo.h') passed
  92. // to the display driver via an 'VIDEO_QUERY_AVAIL_MODES' or
  93. // 'VIDEO_QUERY_CURRENT_MODE' IOCTL.
  94. //
  95. // NOTE: These definitions must match those in the Permedia 3 display driver's
  96. // 'driver.h'!
  97. typedef enum {
  98. CAPS_ZOOM_X_BY2 = 0x00000001, // Hardware has zoomed by 2 in X
  99. CAPS_ZOOM_Y_BY2 = 0x00000002, // Hardware has zoomed by 2 in Y
  100. CAPS_QUEUED_DMA = 0x00000008, // DMA address/count via the FIFO
  101. CAPS_LOGICAL_DMA = 0x00000010, // DMA through logical address table
  102. CAPS_USE_AGP_DMA = 0x00000020, // AGP DMA can be used.
  103. CAPS_P3RD_POINTER = 0x00000040, // Use the 3Dlabs P3RD RAMDAC
  104. CAPS_STEREO = 0x00000080, // Stereo mode enabled.
  105. CAPS_SW_POINTER = 0x00010000, // No hardware pointer; use software simulation
  106. CAPS_GLYPH_EXPAND = 0x00020000, // Use glyph-expand method to draw text.
  107. CAPS_FAST_FILL_BUG = 0x00080000, // chip fast fill bug exists
  108. CAPS_INTERRUPTS = 0x00100000, // interrupts supported
  109. CAPS_DMA_AVAILABLE = 0x00200000, // DMA is supported
  110. CAPS_DISABLE_OVERLAY = 0x00400000, // chip do not support overlay
  111. } CAPS;
  112. //
  113. // The capabilities of a Perm3 board.
  114. //
  115. typedef enum {
  116. PERM3_NOCAPS = 0x00000000, // No additional capabilities
  117. PERM3_SGRAM = 0x00000001, // SGRAM board (else SDRAM)
  118. PERM3_DFP = 0x00000002, // Digital flat panel
  119. PERM3_DFP_MON_ATTACHED = 0x00000010, // DFP Monitor is attached
  120. PERM3_USE_BYTE_DOUBLING = 0x00000040 // Current mode requires byte-doubling
  121. } PERM3_CAPS;
  122. //
  123. // Supported board definitions.
  124. //
  125. typedef enum _PERM3_BOARDS {
  126. PERMEDIA3_BOARD = 17,
  127. } PERM3_BOARDS;
  128. //
  129. // Chip type definitions
  130. //
  131. typedef enum _PERM3_CHIPSETS {
  132. PERMEDIA3 = 5,
  133. } PERM3_CHIPSET;
  134. //
  135. // Supported RAMDAC definitions.
  136. //
  137. typedef enum _PERM3_RAMDACS {
  138. P3RD_RAMDAC = 14,
  139. } PERM3_RAMDACS;
  140. //
  141. // macros to add padding words to the structures. For the core registers we use
  142. // the tag ids when specifying the pad. So we must multiply by 8 to get a byte
  143. // pad. We need to add an id to make each pad field in the struct unique. The
  144. // id is irrelevant as long as it's different from every other id used in the
  145. // same struct.
  146. //
  147. #define PAD(id, n) UCHAR pad##id[n]
  148. #define PADRANGE(id, n) PAD(id, (n)-sizeof(PERM3_REG))
  149. #define PADCORERANGE(id, n) PADRANGE(id, (n)<<3)
  150. //
  151. // Perm3 registers are 32 bits wide and live on 64-bit boundaries.
  152. //
  153. typedef struct {
  154. ULONG reg;
  155. ULONG pad;
  156. } PERM3_REG;
  157. //
  158. // Permedia 3 PCI Region 0 Address MAP:
  159. //
  160. // All registers are on 64-bit boundaries so we have to define a number of
  161. // padding words. The number given in the comments are offsets from the start
  162. // of the PCI region.
  163. //
  164. typedef struct _perm3_region0_map {
  165. // Control Status Registers:
  166. PERM3_REG ResetStatus; // 0000h
  167. PERM3_REG IntEnable; // 0008h
  168. PERM3_REG IntFlags; // 0010h
  169. PERM3_REG InFIFOSpace; // 0018h
  170. PERM3_REG OutFIFOWords; // 0020h
  171. PERM3_REG DMAAddress; // 0028h
  172. PERM3_REG DMACount; // 0030h
  173. PERM3_REG ErrorFlags; // 0038h
  174. PERM3_REG VClkCtl; // 0040h
  175. PERM3_REG TestRegister; // 0048h
  176. union a0 {
  177. // GLINT
  178. struct b0 {
  179. PERM3_REG Aperture0; // 0050h
  180. PERM3_REG Aperture1; // 0058h
  181. };
  182. // PERMEDIA
  183. struct b1 {
  184. PERM3_REG ApertureOne; // 0050h
  185. PERM3_REG ApertureTwo; // 0058h
  186. };
  187. };
  188. PERM3_REG DMAControl; // 0060h
  189. PERM3_REG DisconnectControl; // 0068h
  190. // PERMEDIA only
  191. PERM3_REG ChipConfig; // 0070h
  192. PERM3_REG AGPControl; // 0078h - Px/Rx
  193. PERM3_REG OutDMAAddress; // 0080h
  194. PERM3_REG OutDMACount; // 0088h
  195. PERM3_REG AGPTexBaseAddress; // 0090h
  196. PADRANGE(201, 0xA0-0x90);
  197. PERM3_REG ByDMAAddress; // 00A0h
  198. PADRANGE(202, 0xB8-0xA0);
  199. PERM3_REG ByDMAStride; // 00B8h
  200. PERM3_REG ByDMAMemAddr; // 00C0h
  201. PERM3_REG ByDMASize; // 00C8h
  202. PERM3_REG ByDMAByteMask; // 00D0h
  203. PERM3_REG ByDMAControl; // 00D8h
  204. PADRANGE(203, 0xE8-0xD8);
  205. PERM3_REG ByDMAComplete; // 00E8h
  206. PADRANGE(204, 0x100-0xE8);
  207. // Paged texture management registers.
  208. PERM3_REG HostTextureAddress; // 0100h
  209. PERM3_REG TextureDownloadControl; // 0108h
  210. PERM3_REG TextureOperation; // 0110h
  211. PERM3_REG LogicalTexturePage; // 0118h
  212. PERM3_REG TextureDMAAddress; // 0120h
  213. PERM3_REG TextureFIFOSpace; // 0128h
  214. PADRANGE(205, 0x300-0x128);
  215. PERM3_REG ByAperture1Mode; // 0300h
  216. PERM3_REG ByAperture1Stride; // 0308h
  217. PADRANGE(206, 0x328-0x308);
  218. PERM3_REG ByAperture2Mode; // 0328h
  219. PERM3_REG ByAperture2Stride; // 0330h
  220. PADRANGE(207, 0x350-0x330);
  221. PERM3_REG ByDMAReadMode; // 0350h - Px/Rx only
  222. PERM3_REG ByDMAReadStride; // 0358h - Px/Rx only
  223. PADRANGE(208, 0x800-0x358);
  224. //
  225. // GLINTdelta registers. Registers with the same functionality as on GLINT
  226. // are at the same offset. XXX are not real registers.
  227. //
  228. PERM3_REG DeltaReset; // 0800h
  229. PERM3_REG DeltaIntEnable; // 0808h
  230. PERM3_REG DeltaIntFlags; // 0810h
  231. PERM3_REG DeltaInFIFOSpaceXXX; // 0818h
  232. PERM3_REG DeltaOutFIFOWordsXXX; // 0820h
  233. PERM3_REG DeltaDMAAddressXXX; // 0828h
  234. PERM3_REG DeltaDMACountXXX; // 0830h
  235. PERM3_REG DeltaErrorFlags; // 0838h
  236. PERM3_REG DeltaVClkCtlXXX; // 0840h
  237. PERM3_REG DeltaTestRegister; // 0848h
  238. PERM3_REG DeltaAperture0XXX; // 0850h
  239. PERM3_REG DeltaAperture1XXX; // 0858h
  240. PERM3_REG DeltaDMAControlXXX; // 0860h
  241. PERM3_REG DeltaDisconnectControl; // 0868h
  242. //
  243. // GLINTgamma registers
  244. //
  245. PERM3_REG GammaChipConfig; // 0870h
  246. PERM3_REG GammaCSRAperture; // 0878h
  247. PADRANGE(3, 0x0c00-0x878);
  248. PERM3_REG GammaPageTableAddr; // 0c00h
  249. PERM3_REG GammaPageTableLength; // 0c08h
  250. PADRANGE(301, 0x0c38-0x0c08);
  251. PERM3_REG GammaDelayTimer; // 0c38h
  252. PERM3_REG GammaCommandMode; // 0c40h
  253. PERM3_REG GammaCommandIntEnable; // 0c48h
  254. PERM3_REG GammaCommandIntFlags; // 0c50h
  255. PERM3_REG GammaCommandErrorFlags; // 0c58h
  256. PERM3_REG GammaCommandStatus; // 0c60h
  257. PERM3_REG GammaCommandFaultingAddr; // 0c68h
  258. PERM3_REG GammaVertexFaultingAddr; // 0c70h
  259. PADRANGE(302, 0x0c88-0x0c70);
  260. PERM3_REG GammaWriteFaultingAddr; // 0c88h
  261. PADRANGE(303, 0x0c98-0x0c88);
  262. PERM3_REG GammaFeedbackSelectCount; // 0c98h
  263. PADRANGE(304, 0x0cb8-0x0c98);
  264. PERM3_REG GammaProcessorMode; // 0cb8h
  265. PADRANGE(305, 0x0d00-0x0cb8);
  266. PERM3_REG GammaVGAShadow; // 0d00h
  267. PERM3_REG GammaMultiGLINTAperture; // 0d08h
  268. PERM3_REG GammaMultiGLINT1; // 0d10h
  269. PERM3_REG GammaMultiGLINT2; // 0d18h
  270. PADRANGE(306, 0x0f00-0x0d18);
  271. PERM3_REG GammaSerialAccess; // 0f00h
  272. PADRANGE(307, 0x1000-0x0f00);
  273. // Localbuffer Registers
  274. union x0 { // 1000h
  275. PERM3_REG LBMemoryCtl; // GLINT
  276. PERM3_REG Reboot; // PERMEDIA
  277. };
  278. PERM3_REG LBMemoryEDO; // 1008h
  279. PADRANGE(308, 0x1018-0x1008);
  280. // PERMEDIA3 only
  281. PERM3_REG LocalMemCaps; // 1018h
  282. PERM3_REG LocalMemTiming; // 1020h
  283. PERM3_REG LocalMemControl; // 1028h
  284. PERM3_REG LocalMemRefresh; // 1030h
  285. PERM3_REG LocalMemPowerDown; // 1038h
  286. // PERMEDIA & PERMEDIA2 only
  287. PERM3_REG MemControl; // 1040h
  288. // PERMEDIA3 only
  289. PADRANGE(4, 0x1068-0x1040);
  290. PERM3_REG LocalMemProfileMask0; // 1068h
  291. PERM3_REG LocalMemProfileCount0; // 1070h
  292. PERM3_REG LocalMemProfileMask1; // 1078h
  293. // PERMEDIA & PERMEDIA2 only
  294. PERM3_REG BootAddress; // 1080h [= LocalMemProfileCount1 on PxRx]
  295. PADRANGE(5, 0x10C0-0x1080);
  296. PERM3_REG MemConfig; // 10C0h
  297. PADRANGE(6, 0x1100-0x10C0);
  298. PERM3_REG BypassWriteMask; // 1100h
  299. PADRANGE(7, 0x1140-0x1100);
  300. PERM3_REG FramebufferWriteMask; // 1140h
  301. PADRANGE(8, 0x1180-0x1140);
  302. PERM3_REG Count; // 1180h
  303. PADRANGE(9, 0x1800-0x1180);
  304. // Framebuffer Registers
  305. PERM3_REG FBMemoryCtl; // 1800h
  306. PERM3_REG FBModeSel; // 1808h
  307. PERM3_REG FBGCWrMask; // 1810h
  308. PERM3_REG FBGCColorMask; // 1818h
  309. PERM3_REG FBTXMemCtl; // 1820h
  310. PADRANGE(10, 0x2000-0x1820);
  311. // Graphics Core FIFO Interface
  312. PERM3_REG FIFOInterface; // 2000h
  313. PADRANGE(11, 0x3000-0x2000);
  314. // Internal Video Registers
  315. union x1 {
  316. // GLINT
  317. struct s1 {
  318. PERM3_REG VTGHLimit; // 3000h
  319. PERM3_REG VTGHSyncStart; // 3008h
  320. PERM3_REG VTGHSyncEnd; // 3010h
  321. PERM3_REG VTGHBlankEnd; // 3018h
  322. PERM3_REG VTGVLimit; // 3020h
  323. PERM3_REG VTGVSyncStart; // 3028h
  324. PERM3_REG VTGVSyncEnd; // 3030h
  325. PERM3_REG VTGVBlankEnd; // 3038h
  326. PERM3_REG VTGHGateStart; // 3040h
  327. PERM3_REG VTGHGateEnd; // 3048h
  328. PERM3_REG VTGVGateStart; // 3050h
  329. PERM3_REG VTGVGateEnd; // 3058h
  330. PERM3_REG VTGPolarity; // 3060h
  331. PERM3_REG VTGFrameRowAddr; // 3068h
  332. PERM3_REG VTGVLineNumber; // 3070h
  333. PERM3_REG VTGSerialClk; // 3078h
  334. PERM3_REG VTGModeCtl; // 3080h
  335. };
  336. // PERMEDIA
  337. struct s2 {
  338. PERM3_REG ScreenBase; // 3000h
  339. PERM3_REG ScreenStride; // 3008h
  340. PERM3_REG HTotal; // 3010h
  341. PERM3_REG HgEnd; // 3018h
  342. PERM3_REG HbEnd; // 3020h
  343. PERM3_REG HsStart; // 3028h
  344. PERM3_REG HsEnd; // 3030h
  345. PERM3_REG VTotal; // 3038h
  346. PERM3_REG VbEnd; // 3040h
  347. PERM3_REG VsStart; // 3048h
  348. PERM3_REG VsEnd; // 3050h
  349. PERM3_REG VideoControl; // 3058h
  350. PERM3_REG InterruptLine; // 3060h
  351. PERM3_REG DDCData; // 3068h
  352. PERM3_REG LineCount; // 3070h
  353. PERM3_REG VFifoCtl; // 3078h
  354. PERM3_REG ScreenBaseRight; // 3080h
  355. };
  356. };
  357. PERM3_REG MiscControl; // 3088h
  358. PADRANGE(111, 0x3100-0x3088);
  359. PERM3_REG VideoOverlayUpdate; // 0x3100
  360. PERM3_REG VideoOverlayMode; // 0x3108
  361. PERM3_REG VideoOverlayFifoControl; // 0x3110
  362. PERM3_REG VideoOverlayIndex; // 0x3118
  363. PERM3_REG VideoOverlayBase0; // 0x3120
  364. PERM3_REG VideoOverlayBase1; // 0x3128
  365. PERM3_REG VideoOverlayBase2; // 0x3130
  366. PERM3_REG VideoOverlayStride; // 0x3138
  367. PERM3_REG VideoOverlayWidth; // 0x3140
  368. PERM3_REG VideoOverlayHeight; // 0x3148
  369. PERM3_REG VideoOverlayOrigin; // 0x3150
  370. PERM3_REG VideoOverlayShrinkXDelta; // 0x3158
  371. PERM3_REG VideoOverlayZoomXDelta; // 0x3160
  372. PERM3_REG VideoOverlayYDelta; // 0x3168
  373. PERM3_REG VideoOverlayFieldOffset; // 0x3170
  374. PERM3_REG VideoOverlayStatus; // 0x3178
  375. //
  376. // External Video Control Registers
  377. // Need to cast this to a struct for a particular video generator
  378. //
  379. PADRANGE(12, 0x4000-0x3178);
  380. PERM3_REG ExternalVideo; // 4000h
  381. PADRANGE(13, 0x4080-0x4000);
  382. //
  383. // Mentor Dual-TX clock chip registers
  384. //
  385. PERM3_REG MentorICDControl; // 4080h
  386. //
  387. // for future: MentorDoubleWrite is at 40C0: 0 = single write, 1 = double
  388. // NB must have 2-way interleaved memory
  389. PADRANGE(14, 0x4800-0x4080);
  390. PERM3_REG GloriaControl; // 4800h
  391. PADRANGE(15, 0x5000-0x4800);
  392. PERM3_REG DemonProDWAndStatus; // 5000h - Pro
  393. PADRANGE(151, 0x5800-0x5000);
  394. //
  395. // P2 video streams registers
  396. //
  397. PERM3_REG VSConfiguration; // 5800h
  398. PERM3_REG VSStatus; // 5808h
  399. PERM3_REG VSSerialBusControl; // 5810h
  400. PADRANGE(16, 0x5A00-0x5810);
  401. PERM3_REG VSBControl; // 5A00h
  402. PADRANGE(161, 0x6000-0x5A00);
  403. union x2 {
  404. struct s3 {
  405. PERM3_REG RacerDoubleWrite; // 6000h
  406. PERM3_REG RacerBankSelect; // 6008h
  407. PERM3_REG DualTxVgaSwitch; // 6010h
  408. PERM3_REG DDC1ReadAddress; // 6018h
  409. };
  410. struct s4 {
  411. //
  412. // the following array is actually 1024 bytes long
  413. //
  414. UCHAR PermediaVgaCtrl[4*sizeof(PERM3_REG)];
  415. };
  416. };
  417. PADRANGE(17, 0x7000-0x6018);
  418. union {
  419. PERM3_REG DemonProUBufB; // 7000h - Pro
  420. PERM3_REG TextureDataFifo;
  421. };
  422. PADRANGE(171, 0x8000-0x7000);
  423. } Perm3ControlRegMap, *pPerm3ControlRegMap;
  424. //
  425. // Permedia 3 Interrupt Control Bits
  426. //
  427. // InterruptEnable register
  428. #define INTR_DISABLE_ALL 0
  429. #define INTR_ENABLE_DMA (1 << 0)
  430. #define INTR_ENABLE_SYNC (1 << 1)
  431. #define INTR_ENABLE_EXTERNAL (1 << 2)
  432. #define INTR_ENABLE_ERROR (1 << 3)
  433. #define INTR_ENABLE_VBLANK (1 << 4)
  434. #define INTR_ENABLE_GCOMMAND (1 << 13)
  435. // InterruptFlags register
  436. #define INTR_DMA_SET (1 << 0)
  437. #define INTR_SYNC_SET (1 << 1)
  438. #define INTR_EXTERNAL_SET (1 << 2)
  439. #define INTR_ERROR_SET (1 << 3)
  440. #define INTR_VBLANK_SET (1 << 4)
  441. #define INTR_TEXTURE_FAULT_SET (1 << 6)
  442. #define INTR_GCOMMAND_SET (1 << 13)
  443. #define INTR_CLEAR_ALL (0x1f | (1 << 13))
  444. #define INTR_CLEAR_DMA (1 << 0)
  445. #define INTR_CLEAR_SYNC (1 << 1)
  446. #define INTR_CLEAR_EXTERNAL (1 << 2)
  447. #define INTR_CLEAR_ERROR (1 << 3)
  448. #define INTR_CLEAR_VBLANK (1 << 4)
  449. // Error Flags
  450. #define ERROR_IN_FIFO (1 << 0)
  451. #define ERROR_OUT_FIFO (1 << 1)
  452. #define ERROR_MESSAGE (1 << 2)
  453. #define DMA_ERROR (1 << 3)
  454. #define ERROR_VFIFO_UNDERRUN (1 << 4)
  455. //
  456. // Macros which takes a Perm3 tag name or control register name and translates
  457. // it to a register address. Data must be written to these addresses using
  458. // VideoPortWriteRegisterUlong and read using VideoPortReadRegisterUlong.
  459. // e.g. dma_count = VideoPortReadRegisterUlong(DMA_COUNT);
  460. //
  461. #define CTRL_REG_ADDR(reg) ((PULONG)&(pCtrlRegs->reg))
  462. #define CTRL_REG_OFFSET(regAddr) ((ULONG)(((ULONG_PTR)regAddr) - ((ULONG_PTR)pCtrlRegs)))
  463. //
  464. // Defines for the different control registers needed by Permedia 3.
  465. // These macros can be used as the address part.
  466. //
  467. #define RESET_STATUS CTRL_REG_ADDR(ResetStatus)
  468. #define INT_ENABLE CTRL_REG_ADDR(IntEnable)
  469. #define INT_FLAGS CTRL_REG_ADDR(IntFlags)
  470. #define IN_FIFO_SPACE CTRL_REG_ADDR(InFIFOSpace)
  471. #define OUT_FIFO_WORDS CTRL_REG_ADDR(OutFIFOWords)
  472. #define DMA_ADDRESS CTRL_REG_ADDR(DMAAddress)
  473. #define DMA_COUNT CTRL_REG_ADDR(DMACount)
  474. #define DMA_OUT_ADDRESS CTRL_REG_ADDR(OutDMAAddress)
  475. #define DMA_OUT_COUNT CTRL_REG_ADDR(OutDMACount)
  476. #define ERROR_FLAGS CTRL_REG_ADDR(ErrorFlags)
  477. #define V_CLK_CTL CTRL_REG_ADDR(VClkCtl)
  478. #define TEST_REGISTER CTRL_REG_ADDR(TestRegister)
  479. #define APERTURE_0 CTRL_REG_ADDR(Aperture0)
  480. #define APERTURE_1 CTRL_REG_ADDR(Aperture1)
  481. #define DMA_CONTROL CTRL_REG_ADDR(DMAControl)
  482. #define LB_MEMORY_CTL CTRL_REG_ADDR(LBMemoryCtl)
  483. #define LB_MEMORY_EDO CTRL_REG_ADDR(LBMemoryEDO)
  484. #define FB_MEMORY_CTL CTRL_REG_ADDR(FBMemoryCtl)
  485. #define FB_MODE_SEL CTRL_REG_ADDR(FBModeSel)
  486. #define FB_GC_WRITEMASK CTRL_REG_ADDR(FBGCWrMask)
  487. #define FB_GC_COLORMASK CTRL_REG_ADDR(FBGCColorMask)
  488. #define FB_TX_MEM_CTL CTRL_REG_ADDR(FBTXMemCtl)
  489. #define FIFO_INTERFACE CTRL_REG_ADDR(FIFOInterface)
  490. #define DISCONNECT_CONTROL CTRL_REG_ADDR(DisconnectControl)
  491. #define BY_DMACOMPLETE CTRL_REG_ADDR(ByDMAComplete)
  492. #define AGP_TEX_BASE_ADDRESS CTRL_REG_ADDR(AGPTexBaseAddress)
  493. // Bypass mode registers
  494. #define BY_APERTURE1_MODE CTRL_REG_ADDR(ByAperture1Mode)
  495. #define BY_APERTURE1_STRIDE CTRL_REG_ADDR(ByAperture1Stride)
  496. #define BY_APERTURE2_MODE CTRL_REG_ADDR(ByAperture2Mode)
  497. #define BY_APERTURE2_STRIDE CTRL_REG_ADDR(ByAperture2Stride)
  498. #define BY_DMA_READ_MODE CTRL_REG_ADDR(ByDMAReadMode)
  499. #define BY_DMA_READ_STRIDE CTRL_REG_ADDR(ByDMAReadStride)
  500. // Delta control registers
  501. #define DELTA_RESET_STATUS CTRL_REG_ADDR(DeltaReset)
  502. #define DELTA_INT_ENABLE CTRL_REG_ADDR(DeltaIntEnable)
  503. #define DELTA_INT_FLAGS CTRL_REG_ADDR(DeltaIntFlags)
  504. // Permedia 3 Registers
  505. #define APERTURE_ONE CTRL_REG_ADDR(ApertureOne)
  506. #define APERTURE_TWO CTRL_REG_ADDR(ApertureTwo)
  507. #define BYPASS_WRITE_MASK CTRL_REG_ADDR(BypassWriteMask)
  508. #define FRAMEBUFFER_WRITE_MASK CTRL_REG_ADDR(FramebufferWriteMask)
  509. #define MEM_CONTROL CTRL_REG_ADDR(MemControl)
  510. #define BOOT_ADDRESS CTRL_REG_ADDR(BootAddress)
  511. #define MEM_CONFIG CTRL_REG_ADDR(MemConfig)
  512. #define CHIP_CONFIG CTRL_REG_ADDR(ChipConfig)
  513. #define AGP_CONTROL CTRL_REG_ADDR(AGPControl)
  514. #define SGRAM_REBOOT CTRL_REG_ADDR(Reboot)
  515. #define SCREEN_BASE CTRL_REG_ADDR(ScreenBase)
  516. #define SCREEN_BASE_RIGHT CTRL_REG_ADDR(ScreenBaseRight)
  517. #define SCREEN_STRIDE CTRL_REG_ADDR(ScreenStride)
  518. #define H_TOTAL CTRL_REG_ADDR(HTotal)
  519. #define HG_END CTRL_REG_ADDR(HgEnd)
  520. #define HB_END CTRL_REG_ADDR(HbEnd)
  521. #define HS_START CTRL_REG_ADDR(HsStart)
  522. #define HS_END CTRL_REG_ADDR(HsEnd)
  523. #define V_TOTAL CTRL_REG_ADDR(VTotal)
  524. #define VB_END CTRL_REG_ADDR(VbEnd)
  525. #define VS_START CTRL_REG_ADDR(VsStart)
  526. #define VS_END CTRL_REG_ADDR(VsEnd)
  527. #define VIDEO_CONTROL CTRL_REG_ADDR(VideoControl)
  528. #define INTERRUPT_LINE CTRL_REG_ADDR(InterruptLine)
  529. #define DDC_DATA CTRL_REG_ADDR(DDCData)
  530. #define LINE_COUNT CTRL_REG_ADDR(LineCount)
  531. #define VIDEO_FIFO_CTL CTRL_REG_ADDR(VFifoCtl)
  532. #define MISC_CONTROL CTRL_REG_ADDR(MiscControl)
  533. // Permedia 3 Video Streams registers
  534. #define VSTREAM_CONFIG CTRL_REG_ADDR(VSConfiguration)
  535. #define VSTREAM_SERIAL_CONTROL CTRL_REG_ADDR(VSSerialBusControl)
  536. #define VSTREAM_B_CONTROL CTRL_REG_ADDR(VSBControl)
  537. #define VSTREAM_CONFIG_UNITMODE_MASK (0x7 << 0)
  538. #define VSTREAM_CONFIG_UNITMODE_FP (0x6 << 0)
  539. #define VSTREAM_CONFIG_UNITMODE_CRT (0x0 << 0)
  540. #define VSTREAM_SERIAL_CONTROL_DATAIN (0x1 << 0)
  541. #define VSTREAM_SERIAL_CONTROL_CLKIN (0x1 << 1)
  542. #define VSTREAM_SERIAL_CONTROL_DATAOUT (0x1 << 2)
  543. #define VSTREAM_SERIAL_CONTROL_CLKOUT (0x1 << 3)
  544. #define VSTREAM_B_CONTROL_RAMDAC_ENABLE (0x1 << 14)
  545. #define VSTREAM_B_CONTROL_RAMDAC_DISABLE (0x0 << 14)
  546. //
  547. // Memory mapped VGA access
  548. //
  549. #define PERMEDIA_MMVGA_INDEX_REG ((PVOID)(&(pCtrlRegs->PermediaVgaCtrl[0x3C4])))
  550. #define PERMEDIA_MMVGA_DATA_REG (&(pCtrlRegs->PermediaVgaCtrl[0x3C5]))
  551. #define PERMEDIA_MMVGA_STAT_REG (&(pCtrlRegs->PermediaVgaCtrl[0x3DA]))
  552. #define PERMEDIA_VGA_CTRL_INDEX 5
  553. #define PERMEDIA_VGA_ENABLE (1 << 3)
  554. #define PERMEDIA_VGA_STAT_VSYNC (1 << 3)
  555. #define PERMEDIA_VGA_LOCK_INDEX1 6
  556. #define PERMEDIA_VGA_LOCK_INDEX2 7
  557. #define PERMEDIA_VGA_LOCK_DATA1 0x0
  558. #define PERMEDIA_VGA_LOCK_DATA2 0x0
  559. #define PERMEDIA_VGA_UNLOCK_DATA1 0x3D
  560. #define PERMEDIA_VGA_UNLOCK_DATA2 0xDB
  561. //
  562. // Lock VGA registers, only applicable to P3 and later, note that we only
  563. // need to write to 1 of the LOCK registers not both
  564. //
  565. #define LOCK_VGA_REGISTERS() { \
  566. VideoPortWriteRegisterUchar( PERMEDIA_MMVGA_INDEX_REG, PERMEDIA_VGA_LOCK_INDEX1 ); \
  567. VideoPortWriteRegisterUchar( PERMEDIA_MMVGA_DATA_REG, PERMEDIA_VGA_LOCK_DATA1 ); \
  568. }
  569. //
  570. // Unlock VGA registers, only applicable to P3 and later. We have to write
  571. // special magic code to unlock the registers. Note that this should be done
  572. // using 2 short writes rather than 4 byte ones, but I've left it in for
  573. // readability.
  574. //
  575. #define UNLOCK_VGA_REGISTERS() { \
  576. VideoPortWriteRegisterUchar( PERMEDIA_MMVGA_INDEX_REG, PERMEDIA_VGA_LOCK_INDEX1 ); \
  577. VideoPortWriteRegisterUchar( PERMEDIA_MMVGA_DATA_REG, PERMEDIA_VGA_UNLOCK_DATA1 ); \
  578. VideoPortWriteRegisterUchar( PERMEDIA_MMVGA_INDEX_REG, PERMEDIA_VGA_LOCK_INDEX2 ); \
  579. VideoPortWriteRegisterUchar( PERMEDIA_MMVGA_DATA_REG, PERMEDIA_VGA_UNLOCK_DATA2 ); \
  580. }
  581. #define VC_FORCED_HIGH 0
  582. #define VC_ACTIVE_HIGH 1
  583. #define VC_FORCED_LOW 2
  584. #define VC_ACTIVE_LOW 3
  585. #define VC_HSYNC(x) (x << 3)
  586. #define VC_VSYNC(x) (x << 5)
  587. #define VC_ON 1
  588. #define VC_OFF 0
  589. #define VC_DPMS_MASK (VC_HSYNC(3) | VC_VSYNC(3) | VC_ON)
  590. #define VC_DPMS_STANDBY (VC_HSYNC(VC_FORCED_LOW) | VC_VSYNC(VC_ACTIVE_HIGH) | VC_OFF)
  591. #define VC_DPMS_SUSPEND (VC_HSYNC(VC_ACTIVE_HIGH) | VC_VSYNC(VC_FORCED_LOW) | VC_OFF)
  592. #define VC_DPMS_OFF (VC_HSYNC(VC_FORCED_LOW) | VC_VSYNC(VC_FORCED_LOW) | VC_OFF)
  593. //
  594. // DisconnectControl bits
  595. //
  596. #define DISCONNECT_INPUT_FIFO_ENABLE 0x1
  597. #define DISCONNECT_OUTPUT_FIFO_ENABLE 0x2
  598. #define DISCONNECT_INOUT_ENABLE (DISCONNECT_INPUT_FIFO_ENABLE | \
  599. DISCONNECT_OUTPUT_FIFO_ENABLE)
  600. // PXRX memory timing registers
  601. #define PXRX_LOCAL_MEM_CAPS CTRL_REG_ADDR(LocalMemCaps)
  602. #define PXRX_LOCAL_MEM_CONTROL CTRL_REG_ADDR(LocalMemControl)
  603. #define PXRX_LOCAL_MEM_POWER_DOWN CTRL_REG_ADDR(LocalMemPowerDown)
  604. #define PXRX_LOCAL_MEM_REFRESH CTRL_REG_ADDR(LocalMemRefresh)
  605. #define PXRX_LOCAL_MEM_TIMING CTRL_REG_ADDR(LocalMemTiming)
  606. // Values for the MISC_CONTROL
  607. #define PXRX_MISC_CONTROL_STRIPE_MODE_DISABLE (0 << 0) // Stripe mode
  608. #define PXRX_MISC_CONTROL_STRIPE_MODE_PRIMARY (1 << 0)
  609. #define PXRX_MISC_CONTROL_STRIPE_MODE_SECONDARY (2 << 0)
  610. #define PXRX_MISC_CONTROL_STRIPE_SIZE_1 (0 << 4) // Stripe size
  611. #define PXRX_MISC_CONTROL_STRIPE_SIZE_2 (1 << 4)
  612. #define PXRX_MISC_CONTROL_STRIPE_SIZE_4 (2 << 4)
  613. #define PXRX_MISC_CONTROL_STRIPE_SIZE_8 (3 << 4)
  614. #define PXRX_MISC_CONTROL_STRIPE_SIZE_16 (4 << 4)
  615. #define PXRX_MISC_CONTROL_BYTE_DBL_DISABLE (0 << 7) // Byte doubling
  616. #define PXRX_MISC_CONTROL_BYTE_DBL_ENABLE (1 << 7)
  617. //
  618. // Characteristics of each mode
  619. //
  620. typedef struct _PERM3_VIDEO_MODES {
  621. // Leave INT10 fields in for later chips which have VGA
  622. USHORT Int10ModeNumberContiguous;
  623. USHORT Int10ModeNumberNoncontiguous;
  624. ULONG ScreenStrideContiguous;
  625. VIDEO_MODE_INFORMATION ModeInformation;
  626. } PERM3_VIDEO_MODES, *PPERM3_VIDEO_MODES;
  627. //
  628. // Mode-set specific information.
  629. //
  630. typedef struct _PERM3_VIDEO_FREQUENCIES {
  631. ULONG BitsPerPel;
  632. ULONG ScreenWidth;
  633. ULONG ScreenHeight;
  634. ULONG ScreenFrequency;
  635. PPERM3_VIDEO_MODES ModeEntry;
  636. ULONG ModeIndex;
  637. UCHAR ModeValid;
  638. ULONG PixelClock;
  639. } PERM3_VIDEO_FREQUENCIES, *PPERM3_VIDEO_FREQUENCIES;
  640. //
  641. // Monitor & screen mode information:
  642. // structure of timing data contained in the registry
  643. //
  644. typedef struct {
  645. USHORT HTot; // Hor Total Time
  646. UCHAR HFP; // Hor Front Porch
  647. UCHAR HST; // Hor Sync Time
  648. UCHAR HBP; // Hor Back Porch
  649. UCHAR HSP; // Hor Sync Polarity
  650. USHORT VTot; // Ver Total Time
  651. UCHAR VFP; // Ver Front Porch
  652. UCHAR VST; // Ver Sync Time
  653. UCHAR VBP; // Ver Back Porch
  654. UCHAR VSP; // Ver Sync Polarity
  655. ULONG pClk; // Pixel clock
  656. } VESA_TIMING_STANDARD;
  657. typedef struct {
  658. ULONG width;
  659. ULONG height;
  660. ULONG refresh;
  661. } MODE_INFO;
  662. typedef struct {
  663. MODE_INFO basic;
  664. VESA_TIMING_STANDARD vesa;
  665. } TIMING_INFO;
  666. #define MI_FLAGS_READ_DDC (1 << 3)
  667. #define MI_FLAGS_DOES_DDC (1 << 4)
  668. #define MI_FLAGS_FUDGED_VH (1 << 5)
  669. #define MI_FLAGS_FUDGED_PCLK (1 << 6)
  670. #define MI_FLAGS_FUDGED_XY (1 << 7)
  671. #define MI_FLAGS_LIMIT_XY (1 << 8)
  672. typedef struct {
  673. ULONG flags;
  674. char id[8];
  675. char name[16]; // name[14] but need to ensure dword packing
  676. ULONG fhMin, fhMax;
  677. ULONG fvMin, fvMax;
  678. ULONG pClkMin, pClkMax;
  679. ULONG timingNum;
  680. ULONG xMin, xMax, yMin, yMax;
  681. ULONG timingMax;
  682. TIMING_INFO *timingList;
  683. PERM3_VIDEO_FREQUENCIES *frequencyTable;
  684. ULONG numAvailableModes;
  685. ULONG numTotalModes;
  686. } MONITOR_INFO;
  687. typedef struct {
  688. ULONG fH, fV;
  689. ULONG pClk;
  690. } FREQUENCIES;
  691. //
  692. // Framebuffer Aperture Information: currently only of interest to GeoTwin
  693. // boards to allow for upload DMA directly from FB0 to FB1 and vice versa
  694. //
  695. typedef struct FrameBuffer_Aperture_Info
  696. {
  697. PHYSICAL_ADDRESS pphysBaseAddr;
  698. ULONG cjLength;
  699. }
  700. FBAPI;
  701. //
  702. // PCI device information. Used in an IOCTL return. Ensure this is the same
  703. // as in the display driver
  704. // Never rearrange the existing order, just append to the end (see
  705. // IOCTL_VIDEO_QUERY_DEVICE_INFO in display driver)
  706. //
  707. typedef struct _Perm3_Device_Info {
  708. ULONG SubsystemId;
  709. ULONG SubsystemVendorId;
  710. ULONG VendorId;
  711. ULONG DeviceId;
  712. ULONG RevisionId;
  713. ULONG DeltaRevId;
  714. ULONG GammaRevId;
  715. ULONG BoardId;
  716. ULONG LocalbufferLength;
  717. ULONG LocalbufferWidth;
  718. ULONG ActualDacId;
  719. FBAPI FBAperture[2]; // Physical addresses for geo twin framebuffers
  720. PVOID FBApertureVirtual[2]; // Virtual addresses for geo twin framebuffers
  721. PVOID FBApertureMapped [2]; // Mapped physical/logical addresses for geo twin framebuffers
  722. PUCHAR pCNB20;
  723. PHYSICAL_ADDRESS pphysFrameBuffer; // physical address of the framebuffer (use FBAperture instead for geo twins)
  724. } Perm3_Device_Info;
  725. // Definition of the IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER
  726. typedef struct _GENERAL_DMA_BUFFER {
  727. PHYSICAL_ADDRESS physAddr; // physical address of DMA buffer
  728. PVOID virtAddr; // mapped virtual address
  729. ULONG size; // size in bytes
  730. BOOLEAN cacheEnabled; // Whether buffer is cached
  731. } GENERAL_DMA_BUFFER, *PGENERAL_DMA_BUFFER;
  732. //
  733. // The following are the definition for the LUT cache. The aim of the LUT cache
  734. // is to stop sparkling from occurring, bu only writing those LUT entries that
  735. // have changed to the chip, we can only do this by remembering what is already
  736. // down there. The 'mystify' screen saver on P2 demonstrates the problem.
  737. //
  738. #define LUT_CACHE_INIT() {VideoPortZeroMemory (&(hwDeviceExtension->LUTCache), sizeof (hwDeviceExtension->LUTCache));}
  739. #define LUT_CACHE_SETSIZE(sz) {hwDeviceExtension->LUTCache.LUTCache.NumEntries = (sz);}
  740. #define LUT_CACHE_SETFIRST(frst){hwDeviceExtension->LUTCache.LUTCache.FirstEntry = (frst);}
  741. #define LUT_CACHE_SETRGB(idx,zr,zg,zb) { \
  742. hwDeviceExtension->LUTCache.LUTCache.LookupTable [idx].RgbArray.Red = (UCHAR) (zr); \
  743. hwDeviceExtension->LUTCache.LUTCache.LookupTable [idx].RgbArray.Green = (UCHAR) (zg); \
  744. hwDeviceExtension->LUTCache.LUTCache.LookupTable [idx].RgbArray.Blue = (UCHAR) (zb); \
  745. }
  746. typedef struct {
  747. VIDEO_CLUT LUTCache; // Header plus 1 LUT entry
  748. VIDEO_CLUTDATA LUTData [255]; // the other 255 LUT entries
  749. } LUT_CACHE;
  750. //
  751. // Possible regions:
  752. // Gamma ctl
  753. // Perm3 ctl
  754. // LB
  755. // FB
  756. //
  757. #define MAX_RESERVED_REGIONS 4
  758. #define MAX_REGISTER_INITIALIZATION_TABLE_ENTRIES 10
  759. #define MAX_REGISTER_INITIALIZATION_TABLE_ULONGS (2 * MAX_REGISTER_INITIALIZATION_TABLE_ENTRIES)
  760. //
  761. // Define device extension structure. This is device dependent/private
  762. // information.
  763. //
  764. typedef struct _HW_DEVICE_EXTENSION {
  765. pPerm3ControlRegMap ctrlRegBase[1];
  766. PVOID pFramebuffer;
  767. PVOID pRamdac;
  768. PHYSICAL_ADDRESS PhysicalFrameAddress;
  769. ULONG FrameLength;
  770. PHYSICAL_ADDRESS PhysicalRegisterAddress;
  771. ULONG RegisterLength;
  772. UCHAR RegisterSpace;
  773. ULONG SavedControlAddress;
  774. PPERM3_VIDEO_MODES ActiveModeEntry;
  775. PERM3_VIDEO_FREQUENCIES ActiveFrequencyEntry;
  776. PCI_SLOT_NUMBER pciSlot;
  777. ULONG DacId;
  778. ULONG ChipClockSpeed;
  779. ULONG ChipClockSpeedAlt;
  780. ULONG GlintGammaClockSpeed;
  781. ULONG PXRXLastClockSpeed;
  782. ULONG RefClockSpeed;
  783. ULONG Capabilities;
  784. ULONG AdapterMemorySize;
  785. ULONG PhysicalFrameIoSpace;
  786. BOOLEAN bIsAGP;
  787. Perm3_Device_Info deviceInfo;
  788. ULONG BiosVersionMajorNumber;
  789. ULONG BiosVersionMinorNumber;
  790. //
  791. // Shared memory for comms with the display driver
  792. //
  793. PERM3_INTERRUPT_CTRLBUF InterruptControl;
  794. //
  795. // Shared memory for comms with the display driver
  796. //
  797. PERM3_INTERRUPT_CTRLBUF InterruptTextureControl;
  798. //
  799. // DMA Buffer definitions
  800. //
  801. GENERAL_DMA_BUFFER LineDMABuffer;
  802. GENERAL_DMA_BUFFER P3RXDMABuffer;
  803. //
  804. // PCI Config Information
  805. //
  806. ULONG bVGAEnabled;
  807. VIDEO_ACCESS_RANGE PciAccessRange[MAX_RESERVED_REGIONS+1];
  808. //
  809. // Initialization table
  810. //
  811. ULONG aulInitializationTable[MAX_REGISTER_INITIALIZATION_TABLE_ULONGS];
  812. ULONG culTableEntries;
  813. //
  814. // Extended BIOS initialisation variables
  815. //
  816. BOOLEAN bHaveExtendedClocks;
  817. ULONG ulPXRXCoreClock;
  818. ULONG ulPXRXMemoryClock;
  819. ULONG ulPXRXMemoryClockSrc;
  820. ULONG ulPXRXSetupClock;
  821. ULONG ulPXRXSetupClockSrc;
  822. ULONG ulPXRXGammaClock;
  823. ULONG ulPXRXCoreClockAlt;
  824. //
  825. // LUT cache
  826. //
  827. LUT_CACHE LUTCache;
  828. ULONG IntEnable;
  829. ULONG VideoFifoControlCountdown;
  830. BOOLEAN bVTGRunning;
  831. PPERM3_VIDEO_FREQUENCIES pFrequencyDefault;
  832. //
  833. // State save variables (for power management)
  834. //
  835. ULONG VideoControlMonitorON;
  836. ULONG VideoControl;
  837. ULONG PreviousPowerState;
  838. BOOLEAN bMonitorPoweredOn;
  839. ULONG VideoFifoControl;
  840. //
  841. // Monitor configuration stuff:
  842. //
  843. MONITOR_INFO monitorInfo;
  844. //
  845. // Perm3 Capabilities
  846. //
  847. PERM3_CAPS Perm3Capabilities;
  848. //
  849. // Error detected in interrupt routine
  850. //
  851. ULONG OutputFifoErrors;
  852. ULONG InputFifoErrors;
  853. ULONG UnderflowErrors;
  854. ULONG TotalErrors;
  855. //
  856. // I2C Support
  857. //
  858. BOOLEAN I2CInterfaceAcquired;
  859. VIDEO_PORT_I2C_INTERFACE_2 I2CInterface;
  860. ULONG (*WinXpVideoPortGetAssociatedDeviceID)(PVOID);
  861. VP_STATUS (*WinXpSp1VideoPortRegisterBugcheckCallback)(PVOID,ULONG,PVIDEO_BUGCHECK_CALLBACK,ULONG);
  862. } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
  863. #define VideoPortGetAssociatedDeviceID \
  864. hwDeviceExtension->WinXpVideoPortGetAssociatedDeviceID
  865. // PCI configuration region device specific defines
  866. #define AGP_CAP_ID 2 // PCIsig AGP Cap ID
  867. #define AGP_CAP_PTR_OFFSET 0x34 // offset to start of capabilities list
  868. //
  869. // Highest valid DAC color register index.
  870. //
  871. #define VIDEO_MAX_COLOR_REGISTER 0xFF
  872. #define MAX_CLUT_SIZE (sizeof(VIDEO_CLUT) + (sizeof(ULONG) * (VIDEO_MAX_COLOR_REGISTER+1)))
  873. //
  874. // Data
  875. //
  876. extern PERM3_VIDEO_MODES Perm3Modes[];
  877. extern const ULONG NumPerm3VideoModes;
  878. extern VIDEO_ACCESS_RANGE Perm3LegacyResourceList[];
  879. extern ULONG Perm3LegacyResourceEntries;
  880. //
  881. // PXRX Registry Strings
  882. //
  883. #define PERM3_REG_STRING_CORECLKSPEED L"PXRX.CoreClockSpeed"
  884. #define PERM3_REG_STRING_CORECLKSPEEDALT L"PXRX.CoreClockSpeedAlt"
  885. #define PERM3_REG_STRING_REFCLKSPEED L"PXRX.RefClockSpeed"
  886. //
  887. // IOCTL and structure definitions for mapping DMA buffers
  888. //
  889. #define IOCTL_VIDEO_QUERY_NUM_DMA_BUFFERS \
  890. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD0, METHOD_BUFFERED, FILE_ANY_ACCESS)
  891. #define IOCTL_VIDEO_QUERY_DMA_BUFFERS \
  892. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD1, METHOD_BUFFERED, FILE_ANY_ACCESS)
  893. #define IOCTL_VIDEO_QUERY_DEVICE_INFO \
  894. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD2, METHOD_BUFFERED, FILE_ANY_ACCESS)
  895. #define IOCTL_VIDEO_MAP_INTERRUPT_CMD_BUF \
  896. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD3, METHOD_BUFFERED, FILE_ANY_ACCESS)
  897. #define IOCTL_VIDEO_QUERY_REGISTRY_DWORD \
  898. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD5, METHOD_BUFFERED, FILE_ANY_ACCESS)
  899. #define IOCTL_VIDEO_REG_SAVE_GAMMA_LUT \
  900. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD7, METHOD_BUFFERED, FILE_ANY_ACCESS)
  901. #define IOCTL_VIDEO_REG_RETRIEVE_GAMMA_LUT \
  902. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD8, METHOD_BUFFERED, FILE_ANY_ACCESS)
  903. #define IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER \
  904. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD9, METHOD_BUFFERED, FILE_ANY_ACCESS)
  905. #define IOCTL_VIDEO_GET_COLOR_REGISTERS \
  906. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DDB, METHOD_BUFFERED, FILE_ANY_ACCESS)
  907. //
  908. // Extract timings from VESA structure in a form that can be programmed into
  909. // the Perm3 timing generator.
  910. //
  911. #define GetHtotFromVESA(VESATmgs) ((VESATmgs)->HTot)
  912. #define GetHssFromVESA(VESATmgs) ((VESATmgs)->HFP)
  913. #define GetHseFromVESA(VESATmgs) ((VESATmgs)->HFP + (VESATmgs)->HST)
  914. #define GetHbeFromVESA(VESATmgs) ((VESATmgs)->HFP + (VESATmgs)->HST + (VESATmgs)->HBP)
  915. #define GetHspFromVESA(VESATmgs) ((VESATmgs)->HSP)
  916. #define GetVtotFromVESA(VESATmgs) ((VESATmgs)->VTot)
  917. #define GetVssFromVESA(VESATmgs) ((VESATmgs)->VFP)
  918. #define GetVseFromVESA(VESATmgs) ((VESATmgs)->VFP + (VESATmgs)->VST)
  919. #define GetVbeFromVESA(VESATmgs) ((VESATmgs)->VFP + (VESATmgs)->VST + (VESATmgs)->VBP)
  920. #define GetVspFromVESA(VESATmgs) ((VESATmgs)->VSP)
  921. //
  922. // Permedia 3 programs the video fifo thresholds using an iterative method
  923. // to get the optimal values. Originally I tried this using the error
  924. // interrupt to capture video fifo underruns, unfortunately the Perm3
  925. // generates a number of spurious (I think) host-in DMA errors too
  926. // which makes it too expansive to keep error interrupts on all the time.
  927. // Instead we do a periodic check using the vblank interrupt (this can be
  928. // kept on all the time as it's not too frequent)
  929. //
  930. #define NUM_VBLANKS_BETWEEN_VFIFO_CHECKS 10
  931. #define NUM_VBLANKS_AFTER_VFIFO_ERROR 2
  932. #define SUBVENDORID_3DLABS 0x3D3D // Sub-system Vendor ID
  933. #define SUBDEVICEID_P3_VX1_PCI 0x0121 // Sub-system Device ID: P3+16MB SDRAM
  934. #define SUBDEVICEID_P3_VX1_AGP 0x0125 // Sub-system Device ID: P3+32MB SDRAM (VX1)
  935. #define SUBDEVICEID_P3_VX1_1600SW 0x0800 // Sub-system Device ID: P3+32MB SDRAM (VX1-1600SW)
  936. #define SUBDEVICEID_P3_32D_AGP 0x0127 // Sub-system Device ID: P3+32MB SDRAM (Permedia3 Create!)
  937. #define SUBDEVICEID_P4_VX1_AGP 0x0144 // Sub-system Device ID: P4+32MB SDRAM (VX1)
  938. //
  939. // All our child IDs begin 0x1357bd so they are readily identifiable as our own
  940. //
  941. #define PERM3_DDC_MONITOR (0x1357bd00)
  942. #define PERM3_NONDDC_MONITOR (0x1357bd01)
  943. #define PERM3_DFP_MONITOR (0x1357bd02)
  944. //
  945. // Function prototypes
  946. //
  947. //
  948. // Functions in perm3.c
  949. //
  950. VP_STATUS
  951. Perm3FindAdapter(
  952. PVOID HwDeviceExtension,
  953. PVOID HwContext,
  954. PWSTR ArgumentString,
  955. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  956. PUCHAR Again
  957. );
  958. BOOLEAN
  959. Perm3Initialize(
  960. PVOID HwDeviceExtension
  961. );
  962. VP_STATUS
  963. Perm3QueryInterface(
  964. PVOID HwDeviceExtension,
  965. PQUERY_INTERFACE pQueryInterface
  966. );
  967. VOID
  968. ConstructValidModesList(
  969. PVOID HwDeviceExtension,
  970. MONITOR_INFO *mi
  971. );
  972. VOID
  973. InitializePostRegisters(
  974. PHW_DEVICE_EXTENSION hwDeviceExtension
  975. );
  976. BOOLEAN
  977. Perm3ResetHW(
  978. PVOID HwDeviceExtension,
  979. ULONG Columns,
  980. ULONG Rows
  981. );
  982. VP_STATUS
  983. Perm3SetColorLookup(
  984. PHW_DEVICE_EXTENSION HwDeviceExtension,
  985. PVIDEO_CLUT ClutBuffer,
  986. ULONG ClutBufferSize,
  987. BOOLEAN ForceRAMDACWrite,
  988. BOOLEAN UpdateCache
  989. );
  990. VP_STATUS
  991. Perm3RegistryCallback(
  992. PVOID HwDeviceExtension,
  993. PVOID Context,
  994. PWSTR ValueName,
  995. PVOID ValueData,
  996. ULONG ValueLength
  997. );
  998. VOID
  999. BuildInitializationTable(
  1000. PHW_DEVICE_EXTENSION hwDeviceExtension
  1001. );
  1002. VOID
  1003. CopyROMInitializationTable(
  1004. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1005. PVOID pvROMAddress
  1006. );
  1007. VOID
  1008. GenerateInitializationTable(
  1009. PHW_DEVICE_EXTENSION hwDeviceExtension
  1010. );
  1011. VOID
  1012. ProcessInitializationTable(
  1013. PHW_DEVICE_EXTENSION hwDeviceExtension
  1014. );
  1015. ULONG
  1016. UlongToString(
  1017. ULONG i,
  1018. PWSTR pwsz
  1019. );
  1020. ULONG
  1021. ProbeRAMSize(
  1022. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1023. PULONG FBAddr,
  1024. ULONG FBMappedSize
  1025. );
  1026. BOOLEAN Perm3AssignResources(
  1027. PHW_DEVICE_EXTENSION hwDeviceExtension
  1028. );
  1029. BOOLEAN
  1030. Perm3ConfigurePci(
  1031. PVOID HwDeviceExtension
  1032. );
  1033. ULONG
  1034. GetBoardCapabilities(
  1035. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1036. ULONG SubsystemID,
  1037. ULONG SubdeviceID
  1038. );
  1039. VOID
  1040. SetHardwareInfoRegistries(
  1041. PHW_DEVICE_EXTENSION hwDeviceExtension
  1042. );
  1043. BOOLEAN
  1044. MapResource(
  1045. PHW_DEVICE_EXTENSION hwDeviceExtension
  1046. );
  1047. //
  1048. // Functions in perm3io.c
  1049. //
  1050. BOOLEAN
  1051. Perm3StartIO(
  1052. PVOID HwDeviceExtension,
  1053. PVIDEO_REQUEST_PACKET RequestPacket
  1054. );
  1055. VOID
  1056. Perm3GetClockSpeeds(
  1057. PVOID HwDeviceExtension
  1058. );
  1059. VOID
  1060. ZeroMemAndDac(
  1061. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1062. ULONG RequestedMode
  1063. );
  1064. VP_STATUS
  1065. SetCurrentVideoMode(
  1066. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1067. ULONG modeNumber,
  1068. BOOLEAN bZeroMemory
  1069. );
  1070. VP_STATUS
  1071. Perm3RetrieveGammaCallback(
  1072. PVOID HwDeviceExtension,
  1073. PVOID Context,
  1074. PWSTR ValueName,
  1075. PVOID ValueData,
  1076. ULONG ValueLength
  1077. );
  1078. VOID
  1079. ReadChipClockSpeedFromROM (
  1080. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1081. ULONG * pChipClkSpeed
  1082. );
  1083. //
  1084. // Functions in video.c
  1085. //
  1086. BOOLEAN
  1087. InitializeVideo(
  1088. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1089. PPERM3_VIDEO_FREQUENCIES VideoMode
  1090. );
  1091. VOID
  1092. SwitchToHiResMode(
  1093. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1094. BOOLEAN bHiRes
  1095. );
  1096. BOOLEAN
  1097. Program_P3RD(
  1098. PHW_DEVICE_EXTENSION,
  1099. PPERM3_VIDEO_FREQUENCIES,
  1100. ULONG,
  1101. ULONG,
  1102. ULONG,
  1103. PULONG,
  1104. PULONG,
  1105. PULONG
  1106. );
  1107. ULONG
  1108. P3RD_CalculateMNPForClock(
  1109. PVOID HwDeviceExtension,
  1110. ULONG RefClock,
  1111. ULONG ReqClock,
  1112. ULONG *rM,
  1113. ULONG *rN,
  1114. ULONG *rP
  1115. );
  1116. ULONG
  1117. P4RD_CalculateMNPForClock(
  1118. PVOID HwDeviceExtension,
  1119. ULONG RefClock,
  1120. ULONG ReqClock,
  1121. ULONG *rM,
  1122. ULONG *rN,
  1123. ULONG *rP
  1124. );
  1125. //
  1126. // Functions in power.c
  1127. //
  1128. VP_STATUS
  1129. Perm3GetPowerState(
  1130. PVOID HwDeviceExtension,
  1131. ULONG HwId,
  1132. PVIDEO_POWER_MANAGEMENT VideoPowerControl
  1133. );
  1134. VP_STATUS
  1135. Perm3SetPowerState(
  1136. PVOID HwDeviceExtension,
  1137. ULONG HwId,
  1138. PVIDEO_POWER_MANAGEMENT VideoPowerControl
  1139. );
  1140. ULONG
  1141. Perm3GetChildDescriptor(PVOID HwDeviceExtension,
  1142. PVIDEO_CHILD_ENUM_INFO pChildInfo,
  1143. PVIDEO_CHILD_TYPE pChildType,
  1144. PUCHAR pChildDescriptor,
  1145. PULONG pUId,
  1146. PULONG Unused);
  1147. VOID
  1148. ProgramDFP(
  1149. PHW_DEVICE_EXTENSION hwDeviceExtension
  1150. );
  1151. BOOLEAN
  1152. GetDFPEdid(
  1153. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1154. PUCHAR EdidBuffer,
  1155. LONG EdidSize
  1156. );
  1157. VOID
  1158. I2CWriteClock(
  1159. PVOID HwDeviceExtension,
  1160. UCHAR data
  1161. );
  1162. VOID
  1163. I2CWriteData(
  1164. PVOID HwDeviceExtension,
  1165. UCHAR data
  1166. );
  1167. BOOLEAN
  1168. I2CReadClock(
  1169. PVOID HwDeviceExtension
  1170. );
  1171. BOOLEAN
  1172. I2CReadData(
  1173. PVOID HwDeviceExtension
  1174. );
  1175. VOID
  1176. I2CWriteClockDFP(
  1177. PVOID HwDeviceExtension,
  1178. UCHAR data
  1179. );
  1180. VOID
  1181. I2CWriteDataDFP(
  1182. PVOID HwDeviceExtension,
  1183. UCHAR data
  1184. );
  1185. BOOLEAN
  1186. I2CReadClockDFP(
  1187. PVOID HwDeviceExtension
  1188. );
  1189. BOOLEAN
  1190. I2CReadDataDFP(
  1191. PVOID HwDeviceExtension
  1192. );
  1193. //
  1194. // Functions in interupt.c
  1195. //
  1196. BOOLEAN
  1197. Perm3InitializeInterruptBlock(
  1198. PVOID HwDeviceExtension
  1199. );
  1200. BOOLEAN
  1201. Perm3VideoInterrupt(
  1202. PVOID HwDeviceExtension
  1203. );
  1204. //
  1205. // Functions in perm3dat.c
  1206. //
  1207. BOOLEAN GetVideoTiming (
  1208. PHW_DEVICE_EXTENSION HwDeviceExtension,
  1209. ULONG xRes,
  1210. ULONG yRes,
  1211. ULONG Freq,
  1212. ULONG Depth,
  1213. VESA_TIMING_STANDARD *VESATimings
  1214. );
  1215. BOOLEAN
  1216. BuildFrequencyList(
  1217. PHW_DEVICE_EXTENSION hwDeviceExtension,
  1218. MONITOR_INFO*
  1219. );
  1220. BOOLEAN
  1221. BuildFrequencyListFromVESA(
  1222. MONITOR_INFO *mi,
  1223. PHW_DEVICE_EXTENSION hwDeviceExtension
  1224. );
  1225. BOOLEAN
  1226. BuildFrequencyListForSGIDFP(
  1227. MONITOR_INFO *mi,
  1228. PHW_DEVICE_EXTENSION hwDeviceExtension
  1229. );
  1230. BOOLEAN
  1231. GrowTimingList(
  1232. PVOID HwDeviceExtension,
  1233. MONITOR_INFO *mi
  1234. );
  1235. BOOLEAN
  1236. CopyMonitorTimings(
  1237. PVOID HwDeviceExtension,
  1238. MONITOR_INFO *srcMI,
  1239. MONITOR_INFO *destMI
  1240. );
  1241. VOID
  1242. testExtendRanges(
  1243. MONITOR_INFO *mi,
  1244. TIMING_INFO *ti,
  1245. FREQUENCIES *freq
  1246. );
  1247. //
  1248. // bugcheck callback support
  1249. //
  1250. #if (_WIN32_WINNT < 0x502)
  1251. #define BUGCHECK_DATA_SIZE_RESERVED 48
  1252. #endif
  1253. #define PERM3_BUGCHECK_DATA_SIZE (4000 - BUGCHECK_DATA_SIZE_RESERVED) //bytes
  1254. VOID
  1255. Perm3BugcheckCallback(
  1256. PVOID HwDeviceExtension,
  1257. ULONG BugcheckCode,
  1258. PUCHAR Buffer,
  1259. ULONG BufferSize
  1260. );