CirrusLogic5430.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. /** @file
  2. Cirrus Logic 5430 Controller Driver.
  3. This driver is a sample implementation of the UGA Draw and Graphics Output
  4. Protocols for the Cirrus Logic 5430 family of PCI video controllers.
  5. This driver is only usable in the EFI pre-boot environment.
  6. This sample is intended to show how the UGA Draw and Graphics output Protocol
  7. is able to function.
  8. The UGA I/O Protocol is not implemented in this sample.
  9. A fully compliant EFI UGA driver requires both
  10. the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's
  11. documentation on UGA for details on how to write a UGA driver that is able
  12. to function both in the EFI pre-boot environment and from the OS runtime.
  13. Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
  14. SPDX-License-Identifier: BSD-2-Clause-Patent
  15. **/
  16. //
  17. // Cirrus Logic 5430 Controller Driver
  18. //
  19. #include "CirrusLogic5430.h"
  20. EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = {
  21. CirrusLogic5430ControllerDriverSupported,
  22. CirrusLogic5430ControllerDriverStart,
  23. CirrusLogic5430ControllerDriverStop,
  24. 0x10,
  25. NULL,
  26. NULL
  27. };
  28. ///
  29. /// Generic Attribute Controller Register Settings
  30. ///
  31. UINT8 AttributeController[21] = {
  32. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  33. 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  34. 0x41, 0x00, 0x0F, 0x00, 0x00
  35. };
  36. ///
  37. /// Generic Graphics Controller Register Settings
  38. ///
  39. UINT8 GraphicsController[9] = {
  40. 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF
  41. };
  42. //
  43. // 640 x 480 x 256 color @ 60 Hertz
  44. //
  45. UINT8 Crtc_640_480_256_60[28] = {
  46. 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e,
  47. 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  48. 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3,
  49. 0xff, 0x00, 0x00, 0x22
  50. };
  51. UINT16 Seq_640_480_256_60[15] = {
  52. 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
  53. 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e
  54. };
  55. //
  56. // 800 x 600 x 256 color @ 60 Hertz
  57. //
  58. UINT8 Crtc_800_600_256_60[28] = {
  59. 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0,
  60. 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  61. 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3,
  62. 0xFF, 0x00, 0x00, 0x22
  63. };
  64. UINT16 Seq_800_600_256_60[15] = {
  65. 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
  66. 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e
  67. };
  68. //
  69. // 1024 x 768 x 256 color @ 60 Hertz
  70. //
  71. UINT8 Crtc_1024_768_256_60[28] = {
  72. 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD,
  73. 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  74. 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3,
  75. 0xFF, 0x4A, 0x00, 0x22
  76. };
  77. UINT16 Seq_1024_768_256_60[15] = {
  78. 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b,
  79. 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e
  80. };
  81. ///
  82. /// Table of supported video modes
  83. ///
  84. CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes[] = {
  85. { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 },
  86. { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef },
  87. { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef }
  88. };
  89. /**
  90. CirrusLogic5430ControllerDriverSupported
  91. TODO: This - add argument and description to function comment
  92. TODO: Controller - add argument and description to function comment
  93. TODO: RemainingDevicePath - add argument and description to function comment
  94. **/
  95. EFI_STATUS
  96. EFIAPI
  97. CirrusLogic5430ControllerDriverSupported (
  98. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  99. IN EFI_HANDLE Controller,
  100. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  101. )
  102. {
  103. EFI_STATUS Status;
  104. EFI_PCI_IO_PROTOCOL *PciIo;
  105. PCI_TYPE00 Pci;
  106. EFI_DEV_PATH *Node;
  107. //
  108. // Open the PCI I/O Protocol
  109. //
  110. Status = gBS->OpenProtocol (
  111. Controller,
  112. &gEfiPciIoProtocolGuid,
  113. (VOID **) &PciIo,
  114. This->DriverBindingHandle,
  115. Controller,
  116. EFI_OPEN_PROTOCOL_BY_DRIVER
  117. );
  118. if (EFI_ERROR (Status)) {
  119. return Status;
  120. }
  121. //
  122. // Read the PCI Configuration Header from the PCI Device
  123. //
  124. Status = PciIo->Pci.Read (
  125. PciIo,
  126. EfiPciIoWidthUint32,
  127. 0,
  128. sizeof (Pci) / sizeof (UINT32),
  129. &Pci
  130. );
  131. if (EFI_ERROR (Status)) {
  132. goto Done;
  133. }
  134. Status = EFI_UNSUPPORTED;
  135. //
  136. // See if the I/O enable is on. Most systems only allow one VGA device to be turned on
  137. // at a time, so see if this is one that is turned on.
  138. //
  139. // if (((Pci.Hdr.Command & 0x01) == 0x01)) {
  140. //
  141. // See if this is a Cirrus Logic PCI controller
  142. //
  143. if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) {
  144. //
  145. // See if this is a 5430 or a 5446 PCI controller
  146. //
  147. if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID ||
  148. Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID ||
  149. Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) {
  150. Status = EFI_SUCCESS;
  151. //
  152. // If this is an Intel 945 graphics controller,
  153. // go further check RemainingDevicePath validation
  154. //
  155. if (RemainingDevicePath != NULL) {
  156. Node = (EFI_DEV_PATH *) RemainingDevicePath;
  157. //
  158. // Check if RemainingDevicePath is the End of Device Path Node,
  159. // if yes, return EFI_SUCCESS
  160. //
  161. if (!IsDevicePathEnd (Node)) {
  162. //
  163. // If RemainingDevicePath isn't the End of Device Path Node,
  164. // check its validation
  165. //
  166. if (Node->DevPath.Type != ACPI_DEVICE_PATH ||
  167. Node->DevPath.SubType != ACPI_ADR_DP ||
  168. DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {
  169. Status = EFI_UNSUPPORTED;
  170. }
  171. }
  172. }
  173. }
  174. }
  175. Done:
  176. //
  177. // Close the PCI I/O Protocol
  178. //
  179. gBS->CloseProtocol (
  180. Controller,
  181. &gEfiPciIoProtocolGuid,
  182. This->DriverBindingHandle,
  183. Controller
  184. );
  185. return Status;
  186. }
  187. /**
  188. CirrusLogic5430ControllerDriverStart
  189. TODO: This - add argument and description to function comment
  190. TODO: Controller - add argument and description to function comment
  191. TODO: RemainingDevicePath - add argument and description to function comment
  192. **/
  193. EFI_STATUS
  194. EFIAPI
  195. CirrusLogic5430ControllerDriverStart (
  196. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  197. IN EFI_HANDLE Controller,
  198. IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
  199. )
  200. {
  201. EFI_STATUS Status;
  202. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;
  203. BOOLEAN PciAttributesSaved;
  204. EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
  205. ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
  206. UINT64 Supports;
  207. PciAttributesSaved = FALSE;
  208. //
  209. // Allocate Private context data for UGA Draw inteface.
  210. //
  211. Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA));
  212. if (Private == NULL) {
  213. Status = EFI_OUT_OF_RESOURCES;
  214. goto Error;
  215. }
  216. //
  217. // Set up context record
  218. //
  219. Private->Signature = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE;
  220. Private->Handle = NULL;
  221. //
  222. // Open PCI I/O Protocol
  223. //
  224. Status = gBS->OpenProtocol (
  225. Controller,
  226. &gEfiPciIoProtocolGuid,
  227. (VOID **) &Private->PciIo,
  228. This->DriverBindingHandle,
  229. Controller,
  230. EFI_OPEN_PROTOCOL_BY_DRIVER
  231. );
  232. if (EFI_ERROR (Status)) {
  233. goto Error;
  234. }
  235. //
  236. // Get supported PCI attributes
  237. //
  238. Status = Private->PciIo->Attributes (
  239. Private->PciIo,
  240. EfiPciIoAttributeOperationSupported,
  241. 0,
  242. &Supports
  243. );
  244. if (EFI_ERROR (Status)) {
  245. goto Error;
  246. }
  247. Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);
  248. if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) {
  249. Status = EFI_UNSUPPORTED;
  250. goto Error;
  251. }
  252. //
  253. // Save original PCI attributes
  254. //
  255. Status = Private->PciIo->Attributes (
  256. Private->PciIo,
  257. EfiPciIoAttributeOperationGet,
  258. 0,
  259. &Private->OriginalPciAttributes
  260. );
  261. if (EFI_ERROR (Status)) {
  262. goto Error;
  263. }
  264. PciAttributesSaved = TRUE;
  265. Status = Private->PciIo->Attributes (
  266. Private->PciIo,
  267. EfiPciIoAttributeOperationEnable,
  268. EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports,
  269. NULL
  270. );
  271. if (EFI_ERROR (Status)) {
  272. goto Error;
  273. }
  274. //
  275. // Get ParentDevicePath
  276. //
  277. Status = gBS->HandleProtocol (
  278. Controller,
  279. &gEfiDevicePathProtocolGuid,
  280. (VOID **) &ParentDevicePath
  281. );
  282. if (EFI_ERROR (Status)) {
  283. goto Error;
  284. }
  285. if (FeaturePcdGet (PcdSupportGop)) {
  286. //
  287. // Set Gop Device Path
  288. //
  289. if (RemainingDevicePath == NULL) {
  290. ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
  291. AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
  292. AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
  293. AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
  294. SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
  295. Private->GopDevicePath = AppendDevicePathNode (
  296. ParentDevicePath,
  297. (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
  298. );
  299. } else if (!IsDevicePathEnd (RemainingDevicePath)) {
  300. //
  301. // If RemainingDevicePath isn't the End of Device Path Node,
  302. // only scan the specified device by RemainingDevicePath
  303. //
  304. Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);
  305. } else {
  306. //
  307. // If RemainingDevicePath is the End of Device Path Node,
  308. // don't create child device and return EFI_SUCCESS
  309. //
  310. Private->GopDevicePath = NULL;
  311. }
  312. if (Private->GopDevicePath != NULL) {
  313. //
  314. // Creat child handle and device path protocol firstly
  315. //
  316. Private->Handle = NULL;
  317. Status = gBS->InstallMultipleProtocolInterfaces (
  318. &Private->Handle,
  319. &gEfiDevicePathProtocolGuid,
  320. Private->GopDevicePath,
  321. NULL
  322. );
  323. }
  324. }
  325. //
  326. // Construct video mode buffer
  327. //
  328. Status = CirrusLogic5430VideoModeSetup (Private);
  329. if (EFI_ERROR (Status)) {
  330. goto Error;
  331. }
  332. if (FeaturePcdGet (PcdSupportUga)) {
  333. //
  334. // Start the UGA Draw software stack.
  335. //
  336. Status = CirrusLogic5430UgaDrawConstructor (Private);
  337. ASSERT_EFI_ERROR (Status);
  338. Private->UgaDevicePath = ParentDevicePath;
  339. Status = gBS->InstallMultipleProtocolInterfaces (
  340. &Controller,
  341. &gEfiUgaDrawProtocolGuid,
  342. &Private->UgaDraw,
  343. &gEfiDevicePathProtocolGuid,
  344. Private->UgaDevicePath,
  345. NULL
  346. );
  347. } else if (FeaturePcdGet (PcdSupportGop)) {
  348. if (Private->GopDevicePath == NULL) {
  349. //
  350. // If RemainingDevicePath is the End of Device Path Node,
  351. // don't create child device and return EFI_SUCCESS
  352. //
  353. Status = EFI_SUCCESS;
  354. } else {
  355. //
  356. // Start the GOP software stack.
  357. //
  358. Status = CirrusLogic5430GraphicsOutputConstructor (Private);
  359. ASSERT_EFI_ERROR (Status);
  360. Status = gBS->InstallMultipleProtocolInterfaces (
  361. &Private->Handle,
  362. &gEfiGraphicsOutputProtocolGuid,
  363. &Private->GraphicsOutput,
  364. &gEfiEdidDiscoveredProtocolGuid,
  365. &Private->EdidDiscovered,
  366. &gEfiEdidActiveProtocolGuid,
  367. &Private->EdidActive,
  368. NULL
  369. );
  370. }
  371. } else {
  372. //
  373. // This driver must support eithor GOP or UGA or both.
  374. //
  375. ASSERT (FALSE);
  376. Status = EFI_UNSUPPORTED;
  377. }
  378. Error:
  379. if (EFI_ERROR (Status)) {
  380. if (Private) {
  381. if (Private->PciIo) {
  382. if (PciAttributesSaved == TRUE) {
  383. //
  384. // Restore original PCI attributes
  385. //
  386. Private->PciIo->Attributes (
  387. Private->PciIo,
  388. EfiPciIoAttributeOperationSet,
  389. Private->OriginalPciAttributes,
  390. NULL
  391. );
  392. }
  393. //
  394. // Close the PCI I/O Protocol
  395. //
  396. gBS->CloseProtocol (
  397. Private->Handle,
  398. &gEfiPciIoProtocolGuid,
  399. This->DriverBindingHandle,
  400. Private->Handle
  401. );
  402. }
  403. gBS->FreePool (Private);
  404. }
  405. }
  406. return Status;
  407. }
  408. /**
  409. CirrusLogic5430ControllerDriverStop
  410. TODO: This - add argument and description to function comment
  411. TODO: Controller - add argument and description to function comment
  412. TODO: NumberOfChildren - add argument and description to function comment
  413. TODO: ChildHandleBuffer - add argument and description to function comment
  414. TODO: EFI_SUCCESS - add return value to function comment
  415. **/
  416. EFI_STATUS
  417. EFIAPI
  418. CirrusLogic5430ControllerDriverStop (
  419. IN EFI_DRIVER_BINDING_PROTOCOL *This,
  420. IN EFI_HANDLE Controller,
  421. IN UINTN NumberOfChildren,
  422. IN EFI_HANDLE *ChildHandleBuffer
  423. )
  424. {
  425. EFI_UGA_DRAW_PROTOCOL *UgaDraw;
  426. EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
  427. EFI_STATUS Status;
  428. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private;
  429. if (FeaturePcdGet (PcdSupportUga)) {
  430. Status = gBS->OpenProtocol (
  431. Controller,
  432. &gEfiUgaDrawProtocolGuid,
  433. (VOID **) &UgaDraw,
  434. This->DriverBindingHandle,
  435. Controller,
  436. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  437. );
  438. if (EFI_ERROR (Status)) {
  439. return Status;
  440. }
  441. //
  442. // Get our private context information
  443. //
  444. Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);
  445. CirrusLogic5430UgaDrawDestructor (Private);
  446. if (FeaturePcdGet (PcdSupportGop)) {
  447. CirrusLogic5430GraphicsOutputDestructor (Private);
  448. //
  449. // Remove the UGA and GOP protocol interface from the system
  450. //
  451. Status = gBS->UninstallMultipleProtocolInterfaces (
  452. Private->Handle,
  453. &gEfiUgaDrawProtocolGuid,
  454. &Private->UgaDraw,
  455. &gEfiGraphicsOutputProtocolGuid,
  456. &Private->GraphicsOutput,
  457. NULL
  458. );
  459. } else {
  460. //
  461. // Remove the UGA Draw interface from the system
  462. //
  463. Status = gBS->UninstallMultipleProtocolInterfaces (
  464. Private->Handle,
  465. &gEfiUgaDrawProtocolGuid,
  466. &Private->UgaDraw,
  467. NULL
  468. );
  469. }
  470. } else {
  471. Status = gBS->OpenProtocol (
  472. Controller,
  473. &gEfiGraphicsOutputProtocolGuid,
  474. (VOID **) &GraphicsOutput,
  475. This->DriverBindingHandle,
  476. Controller,
  477. EFI_OPEN_PROTOCOL_GET_PROTOCOL
  478. );
  479. if (EFI_ERROR (Status)) {
  480. return Status;
  481. }
  482. //
  483. // Get our private context information
  484. //
  485. Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
  486. CirrusLogic5430GraphicsOutputDestructor (Private);
  487. //
  488. // Remove the GOP protocol interface from the system
  489. //
  490. Status = gBS->UninstallMultipleProtocolInterfaces (
  491. Private->Handle,
  492. &gEfiUgaDrawProtocolGuid,
  493. &Private->UgaDraw,
  494. &gEfiGraphicsOutputProtocolGuid,
  495. &Private->GraphicsOutput,
  496. NULL
  497. );
  498. }
  499. if (EFI_ERROR (Status)) {
  500. return Status;
  501. }
  502. //
  503. // Restore original PCI attributes
  504. //
  505. Private->PciIo->Attributes (
  506. Private->PciIo,
  507. EfiPciIoAttributeOperationSet,
  508. Private->OriginalPciAttributes,
  509. NULL
  510. );
  511. //
  512. // Close the PCI I/O Protocol
  513. //
  514. gBS->CloseProtocol (
  515. Controller,
  516. &gEfiPciIoProtocolGuid,
  517. This->DriverBindingHandle,
  518. Controller
  519. );
  520. //
  521. // Free our instance data
  522. //
  523. gBS->FreePool (Private);
  524. return EFI_SUCCESS;
  525. }
  526. /**
  527. CirrusLogic5430UgaDrawDestructor
  528. TODO: Private - add argument and description to function comment
  529. TODO: EFI_SUCCESS - add return value to function comment
  530. **/
  531. EFI_STATUS
  532. CirrusLogic5430UgaDrawDestructor (
  533. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
  534. )
  535. {
  536. return EFI_SUCCESS;
  537. }
  538. /**
  539. TODO: Add function description
  540. @param Private TODO: add argument description
  541. @param Address TODO: add argument description
  542. @param Data TODO: add argument description
  543. TODO: add return values
  544. **/
  545. VOID
  546. outb (
  547. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
  548. UINTN Address,
  549. UINT8 Data
  550. )
  551. {
  552. Private->PciIo->Io.Write (
  553. Private->PciIo,
  554. EfiPciIoWidthUint8,
  555. EFI_PCI_IO_PASS_THROUGH_BAR,
  556. Address,
  557. 1,
  558. &Data
  559. );
  560. }
  561. /**
  562. TODO: Add function description
  563. @param Private TODO: add argument description
  564. @param Address TODO: add argument description
  565. @param Data TODO: add argument description
  566. TODO: add return values
  567. **/
  568. VOID
  569. outw (
  570. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
  571. UINTN Address,
  572. UINT16 Data
  573. )
  574. {
  575. Private->PciIo->Io.Write (
  576. Private->PciIo,
  577. EfiPciIoWidthUint16,
  578. EFI_PCI_IO_PASS_THROUGH_BAR,
  579. Address,
  580. 1,
  581. &Data
  582. );
  583. }
  584. /**
  585. TODO: Add function description
  586. @param Private TODO: add argument description
  587. @param Address TODO: add argument description
  588. TODO: add return values
  589. **/
  590. UINT8
  591. inb (
  592. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
  593. UINTN Address
  594. )
  595. {
  596. UINT8 Data;
  597. Private->PciIo->Io.Read (
  598. Private->PciIo,
  599. EfiPciIoWidthUint8,
  600. EFI_PCI_IO_PASS_THROUGH_BAR,
  601. Address,
  602. 1,
  603. &Data
  604. );
  605. return Data;
  606. }
  607. /**
  608. TODO: Add function description
  609. @param Private TODO: add argument description
  610. @param Address TODO: add argument description
  611. TODO: add return values
  612. **/
  613. UINT16
  614. inw (
  615. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
  616. UINTN Address
  617. )
  618. {
  619. UINT16 Data;
  620. Private->PciIo->Io.Read (
  621. Private->PciIo,
  622. EfiPciIoWidthUint16,
  623. EFI_PCI_IO_PASS_THROUGH_BAR,
  624. Address,
  625. 1,
  626. &Data
  627. );
  628. return Data;
  629. }
  630. /**
  631. TODO: Add function description
  632. @param Private TODO: add argument description
  633. @param Index TODO: add argument description
  634. @param Red TODO: add argument description
  635. @param Green TODO: add argument description
  636. @param Blue TODO: add argument description
  637. TODO: add return values
  638. **/
  639. VOID
  640. SetPaletteColor (
  641. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
  642. UINTN Index,
  643. UINT8 Red,
  644. UINT8 Green,
  645. UINT8 Blue
  646. )
  647. {
  648. outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index);
  649. outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
  650. outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
  651. outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
  652. }
  653. /**
  654. TODO: Add function description
  655. @param Private TODO: add argument description
  656. TODO: add return values
  657. **/
  658. VOID
  659. SetDefaultPalette (
  660. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
  661. )
  662. {
  663. UINTN Index;
  664. UINTN RedIndex;
  665. UINTN GreenIndex;
  666. UINTN BlueIndex;
  667. Index = 0;
  668. for (RedIndex = 0; RedIndex < 8; RedIndex++) {
  669. for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
  670. for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
  671. SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));
  672. Index++;
  673. }
  674. }
  675. }
  676. }
  677. /**
  678. TODO: Add function description
  679. @param Private TODO: add argument description
  680. TODO: add return values
  681. **/
  682. VOID
  683. ClearScreen (
  684. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private
  685. )
  686. {
  687. UINT32 Color;
  688. Color = 0;
  689. Private->PciIo->Mem.Write (
  690. Private->PciIo,
  691. EfiPciIoWidthFillUint32,
  692. 0,
  693. 0,
  694. 0x100000 >> 2,
  695. &Color
  696. );
  697. }
  698. /**
  699. TODO: Add function description
  700. @param Private TODO: add argument description
  701. TODO: add return values
  702. **/
  703. VOID
  704. DrawLogo (
  705. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
  706. UINTN ScreenWidth,
  707. UINTN ScreenHeight
  708. )
  709. {
  710. }
  711. /**
  712. TODO: Add function description
  713. @param Private TODO: add argument description
  714. @param ModeData TODO: add argument description
  715. TODO: add return values
  716. **/
  717. VOID
  718. InitializeGraphicsMode (
  719. CIRRUS_LOGIC_5430_PRIVATE_DATA *Private,
  720. CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData
  721. )
  722. {
  723. UINT8 Byte;
  724. UINTN Index;
  725. UINT16 DeviceId;
  726. EFI_STATUS Status;
  727. Status = Private->PciIo->Pci.Read (
  728. Private->PciIo,
  729. EfiPciIoWidthUint16,
  730. PCI_DEVICE_ID_OFFSET,
  731. 1,
  732. &DeviceId
  733. );
  734. //
  735. // Read the PCI Configuration Header from the PCI Device
  736. //
  737. ASSERT_EFI_ERROR (Status);
  738. outw (Private, SEQ_ADDRESS_REGISTER, 0x1206);
  739. outw (Private, SEQ_ADDRESS_REGISTER, 0x0012);
  740. for (Index = 0; Index < 15; Index++) {
  741. outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]);
  742. }
  743. if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) {
  744. outb (Private, SEQ_ADDRESS_REGISTER, 0x0f);
  745. Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30);
  746. outb (Private, SEQ_DATA_REGISTER, Byte);
  747. }
  748. outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
  749. outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506);
  750. outw (Private, SEQ_ADDRESS_REGISTER, 0x0300);
  751. outw (Private, CRTC_ADDRESS_REGISTER, 0x2011);
  752. for (Index = 0; Index < 28; Index++) {
  753. outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index));
  754. }
  755. for (Index = 0; Index < 9; Index++) {
  756. outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index));
  757. }
  758. inb (Private, INPUT_STATUS_1_REGISTER);
  759. for (Index = 0; Index < 21; Index++) {
  760. outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index);
  761. outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]);
  762. }
  763. outb (Private, ATT_ADDRESS_REGISTER, 0x20);
  764. outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009);
  765. outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a);
  766. outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b);
  767. outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff);
  768. SetDefaultPalette (Private);
  769. ClearScreen (Private);
  770. }
  771. EFI_STATUS
  772. EFIAPI
  773. InitializeCirrusLogic5430 (
  774. IN EFI_HANDLE ImageHandle,
  775. IN EFI_SYSTEM_TABLE *SystemTable
  776. )
  777. {
  778. EFI_STATUS Status;
  779. Status = EfiLibInstallDriverBindingComponentName2 (
  780. ImageHandle,
  781. SystemTable,
  782. &gCirrusLogic5430DriverBinding,
  783. ImageHandle,
  784. &gCirrusLogic5430ComponentName,
  785. &gCirrusLogic5430ComponentName2
  786. );
  787. ASSERT_EFI_ERROR (Status);
  788. //
  789. // Install EFI Driver Supported EFI Version Protocol required for
  790. // EFI drivers that are on PCI and other plug in cards.
  791. //
  792. gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
  793. Status = gBS->InstallMultipleProtocolInterfaces (
  794. &ImageHandle,
  795. &gEfiDriverSupportedEfiVersionProtocolGuid,
  796. &gCirrusLogic5430DriverSupportedEfiVersion,
  797. NULL
  798. );
  799. ASSERT_EFI_ERROR (Status);
  800. return Status;
  801. }