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.

1149 lines
34 KiB

  1. //***************************************************************************
  2. //
  3. // Module Name:
  4. //
  5. // permedia.h
  6. //
  7. // Abstract:
  8. //
  9. // This module contains the definitions for the Permedia2 miniport driver
  10. //
  11. // Environment:
  12. //
  13. // Kernel mode
  14. //
  15. // Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  16. // Copyright (c) 1995-1999 Microsoft Corporation. All Rights Reserved.
  17. //
  18. //***************************************************************************
  19. #include "winerror.h"
  20. #include "devioctl.h"
  21. #include "miniport.h"
  22. #include "ntddvdeo.h"
  23. #include "video.h"
  24. #include "interupt.h"
  25. #include "perm2tag.h"
  26. //
  27. // define an assert macro for debugging
  28. //
  29. #if DBG
  30. #define RIP(x) { VideoDebugPrint((0, x)); ASSERT(FALSE); }
  31. #define P2_ASSERT(x, y) if (!(x)) RIP(y)
  32. #else
  33. #define P2_ASSERT(x, y)
  34. #endif
  35. #if DBG
  36. #define DEBUG_PRINT(arg) VideoDebugPrint(arg)
  37. #else
  38. #define DEBUG_PRINT(arg)
  39. #endif
  40. //
  41. // RAMDAC registers live on 64 bit boundaries. Leave it up to individual
  42. // RAMDAC definitions to determine what registers are available and how
  43. // many bits wide the registers really are.
  44. //
  45. typedef struct {
  46. volatile ULONG reg;
  47. volatile ULONG pad;
  48. } RAMDAC_REG;
  49. //
  50. // include definitions for all supported RAMDACS
  51. //
  52. #include "tvp4020.h"
  53. #include "p2rd.h"
  54. #define PAGE_SIZE 0x1000
  55. //
  56. // default clock speed in Hz for the reference board. The actual speed
  57. // is looked up in the registry. Use this if no registry entry is found
  58. // or the registry entry is zero.
  59. //
  60. #define PERMEDIA_DEFAULT_CLOCK_SPEED ( 60 * (1000*1000))
  61. #define PERMEDIA_4MB_DEFAULT_CLOCK_SPEED ( 70 * (1000*1000))
  62. #define PERMEDIA_8MB_DEFAULT_CLOCK_SPEED ( 60 * (1000*1000))
  63. #define PERMEDIA_LC_DEFAULT_CLOCK_SPEED ( 83 * (1000*1000))
  64. #define MAX_PERMEDIA_CLOCK_SPEED (100 * (1000*1000))
  65. #define MIN_PERMEDIA_CLOCK_SPEED ( 50 * (1000*1000))
  66. #define REF_CLOCK_SPEED 14318200
  67. #define PERMEDIA2_DEFAULT_CLOCK_SPEED ( 70 * (1000*1000))
  68. //
  69. // Maximum pixelclock values that the RAMDAC can handle (in 100's hz).
  70. //
  71. #define P2_MAX_PIXELCLOCK 2200000 // RAMDAC rated at 220 Mhz
  72. //
  73. // Maximum amount of video data per second, that the rasterizer
  74. // chip can send to the RAMDAC (limited by SDRAM/SGRAM throuput).
  75. //
  76. #define P2_MAX_PIXELDATA 5000000 // 500 million bytes/sec (in 100's bytes)
  77. //
  78. // Base address numbers for the Permedia2 PCI regions in which we're interested.
  79. // These are indexes into the AccessRanges array we get from probing the
  80. // device.
  81. //
  82. #define PCI_CTRL_BASE_INDEX 0
  83. #define PCI_LB_BASE_INDEX 1
  84. #define PCI_FB_BASE_INDEX 2
  85. #define VENDOR_ID_3DLABS 0x3D3D
  86. #define VENDOR_ID_TI 0x104C
  87. #define PERMEDIA2_ID 0x0007 // 3Dlabs Permedia 2 (TI4020 RAMDAC)
  88. #define PERMEDIA_P2_ID 0x3D07 // TI Permedia 2 (TI4020 RAMDAC)
  89. #define PERMEDIA_P2S_ID 0x0009 // 3Dlabs Permedia 2 (P2RD RAMDAC)
  90. #define DEVICE_FAMILY_ID(id) ((id) & 0xff)
  91. #define PERMEDIA_REV_1 0x0001
  92. #define PERMEDIA2A_REV_ID 0x0011
  93. //
  94. // Capabilities flags
  95. //
  96. // These are private flags passed to the Permedia2 display driver. They're
  97. // put in the high word of the 'AttributeFlags' field of the
  98. // 'VIDEO_MODE_INFORMATION' structure (found in 'ntddvdeo.h') passed
  99. // to the display driver via an 'VIDEO_QUERY_AVAIL_MODES' or
  100. // 'VIDEO_QUERY_CURRENT_MODE' IOCTL.
  101. //
  102. // NOTE: These definitions must match those in the Permedia2 display driver's
  103. // 'driver.h'!
  104. //
  105. typedef enum {
  106. CAPS_ZOOM_X_BY2 = 0x00000001, // Hardware has zoomed by 2 in X
  107. CAPS_ZOOM_Y_BY2 = 0x00000002, // Hardware has zoomed by 2 in Y
  108. CAPS_SPARSE_SPACE = 0x00000004, // Framebuffer is sparsely mapped
  109. // (don't allow direct access). The machine
  110. // is probably an Alpha.
  111. CAPS_SW_POINTER = 0x00010000, // No hardware pointer; use software
  112. // simulation
  113. CAPS_GLYPH_EXPAND = 0x00020000, // Use glyph-expand method to draw
  114. // text.
  115. CAPS_RGB525_POINTER = 0x00040000, // Use IBM RGB525 cursor
  116. CAPS_FAST_FILL_BUG = 0x00080000, // chip fast fill bug exists
  117. // CAPS_INTERRUPTS = 0x00100000, // interrupts supported
  118. // CAPS_DMA_AVAILABLE = 0x00200000, // DMA is supported
  119. CAPS_TVP3026_POINTER = 0x00400000, // Use TI TVP3026 pointer
  120. CAPS_8BPP_RGB = 0x00800000, // Use RGB in 8bpp mode
  121. CAPS_RGB640_POINTER = 0x01000000, // Use IBM RGB640 cursor
  122. CAPS_DUAL_GLINT = 0x02000000, // Dual-TX board
  123. CAPS_GLINT2_RAMDAC = 0x04000000, // Second TX/MX attached to the RAMDAC
  124. CAPS_ENHANCED_TX = 0x08000000, // TX is in enhanced mode
  125. CAPS_ACCEL_HW_PRESENT = 0x10000000, // Accel Graphics Hardware
  126. CAPS_TVP4020_POINTER = 0x20000000, // Use TI TVP3026 pointer
  127. CAPS_P2RD_POINTER = 0x80000000 // Use the 3Dlabs P2RD RAMDAC
  128. } CAPS;
  129. //
  130. // Supported board definitions.
  131. //
  132. typedef enum _PERM2_BOARDS {
  133. PERMEDIA2_BOARD = 1,
  134. } PERM2_BOARDS;
  135. //
  136. // Supported RAMDAC definitions.
  137. //
  138. typedef enum _PERM2_RAMDACS {
  139. TVP4020_RAMDAC = 1,
  140. P2RD_RAMDAC,
  141. } PERM2_RAMDACS;
  142. //
  143. // macros to add padding words to the structures. For the core registers we use
  144. // the tag ids when specifying the pad. So we must multiply by 8 to get a byte
  145. // pad. We need to add an id to make each pad field in the struct unique. The id
  146. // is irrelevant as long as it's different from every other id used in the same
  147. // struct. It's a pity pad##__LINE__ doesn't work.
  148. //
  149. #define PAD(id, n) UCHAR pad##id[n]
  150. #define PADRANGE(id, n) PAD(id, (n)-sizeof(P2_REG))
  151. #define PADCORERANGE(id, n) PADRANGE(id, (n)<<3)
  152. //
  153. // Permedia2 registers are 32 bits wide and live on 64-bit boundaries.
  154. //
  155. typedef struct {
  156. ULONG reg;
  157. ULONG pad;
  158. } P2_REG;
  159. //
  160. // Permedia2 PCI Region 0 Address MAP:
  161. //
  162. // All registers are on 64-bit boundaries so we have to define a number of
  163. // padding words. The number given in the comments are offsets from the start
  164. // of the PCI region.
  165. //
  166. typedef struct _p2_region0_map {
  167. // Control Status Registers:
  168. P2_REG ResetStatus; // 0000h
  169. P2_REG IntEnable; // 0008h
  170. P2_REG IntFlags; // 0010h
  171. P2_REG InFIFOSpace; // 0018h
  172. P2_REG OutFIFOWords; // 0020h
  173. P2_REG DMAAddress; // 0028h
  174. P2_REG DMACount; // 0030h
  175. P2_REG ErrorFlags; // 0038h
  176. P2_REG VClkCtl; // 0040h
  177. P2_REG TestRegister; // 0048h
  178. union a0 {
  179. // GLINT
  180. struct b0 {
  181. P2_REG Aperture0; // 0050h
  182. P2_REG Aperture1; // 0058h
  183. };
  184. // PERMEDIA
  185. struct b1 {
  186. P2_REG ApertureOne; // 0050h
  187. P2_REG ApertureTwo; // 0058h
  188. };
  189. };
  190. P2_REG DMAControl; // 0060h
  191. P2_REG DisconnectControl; // 0068h
  192. // PERMEDIA only
  193. P2_REG ChipConfig; // 0070h
  194. PADRANGE(1, 0x80-0x70);
  195. P2_REG OutDMAAddress; // 0080h
  196. P2_REG OutDMACount; // 0088h
  197. PADRANGE(1a, 0x800-0x88);
  198. // GLINTdelta registers. Registers with the same functionality as on GLINT
  199. // are at the same offset. XXX are not real registers.
  200. //
  201. P2_REG DeltaReset; // 0800h
  202. P2_REG DeltaIntEnable; // 0808h
  203. P2_REG DeltaIntFlags; // 0810h
  204. P2_REG DeltaInFIFOSpaceXXX; // 0818h
  205. P2_REG DeltaOutFIFOWordsXXX; // 0820h
  206. P2_REG DeltaDMAAddressXXX; // 0828h
  207. P2_REG DeltaDMACountXXX; // 0830h
  208. P2_REG DeltaErrorFlags; // 0838h
  209. P2_REG DeltaVClkCtlXXX; // 0840h
  210. P2_REG DeltaTestRegister; // 0848h
  211. P2_REG DeltaAperture0XXX; // 0850h
  212. P2_REG DeltaAperture1XXX; // 0858h
  213. P2_REG DeltaDMAControlXXX; // 0860h
  214. P2_REG DeltaDisconnectControl; // 0868h
  215. PADRANGE(2, 0x1000-0x868);
  216. // Localbuffer Registers
  217. union x0 { // 1000h
  218. P2_REG LBMemoryCtl; // GLINT
  219. P2_REG Reboot; // PERMEDIA
  220. };
  221. P2_REG LBMemoryEDO; // 1008h
  222. PADRANGE(3, 0x1040-0x1008);
  223. // PERMEDIA only
  224. P2_REG RomControl; // 1040h
  225. PADRANGE(4, 0x1080-0x1040);
  226. P2_REG BootAddress; // 1080h
  227. PADRANGE(5, 0x10C0-0x1080);
  228. P2_REG MemConfig; // 10C0h
  229. PADRANGE(6, 0x1100-0x10C0);
  230. P2_REG BypassWriteMask; // 1100h
  231. PADRANGE(7, 0x1140-0x1100);
  232. P2_REG FramebufferWriteMask; // 1140h
  233. PADRANGE(8, 0x1180-0x1140);
  234. P2_REG Count; // 1180h
  235. PADRANGE(9, 0x1800-0x1180);
  236. // Framebuffer Registers
  237. P2_REG FBMemoryCtl; // 1800h
  238. P2_REG FBModeSel; // 1808h
  239. P2_REG FBGCWrMask; // 1810h
  240. P2_REG FBGCColorMask; // 1818h
  241. P2_REG FBTXMemCtl; // 1820h
  242. PADRANGE(10, 0x2000-0x1820);
  243. // Graphics Core FIFO Interface
  244. P2_REG FIFOInterface; // 2000h
  245. PADRANGE(11, 0x3000-0x2000);
  246. // Internal Video Registers
  247. union x1 {
  248. // GLINT
  249. struct s1 {
  250. P2_REG VTGHLimit; // 3000h
  251. P2_REG VTGHSyncStart; // 3008h
  252. P2_REG VTGHSyncEnd; // 3010h
  253. P2_REG VTGHBlankEnd; // 3018h
  254. P2_REG VTGVLimit; // 3020h
  255. P2_REG VTGVSyncStart; // 3028h
  256. P2_REG VTGVSyncEnd; // 3030h
  257. P2_REG VTGVBlankEnd; // 3038h
  258. P2_REG VTGHGateStart; // 3040h
  259. P2_REG VTGHGateEnd; // 3048h
  260. P2_REG VTGVGateStart; // 3050h
  261. P2_REG VTGVGateEnd; // 3058h
  262. P2_REG VTGPolarity; // 3060h
  263. P2_REG VTGFrameRowAddr; // 3068h
  264. P2_REG VTGVLineNumber; // 3070h
  265. P2_REG VTGSerialClk; // 3078h
  266. };
  267. // PERMEDIA
  268. struct s2 {
  269. P2_REG ScreenBase; // 3000h
  270. P2_REG ScreenStride; // 3008h
  271. P2_REG HTotal; // 3010h
  272. P2_REG HgEnd; // 3018h
  273. P2_REG HbEnd; // 3020h
  274. P2_REG HsStart; // 3028h
  275. P2_REG HsEnd; // 3030h
  276. P2_REG VTotal; // 3038h
  277. P2_REG VbEnd; // 3040h
  278. P2_REG VsStart; // 3048h
  279. P2_REG VsEnd; // 3050h
  280. P2_REG VideoControl; // 3058h
  281. P2_REG InterruptLine; // 3060h
  282. P2_REG DDCData; // 3068h
  283. P2_REG LineCount; // 3070h
  284. P2_REG VFifoCtl; // 3078h
  285. };
  286. };
  287. P2_REG VTGModeCtl; // 3080h
  288. PADRANGE(12, 0x4000-0x3080);
  289. // External Video Control Registers
  290. // Need to cast this to a struct for a particular video generator
  291. P2_REG ExternalVideo; // 4000h
  292. PADRANGE(13, 0x4080-0x4000);
  293. // Mentor Dual-TX clock chip registers
  294. P2_REG MentorICDControl; // 4080h
  295. // for future: MentorDoubleWrite is at 40C0: 0 = single write, 1 = double
  296. // NB must have 2-way interleaved memory
  297. PADRANGE(14, 0x5800-0x4080);
  298. // P2 video streams registers
  299. P2_REG VSConfiguration; // 5800h
  300. PADRANGE(15, 0x6000-0x5800);
  301. union x2 {
  302. struct s3 {
  303. P2_REG RacerDoubleWrite; // 6000h
  304. P2_REG RacerBankSelect; // 6008h
  305. P2_REG DualTxVgaSwitch; // 6010h
  306. P2_REG DDC1ReadAddress; // 6018h
  307. };
  308. struct s4 {
  309. // the following array is actually 1024 bytes long
  310. UCHAR PermediaVgaCtrl[4*sizeof(P2_REG)];
  311. };
  312. };
  313. } P2ControlRegMap, *pP2ControlRegMap;
  314. //
  315. // Permedia2 Interrupt Control Bits
  316. //
  317. //
  318. // InterruptEnable register
  319. //
  320. #define INTR_DISABLE_ALL 0x00
  321. #define INTR_ENABLE_DMA 0x01
  322. #define INTR_ENABLE_SYNC 0x02
  323. #define INTR_ENABLE_EXTERNAL 0x04
  324. #define INTR_ENABLE_ERROR 0x08
  325. #define INTR_ENABLE_VBLANK 0x10
  326. //
  327. // InterruptFlags register
  328. //
  329. #define INTR_DMA_SET 0x01
  330. #define INTR_SYNC_SET 0x02
  331. #define INTR_EXTERNAL_SET 0x04
  332. #define INTR_ERROR_SET 0x08
  333. #define INTR_VBLANK_SET 0x10
  334. #define INTR_SVGA_SET 0X80000000
  335. #define INTR_CLEAR_ALL 0x1f
  336. #define INTR_CLEAR_DMA 0x01
  337. #define INTR_CLEAR_SYNC 0x02
  338. #define INTR_CLEAR_EXTERNAL 0x04
  339. #define INTR_CLEAR_ERROR 0x08
  340. #define INTR_CLEAR_VBLANK 0x10
  341. //
  342. // Macro to declare local variables at the start of any function that wants to
  343. // load Permedia2 registers. Assumes PHW_DEVICE_EXTENSION *hwDeviceExtension
  344. // has already been declared.
  345. //
  346. #define P2_DECL_VARS \
  347. pP2ControlRegMap pCtrlRegs
  348. #define P2_DECL \
  349. pP2ControlRegMap pCtrlRegs = hwDeviceExtension->ctrlRegBase
  350. //
  351. // generic RAMDAC declaration. Used when we have table driven I/O. Must be
  352. // declared after P2_DECL
  353. //
  354. #define RAMDAC_DECL \
  355. P2_REG *pRAMDAC = &(pCtrlRegs->ExternalVideo)
  356. //
  357. // macros which takes a Permedia2 tag name or control register name and translates
  358. // it to a register address. Data must be written to these addresses using
  359. // VideoPortWriteRegisterUlong and read using VideoPortReadRegisterUlong.
  360. // e.g. dma_count = VideoPortReadRegisterUlong(DMA_COUNT);
  361. //
  362. #define CTRL_REG_ADDR(reg) ((PULONG)&(pCtrlRegs->reg))
  363. #define CTRL_REG_OFFSET(regAddr) ((ULONG)(((ULONG_PTR)regAddr) - ((ULONG_PTR)pCtrlRegs)))
  364. //
  365. // defines for the different control registers needed by Permedia2. These macros
  366. // can be used as the address part.
  367. //
  368. #define RESET_STATUS CTRL_REG_ADDR(ResetStatus)
  369. #define INT_ENABLE CTRL_REG_ADDR(IntEnable)
  370. #define INT_FLAGS CTRL_REG_ADDR(IntFlags)
  371. #define IN_FIFO_SPACE CTRL_REG_ADDR(InFIFOSpace)
  372. #define OUT_FIFO_WORDS CTRL_REG_ADDR(OutFIFOWords)
  373. #define DMA_ADDRESS CTRL_REG_ADDR(DMAAddress)
  374. #define DMA_COUNT CTRL_REG_ADDR(DMACount)
  375. #define DMA_OUT_ADDRESS CTRL_REG_ADDR(OutDMAAddress) // P2 only
  376. #define DMA_OUT_COUNT CTRL_REG_ADDR(OutDMACount) // P2 only
  377. #define ERROR_FLAGS CTRL_REG_ADDR(ErrorFlags)
  378. #define V_CLK_CTL CTRL_REG_ADDR(VClkCtl)
  379. #define TEST_REGISTER CTRL_REG_ADDR(TestRegister)
  380. #define APERTURE_0 CTRL_REG_ADDR(Aperture0)
  381. #define APERTURE_1 CTRL_REG_ADDR(Aperture1)
  382. #define DMA_CONTROL CTRL_REG_ADDR(DMAControl)
  383. #define LB_MEMORY_CTL CTRL_REG_ADDR(LBMemoryCtl)
  384. #define LB_MEMORY_EDO CTRL_REG_ADDR(LBMemoryEDO)
  385. #define FB_MEMORY_CTL CTRL_REG_ADDR(FBMemoryCtl)
  386. #define FB_MODE_SEL CTRL_REG_ADDR(FBModeSel)
  387. #define FB_GC_WRITEMASK CTRL_REG_ADDR(FBGCWrMask)
  388. #define FB_GC_COLORMASK CTRL_REG_ADDR(FBGCColorMask)
  389. #define FB_TX_MEM_CTL CTRL_REG_ADDR(FBTXMemCtl)
  390. #define FIFO_INTERFACE CTRL_REG_ADDR(FIFOInterface)
  391. #define DISCONNECT_CONTROL CTRL_REG_ADDR(DisconnectControl)
  392. //
  393. // internal timing registers
  394. //
  395. #define VTG_HLIMIT CTRL_REG_ADDR(VTGHLimit)
  396. #define VTG_HSYNC_START CTRL_REG_ADDR(VTGHSyncStart)
  397. #define VTG_HSYNC_END CTRL_REG_ADDR(VTGHSyncEnd)
  398. #define VTG_HBLANK_END CTRL_REG_ADDR(VTGHBlankEnd)
  399. #define VTG_VLIMIT CTRL_REG_ADDR(VTGVLimit)
  400. #define VTG_VSYNC_START CTRL_REG_ADDR(VTGVSyncStart)
  401. #define VTG_VSYNC_END CTRL_REG_ADDR(VTGVSyncEnd)
  402. #define VTG_VBLANK_END CTRL_REG_ADDR(VTGVBlankEnd)
  403. #define VTG_HGATE_START CTRL_REG_ADDR(VTGHGateStart)
  404. #define VTG_HGATE_END CTRL_REG_ADDR(VTGHGateEnd)
  405. #define VTG_VGATE_START CTRL_REG_ADDR(VTGVGateStart)
  406. #define VTG_VGATE_END CTRL_REG_ADDR(VTGVGateEnd)
  407. #define VTG_POLARITY CTRL_REG_ADDR(VTGPolarity)
  408. #define VTG_FRAME_ROW_ADDR CTRL_REG_ADDR(VTGFrameRowAddr)
  409. #define VTG_VLINE_NUMBER CTRL_REG_ADDR(VTGVLineNumber)
  410. #define VTG_SERIAL_CLK CTRL_REG_ADDR(VTGSerialClk)
  411. #define VTG_MODE_CTL CTRL_REG_ADDR(VTGModeCtl)
  412. #define SUSPEND_UNTIL_FRAME_BLANK (1 << 2)
  413. #define TX_ENHANCED_ENABLE (1 << 1)
  414. //
  415. // Permedia registers
  416. //
  417. #define APERTURE_ONE CTRL_REG_ADDR(ApertureOne)
  418. #define APERTURE_TWO CTRL_REG_ADDR(ApertureTwo)
  419. #define BYPASS_WRITE_MASK CTRL_REG_ADDR(BypassWriteMask)
  420. #define ROM_CONTROL CTRL_REG_ADDR(RomControl)
  421. #define BOOT_ADDRESS CTRL_REG_ADDR(BootAddress)
  422. #define MEM_CONFIG CTRL_REG_ADDR(MemConfig)
  423. #define CHIP_CONFIG CTRL_REG_ADDR(ChipConfig)
  424. #define SGRAM_REBOOT CTRL_REG_ADDR(Reboot)
  425. #define SCREEN_BASE CTRL_REG_ADDR(ScreenBase)
  426. #define SCREEN_STRIDE CTRL_REG_ADDR(ScreenStride)
  427. #define H_TOTAL CTRL_REG_ADDR(HTotal)
  428. #define HG_END CTRL_REG_ADDR(HgEnd)
  429. #define HB_END CTRL_REG_ADDR(HbEnd)
  430. #define HS_START CTRL_REG_ADDR(HsStart)
  431. #define HS_END CTRL_REG_ADDR(HsEnd)
  432. #define V_TOTAL CTRL_REG_ADDR(VTotal)
  433. #define VB_END CTRL_REG_ADDR(VbEnd)
  434. #define VS_START CTRL_REG_ADDR(VsStart)
  435. #define VS_END CTRL_REG_ADDR(VsEnd)
  436. #define VIDEO_CONTROL CTRL_REG_ADDR(VideoControl)
  437. #define INTERRUPT_LINE CTRL_REG_ADDR(InterruptLine)
  438. #define DDC_DATA CTRL_REG_ADDR(DDCData)
  439. #define LINE_COUNT CTRL_REG_ADDR(LineCount)
  440. #define VIDEO_FIFO_CTL CTRL_REG_ADDR(VFifoCtl)
  441. //
  442. // Permedia 2 Video Streams registers
  443. //
  444. #define VSTREAM_CONFIG CTRL_REG_ADDR(VSConfiguration)
  445. // PERMEDIA memory mapped VGA access
  446. #define PERMEDIA_MMVGA_INDEX_REG ((PVOID)(&(pCtrlRegs->PermediaVgaCtrl[0x3C4])))
  447. #define PERMEDIA_MMVGA_DATA_REG (&(pCtrlRegs->PermediaVgaCtrl[0x3C5]))
  448. #define PERMEDIA_MMVGA_CRTC_INDEX_REG ((PVOID)(&(pCtrlRegs->PermediaVgaCtrl[0x3D4])))
  449. #define PERMEDIA_MMVGA_CRTC_DATA_REG (&(pCtrlRegs->PermediaVgaCtrl[0x3D5]))
  450. #define PERMEDIA_MMVGA_STAT_REG (&(pCtrlRegs->PermediaVgaCtrl[0x3DA]))
  451. #define PERMEDIA_VGA_CTRL_INDEX 5
  452. #define PERMEDIA_VGA_CR11_INDEX 0x11
  453. #define PERMEDIA_VGA_ENABLE (1 << 3)
  454. #define PERMEDIA_VGA_INTERRUPT_ENABLE (1 << 2)
  455. #define PERMEDIA_VGA_STAT_VSYNC (1 << 3)
  456. #define PERMEDIA_VGA_SYNC_INTERRUPT (1 << 4)
  457. //
  458. // magic bits in the FBMemoryCtl and LBMemoryCtl registers
  459. //
  460. #define LBCTL_RAS_CAS_LOW_MASK (3 << 3)
  461. #define LBCTL_RAS_CAS_LOW_2_CLK (0 << 3)
  462. #define LBCTL_RAS_CAS_LOW_3_CLK (1 << 3)
  463. #define LBCTL_RAS_CAS_LOW_4_CLK (2 << 3)
  464. #define LBCTL_RAS_CAS_LOW_5_CLK (3 << 3)
  465. #define LBCTL_RAS_PRECHARGE_MASK (3 << 5)
  466. #define LBCTL_RAS_PRECHARGE_2_CLK (0 << 5)
  467. #define LBCTL_RAS_PRECHARGE_3_CLK (1 << 5)
  468. #define LBCTL_RAS_PRECHARGE_4_CLK (2 << 5)
  469. #define LBCTL_RAS_PRECHARGE_5_CLK (3 << 5)
  470. #define LBCTL_CAS_LOW_MASK (3 << 7)
  471. #define LBCTL_CAS_LOW_1_CLK (0 << 7)
  472. #define LBCTL_CAS_LOW_2_CLK (1 << 7)
  473. #define LBCTL_CAS_LOW_3_CLK (2 << 7)
  474. #define LBCTL_CAS_LOW_4_CLK (3 << 7)
  475. #define FBCTL_RAS_CAS_LOW_MASK (3 << 0)
  476. #define FBCTL_RAS_CAS_LOW_2_CLK (0 << 0)
  477. #define FBCTL_RAS_CAS_LOW_3_CLK (1 << 0)
  478. #define FBCTL_RAS_CAS_LOW_4_CLK (2 << 0)
  479. #define FBCTL_RAS_CAS_LOW_5_CLK (3 << 0)
  480. #define FBCTL_RAS_PRECHARGE_MASK (3 << 2)
  481. #define FBCTL_RAS_PRECHARGE_2_CLK (0 << 2)
  482. #define FBCTL_RAS_PRECHARGE_3_CLK (1 << 2)
  483. #define FBCTL_RAS_PRECHARGE_4_CLK (2 << 2)
  484. #define FBCTL_RAS_PRECHARGE_5_CLK (3 << 2)
  485. #define FBCTL_CAS_LOW_MASK (3 << 4)
  486. #define FBCTL_CAS_LOW_1_CLK (0 << 4)
  487. #define FBCTL_CAS_LOW_2_CLK (1 << 4)
  488. #define FBCTL_CAS_LOW_3_CLK (2 << 4)
  489. #define FBCTL_CAS_LOW_4_CLK (3 << 4)
  490. //
  491. // DisconnectControl bits
  492. //
  493. #define DISCONNECT_INPUT_FIFO_ENABLE 0x1
  494. #define DISCONNECT_OUTPUT_FIFO_ENABLE 0x2
  495. #define DISCONNECT_INOUT_ENABLE (DISCONNECT_INPUT_FIFO_ENABLE | \
  496. DISCONNECT_OUTPUT_FIFO_ENABLE)
  497. //
  498. // structure of timing data contained in the registry
  499. //
  500. typedef struct {
  501. USHORT HTot; // Hor Total Time
  502. UCHAR HFP; // Hor Front Porch
  503. UCHAR HST; // Hor Sync Time
  504. UCHAR HBP; // Hor Back Porch
  505. UCHAR HSP; // Hor Sync Polarity
  506. USHORT VTot; // Ver Total Time
  507. UCHAR VFP; // Ver Front Porch
  508. UCHAR VST; // Ver Sync Time
  509. UCHAR VBP; // Ver Back Porch
  510. UCHAR VSP; // Ver Sync Polarity
  511. } VESA_TIMING_STANDARD;
  512. //
  513. // Characteristics of each mode
  514. //
  515. typedef struct _P2_VIDEO_MODES {
  516. // Leave INT10 fields in for later chips which have VGA
  517. USHORT Int10ModeNumberContiguous;
  518. USHORT Int10ModeNumberNoncontiguous;
  519. ULONG ScreenStrideContiguous;
  520. VIDEO_MODE_INFORMATION ModeInformation;
  521. } P2_VIDEO_MODES, *PP2_VIDEO_MODES;
  522. //
  523. // Mode-set specific information.
  524. //
  525. //
  526. // for a given (frequency x resolution x depth) combination we have:
  527. // frequency x resolution only dependent initialization
  528. // frequency x resolution x depth dependent initialization
  529. // We split these into 2 tables to save space in the driver.
  530. //
  531. typedef struct _frd_tables {
  532. PULONG FRTable;
  533. PULONG FRDTable;
  534. } FRDTable;
  535. typedef struct _P2_VIDEO_FREQUENCIES {
  536. ULONG BitsPerPel;
  537. ULONG ScreenWidth;
  538. ULONG ScreenHeight;
  539. ULONG ScreenFrequency;
  540. PP2_VIDEO_MODES ModeEntry;
  541. ULONG ModeIndex;
  542. UCHAR ModeValid;
  543. ULONG PixelClock;
  544. } P2_VIDEO_FREQUENCIES, *PP2_VIDEO_FREQUENCIES;
  545. //
  546. // PCI device information. Used in an IOCTL return. Ensure this is the same
  547. // as in the display drivers
  548. //
  549. typedef struct _P2_Device_Info {
  550. ULONG SubsystemId;
  551. ULONG SubsystemVendorId;
  552. ULONG VendorId;
  553. ULONG DeviceId;
  554. ULONG RevisionId;
  555. ULONG DeltaRevId;
  556. ULONG GammaRevId;
  557. ULONG BoardId;
  558. ULONG LocalbufferLength;
  559. ULONG LocalbufferWidth;
  560. ULONG ActualDacId;
  561. } P2_Device_Info;
  562. //
  563. // Definition of the IOCTL_VIDEO_QUERY_LINE_DMA_BUFFER
  564. //
  565. typedef struct _LINE_DMA_BUFFER {
  566. PHYSICAL_ADDRESS physAddr; // physical address of DMA buffer
  567. PVOID virtAddr; // mapped virtual address
  568. ULONG size; // size in bytes
  569. BOOLEAN cacheEnabled; // Whether buffer is cached
  570. } LINE_DMA_BUFFER, *PLINE_DMA_BUFFER;
  571. //
  572. // Definition of the IOCTL_VIDEO_QUERY_EMULATED_DMA_BUFFER
  573. //
  574. typedef struct _EMULATED_DMA_BUFFER {
  575. PVOID virtAddr; // virtual address
  576. ULONG size; // size in bytes
  577. ULONG tag; // allocation tag
  578. } EMULATED_DMA_BUFFER, *PEMULATED_DMA_BUFFER;
  579. //
  580. // The following are the definition for the LUT cache. The aim of the LUT cache
  581. // is to stop sparkling from occurring, bu only writing those LUT entries that
  582. // have changed to the chip, we can only do this by remembering what is already
  583. // down there. The 'mystify' screen saver on P2 demonstrates the problem.
  584. //
  585. #define LUT_CACHE_INIT() {VideoPortZeroMemory (&(hwDeviceExtension->LUTCache), sizeof (hwDeviceExtension->LUTCache));}
  586. #define LUT_CACHE_SETSIZE(sz) {hwDeviceExtension->LUTCache.LUTCache.NumEntries = (sz);}
  587. #define LUT_CACHE_SETFIRST(frst){hwDeviceExtension->LUTCache.LUTCache.FirstEntry = (frst);}
  588. #define LUT_CACHE_SETRGB(idx,zr,zg,zb) { \
  589. hwDeviceExtension->LUTCache.LUTCache.LookupTable [idx].RgbArray.Red = (UCHAR) (zr); \
  590. hwDeviceExtension->LUTCache.LUTCache.LookupTable [idx].RgbArray.Green = (UCHAR) (zg); \
  591. hwDeviceExtension->LUTCache.LUTCache.LookupTable [idx].RgbArray.Blue = (UCHAR) (zb); \
  592. }
  593. //
  594. // The LUT cache
  595. //
  596. typedef struct {
  597. VIDEO_CLUT LUTCache; // Header plus 1 LUT entry
  598. VIDEO_CLUTDATA LUTData [255]; // the other 255 LUT entries
  599. } LUT_CACHE;
  600. #define MAX_REGISTER_INITIALIZATION_TABLE_ENTRIES 10
  601. #define MAX_REGISTER_INITIALIZATION_TABLE_ULONGS (2 * MAX_REGISTER_INITIALIZATION_TABLE_ENTRIES)
  602. //
  603. // Define device extension structure. This is device dependent/private
  604. // information.
  605. //
  606. typedef struct _HW_DEVICE_EXTENSION {
  607. pP2ControlRegMap ctrlRegBase;
  608. PVOID pFramebuffer;
  609. PVOID pRamdac;
  610. PHYSICAL_ADDRESS PhysicalFrameAddress;
  611. ULONG FrameLength;
  612. PHYSICAL_ADDRESS PhysicalRegisterAddress;
  613. ULONG RegisterLength;
  614. UCHAR RegisterSpace;
  615. PP2_VIDEO_MODES ActiveModeEntry;
  616. P2_VIDEO_FREQUENCIES ActiveFrequencyEntry;
  617. PP2_VIDEO_FREQUENCIES FrequencyTable;
  618. PCI_SLOT_NUMBER pciSlot;
  619. ULONG pciBus;
  620. ULONG BoardNumber;
  621. ULONG DacId;
  622. ULONG ChipClockSpeed;
  623. ULONG RefClockSpeed;
  624. ULONG Capabilities;
  625. ULONG NumAvailableModes;
  626. ULONG NumTotalModes;
  627. ULONG AdapterMemorySize;
  628. ULONG PhysicalFrameIoSpace;
  629. P2_Device_Info deviceInfo;
  630. //
  631. // Shared memory for communications with the display driver
  632. //
  633. P2_INTERRUPT_CTRLBUF InterruptControl;
  634. //
  635. // defaults for registry variable values
  636. //
  637. ULONG UseSoftwareCursor;
  638. ULONG P28bppRGB;
  639. ULONG ExportNon3DModes;
  640. //
  641. // DMA Buffer definition
  642. // allocate only one copy of DMA buffer at start of day
  643. // and keep it until system is shut down or display drivers say goodbye
  644. //
  645. ULONG ulLineDMABufferUsage;
  646. LINE_DMA_BUFFER LineDMABuffer;
  647. //
  648. // PCI Config Information
  649. //
  650. ULONG bVGAEnabled;
  651. ULONG bDMAEnabled;
  652. ULONG PciSpeed;
  653. VIDEO_ACCESS_RANGE PciAccessRange[PCI_TYPE0_ADDRESSES+1];
  654. //
  655. // Initialisation table
  656. //
  657. ULONG aulInitializationTable[MAX_REGISTER_INITIALIZATION_TABLE_ULONGS];
  658. ULONG culTableEntries;
  659. //
  660. // LUT cache
  661. //
  662. LUT_CACHE LUTCache;
  663. BOOLEAN bVTGRunning;
  664. PP2_VIDEO_FREQUENCIES pFrequencyDefault;
  665. //
  666. // state save variables (for during power-saving)
  667. //
  668. ULONG VideoControl;
  669. ULONG IntEnable;
  670. ULONG PreviousPowerState;
  671. BOOLEAN bMonitorPoweredOn;
  672. //
  673. // current NT version
  674. //
  675. USHORT NtVersion;
  676. //
  677. // pointers of VideoPort function that not available on NT4
  678. //
  679. PVOID (*Win2kVideoPortGetRomImage)();
  680. PVOID (*Win2kVideoPortGetCommonBuffer)();
  681. PVOID (*Win2kVideoPortFreeCommonBuffer)();
  682. BOOLEAN (*Win2kVideoPortDDCMonitorHelper)();
  683. LONG (FASTCALL *Win2kVideoPortInterlockedExchange)();
  684. VP_STATUS (*Win2kVideoPortGetVgaStatus)();
  685. //
  686. // if the SubSystemId/SubVendorId in PCI config space are read only
  687. //
  688. BOOLEAN HardwiredSubSystemId;
  689. } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
  690. //
  691. // definitions for the purpose of binary level compatable with NT4
  692. //
  693. #define NT4 400
  694. #define WIN2K 500
  695. #define VideoPortGetRomImage \
  696. hwDeviceExtension->Win2kVideoPortGetRomImage
  697. #define VideoPortGetCommonBuffer \
  698. hwDeviceExtension->Win2kVideoPortGetCommonBuffer
  699. #define VideoPortFreeCommonBuffer \
  700. hwDeviceExtension->Win2kVideoPortFreeCommonBuffer
  701. #define VideoPortDDCMonitorHelper \
  702. hwDeviceExtension->Win2kVideoPortDDCMonitorHelper
  703. #define VideoPortInterlockedExchange \
  704. hwDeviceExtension->Win2kVideoPortInterlockedExchange
  705. #define VideoPortGetVgaStatus \
  706. hwDeviceExtension->Win2kVideoPortGetVgaStatus
  707. //
  708. // Highest valid DAC color register index.
  709. //
  710. #define VIDEO_MAX_COLOR_REGISTER 0xFF
  711. #define MAX_CLUT_SIZE (sizeof(VIDEO_CLUT) + (sizeof(ULONG) * (VIDEO_MAX_COLOR_REGISTER+1)))
  712. //
  713. // Data
  714. //
  715. extern ULONG bPal8[];
  716. extern ULONG bPal4[];
  717. extern P2_VIDEO_MODES P2Modes[];
  718. extern ULONG NumP2VideoModes;
  719. //
  720. // Permedia2 Legacy Resources
  721. //
  722. extern VIDEO_ACCESS_RANGE P2LegacyResourceList[];
  723. extern ULONG P2LegacyResourceEntries;
  724. //
  725. // Function prototypes
  726. //
  727. //
  728. // permedia.c
  729. //
  730. BOOLEAN
  731. InitializeVideo(
  732. PHW_DEVICE_EXTENSION HwDeviceExtension,
  733. PP2_VIDEO_FREQUENCIES VideoMode
  734. );
  735. BOOLEAN
  736. Permedia2AssignResources(
  737. PVOID HwDeviceExtension,
  738. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  739. ULONG NumRegions,
  740. PVIDEO_ACCESS_RANGE AccessRange
  741. );
  742. BOOLEAN
  743. Permedia2AssignResourcesNT4(
  744. PVOID HwDeviceExtension,
  745. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  746. ULONG NumRegions,
  747. PVIDEO_ACCESS_RANGE AccessRange
  748. );
  749. ULONG
  750. DriverEntry (
  751. PVOID Context1,
  752. PVOID Context2
  753. );
  754. VP_STATUS
  755. Permedia2FindAdapter(
  756. PVOID HwDeviceExtension,
  757. PVOID HwContext,
  758. PWSTR ArgumentString,
  759. PVIDEO_PORT_CONFIG_INFO ConfigInfo,
  760. PUCHAR Again
  761. );
  762. BOOLEAN
  763. InitializeAndSizeRAM(
  764. PVOID HwDeviceExtension,
  765. PVIDEO_ACCESS_RANGE AccessRange
  766. );
  767. VOID
  768. ConstructValidModesList(
  769. PVOID HwDeviceExtension,
  770. PHW_DEVICE_EXTENSION hwDeviceExtension
  771. );
  772. BOOLEAN
  773. Permedia2Initialize(
  774. PVOID HwDeviceExtension
  775. );
  776. BOOLEAN
  777. Permedia2StartIO(
  778. PVOID HwDeviceExtension,
  779. PVIDEO_REQUEST_PACKET RequestPacket
  780. );
  781. BOOLEAN
  782. Permedia2ResetHW(
  783. PVOID HwDeviceExtension,
  784. ULONG Columns,
  785. ULONG Rows
  786. );
  787. VP_STATUS
  788. Permedia2GetPowerState(
  789. PVOID HwDeviceExtension,
  790. ULONG HwId,
  791. PVIDEO_POWER_MANAGEMENT VideoPowerControl
  792. );
  793. VP_STATUS
  794. Permedia2SetPowerState(
  795. PVOID HwDeviceExtension,
  796. ULONG HwId,
  797. PVIDEO_POWER_MANAGEMENT VideoPowerControl
  798. );
  799. ULONG
  800. Permedia2GetChildDescriptor (
  801. IN PVOID HwDeviceExtension,
  802. IN PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  803. OUT PVIDEO_CHILD_TYPE pChildType,
  804. OUT PVOID pChildDescriptor,
  805. OUT PULONG pUId,
  806. OUT PULONG pUnused
  807. );
  808. BOOLEAN
  809. PowerOnReset(
  810. PHW_DEVICE_EXTENSION hwDeviceExtension
  811. );
  812. VP_STATUS
  813. Permedia2SetColorLookup(
  814. PHW_DEVICE_EXTENSION HwDeviceExtension,
  815. PVIDEO_CLUT ClutBuffer,
  816. ULONG ClutBufferSize,
  817. BOOLEAN ForceRAMDACWrite,
  818. BOOLEAN UpdateCache
  819. );
  820. VP_STATUS
  821. Permedia2RegistryCallback(
  822. PVOID HwDeviceExtension,
  823. PVOID Context,
  824. PWSTR ValueName,
  825. PVOID ValueData,
  826. ULONG ValueLength
  827. );
  828. VP_STATUS
  829. Permedia2RetrieveGammaCallback(
  830. PVOID HwDeviceExtension,
  831. PVOID Context,
  832. PWSTR ValueName,
  833. PVOID ValueData,
  834. ULONG ValueLength
  835. );
  836. VOID
  837. Permedia2GetClockSpeeds(
  838. PVOID HwDeviceExtension
  839. );
  840. VOID
  841. ZeroMemAndDac(
  842. PHW_DEVICE_EXTENSION HwDeviceExtension,
  843. ULONG RequestedMode
  844. );
  845. BOOLEAN
  846. Permedia2InitializeInterruptBlock(
  847. PVOID HwDeviceExtension
  848. );
  849. BOOLEAN
  850. Permedia2VidInterrupt(
  851. PVOID HwDeviceExtension
  852. );
  853. BOOLEAN
  854. Permedia2InitializeDMABuffers(
  855. PVOID HwDeviceExtension
  856. );
  857. BOOLEAN
  858. DMAExecute(PVOID Context);
  859. #if DBG
  860. VOID
  861. DumpPCIConfigSpace(
  862. PVOID HwDeviceExtension,
  863. ULONG bus,
  864. ULONG slot
  865. );
  866. #endif
  867. VOID
  868. CopyROMInitializationTable(
  869. PHW_DEVICE_EXTENSION hwDeviceExtension
  870. );
  871. VOID
  872. GenerateInitializationTable(
  873. PHW_DEVICE_EXTENSION hwDeviceExtension
  874. );
  875. VOID
  876. ProcessInitializationTable(
  877. PHW_DEVICE_EXTENSION hwDeviceExtension
  878. );
  879. BOOLEAN
  880. VerifyBiosSettings(
  881. PHW_DEVICE_EXTENSION hwDeviceExtension
  882. );
  883. LONG
  884. IntergerToUnicode(
  885. IN ULONG number,
  886. OUT PWSTR string
  887. );
  888. LONG
  889. GetBiosVersion (
  890. PHW_DEVICE_EXTENSION hwDeviceExtension,
  891. OUT PWSTR BiosVersion
  892. );
  893. #if defined(_ALPHA_)
  894. #define abs(a) ( ((LONG)(a)) > 0 ? ((LONG)(a)) : -((LONG)(a)) )
  895. #endif
  896. BOOLEAN
  897. GetVideoTiming (
  898. PHW_DEVICE_EXTENSION hwDeviceExtension,
  899. ULONG xRes,
  900. ULONG yRes,
  901. ULONG Freq,
  902. ULONG Depth,
  903. VESA_TIMING_STANDARD * VESATimings
  904. );
  905. LONG BuildFrequencyList (
  906. PHW_DEVICE_EXTENSION hwDeviceExtension
  907. );
  908. //
  909. // Registry Strings
  910. //
  911. #define PERM2_EXPORT_HIRES_REG_STRING L"ExportSingleBufferedModes"
  912. #define IOCTL_VIDEO_MAP_CPERMEDIA \
  913. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD0, METHOD_BUFFERED, FILE_ANY_ACCESS)
  914. #define IOCTL_VIDEO_QUERY_DEVICE_INFO \
  915. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD2, METHOD_BUFFERED, FILE_ANY_ACCESS)
  916. #define IOCTL_VIDEO_MAP_INTERRUPT_CMD_BUF \
  917. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD3, METHOD_BUFFERED, FILE_ANY_ACCESS)
  918. #define IOCTL_VIDEO_STALL_EXECUTION \
  919. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD4, METHOD_BUFFERED, FILE_ANY_ACCESS)
  920. #define IOCTL_VIDEO_QUERY_REGISTRY_DWORD \
  921. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD5, METHOD_BUFFERED, FILE_ANY_ACCESS)
  922. #define IOCTL_VIDEO_REG_SAVE_GAMMA_LUT \
  923. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD7, METHOD_BUFFERED, FILE_ANY_ACCESS)
  924. #define IOCTL_VIDEO_REG_RETRIEVE_GAMMA_LUT \
  925. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD8, METHOD_BUFFERED, FILE_ANY_ACCESS)
  926. #define IOCTL_VIDEO_QUERY_LINE_DMA_BUFFER \
  927. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD9, METHOD_BUFFERED, FILE_ANY_ACCESS)
  928. #define IOCTL_VIDEO_GET_COLOR_REGISTERS \
  929. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DDB, METHOD_BUFFERED, FILE_ANY_ACCESS)
  930. #define IOCTL_VIDEO_SLEEP \
  931. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DDF, METHOD_BUFFERED, FILE_ANY_ACCESS)
  932. #define IOCTL_VIDEO_QUERY_INTERLOCKEDEXCHANGE \
  933. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DD6, METHOD_BUFFERED, FILE_ANY_ACCESS)
  934. #define IOCTL_VIDEO_QUERY_EMULATED_DMA_BUFFER \
  935. CTL_CODE(FILE_DEVICE_VIDEO, 0x3DDE, METHOD_BUFFERED, FILE_ANY_ACCESS)