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.

781 lines
16 KiB

  1. /*++
  2. Copyright (c) 1994 Weitek Corporation
  3. Module Name:
  4. ibm525.c
  5. Abstract:
  6. This module contains code specific for the IBM 525RGB DAC on P9100
  7. adapters.
  8. Environment:
  9. Kernel mode
  10. Revision History may be found at the end of this file.
  11. --*/
  12. #include "p9.h"
  13. #include "p9000.h"
  14. #include "p9gbl.h"
  15. #include "p91dac.h" // Include before ibm525.h
  16. #include "ibm525.h"
  17. #include "p91regs.h"
  18. //
  19. // DAC specific static data.
  20. //
  21. //
  22. // Function Prototypes for the IBM525 DAC which are defined in IBM525.C.
  23. //
  24. //
  25. // IBM525 function prototypes.
  26. //
  27. VOID
  28. WriteIBM525(
  29. PHW_DEVICE_EXTENSION HwDeviceExtension,
  30. USHORT index,
  31. UCHAR bvalue
  32. );
  33. VOID
  34. IBM525SetPalette(
  35. PHW_DEVICE_EXTENSION HwDeviceExtension,
  36. ULONG *pPal,
  37. ULONG StartIndex,
  38. ULONG Count
  39. );
  40. VOID
  41. IBM525SetPointerPos(
  42. PHW_DEVICE_EXTENSION HwDeviceExtension,
  43. ULONG ptlX,
  44. ULONG ptlY
  45. );
  46. VOID
  47. IBM525SetPointerShape(
  48. PHW_DEVICE_EXTENSION HwDeviceExtension,
  49. PUCHAR pHWCursorShape
  50. );
  51. VOID
  52. IBM525PointerOn(
  53. PHW_DEVICE_EXTENSION HwDeviceExtension
  54. );
  55. VOID
  56. IBM525PointerOff(
  57. PHW_DEVICE_EXTENSION HwDeviceExtension
  58. );
  59. VOID
  60. IBM525ClearPalette(
  61. PHW_DEVICE_EXTENSION HwDeviceExtension
  62. );
  63. BOOLEAN
  64. IBM525SetMode(
  65. PHW_DEVICE_EXTENSION HwDeviceExtension
  66. );
  67. VOID
  68. IBM525RestoreMode(
  69. PHW_DEVICE_EXTENSION HwDeviceExtension
  70. );
  71. VOID
  72. IBM525SetClkDoubler(
  73. PHW_DEVICE_EXTENSION HwDeviceExtension
  74. );
  75. VOID
  76. IBM525ClrClkDoubler(
  77. PHW_DEVICE_EXTENSION HwDeviceExtension
  78. );
  79. //
  80. // Define the DAC support routines structure for the IBM525 DAC.
  81. //
  82. DAC Ibm525 = {
  83. DAC_ID_IBM525,
  84. NUM_DAC_REGS,
  85. IBM525SetMode,
  86. IBM525RestoreMode,
  87. IBM525SetPalette,
  88. IBM525ClearPalette,
  89. IBM525PointerOn,
  90. IBM525PointerOff,
  91. IBM525SetPointerPos,
  92. IBM525SetPointerShape,
  93. CLK_MAX_FREQ_IBM525,
  94. IBM525SetClkDoubler,
  95. IBM525ClrClkDoubler,
  96. DAC_ID_IBM525,
  97. 64,
  98. FALSE,
  99. TRUE,
  100. TRUE
  101. };
  102. VOID
  103. WriteIBM525(
  104. PHW_DEVICE_EXTENSION HwDeviceExtension,
  105. USHORT index,
  106. UCHAR value
  107. )
  108. /*++
  109. Routine Description:
  110. Writes specified data to an indexed register inside the RGB525 Ramdac.
  111. Arguments:
  112. Index register and data.
  113. Return Value:
  114. None.
  115. --*/
  116. {
  117. IBM525_WR_DAC(P9100_IBM525_INDEX_LOW, (UCHAR) (index & 0x00FF));
  118. IBM525_WR_DAC(P9100_IBM525_INDEX_HIGH, (UCHAR) ((index & 0xFF00) >> 8));
  119. IBM525_WR_DAC(P9100_IBM525_INDEX_DATA, (UCHAR) value);
  120. (void) P9_RD_REG(P91_MEM_CONFIG); // Needed for timinig...
  121. } // End of WriteIBM525()
  122. UCHAR
  123. ReadIBM525(
  124. PHW_DEVICE_EXTENSION HwDeviceExtension,
  125. USHORT index
  126. )
  127. /*++
  128. Routine Description:
  129. Reads data from an indexed register inside the RGB525 Ramdac.
  130. Arguments:
  131. Index register.
  132. Return Value:
  133. None.
  134. --*/
  135. {
  136. UCHAR j;
  137. IBM525_WR_DAC(P9100_IBM525_INDEX_LOW, (UCHAR) (index & 0x00FF));
  138. IBM525_WR_DAC(P9100_IBM525_INDEX_HIGH, (UCHAR) ((index & 0xFF00) >> 8));
  139. IBM525_RD_DAC(P9100_IBM525_INDEX_DATA, j);
  140. return(j);
  141. } // End of ReadIBM525()
  142. VOID
  143. IBM525SetPalette(
  144. PHW_DEVICE_EXTENSION HwDeviceExtension,
  145. ULONG *pPal,
  146. ULONG StartIndex,
  147. ULONG Count
  148. )
  149. /*++
  150. Routine Description:
  151. Sets the Device palette
  152. Arguments:
  153. HwDeviceExtension - Pointer to the miniport driver's device extension.
  154. pPal - Pointer to the array of pallete entries.
  155. StartIndex - Specifies the first pallete entry provided in pPal.
  156. Count - Number of palette entries in pPal
  157. Return Value:
  158. None.
  159. --*/
  160. {
  161. UCHAR *pBytePal;
  162. int i;
  163. #define STALL_TIME 11
  164. VideoDebugPrint((3, "IBM525SetPalette: ----------\n"));
  165. IBM525_WR_DAC(P9100_RAMWRITE, (UCHAR) StartIndex);
  166. VideoPortStallExecution(STALL_TIME);
  167. pBytePal = (PUCHAR) pPal;
  168. //
  169. // Load the palette with RGB values. The input palette has 4 bytes
  170. // per entry, the last of which is ignored.
  171. //
  172. while (Count--)
  173. {
  174. IBM525_WR_DAC(P9100_PALETDATA, *pBytePal++);
  175. VideoPortStallExecution(STALL_TIME);
  176. IBM525_WR_DAC(P9100_PALETDATA, *pBytePal++);
  177. VideoPortStallExecution(STALL_TIME);
  178. IBM525_WR_DAC(P9100_PALETDATA, *pBytePal++);
  179. VideoPortStallExecution(STALL_TIME);
  180. pBytePal++;
  181. }
  182. }
  183. VOID
  184. IBM525SetPointerPos(
  185. PHW_DEVICE_EXTENSION HwDeviceExtension,
  186. ULONG ptlX,
  187. ULONG ptlY
  188. )
  189. /*++
  190. Routine Description:
  191. Move Hardware Pointer.
  192. Arguments:
  193. HwDeviceExtension - Pointer to the miniport driver's device extension.
  194. ptlX, ptlY - Requested X,Y position for the pointer.
  195. Return Value:
  196. TRUE
  197. --*/
  198. {
  199. WR_CURS_POS_X_IBM525(ptlX);
  200. WR_CURS_POS_Y_IBM525(ptlY);
  201. return;
  202. }
  203. VOID
  204. IBM525SetPointerShape(
  205. PHW_DEVICE_EXTENSION HwDeviceExtension,
  206. PUCHAR pHWCursorShape
  207. )
  208. /*++
  209. Routine Description:
  210. Sets the hardware cursor shape.
  211. Arguments:
  212. HwDeviceExtension - Pointer to the miniport driver's device extension.
  213. pHWCursorShape - Pointer to the cursor bitmap.
  214. Return Value:
  215. None.
  216. --*/
  217. {
  218. int i, j, iCursorIndex;
  219. UCHAR ucPacked;
  220. USHORT usExpanded;
  221. VideoDebugPrint((3, "IBM525SetPointerShape: ----------\n"));
  222. //
  223. // Calculate # bytes for Pixel data. The IBMRGB525 DAC provides support
  224. // for 32x32 and 64x64 cursors. Two bits for each pixel.
  225. //
  226. // 2 bit per pixel = 4 pixel per byte (8 / 2).
  227. // 256 bytes for 32x32 cursor, and 1024 bytes for 64x64 cursor.
  228. // Note that we can store up to four 32x32 cursors.
  229. //
  230. // Specify:
  231. // 32x32 cursor; 2-color & highlighting cursor; delayed cursor update;
  232. // read actual location; pixel order left to right and partion 00.
  233. //
  234. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_CTL, 0x32);
  235. //
  236. // Set color 1 to Black, and color 2 to white...
  237. //
  238. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_1_RED, 0x00); // Black
  239. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_1_GREEN, 0x00);
  240. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_1_BLUE, 0x00);
  241. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_2_RED, 0xFF); // White
  242. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_2_GREEN, 0xFF);
  243. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_2_BLUE, 0xFF);
  244. //
  245. // Set cursor hot-spot to upper/left of cursor...
  246. //
  247. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_HOT_X, 0x00);
  248. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_HOT_Y, 0x00);
  249. //
  250. // WinNT provides a monochrome or color bitmap for a specific cursor.
  251. // The mono bitmap has the same width as the cursor, but has twice the
  252. // vertical extent, which contains two masks. The first mask is the
  253. // AND mask, while the second mask is the XOR mask. Normally, the AND
  254. // mask will be loaded into Plane1 while the XOR mask will be loaded
  255. // into Plane0 as is for Ramdacs like the BT485. However, since the
  256. // IBMRGB525 Ramdac only allows for a color cursor, we must combine
  257. // both the AND and XOR mask into one, two bits per pixel bit mask.
  258. //
  259. iCursorIndex = RGB525_CURSOR_ARRAY; // Beginning cursor index
  260. WAIT_FOR_RETRACE();
  261. for (i = 0; i < ((CURSOR_WIDTH * CURSOR_HEIGHT) / 8); i++)
  262. {
  263. usExpanded = 0;
  264. ucPacked = *pHWCursorShape; // Get AND mask byte
  265. for (j = 0; j < 8; j++)
  266. {
  267. if (ucPacked & (0x1 << j))
  268. usExpanded |= (0x2 << (j*2));
  269. }
  270. ucPacked = *(pHWCursorShape + 128); // Get XOR mask byte
  271. for (j = 0; j < 8; j++)
  272. {
  273. if (ucPacked & (0x1 << j))
  274. usExpanded |= (0x1 << (j*2));
  275. }
  276. ++pHWCursorShape;
  277. WriteIBM525(HwDeviceExtension,
  278. (USHORT) iCursorIndex++,
  279. (UCHAR) ((usExpanded & 0xFF00) >> 8));
  280. WriteIBM525(HwDeviceExtension,
  281. (USHORT) iCursorIndex++,
  282. (UCHAR) (usExpanded & 0x00FF));
  283. }
  284. return;
  285. } // End of IBM525SetPointerShape()
  286. VOID
  287. IBM525PointerOn(
  288. PHW_DEVICE_EXTENSION HwDeviceExtension
  289. )
  290. /*++
  291. Routine Description:
  292. Turn on the hardware cursor.
  293. Arguments:
  294. HwDeviceExtension - Pointer to the miniport driver's device extension.
  295. Return Value:
  296. None.
  297. --*/
  298. {
  299. //
  300. // Turn the cursor on only if it was disabled.
  301. //
  302. VideoDebugPrint((3, "IBM525PointerOn: ----------\n"));
  303. if (!CURS_IS_ON_IBM525())
  304. {
  305. WAIT_FOR_RETRACE();
  306. CURS_ON_IBM525();
  307. }
  308. return;
  309. }
  310. VOID
  311. IBM525PointerOff(
  312. PHW_DEVICE_EXTENSION HwDeviceExtension
  313. )
  314. /*++
  315. Routine Description:
  316. Turn off the hardware cursor.
  317. Arguments:
  318. HwDeviceExtension - Pointer to the miniport driver's device extension.
  319. Return Value:
  320. None.
  321. --*/
  322. {
  323. //
  324. // Turn the cursor off only if it was enabled.
  325. //
  326. VideoDebugPrint((3, "IBM525PointerOff: ----------\n"));
  327. if (CURS_IS_ON_IBM525())
  328. {
  329. WAIT_FOR_RETRACE();
  330. CURS_OFF_IBM525();
  331. }
  332. return;
  333. }
  334. VOID
  335. IBM525ClearPalette(
  336. PHW_DEVICE_EXTENSION HwDeviceExtension
  337. )
  338. /*++
  339. Routine Description:
  340. Clears the palette to all 0's
  341. Arguments:
  342. HwDeviceExtension - Pointer to the miniport driver's device extension.
  343. Return Value:
  344. None.
  345. --*/
  346. {
  347. int i, Count;
  348. VideoDebugPrint((3, "IBM525ClearPalette: ----------\n"));
  349. //
  350. // Calculate the number of palette entries. It is assumed that the
  351. // caller has already determined that the current mode makes use
  352. // of the palette,
  353. //
  354. Count = 256; // 256 x 8 x 3
  355. //
  356. // Fill the palette with RGB values of 0.
  357. //
  358. IBM525_WR_DAC(P9100_RAMWRITE, (UCHAR) 0);
  359. VideoPortStallExecution(5);
  360. while (Count--)
  361. {
  362. IBM525_WR_DAC(P9100_PALETDATA, 0);
  363. VideoPortStallExecution(5);
  364. IBM525_WR_DAC(P9100_PALETDATA, 0);
  365. VideoPortStallExecution(5);
  366. IBM525_WR_DAC(P9100_PALETDATA, 0);
  367. VideoPortStallExecution(5);
  368. }
  369. return;
  370. }
  371. BOOLEAN
  372. IBM525SetMode(
  373. PHW_DEVICE_EXTENSION HwDeviceExtension
  374. )
  375. /*++
  376. Routine Description:
  377. Initializes the DAC for the current mode.
  378. Arguments:
  379. HwDeviceExtension - Pointer to the miniport driver's device extension.
  380. Return Value:
  381. None.
  382. --*/
  383. {
  384. VideoDebugPrint((2, "IBM525SetMode: - Entry\n"));
  385. //
  386. // Set the pixel read mask.
  387. //
  388. P9_WR_BYTE_REG(P9100_PIXELMASK, 0xff);
  389. //
  390. // Select the fast DAC slew rate for the sharpest pixels
  391. //
  392. WriteIBM525(HwDeviceExtension, RGB525_DAC_OPER, 0x02);
  393. //
  394. // Enable the 64-bit VRAM pixel port
  395. //
  396. WriteIBM525(HwDeviceExtension, RGB525_MISC_CTL1, 0x01);
  397. //
  398. // The Dac.bRamdacUsePLL flag determines whether or not
  399. // we use the RAMDAC's internal PLL.
  400. //
  401. VideoDebugPrint((3, "IBM525SetMode: bRamdacUsePLL = %d\n",
  402. HwDeviceExtension->Dac.bRamdacUsePLL));
  403. if (!HwDeviceExtension->Dac.bRamdacUsePLL)
  404. {
  405. //
  406. // Use the external clock instead of the RAMDAC PLL
  407. // Useful for debugging if you can't get the RAMDAC
  408. // PLL on your board to lock for whatever reason.
  409. //
  410. WriteIBM525(HwDeviceExtension, RGB525_MISC_CTL2, 0x85);
  411. }
  412. else
  413. {
  414. //
  415. // Internal PLL output used for pixel clock 8-bit DACs
  416. // VRAM pixel port inputs.
  417. //
  418. WriteIBM525(HwDeviceExtension, RGB525_MISC_CTL2, 0x45);
  419. }
  420. VideoDebugPrint((3, "IBM525SetMode: bRamdacDivides = %d\n",
  421. HwDeviceExtension->Dac.bRamdacDivides));
  422. switch(HwDeviceExtension->usBitsPixel)
  423. {
  424. case 32:
  425. //
  426. // Select 32bpp (bypass palette)
  427. //
  428. //
  429. // If Dac.bRamdacDivides == TRUE then we set up the RAMDAC
  430. // so that we can use the ddotclk output instead of SCLK if
  431. // necessary, by setting up the ddotclk divisor.
  432. // Otherwise we have the RAMDAC send out the pixel clock.
  433. //
  434. if (HwDeviceExtension->Dac.bRamdacDivides)
  435. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x23);
  436. else
  437. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x21);
  438. WriteIBM525(HwDeviceExtension, RGB525_PIXEL_FORMAT, 0x06);
  439. WriteIBM525(HwDeviceExtension, RGB525_32BPP_CTL, 0x03);
  440. break;
  441. case 24:
  442. //
  443. // 24BPP packed
  444. //
  445. //
  446. // This first line doesn't matter too much because SCLK
  447. // will be sent out both the SCLK and DDOTCLK outputs in
  448. // 24bpp mode
  449. //
  450. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x27);
  451. WriteIBM525(HwDeviceExtension, RGB525_PIXEL_FORMAT, 0x05);
  452. WriteIBM525(HwDeviceExtension, RGB525_24BPP_CTL, 0x01);
  453. break;
  454. case 16:
  455. //
  456. // Note: 16-bpp is really 15-bpp (555)
  457. // Select 15bpp (bypass palette)
  458. //
  459. if (HwDeviceExtension->Dac.bRamdacDivides)
  460. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x25);
  461. else
  462. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x21);
  463. WriteIBM525(HwDeviceExtension, RGB525_PIXEL_FORMAT, 0x04);
  464. WriteIBM525(HwDeviceExtension, RGB525_16BPP_CTL, 0xc4);
  465. break;
  466. case 15:
  467. //
  468. // This is really 16-bpp (565).
  469. // Select 16bpp (bypass palette)
  470. //
  471. if (HwDeviceExtension->Dac.bRamdacDivides)
  472. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x25);
  473. else
  474. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x21);
  475. WriteIBM525(HwDeviceExtension, RGB525_PIXEL_FORMAT, 0x04);
  476. WriteIBM525(HwDeviceExtension, RGB525_16BPP_CTL, 0xc6);
  477. break;
  478. case 8:
  479. //
  480. // Select 8bpp
  481. //
  482. if (HwDeviceExtension->Dac.bRamdacDivides)
  483. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x27);
  484. else
  485. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x21);
  486. WriteIBM525(HwDeviceExtension, RGB525_PIXEL_FORMAT, 0x03);
  487. WriteIBM525(HwDeviceExtension, RGB525_8BPP_CTL, 0x00);
  488. break;
  489. };
  490. VideoDebugPrint((2, "IBM525SetMode: - Exit\n"));
  491. return(TRUE);
  492. }
  493. VOID
  494. IBM525RestoreMode(
  495. PHW_DEVICE_EXTENSION HwDeviceExtension
  496. )
  497. /*++
  498. routine description:
  499. Restore the DAC to its pristine state. For the P9100, the disable
  500. video function will reset the DAC via a call to INT10 for VGA mode
  501. 3. Since the Video BIOS cannot switch to protected mode, and therefore
  502. cannot enter P9100 native mode, it cannot completely initialize the
  503. IBMRGB525 DAC, so we will do the initialization here.
  504. arguments:
  505. hwdeviceextension - pointer to the miniport driver's device extension.
  506. return value:
  507. --*/
  508. {
  509. VideoDebugPrint((3, "IBM525RestoreMode: ----------\n"));
  510. //
  511. // Check if there is an override value for the PLL Reference Divider.
  512. //
  513. if (HwDeviceExtension->VideoData.ul525RefClkCnt != 0xFFFFFFFF)
  514. {
  515. //
  516. // Program REFCLK to the specified override...
  517. //
  518. WriteIBM525(HwDeviceExtension,
  519. RGB525_FIXED_PLL_REF_DIV,
  520. (UCHAR) HwDeviceExtension->VideoData.ul525RefClkCnt);
  521. }
  522. else
  523. {
  524. //
  525. // Program REFCLK to a fixed 50MHz.
  526. //
  527. WriteIBM525(HwDeviceExtension, RGB525_FIXED_PLL_REF_DIV,
  528. IBM525_PLLD_50MHZ);
  529. }
  530. //
  531. // REFCLK Input, External
  532. //
  533. WriteIBM525(HwDeviceExtension, RGB525_PLL_CTL1, 0x00);
  534. //
  535. // Set F0 to 25.25 Mhz
  536. //
  537. WriteIBM525(HwDeviceExtension, RGB525_F0, 0x24);
  538. //
  539. // Set F1 to 28.25 Mhz
  540. //
  541. WriteIBM525(HwDeviceExtension, RGB525_F1, 0x30);
  542. //
  543. // PLL Enable
  544. //
  545. WriteIBM525(HwDeviceExtension, RGB525_MISC_CLOCK_CTL, 0x01);
  546. //
  547. // Cursor OFF
  548. //
  549. WriteIBM525(HwDeviceExtension, RGB525_CURSOR_CTL, 0x00);
  550. WriteIBM525(HwDeviceExtension, RGB525_VRAM_MASK_LOW, 0x03);
  551. WriteIBM525(HwDeviceExtension, RGB525_MISC_CTL1, 0x40);
  552. WriteIBM525(HwDeviceExtension, RGB525_PIXEL_FORMAT, 0x03);
  553. WriteIBM525(HwDeviceExtension, RGB525_MISC_CTL2, 0x41);
  554. WriteIBM525(HwDeviceExtension, RGB525_MISC_CTL2, 0x00);
  555. WriteIBM525(HwDeviceExtension, RGB525_MISC_CTL1, 0x00);
  556. WriteIBM525(HwDeviceExtension, RGB525_VRAM_MASK_LOW, 0x00);
  557. return;
  558. }
  559. VOID
  560. IBM525SetClkDoubler(
  561. PHW_DEVICE_EXTENSION HwDeviceExtension
  562. )
  563. {
  564. return; // Nothing to do... just return.
  565. }
  566. VOID
  567. IBM525ClrClkDoubler(
  568. PHW_DEVICE_EXTENSION HwDeviceExtension
  569. )
  570. {
  571. return; // Nothing to do... just return.
  572. }