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.

985 lines
26 KiB

  1. /*++
  2. Copyright (c) 1993, 1994 Weitek Corporation
  3. Module Name:
  4. wtkp91vl.c
  5. Abstract:
  6. This module contains OEM specific functions for the Weitek P9100
  7. VL evaluation board.
  8. Environment:
  9. Kernel mode
  10. Revision History may be found at the end of this file.
  11. --*/
  12. #include "p9.h"
  13. #include "p9gbl.h"
  14. #include "wtkp9xvl.h"
  15. #include "bt485.h"
  16. #include "vga.h"
  17. #include "p91regs.h"
  18. #include "p91dac.h"
  19. #include "pci.h"
  20. #include "p9000.h"
  21. /***********************************************************************
  22. *
  23. **********************************************************************/
  24. VOID vDumpPCIConfig(PHW_DEVICE_EXTENSION HwDeviceExtension,
  25. PUCHAR psz)
  26. {
  27. ULONG i, j;
  28. ULONG ulPciData[64];
  29. VideoDebugPrint((1, "\n%s\n", psz));
  30. VideoPortGetBusData(HwDeviceExtension,
  31. PCIConfiguration,
  32. HwDeviceExtension->PciSlotNum,
  33. (PVOID) ulPciData,
  34. 0,
  35. sizeof(ulPciData));
  36. for (i = 0, j = 0; i < (64 / 4); i++)
  37. {
  38. VideoDebugPrint((1,
  39. "0x%04.4x\t %08.8x, %08.8x, %08.8x, %08.8x\n",
  40. j * sizeof(ULONG),
  41. ulPciData[j], ulPciData[j+1],
  42. ulPciData[j+2], ulPciData[j+3]));
  43. j += 4;
  44. }
  45. }
  46. BOOLEAN
  47. VLGetBaseAddrP91(
  48. PHW_DEVICE_EXTENSION HwDeviceExtension
  49. )
  50. /*++
  51. Routine Description:
  52. Perform board detection and if present return the P9100 base address.
  53. Arguments:
  54. HwDeviceExtension - Pointer to the miniport driver's device extension.
  55. Return Value:
  56. TRUE - Board found, P9100 and Frame buffer address info was placed in
  57. the device extension.
  58. FALSE - Board not found.
  59. --*/
  60. {
  61. VP_STATUS status;
  62. VIDEO_ACCESS_RANGE VLAccessRange;
  63. USHORT usTemp;
  64. VideoDebugPrint((1, "VLGetBaseAddrP91 - Entry\n"));
  65. //
  66. // Only the viper p9000 works on the Siemens boxes
  67. //
  68. if (HwDeviceExtension->MachineType == SIEMENS)
  69. {
  70. return FALSE;
  71. }
  72. //
  73. // Always use the defined address for the p9100
  74. //
  75. if (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB)
  76. {
  77. HwDeviceExtension->P9PhysAddr.LowPart = MemBase;
  78. }
  79. //
  80. // Set the bus-type for accessing the VLB configuration space...
  81. //
  82. HwDeviceExtension->usBusType = VESA;
  83. //
  84. // Now, detect the board
  85. //
  86. //
  87. //
  88. // OEM Notice:
  89. //
  90. // Here we assume that the configuration space will always
  91. // be mapped to 0x9100 for VL cards. Since this is determined
  92. // by pull-down resistors on the VL cards this is probably
  93. // a safe assumption. If anyone decides to use a different
  94. // address then we should scan for the P9100 chip. The danger
  95. // with scanning is that it is potentially destructive.
  96. //
  97. // Note that we cannot read the power-up configuration register
  98. // until we setup addressability for the VESA local bus adapter.
  99. //
  100. // Also, on VESA LB you must read the VL configuration registers
  101. // using byte port reads.
  102. //
  103. VLAccessRange.RangeInIoSpace = TRUE;
  104. VLAccessRange.RangeVisible = TRUE;
  105. VLAccessRange.RangeShareable = TRUE;
  106. VLAccessRange.RangeStart.LowPart = P91_CONFIG_INDEX;
  107. if (HwDeviceExtension->MachineType == SIEMENS_P9100_VLB)
  108. {
  109. VLAccessRange.RangeStart.LowPart |=
  110. ((DriverAccessRanges[1].RangeStart.LowPart & 0xff000000)) ;
  111. }
  112. VLAccessRange.RangeStart.HighPart = 0;
  113. VLAccessRange.RangeLength = P91_CONFIG_CKSEL+1;
  114. if (VideoPortVerifyAccessRanges(HwDeviceExtension,
  115. 1,
  116. &VLAccessRange) != NO_ERROR)
  117. {
  118. return(FALSE);
  119. }
  120. VideoDebugPrint((1, "VLGetBaseAddrP91: RangeStart = %lx\n",
  121. VLAccessRange.RangeStart));
  122. VideoDebugPrint((1, "VLGetBaseAddrP91: RangeLength = %lx\n",
  123. VLAccessRange.RangeLength));
  124. if ((HwDeviceExtension->ConfigAddr =
  125. VideoPortGetDeviceBase(HwDeviceExtension,
  126. VLAccessRange.RangeStart,
  127. VLAccessRange.RangeLength,
  128. VLAccessRange.RangeInIoSpace)) == 0)
  129. {
  130. return(FALSE);
  131. }
  132. // Verify that we can write to the index registers...
  133. //
  134. VideoPortWritePortUchar(
  135. (PUCHAR) HwDeviceExtension->ConfigAddr, 0x55);
  136. if (VideoPortReadPortUchar(
  137. (PUCHAR) HwDeviceExtension->ConfigAddr) != 0x55)
  138. {
  139. VideoDebugPrint((1, "VLGetBaseAddrP91: Could not access VESA LB Config space!\n"));
  140. VideoDebugPrint((1, "VLGetBaseAddrP91: Wrote: 0x55, Read: %lx\n",
  141. VideoPortReadPortUchar((PUCHAR) HwDeviceExtension->ConfigAddr)));
  142. return(FALSE);
  143. }
  144. //
  145. // Verify Vendor ID...
  146. //
  147. usTemp = ReadP9ConfigRegister(HwDeviceExtension,
  148. P91_CONFIG_VENDOR_HIGH) << 8;
  149. usTemp |= ReadP9ConfigRegister(HwDeviceExtension,
  150. P91_CONFIG_VENDOR_LOW);
  151. if (usTemp != WTK_VENDOR_ID)
  152. {
  153. VideoDebugPrint((1, "Invalid Vendor ID: %x\n", usTemp));
  154. return(FALSE);
  155. }
  156. //
  157. // Verify Device ID...
  158. //
  159. usTemp = ReadP9ConfigRegister(HwDeviceExtension,
  160. P91_CONFIG_DEVICE_HIGH) << 8;
  161. usTemp |= ReadP9ConfigRegister(HwDeviceExtension,
  162. P91_CONFIG_DEVICE_LOW);
  163. if (usTemp != WTK_9100_ID)
  164. {
  165. VideoDebugPrint((1, "Invalid Device ID: %x\n", usTemp));
  166. return(FALSE);
  167. }
  168. //
  169. // Now program the P9100 to respond to the requested physical address...
  170. //
  171. if (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB)
  172. {
  173. WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_WBASE,
  174. (UCHAR)(((HwDeviceExtension->P9PhysAddr.LowPart >> 24) & 0xFF)));
  175. }
  176. else
  177. {
  178. //
  179. // The physical address base put on the VL-bus (in its memory space)
  180. // is always set to zero by the FirmWare (in the MapVLBase register).
  181. //
  182. WriteP9ConfigRegister (HwDeviceExtension ,P91_CONFIG_WBASE ,0) ;
  183. }
  184. VideoDebugPrint((1, "VLGetBaseAddrP91: Found a P9100 VLB Adapter!\n"));
  185. return(TRUE);
  186. }
  187. VOID
  188. VLSetModeP91(
  189. PHW_DEVICE_EXTENSION HwDeviceExtension
  190. )
  191. /*++
  192. Routine Description:
  193. This routine sets the video mode. Different OEM adapter implementations
  194. require that initialization operations be performed in a certain
  195. order. This routine uses the standard order which addresses most
  196. implementations (VL, Ajax, Weitek PCI, Tulip).
  197. Arguments:
  198. HwDeviceExtension - Pointer to the miniport driver's device extension.
  199. Return Value:
  200. None.
  201. --*/
  202. {
  203. VideoDebugPrint((2, "VLSetModeP91 - Entry\n"));
  204. //
  205. // Enable P9100 video if not already enabled.
  206. //
  207. if (!HwDeviceExtension->p91State.bEnabled)
  208. HwDeviceExtension->AdapterDesc.P9EnableVideo(HwDeviceExtension);
  209. //
  210. // If this mode uses the palette, clear it to all 0s.
  211. //
  212. if (P9Modes[HwDeviceExtension->CurrentModeNumber].modeInformation.AttributeFlags
  213. & VIDEO_MODE_PALETTE_DRIVEN)
  214. {
  215. HwDeviceExtension->Dac.DACClearPalette(HwDeviceExtension);
  216. }
  217. VideoDebugPrint((2, "VLSetModeP91 - Exit\n"));
  218. } // End of VLSetModeP91()
  219. VOID
  220. VLEnableP91(
  221. PHW_DEVICE_EXTENSION HwDeviceExtension
  222. )
  223. /*++
  224. Routine Description:
  225. Perform the OEM specific tasks necessary to enable P9100 Video. These
  226. include memory mapping, setting the sync polarities, and enabling the
  227. P9100 video output.
  228. Arguments:
  229. HwDeviceExtension - Pointer to the miniport driver's device extension.
  230. Return Value:
  231. None.
  232. --*/
  233. {
  234. USHORT usMemClkInUse;
  235. VideoDebugPrint((2, "VLEnableP91 - Entry\n"));
  236. //
  237. // Enable native mode to: No RAMDAC shadowing, memory & I/O enabled.
  238. //
  239. if (HwDeviceExtension->usBusType == VESA)
  240. {
  241. WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_CONFIGURATION, 3);
  242. }
  243. WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0); // Native mode
  244. //
  245. // Only initialize the P9100 once...
  246. //
  247. if (!HwDeviceExtension->p91State.bInitialized)
  248. {
  249. HwDeviceExtension->p91State.bInitialized = TRUE;
  250. //
  251. // Now read the power-up configuration register to determine the actual
  252. // board-options.
  253. //
  254. HwDeviceExtension->p91State.ulPuConfig = P9_RD_REG(P91_PU_CONFIG);
  255. #if 0
  256. vDumpPCIConfig(HwDeviceExtension, "VLEnableP91, just after reading P91_PU_CONFIG");
  257. #endif
  258. //
  259. // Determine the VRAM type:
  260. //
  261. HwDeviceExtension->p91State.bVram256 =
  262. (HwDeviceExtension->p91State.ulPuConfig & P91_PUC_MEMORY_DEPTH)
  263. ? FALSE : TRUE;
  264. //
  265. // Determine the type of Clock Synthesizer:
  266. //
  267. switch((HwDeviceExtension->p91State.ulPuConfig &
  268. P91_PUC_FREQ_SYNTH_TYPE) >> P91_PUC_SYNTH_SHIFT_CNT)
  269. {
  270. case CLK_ID_ICD2061A:
  271. HwDeviceExtension->p91State.usClockID = CLK_ID_ICD2061A;
  272. break;
  273. case CLK_ID_FIXED_MEMCLK:
  274. HwDeviceExtension->p91State.usClockID = CLK_ID_FIXED_MEMCLK;
  275. break;
  276. default: // Set to ICD2061a & complain... (but continue)
  277. HwDeviceExtension->p91State.usClockID = CLK_ID_ICD2061A;
  278. VideoDebugPrint((1, "Unrecognized frequency synthesizer; Assuming ICD2061A.\n"));
  279. break;
  280. }
  281. //
  282. // Determine the type of RAMDAC:
  283. //
  284. switch((HwDeviceExtension->p91State.ulPuConfig &
  285. P91_PUC_RAMDAC_TYPE) >> P91_PUC_RAMDAC_SHIFT_CNT)
  286. {
  287. case DAC_ID_BT485:
  288. HwDeviceExtension->Dac.usRamdacID = DAC_ID_BT485;
  289. HwDeviceExtension->Dac.usRamdacWidth = 32;
  290. HwDeviceExtension->Dac.bRamdacUsePLL = FALSE;
  291. break;
  292. case DAC_ID_BT489:
  293. HwDeviceExtension->Dac.usRamdacID = DAC_ID_BT489;
  294. HwDeviceExtension->Dac.usRamdacWidth = 64;
  295. HwDeviceExtension->Dac.bRamdacUsePLL = FALSE;
  296. break;
  297. case DAC_ID_IBM525:
  298. HwDeviceExtension->Dac.usRamdacID = DAC_ID_IBM525;
  299. HwDeviceExtension->Dac.usRamdacWidth = 64;
  300. HwDeviceExtension->Dac.bRamdacUsePLL = TRUE; // Assume PLL
  301. break;
  302. default: // Set to BT485 & complain... (but continue)
  303. HwDeviceExtension->Dac.usRamdacID = DAC_ID_BT485;
  304. HwDeviceExtension->Dac.usRamdacWidth = 32;
  305. HwDeviceExtension->Dac.bRamdacUsePLL = FALSE;
  306. VideoDebugPrint((1, "Unrecognized RAMDAC specified; Assuming BT485.\n"));
  307. break;
  308. }
  309. //
  310. // Read and store P9100 revision ID for later reference...
  311. //
  312. P9_WR_REG(P91_SYSCONFIG, 0x00000000);
  313. HwDeviceExtension->p91State.usRevisionID = (USHORT)
  314. (P9_RD_REG(P91_SYSCONFIG) & 0x00000007);
  315. }
  316. //
  317. // Now program the detected hardware...
  318. //
  319. //
  320. // A1/A2 silicon SPLIT SHIFT TRANSFER BUG FIX
  321. //
  322. // This is the main logic for the split shift transfer bug software work
  323. // around. The current assumption is that the RAMDAC will always be doing
  324. // the dividing of the clock.
  325. //
  326. HwDeviceExtension->Dac.bRamdacDivides = TRUE;
  327. HwDeviceExtension->Dac.DACRestore(HwDeviceExtension);
  328. //
  329. // First setup the MEMCLK frequency...
  330. //
  331. usMemClkInUse = (HwDeviceExtension->p91State.usRevisionID ==
  332. WTK_9100_REV1) ? DEF_P9100_REV1_MEMCLK :
  333. DEF_P9100_MEMCLK;
  334. // Program MEMCLK
  335. ProgramClockSynth(HwDeviceExtension, usMemClkInUse, TRUE, FALSE);
  336. //
  337. // Next setup the pixel clock frequency. We have to handle potential
  338. // clock multiplicaiton by the RAMDAC. On the BT485 if the dotfreq
  339. // is greater than the maximum clock freq then we will adjust the
  340. // dot frequency to program the clock with.
  341. //
  342. //
  343. // Program Pix clk
  344. //
  345. ProgramClockSynth(HwDeviceExtension,
  346. (USHORT) HwDeviceExtension->VideoData.dotfreq1,
  347. FALSE,
  348. TRUE);
  349. //
  350. // Determine size of Vram (ulFrameBufferSize)...
  351. //
  352. if (HwDeviceExtension->p91State.bVram256)
  353. {
  354. if (HwDeviceExtension->p91State.ulFrameBufferSize == 0x0400000)
  355. {
  356. P9_WR_REG(P91_MEM_CONFIG, 0x00000007);
  357. }
  358. else
  359. {
  360. P9_WR_REG(P91_MEM_CONFIG, 0x00000005);
  361. }
  362. }
  363. else
  364. {
  365. P9_WR_REG(P91_MEM_CONFIG, 0x00000003);
  366. }
  367. #if 0
  368. //
  369. // Here we will attempt to attempt to free the virtual address space
  370. // for the initial frame buffer setting, and we will attempt to re-map
  371. // the frambuffer into system virtual address space to reflect the
  372. // actual size of the framebuffer.
  373. //
  374. VideoPortFreeDeviceBase(HwDeviceExtension, HwDeviceExtension->FrameAddress);
  375. // Set the actual size
  376. DriverAccessRanges[2].RangeLength = HwDeviceExtension->p91State.ulFrameBufferSize;
  377. if ( (HwDeviceExtension->FrameAddress = (PVOID)
  378. VideoPortGetDeviceBase(HwDeviceExtension,
  379. DriverAccessRanges[2].RangeStart,
  380. DriverAccessRanges[2].RangeLength,
  381. DriverAccessRanges[2].RangeInIoSpace)) == 0)
  382. {
  383. return;
  384. }
  385. #endif
  386. //
  387. // Setup actual framebuffer length...
  388. //
  389. HwDeviceExtension->FrameLength =
  390. HwDeviceExtension->p91State.ulFrameBufferSize;
  391. //
  392. // Init system config & clipping registers...
  393. //
  394. P91_SysConf(HwDeviceExtension);
  395. //
  396. // Calculate memconfig and srtctl register values...
  397. //
  398. CalcP9100MemConfig(HwDeviceExtension);
  399. //
  400. // Now apply the AND and OR masks specified in the mode information
  401. // structure.
  402. //
  403. // Note: It is assumed that if these values are not specified in the .DAT
  404. // file, then they will be initialized as 0xFFFFFFFF for the AND
  405. // mask and 0x00000000 for the OR mask.
  406. //
  407. // Only the blank_edge (bit 19) and the blnkdly (bits 27-28) are valid
  408. // fields for override.
  409. //
  410. // Apply the AND mask to clear the specified bits.
  411. //
  412. HwDeviceExtension->p91State.ulMemConfVal &=
  413. ((ULONG) HwDeviceExtension->VideoData.ulMemCfgClr |
  414. ~((ULONG) P91_MC_BLANK_EDGE_MSK |
  415. (ULONG) P91_MC_BLNKDLY_MSK));
  416. //
  417. // Apply the OR mask to set the specified bits.
  418. //
  419. HwDeviceExtension->p91State.ulMemConfVal |=
  420. ((ULONG) HwDeviceExtension->VideoData.ulMemCfgSet &
  421. ((ULONG) P91_MC_BLANK_EDGE_MSK |
  422. (ULONG) P91_MC_BLNKDLY_MSK));
  423. //
  424. // Load the video timing registers...
  425. //
  426. P91_WriteTiming(HwDeviceExtension);
  427. //
  428. // Setup the RAMDAC to the current mode...
  429. //
  430. HwDeviceExtension->Dac.DACInit(HwDeviceExtension);
  431. //
  432. // Setup MEMCONFIG and SRTCTL regs
  433. //
  434. SetupVideoBackend(HwDeviceExtension);
  435. //
  436. // Set the native-mode enabled flag...
  437. //
  438. HwDeviceExtension->p91State.bEnabled = TRUE;
  439. #ifdef _MIPS_
  440. if(HwDeviceExtension->MachineType == SIEMENS_P9100_VLB) {
  441. // SNI specific
  442. // First point:
  443. // Od: 27-11-95 The vram_miss_adj/vram_read_adj/vram_read_sample bits
  444. // are documented to be set to 1 by WEITECK or risk some troubles...
  445. // anyway, on our Mips/VL architecture, it helps hardfully when
  446. // they are cleared; otherwhise, we lost about 1 bit every 1500 Kilo bytes
  447. // during largescreen to host transfers...
  448. // Any Way we feel it confortable because it should speed up our graphics...
  449. {
  450. ULONG ulMemConfig;
  451. // 1/ read the value programmed by CalcP9100MemConfig
  452. ulMemConfig = P9_RD_REG(P91_MEM_CONFIG);
  453. // 2/ clear the 3 read-delaies bits
  454. ulMemConfig &= ~(P91_MC_MISS_ADJ_1|P91_MC_READ_ADJ_1
  455. |P91_MC_READ_SMPL_ADJ_1);
  456. // 3/ write it back
  457. P9_WR_REG(P91_MEM_CONFIG, ulMemConfig);
  458. }
  459. // Second point:
  460. // Od: 2/10/95B: with large resolution, the frame buffer will overlap
  461. // with the good old ROM Bios, around xC0000 to xE0000, x=8,9,...
  462. // since ROM relocation does NOT run on VLB systems (hard wired..)
  463. // we relocate the frame buffer instead:
  464. {
  465. unsigned char * HiOrderByteReg, HiOrderByteVal;
  466. // to achieve that goal,
  467. // 1/ we ask the P9100 to respond to 8xxxxxxxx address rather than 0xxxxxxxx
  468. HiOrderByteVal=0x80; // Od: why not ?
  469. WriteP9ConfigRegister(HwDeviceExtension,P91_CONFIG_WBASE,HiOrderByteVal);
  470. // 2/ we tell the mother board to set the high order byte for each
  471. // related addresses
  472. {
  473. extern VP_STATUS GetCPUIdCallback(
  474. PVOID HwDeviceExtension,
  475. PVOID Context,
  476. VIDEO_DEVICE_DATA_TYPE DeviceDataType,
  477. PVOID Identifier,
  478. ULONG IdentifierLength,
  479. PVOID ConfigurationData,
  480. ULONG ConfigurationDataLength,
  481. PVOID ComponentInformation,
  482. ULONG ComponentInformationLength
  483. );
  484. if(VideoPortIsCpu(L"RM200"))
  485. HiOrderByteReg = (unsigned char *) 0xBFCC0000;
  486. else
  487. if(VideoPortIsCpu(L"RM400-MT"))
  488. {
  489. HiOrderByteReg = (unsigned char *) 0xBC010000;
  490. HiOrderByteVal = ~HiOrderByteVal;
  491. }
  492. else
  493. if(VideoPortIsCpu(L"RM400-T")
  494. || VideoPortIsCpu(L"RM400-T MP"))
  495. {
  496. HiOrderByteReg = (unsigned char *) 0xBC0C0000;
  497. HiOrderByteVal = ~HiOrderByteVal;
  498. }
  499. }
  500. *HiOrderByteReg = HiOrderByteVal;
  501. // NOTE that at this point (Dll ending up init by enabling the surface),
  502. // we will not be able to switch back to VGA;
  503. }
  504. }
  505. #endif // SIEMENS_P9100_VLB
  506. VideoDebugPrint((2, "VLEnableP91 - Exit\n"));
  507. return;
  508. } // End of VLEnableP91()
  509. BOOLEAN
  510. VLDisableP91(
  511. PHW_DEVICE_EXTENSION HwDeviceExtension
  512. )
  513. /*++
  514. Routine Description:
  515. Disables native mode (switches to emulation mode (VGA)) and does
  516. an INT10 for mode 3. Note that this will also reset the DAC to
  517. VGA mode/3.
  518. Arguments:
  519. HwDeviceExtension - Pointer to the miniport driver's device extension.
  520. pPal - Pointer to the array of pallete entries.
  521. StartIndex - Specifies the first pallete entry provided in pPal.
  522. Count - Number of palette entries in pPal
  523. Return Value:
  524. FALSE, indicating an int10 modeset needs to be done to complete the
  525. switch.
  526. --*/
  527. {
  528. VideoDebugPrint((2, "VLDisableP91 - Entry\n"));
  529. //
  530. // Disable native-mode (set emulation-mode) only if native-mode is
  531. // already enabled...
  532. //
  533. if (!HwDeviceExtension->p91State.bEnabled)
  534. return (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB) ?
  535. TRUE : FALSE;
  536. //
  537. // Set emulation-mode (VGA)...
  538. //
  539. WriteP9ConfigRegister(HwDeviceExtension, P91_CONFIG_MODE, 0x02);
  540. //
  541. // Set enabled flag
  542. //
  543. HwDeviceExtension->p91State.bEnabled = FALSE;
  544. VideoDebugPrint((2, "VLDisableP91 - Exit\n"));
  545. return (HwDeviceExtension->MachineType != SIEMENS_P9100_VLB) ?
  546. FALSE : TRUE;
  547. } // End of VLDisableP91()
  548. UCHAR
  549. ReadP9ConfigRegister(
  550. PHW_DEVICE_EXTENSION HwDeviceExtension,
  551. UCHAR regnum
  552. )
  553. /*++
  554. Routine Description:
  555. Reads and returns value from the specified VLB or PCI configuration space.
  556. Arguments:
  557. regnum - register to read.
  558. Return Value:
  559. Returns specified registers 8-bit value.
  560. --*/
  561. {
  562. ULONG ulTemp;
  563. VideoDebugPrint((2, "ReadP9ConfigRegister - Entry\n"));
  564. ulTemp = 0;
  565. switch (HwDeviceExtension->usBusType)
  566. {
  567. case VESA:
  568. //
  569. // Select the register, and return the value.
  570. //
  571. VideoPortWritePortUchar((PUCHAR) HwDeviceExtension->ConfigAddr, regnum);
  572. ulTemp = VideoPortReadPortUchar((PUCHAR) HwDeviceExtension->ConfigAddr + 4L);
  573. break;
  574. case PCI:
  575. if (!VideoPortGetBusData(HwDeviceExtension,
  576. PCIConfiguration,
  577. HwDeviceExtension->PciSlotNum,
  578. &ulTemp,
  579. regnum,
  580. sizeof(ulTemp)))
  581. {
  582. VideoDebugPrint((1, "ReadP9ConfigRegister: Cannot read from PCI Config Space!\n"));
  583. }
  584. break;
  585. default:
  586. VideoDebugPrint((1, "ReadP9ConfigRegister: Unknown bus-type!\n"));
  587. ulTemp = 0;
  588. break;
  589. }
  590. VideoDebugPrint((2, "ReadP9ConfigRegister - Exit\n"));
  591. return ((UCHAR) ulTemp);
  592. } // End of ReadP9ConfigRegister()
  593. VOID
  594. WriteP9ConfigRegister(
  595. PHW_DEVICE_EXTENSION HwDeviceExtension,
  596. UCHAR regnum,
  597. UCHAR jValue
  598. )
  599. /*++
  600. Routine Description:
  601. Writes the specified value to the specified register within the VLB
  602. or PCI configuration space.
  603. Arguments:
  604. regnum - desired register,
  605. value - value to write.
  606. Return Value:
  607. None.
  608. --*/
  609. {
  610. VideoDebugPrint((3, "WriteP9ConfigRegister - Entry\n"));
  611. switch (HwDeviceExtension->usBusType)
  612. {
  613. case VESA:
  614. //
  615. // Select the register, and write the value.
  616. //
  617. VideoPortWritePortUchar((PUCHAR) HwDeviceExtension->ConfigAddr, regnum);
  618. VideoPortWritePortUchar((PUCHAR) HwDeviceExtension->ConfigAddr+4L, jValue);
  619. break;
  620. case PCI:
  621. if (!VideoPortSetBusData(HwDeviceExtension,
  622. PCIConfiguration,
  623. HwDeviceExtension->PciSlotNum,
  624. &jValue,
  625. regnum,
  626. 1))
  627. {
  628. VideoDebugPrint((1, "WriteP9ConfigRegister: Cannot write to PCI Config Space!\n"));
  629. }
  630. break;
  631. default:
  632. VideoDebugPrint((1, "ERROR: WriteP9ConfigRegister - Unknown bus-type!\n"));
  633. break;
  634. }
  635. VideoDebugPrint((3, "WriteP9ConfigRegister - Exit\n"));
  636. } // End of WriteP9ConfigRegister()
  637. VOID
  638. SetupVideoBackend(
  639. PHW_DEVICE_EXTENSION HwDeviceExtension
  640. )
  641. /*++
  642. Routine Description:
  643. Program the MEMCONFIG and SRTCTL registers (see comments). For the
  644. Power 9100 only.
  645. Arguments:
  646. HwDeviceExtension - Pointer to the miniport driver's device extension.
  647. Return Value:
  648. None.
  649. --*/
  650. {
  651. ULONG ulSRTCTL2;
  652. VideoDebugPrint((2, "SetupVideoBackend - Entry\n"));
  653. //
  654. // Program the MEMCONFIG and SRTCTL registers
  655. //
  656. // There are two main modes in which the video backend can operate:
  657. // One is a mode in which the P9100 gets the pixel clock (pixclk) and
  658. // divides it to generate the RAMDAC load clock, and the other is
  659. // a mode in which the RAMDAC divides the clock and supplies it through
  660. // the divpixclk input.
  661. //
  662. // If you are using the mode where the RAMDAC provides the divided clock
  663. // then you must make sure that the RAMDAC is generating the divided clock
  664. // before you switch MEMCONFIG to use the divided clock. Otherwise, you
  665. // run the risk of hanging the P9100 since certain synchronizers depend
  666. // upon a video clock to operate. For instance: when you write to a video
  667. // register you must have a video clock running or the P9100 will not be
  668. // able to complete the write, and it will hang the system.
  669. //
  670. // Note that the Ramdac should always divide the pixclk in 24(bits)pp mode.
  671. //
  672. //
  673. // The SRTCTL2 register controls the sync polarities and can also force
  674. // the syncs high or low for the monitor power-down modes.
  675. //
  676. ulSRTCTL2 = 0L;
  677. ulSRTCTL2 |= (HwDeviceExtension->VideoData.hp) ? P91_HSYNC_HIGH_TRUE :
  678. P91_HSYNC_LOW_TRUE;
  679. ulSRTCTL2 |= (HwDeviceExtension->VideoData.vp) ? P91_VSYNC_HIGH_TRUE :
  680. P91_VSYNC_LOW_TRUE;
  681. P9_WR_REG(P91_MEM_CONFIG, HwDeviceExtension->p91State.ulMemConfVal);
  682. P9_WR_REG(P91_SRTCTL, HwDeviceExtension->p91State.ulSrctlVal);
  683. P9_WR_REG(P91_SRTCTL2, ulSRTCTL2);
  684. VideoDebugPrint((2, "SetupVideoBackend: ulMemConfVal = %lx\n",
  685. HwDeviceExtension->p91State.ulMemConfVal));
  686. VideoDebugPrint((2, "SetupVideoBackend: ulSrctlVal = %lx\n",
  687. HwDeviceExtension->p91State.ulSrctlVal));
  688. VideoDebugPrint((2, "SetupVideoBackend: ulSRTCTL2 = %lx\n", ulSRTCTL2));
  689. VideoDebugPrint((2, "SetupVideoBackend: dotfreq1 = %ld\n",
  690. HwDeviceExtension->VideoData.dotfreq1));
  691. VideoDebugPrint((2, "SetupVideoBackend: XSize = %ld\n",
  692. HwDeviceExtension->VideoData.XSize));
  693. VideoDebugPrint((2, "SetupVideoBackend: YSize = %ld\n",
  694. HwDeviceExtension->VideoData.YSize));
  695. VideoDebugPrint((2, "SetupVideoBackend: usBitsPixel = %ld\n",
  696. HwDeviceExtension->usBitsPixel));
  697. VideoDebugPrint((2, "SetupVideoBackend: iClkDiv = %ld\n",
  698. HwDeviceExtension->AdapterDesc.iClkDiv));
  699. VideoDebugPrint((2, "SetupVideoBackend: bRamdacDivides: %d\n",
  700. HwDeviceExtension->Dac.bRamdacDivides));
  701. VideoDebugPrint((2, "SetupVideoBackend: bRamdacUsePLL: %d\n",
  702. HwDeviceExtension->Dac.bRamdacUsePLL));
  703. VideoDebugPrint((2, "SetupVideoBackend: usRevisionID: %d\n",
  704. HwDeviceExtension->p91State.usRevisionID));
  705. VideoDebugPrint((2, "SetupVideoBackend: usBlnkDlyAdj: %d\n",
  706. HwDeviceExtension->p91State.ulBlnkDlyAdj));
  707. VideoDebugPrint((2, "SetupVideoBackend - Exit\n"));
  708. return;
  709. } // End of SetupVideoBackend()