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.

843 lines
22 KiB

  1. //***************************************************************************
  2. //
  3. // Module Name:
  4. //
  5. // power.c
  6. //
  7. // Abstract:
  8. // This module contains the code that implements the Plug & Play and
  9. // power management features
  10. //
  11. // Environment:
  12. //
  13. // Kernel mode
  14. //
  15. //
  16. // Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  17. // Copyright (c) 1995-1999 Microsoft Corporation. All Rights Reserved.
  18. //
  19. //***************************************************************************
  20. #include "permedia.h"
  21. #define VESA_POWER_FUNCTION 0x4f10
  22. #define VESA_POWER_ON 0x0000
  23. #define VESA_POWER_STANDBY 0x0100
  24. #define VESA_POWER_SUSPEND 0x0200
  25. #define VESA_POWER_OFF 0x0400
  26. #define VESA_GET_POWER_FUNC 0x0000
  27. #define VESA_SET_POWER_FUNC 0x0001
  28. #define VESA_STATUS_SUCCESS 0x004f
  29. //
  30. // all our IDs begin with 0x1357bd so they are readily identifiable as our own
  31. //
  32. #define P2_DDC_MONITOR (0x1357bd00)
  33. #define P2_NONDDC_MONITOR (0x1357bd01)
  34. BOOLEAN PowerOnReset( PHW_DEVICE_EXTENSION hwDeviceExtension );
  35. VOID SaveDeviceState( PHW_DEVICE_EXTENSION hwDeviceExtension );
  36. VOID RestoreDeviceState( PHW_DEVICE_EXTENSION hwDeviceExtension );
  37. VOID I2CWriteClock(PVOID HwDeviceExtension, UCHAR data);
  38. VOID I2CWriteData(PVOID HwDeviceExtension, UCHAR data);
  39. BOOLEAN I2CReadClock(PVOID HwDeviceExtension);
  40. BOOLEAN I2CReadData(PVOID HwDeviceExtension);
  41. VOID I2CWaitVSync(PVOID HwDeviceExtension);
  42. #if defined(ALLOC_PRAGMA)
  43. #pragma alloc_text(PAGE, PowerOnReset)
  44. #pragma alloc_text(PAGE, SaveDeviceState)
  45. #pragma alloc_text(PAGE, RestoreDeviceState)
  46. #pragma alloc_text(PAGE, Permedia2GetPowerState)
  47. #pragma alloc_text(PAGE, Permedia2SetPowerState)
  48. #pragma alloc_text(PAGE, Permedia2GetChildDescriptor)
  49. #pragma alloc_text(PAGE, I2CWriteClock)
  50. #pragma alloc_text(PAGE, I2CWriteData)
  51. #pragma alloc_text(PAGE, I2CReadClock)
  52. #pragma alloc_text(PAGE, I2CReadData)
  53. #pragma alloc_text(PAGE, I2CWaitVSync)
  54. #endif
  55. I2C_FNC_TABLE I2CFunctionTable =
  56. {
  57. sizeof(I2C_FNC_TABLE),
  58. I2CWriteClock,
  59. I2CWriteData,
  60. I2CReadClock,
  61. I2CReadData,
  62. I2CWaitVSync,
  63. NULL
  64. };
  65. VP_STATUS Permedia2GetPowerState (
  66. PVOID HwDeviceExtension,
  67. ULONG HwId,
  68. PVIDEO_POWER_MANAGEMENT VideoPowerControl
  69. )
  70. /*++
  71. Routine Description:
  72. Returns power state information.
  73. Arguments:
  74. HwDeviceExtension - Pointer to our hardware device extension structure.
  75. HwId - Private unique 32 bit ID identifing the device.
  76. VideoPowerControl - Points to a VIDEO_POWER_MANAGEMENT structure that
  77. specifies the power state for which support is
  78. being queried.
  79. Return Value:
  80. VP_STATUS value (NO_ERROR or error value)
  81. --*/
  82. {
  83. VIDEO_X86_BIOS_ARGUMENTS biosArguments;
  84. VP_STATUS status;
  85. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  86. DEBUG_PRINT((2, "Permedia2GetPowerState: hwId(%xh) state = %d\n",
  87. (int)HwId, (int)VideoPowerControl->PowerState));
  88. switch((int)HwId)
  89. {
  90. case P2_DDC_MONITOR:
  91. case P2_NONDDC_MONITOR:
  92. switch (VideoPowerControl->PowerState)
  93. {
  94. case VideoPowerOn:
  95. case VideoPowerStandBy:
  96. case VideoPowerSuspend:
  97. case VideoPowerOff:
  98. case VideoPowerHibernate:
  99. case VideoPowerShutdown:
  100. status = NO_ERROR;
  101. break;
  102. default:
  103. DEBUG_PRINT((2, "Permedia2GetPowerState: Unknown monitor PowerState(%xh)\n",
  104. (int)VideoPowerControl->PowerState));
  105. ASSERT(FALSE);
  106. status = ERROR_INVALID_PARAMETER;
  107. }
  108. break;
  109. case DISPLAY_ADAPTER_HW_ID:
  110. //
  111. // only support ON at the moment
  112. //
  113. switch (VideoPowerControl->PowerState)
  114. {
  115. case VideoPowerOn:
  116. case VideoPowerStandBy:
  117. case VideoPowerSuspend:
  118. case VideoPowerHibernate:
  119. case VideoPowerShutdown:
  120. status = NO_ERROR;
  121. break;
  122. case VideoPowerOff:
  123. if( hwDeviceExtension->HardwiredSubSystemId )
  124. {
  125. status = NO_ERROR;
  126. }
  127. else
  128. {
  129. //
  130. // If SubSystemId is not hardwired in a read-only way,
  131. // it is possible we'll see a different value when
  132. // system comes back form S3 mode. This will cause
  133. // problem since os will assume this is a different
  134. // device
  135. //
  136. DEBUG_PRINT((2, "Permedia2GetPowerState: VideoPowerOff is not suported by this card!\n"));
  137. status = ERROR_INVALID_FUNCTION;
  138. }
  139. break;
  140. default:
  141. DEBUG_PRINT((2, "Permedia2GetPowerState: Unknown adapter PowerState(%xh)\n",
  142. (int)VideoPowerControl->PowerState));
  143. ASSERT(FALSE);
  144. status = ERROR_INVALID_PARAMETER;
  145. }
  146. break;
  147. default:
  148. DEBUG_PRINT((1, "Permedia2GetPowerState: Unknown hwId(%xh)",
  149. (int)HwId));
  150. ASSERT(FALSE);
  151. status = ERROR_INVALID_PARAMETER;
  152. }
  153. DEBUG_PRINT((2, "Permedia2GetPowerState: returning %xh\n", status));
  154. return(status);
  155. }
  156. VP_STATUS Permedia2SetPowerState (
  157. PVOID HwDeviceExtension,
  158. ULONG HwId,
  159. PVIDEO_POWER_MANAGEMENT VideoPowerControl
  160. )
  161. /*++
  162. Routine Description:
  163. Set the power state for a given device.
  164. Arguments:
  165. HwDeviceExtension - Pointer to our hardware device extension structure.
  166. HwId - Private unique 32 bit ID identifing the device.
  167. VideoPowerControl - Points to a VIDEO_POWER_MANAGEMENT structure that
  168. specifies the power state to be set.
  169. Return Value:
  170. VP_STATUS value (NO_ERROR, if all's well)
  171. --*/
  172. {
  173. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  174. ULONG Polarity;
  175. VIDEO_X86_BIOS_ARGUMENTS biosArguments;
  176. VP_STATUS status;
  177. P2_DECL;
  178. DEBUG_PRINT((2, "Permedia2SetPowerState: hwId(%xh) state = %d\n",
  179. (int)HwId, (int)VideoPowerControl->PowerState));
  180. switch((int)HwId)
  181. {
  182. case P2_DDC_MONITOR:
  183. case P2_NONDDC_MONITOR:
  184. Polarity = VideoPortReadRegisterUlong(VIDEO_CONTROL);
  185. Polarity &= ~((1 << 5) | (1 << 3) | 1);
  186. switch (VideoPowerControl->PowerState)
  187. {
  188. case VideoPowerHibernate:
  189. case VideoPowerShutdown:
  190. //
  191. // Do nothing for hibernate as the monitor must stay on.
  192. //
  193. status = NO_ERROR;
  194. break;
  195. case VideoPowerOn:
  196. RestoreDeviceState(hwDeviceExtension);
  197. status = NO_ERROR;
  198. break;
  199. case VideoPowerStandBy:
  200. //
  201. // hsync low, vsync active high, video disabled
  202. //
  203. SaveDeviceState(hwDeviceExtension);
  204. VideoPortWriteRegisterUlong(VIDEO_CONTROL,
  205. Polarity | (1 << 5) | (2 << 3) | 0);
  206. status = NO_ERROR;
  207. break;
  208. case VideoPowerSuspend:
  209. //
  210. // vsync low, hsync active high, video disabled
  211. //
  212. VideoPortWriteRegisterUlong(VIDEO_CONTROL,
  213. Polarity | (2 << 5) | (1 << 3) | 0);
  214. status = NO_ERROR;
  215. break;
  216. case VideoPowerOff:
  217. //
  218. // vsync low, hsync low, video disabled
  219. //
  220. VideoPortWriteRegisterUlong(VIDEO_CONTROL,
  221. Polarity | (2 << 5) | (2 << 3) | 0);
  222. status = NO_ERROR;
  223. break;
  224. default:
  225. DEBUG_PRINT((2, "Permedia2GetPowerState: Unknown monitor PowerState(%xh)\n",
  226. (int)VideoPowerControl->PowerState));
  227. ASSERT(FALSE);
  228. status = ERROR_INVALID_PARAMETER;
  229. }
  230. //
  231. // Track the current monitor power state
  232. //
  233. hwDeviceExtension->bMonitorPoweredOn =
  234. (VideoPowerControl->PowerState == VideoPowerOn) ||
  235. (VideoPowerControl->PowerState == VideoPowerHibernate);
  236. Polarity = VideoPortReadRegisterUlong(VIDEO_CONTROL);
  237. break;
  238. case DISPLAY_ADAPTER_HW_ID:
  239. switch (VideoPowerControl->PowerState)
  240. {
  241. case VideoPowerHibernate:
  242. status = NO_ERROR;
  243. break;
  244. case VideoPowerShutdown:
  245. //
  246. // We need to make sure no interrupts will be generated
  247. // after the device being powered down
  248. //
  249. VideoPortWriteRegisterUlong(INT_ENABLE, 0);
  250. status = NO_ERROR;
  251. break;
  252. case VideoPowerOn:
  253. if ((hwDeviceExtension->PreviousPowerState == VideoPowerOff) ||
  254. (hwDeviceExtension->PreviousPowerState == VideoPowerSuspend) ||
  255. (hwDeviceExtension->PreviousPowerState == VideoPowerHibernate))
  256. {
  257. PowerOnReset(hwDeviceExtension);
  258. }
  259. status = NO_ERROR;
  260. break;
  261. case VideoPowerStandBy:
  262. status = NO_ERROR;
  263. break;
  264. case VideoPowerSuspend:
  265. status = NO_ERROR;
  266. break;
  267. case VideoPowerOff:
  268. status = NO_ERROR;
  269. break;
  270. default:
  271. DEBUG_PRINT((2, "Permedia2GetPowerState: Unknown adapter PowerState(%xh)\n",
  272. (int)VideoPowerControl->PowerState));
  273. ASSERT(FALSE);
  274. status = ERROR_INVALID_PARAMETER;
  275. }
  276. hwDeviceExtension->PreviousPowerState =
  277. VideoPowerControl->PowerState;
  278. break;
  279. default:
  280. DEBUG_PRINT((1, "Permedia2SetPowerState: Unknown hwId(%xh)\n",
  281. (int)HwId));
  282. ASSERT(FALSE);
  283. status = ERROR_INVALID_PARAMETER;
  284. }
  285. return(status);
  286. }
  287. BOOLEAN PowerOnReset(
  288. PHW_DEVICE_EXTENSION hwDeviceExtension
  289. )
  290. /*++
  291. Routine Description:
  292. Called when the adapter is powered on
  293. --*/
  294. {
  295. int i;
  296. ULONG ulValue;
  297. BOOLEAN bOK;
  298. P2_DECL;
  299. if(!hwDeviceExtension->bVGAEnabled ||
  300. !hwDeviceExtension->bDMAEnabled)
  301. {
  302. PCI_COMMON_CONFIG PciData;
  303. //
  304. // in a multi-adapter system we'll need to turn on the DMA and
  305. // memory space for the secondary adapters
  306. //
  307. DEBUG_PRINT((1, "PowerOnReset() enabling memory space access for the secondary card\n"));
  308. VideoPortGetBusData( hwDeviceExtension,
  309. PCIConfiguration,
  310. 0,
  311. &PciData,
  312. 0,
  313. PCI_COMMON_HDR_LENGTH);
  314. PciData.Command |= PCI_ENABLE_MEMORY_SPACE;
  315. PciData.Command |= PCI_ENABLE_BUS_MASTER;
  316. VideoPortSetBusData( hwDeviceExtension,
  317. PCIConfiguration,
  318. 0,
  319. &PciData,
  320. 0,
  321. PCI_COMMON_HDR_LENGTH );
  322. #if DBG
  323. DumpPCIConfigSpace(hwDeviceExtension, hwDeviceExtension->pciBus,
  324. (ULONG)hwDeviceExtension->pciSlot.u.AsULONG);
  325. #endif
  326. }
  327. //
  328. // While waking up from hibernation, we usually don't need
  329. // to reset perm2 and call ProcessInitializationTable()
  330. // for the primary card since video bios will get posted.
  331. // We do so here because we saw cases that the perm2 bios
  332. // failed to worked correctly on some machines.
  333. //
  334. //
  335. // reset the device
  336. //
  337. VideoPortWriteRegisterUlong(RESET_STATUS, 0);
  338. for(i = 0; i < 100000; ++i)
  339. {
  340. ulValue = VideoPortReadRegisterUlong(RESET_STATUS);
  341. if (ulValue == 0)
  342. break;
  343. }
  344. if(ulValue)
  345. {
  346. DEBUG_PRINT((1, "PowerOnReset() Read RESET_STATUS(%xh) - failed to reset\n",
  347. ulValue));
  348. ASSERT(FALSE);
  349. bOK = FALSE;
  350. }
  351. else
  352. {
  353. //
  354. // reload registers given in ROM
  355. //
  356. if(hwDeviceExtension->culTableEntries)
  357. {
  358. ProcessInitializationTable(hwDeviceExtension);
  359. }
  360. //
  361. // set-up other registers not set in InitializeVideo
  362. //
  363. VideoPortWriteRegisterUlong(BYPASS_WRITE_MASK, 0xFFFFFFFF);
  364. VideoPortWriteRegisterUlong(APERTURE_ONE, 0x0);
  365. VideoPortWriteRegisterUlong(APERTURE_TWO, 0x0);
  366. bOK = TRUE;
  367. }
  368. return(bOK);
  369. }
  370. VOID SaveDeviceState(PHW_DEVICE_EXTENSION hwDeviceExtension)
  371. /*++
  372. Routine Description:
  373. Save any registers that will be destroyed when we power down the monitor
  374. --*/
  375. {
  376. P2_DECL;
  377. DEBUG_PRINT((2, "SaveDeviceState() called\n"));
  378. //
  379. // hwDeviceExtension->VideoControl should be set in InitializeVideo,
  380. // just in case we get here before InitializeVideo
  381. //
  382. if( !(hwDeviceExtension->VideoControl) )
  383. {
  384. hwDeviceExtension->VideoControl =
  385. VideoPortReadRegisterUlong(VIDEO_CONTROL);
  386. }
  387. hwDeviceExtension->IntEnable = VideoPortReadRegisterUlong(INT_ENABLE);
  388. }
  389. VOID RestoreDeviceState(PHW_DEVICE_EXTENSION hwDeviceExtension)
  390. /*++
  391. Routine Description:
  392. Restore registers saved before monitor power down
  393. --*/
  394. {
  395. P2_DECL;
  396. DEBUG_PRINT((2, "RestoreDeviceState() called\n"));
  397. VideoPortWriteRegisterUlong(VIDEO_CONTROL, hwDeviceExtension->VideoControl);
  398. VideoPortWriteRegisterUlong(INT_ENABLE, hwDeviceExtension->IntEnable);
  399. }
  400. ULONG
  401. Permedia2GetChildDescriptor(
  402. PVOID HwDeviceExtension,
  403. PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
  404. PVIDEO_CHILD_TYPE pChildType,
  405. PVOID pChildDescriptor,
  406. PULONG pUId,
  407. PULONG pUnused )
  408. /*++
  409. Routine Description:
  410. Enumerate all child devices controlled by the Permedia 2 chip.
  411. This includes DDC monitors attached to the board, as well as other devices
  412. which may be connected to a proprietary bus.
  413. Arguments:
  414. HwDeviceExtension -
  415. Pointer to our hardware device extension structure.
  416. ChildEnumInfo -
  417. Information about the device that should be enumerated.
  418. pChildType -
  419. Type of child we are enumerating - monitor, I2C ...
  420. pChildDescriptor -
  421. Identification structure of the device (EDID, string)
  422. pUId -
  423. Private unique 32 bit ID to passed back to the miniport
  424. pUnused -
  425. Do not use
  426. Return Value:
  427. ERROR_NO_MORE_DEVICES -
  428. if no more child devices exist.
  429. ERROR_INVALID_NAME -
  430. The miniport could not enumerate the child device identified in
  431. ChildEnumInfo but does have more devices to be enumerated.
  432. ERROR_MORE_DATA -
  433. There are more devices to be enumerated.
  434. Note:
  435. In the event of a failure return, none of the fields are valid except for
  436. the return value and the pMoreChildren field.
  437. --*/
  438. {
  439. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  440. DEBUG_PRINT((2, "Permedia2GetChildDescriptor called\n"));
  441. switch (ChildEnumInfo->ChildIndex)
  442. {
  443. case 0:
  444. //
  445. // Case 0 is used to enumerate devices found by the ACPI firmware.
  446. // We do not currently support ACPI devices
  447. //
  448. return ERROR_NO_MORE_DEVICES;
  449. case 1:
  450. //
  451. // Treat index 1 as the monitor
  452. //
  453. *pChildType = Monitor;
  454. //
  455. // if it's a DDC monitor we return its EDID in pjBuffer
  456. // (always 128 bytes)
  457. //
  458. if(VideoPortDDCMonitorHelper(HwDeviceExtension,
  459. &I2CFunctionTable,
  460. pChildDescriptor,
  461. ChildEnumInfo->ChildDescriptorSize))
  462. {
  463. //
  464. // found a DDC monitor
  465. //
  466. DEBUG_PRINT((2, "Permedia2GetChildDescriptor: found a DDC monitor\n"));
  467. *pUId = P2_DDC_MONITOR;
  468. }
  469. else
  470. {
  471. //
  472. // failed: assume non-DDC monitor
  473. //
  474. DEBUG_PRINT((2, "Permedia2GetChildDescriptor: found a non-DDC monitor\n"));
  475. *pUId = P2_NONDDC_MONITOR;
  476. }
  477. return ERROR_MORE_DATA;
  478. default:
  479. return ERROR_NO_MORE_DEVICES;
  480. }
  481. }
  482. VOID I2CWriteClock(PVOID HwDeviceExtension, UCHAR data)
  483. {
  484. const ULONG nbitClock = 3;
  485. const ULONG Clock = 1 << nbitClock;
  486. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  487. ULONG ul;
  488. P2_DECL;
  489. ul = VideoPortReadRegisterUlong(DDC_DATA);
  490. ul &= ~Clock;
  491. ul |= (data & 1) << nbitClock;
  492. VideoPortWriteRegisterUlong(DDC_DATA, ul);
  493. }
  494. VOID I2CWriteData(PVOID HwDeviceExtension, UCHAR data)
  495. {
  496. const ULONG nbitData = 2;
  497. const ULONG Data = 1 << nbitData;
  498. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  499. ULONG ul;
  500. P2_DECL;
  501. ul = VideoPortReadRegisterUlong(DDC_DATA);
  502. ul &= ~Data;
  503. ul |= ((data & 1) << nbitData);
  504. VideoPortWriteRegisterUlong(DDC_DATA, ul);
  505. }
  506. BOOLEAN I2CReadClock(PVOID HwDeviceExtension)
  507. {
  508. const ULONG nbitClock = 1;
  509. const ULONG Clock = 1 << nbitClock;
  510. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  511. ULONG ul;
  512. P2_DECL;
  513. ul = VideoPortReadRegisterUlong(DDC_DATA);
  514. ul &= Clock;
  515. ul >>= nbitClock;
  516. return((BOOLEAN)ul);
  517. }
  518. BOOLEAN I2CReadData(PVOID HwDeviceExtension)
  519. {
  520. const ULONG nbitData = 0;
  521. const ULONG Data = 1 << nbitData;
  522. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  523. ULONG ul;
  524. P2_DECL;
  525. ul = VideoPortReadRegisterUlong(DDC_DATA);
  526. ul &= Data;
  527. ul >>= nbitData;
  528. return((BOOLEAN)ul);
  529. }
  530. VOID I2CWaitVSync(PVOID HwDeviceExtension)
  531. {
  532. PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
  533. UCHAR jIndexSaved, jStatus;
  534. P2_DECL;
  535. if(hwDeviceExtension->bVGAEnabled)
  536. {
  537. //
  538. // VGA run on this board, is it currently in VGA or VTG mode?
  539. //
  540. jIndexSaved = VideoPortReadRegisterUchar(PERMEDIA_MMVGA_INDEX_REG);
  541. VideoPortWriteRegisterUchar(PERMEDIA_MMVGA_INDEX_REG,
  542. PERMEDIA_VGA_CTRL_INDEX);
  543. jStatus = VideoPortReadRegisterUchar(PERMEDIA_MMVGA_DATA_REG);
  544. VideoPortWriteRegisterUchar(PERMEDIA_MMVGA_INDEX_REG, jIndexSaved);
  545. }
  546. else
  547. {
  548. //
  549. // VGA not run
  550. //
  551. jStatus = 0;
  552. }
  553. if(jStatus & PERMEDIA_VGA_ENABLE)
  554. {
  555. //
  556. // in VGA, so check VSync via the VGA registers
  557. // 1. if we're in VSync, wait for it to end
  558. //
  559. while( (VideoPortReadRegisterUchar(PERMEDIA_MMVGA_STAT_REG) &
  560. PERMEDIA_VGA_STAT_VSYNC) == 1);
  561. //
  562. // 2. wait for the start of VSync
  563. //
  564. while( (VideoPortReadRegisterUchar(PERMEDIA_MMVGA_STAT_REG) &
  565. PERMEDIA_VGA_STAT_VSYNC) == 0);
  566. }
  567. else
  568. {
  569. if(!hwDeviceExtension->bVTGRunning)
  570. {
  571. //
  572. // time to set-up the VTG - we'll need a valid mode to do this,
  573. // so we;ll choose 640x480x8 we get here (at boot-up only) if
  574. // the secondary card has VGA disabled: GetChildDescriptor is
  575. // called before InitializeVideo so that the VTG hasn't been
  576. // programmed yet
  577. //
  578. DEBUG_PRINT((2, "I2CWaitVSync() - VGA nor VTG running: attempting to setup VTG\n"));
  579. if(hwDeviceExtension->pFrequencyDefault == NULL)
  580. {
  581. DEBUG_PRINT((1, "I2CWaitVSync() - no valid modes to use: can't set-up VTG\n"));
  582. return;
  583. }
  584. Permedia2GetClockSpeeds(HwDeviceExtension);
  585. ZeroMemAndDac(hwDeviceExtension, 0);
  586. if (!InitializeVideo( HwDeviceExtension,
  587. hwDeviceExtension->pFrequencyDefault) )
  588. {
  589. DEBUG_PRINT((1, "I2CWaitVSync() - InitializeVideo failed\n"));
  590. return;
  591. }
  592. }
  593. //
  594. // VTG has been set-up: check via the control registers
  595. //
  596. VideoPortWriteRegisterUlong ( INT_FLAGS,
  597. INTR_VBLANK_SET );
  598. while (( (VideoPortReadRegisterUlong (INT_FLAGS) ) &
  599. INTR_VBLANK_SET ) == 0 );
  600. }
  601. }