]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/Drivers/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
ArmPlatformPkg/NorFlashDxe: prepare for devicepath format change
[mirror_edk2.git] / ArmPlatformPkg / Drivers / LcdGraphicsOutputDxe / LcdGraphicsOutputDxe.c
index 34a56b3d8dc6d4a9216d1850a0935b1bded228b6..872361cd23fbdf52c5f128d0e172701e76d832b2 100644 (file)
@@ -1,15 +1,16 @@
 /** @file\r
+  This file implements the Graphics Output protocol for Arm platforms\r
 \r
Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution.  The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
 Copyright (c) 2011-2018, ARM Ltd. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
 http://opensource.org/licenses/bsd-license.php\r
 \r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
- **/\r
+**/\r
 \r
 #include <PiDxe.h>\r
 #include <Library/BaseMemoryLib.h>\r
 \r
 #include "LcdGraphicsOutputDxe.h"\r
 \r
-/**********************************************************************\r
- *\r
- *  This file implements the Graphics Output protocol on ArmVersatileExpress\r
- *  using the Lcd controller\r
- *\r
- **********************************************************************/\r
-\r
 //\r
 // Global variables\r
 //\r
@@ -43,7 +37,7 @@ LCD_INSTANCE mLcdTemplate = {
     0, // HorizontalResolution\r
     0, // VerticalResolution\r
     PixelBltOnly, // PixelFormat\r
-    0, // PixelInformation\r
+    { 0 }, // PixelInformation\r
     0, // PixelsPerScanLine\r
   },\r
   {\r
@@ -64,8 +58,10 @@ LCD_INSTANCE mLcdTemplate = {
     {\r
       {\r
         HARDWARE_DEVICE_PATH, HW_VENDOR_DP,\r
-        (UINT8) (sizeof(VENDOR_DEVICE_PATH)),\r
-        (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8),\r
+        {\r
+          (UINT8)(sizeof (VENDOR_DEVICE_PATH)),\r
+          (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+        },\r
       },\r
       // Hardware Device Path for Lcd\r
       EFI_CALLER_ID_GUID // Use the driver's GUID\r
@@ -74,11 +70,13 @@ LCD_INSTANCE mLcdTemplate = {
     {\r
       END_DEVICE_PATH_TYPE,\r
       END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
-      sizeof(EFI_DEVICE_PATH_PROTOCOL),\r
-      0\r
+      {\r
+        sizeof (EFI_DEVICE_PATH_PROTOCOL),\r
+        0\r
+      }\r
     }\r
   },\r
-  (EFI_EVENT) NULL // ExitBootServicesEvent\r
+  (EFI_EVENT)NULL // ExitBootServicesEvent\r
 };\r
 \r
 EFI_STATUS\r
@@ -88,7 +86,7 @@ LcdInstanceContructor (
 {\r
   LCD_INSTANCE* Instance;\r
 \r
-  Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate);\r
+  Instance = AllocateCopyPool (sizeof (LCD_INSTANCE), &mLcdTemplate);\r
   if (Instance == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
@@ -115,25 +113,24 @@ InitializeDisplay (
   UINTN                  VramSize;\r
 \r
   Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
   // Setup the LCD\r
   Status = LcdInitialize (VramBaseAddress);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto EXIT_ERROR_LCD_SHUTDOWN;\r
   }\r
 \r
   Status = LcdPlatformInitializeDisplay (Instance->Handle);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto EXIT_ERROR_LCD_SHUTDOWN;\r
   }\r
 \r
   // Setup all the relevant mode information\r
-  Instance->Gop.Mode->SizeOfInfo      = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+  Instance->Gop.Mode->SizeOfInfo      = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
   Instance->Gop.Mode->FrameBufferBase = VramBaseAddress;\r
-  Instance->Gop.Mode->FrameBufferSize = VramSize;\r
 \r
   // Set the flag before changing the mode, to avoid infinite loops\r
   mDisplayInitialized = TRUE;\r
@@ -142,7 +139,8 @@ InitializeDisplay (
   goto EXIT;\r
 \r
 EXIT_ERROR_LCD_SHUTDOWN:\r
-  DEBUG((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status));\r
+  DEBUG ((DEBUG_ERROR, "InitializeDisplay: ERROR - Can not initialise the display. Exit Status=%r\n", Status));\r
+\r
   LcdShutdown ();\r
 \r
 EXIT:\r
@@ -159,176 +157,201 @@ LcdGraphicsOutputDxeInitialize (
   EFI_STATUS  Status = EFI_SUCCESS;\r
   LCD_INSTANCE* Instance;\r
 \r
+  Status = LcdIdentify ();\r
+  if (EFI_ERROR (Status)) {\r
+    goto EXIT;\r
+  }\r
+\r
   Status = LcdInstanceContructor (&Instance);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     goto EXIT;\r
   }\r
 \r
-       // Install the Graphics Output Protocol and the Device Path\r
-       Status = gBS->InstallMultipleProtocolInterfaces(\r
-                       &Instance->Handle,\r
-                       &gEfiGraphicsOutputProtocolGuid, &Instance->Gop,\r
-                       &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,\r
-                       NULL\r
-          );\r
-\r
-       if (EFI_ERROR(Status)) {\r
-         DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));\r
-               goto EXIT;\r
-       }\r
-\r
-       // Register for an ExitBootServicesEvent\r
-       // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,\r
-       // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.\r
-       Status = gBS->CreateEvent (\r
-           EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
-           TPL_NOTIFY,\r
-           LcdGraphicsExitBootServicesEvent, NULL,\r
-                       &Instance->ExitBootServicesEvent\r
-                       );\r
-\r
-       if (EFI_ERROR(Status)) {\r
-         DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));\r
-               goto EXIT_ERROR_UNINSTALL_PROTOCOL;\r
-       }\r
-\r
-       // To get here, everything must be fine, so just exit\r
-       goto EXIT;\r
+  // Install the Graphics Output Protocol and the Device Path\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Instance->Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  &Instance->Gop,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &Instance->DevicePath,\r
+                  NULL\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "LcdGraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));\r
+    goto EXIT;\r
+  }\r
+\r
+  // Register for an ExitBootServicesEvent\r
+  // When ExitBootServices starts, this function will make sure that the\r
+  // graphics driver shuts down properly, i.e. it will free up all\r
+  // allocated memory and perform any necessary hardware re-configuration.\r
+  Status = gBS->CreateEvent (\r
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
+                  TPL_NOTIFY,\r
+                  LcdGraphicsExitBootServicesEvent,\r
+                  NULL,\r
+                  &Instance->ExitBootServicesEvent\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "LcdGraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));\r
+    goto EXIT_ERROR_UNINSTALL_PROTOCOL;\r
+  }\r
+\r
+  // To get here, everything must be fine, so just exit\r
+  goto EXIT;\r
 \r
 EXIT_ERROR_UNINSTALL_PROTOCOL:\r
-       /* The following function could return an error message,\r
-        * however, to get here something must have gone wrong already,\r
-        * so preserve the original error, i.e. don't change\r
-        * the Status variable, even it fails to uninstall the protocol.\r
-        */\r
-       gBS->UninstallMultipleProtocolInterfaces (\r
-           Instance->Handle,\r
-           &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol\r
-           &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,     // Uninstall device path\r
-           NULL\r
-           );\r
+  // The following function could return an error message,\r
+  // however, to get here something must have gone wrong already,\r
+  // so preserve the original error, i.e. don't change\r
+  // the Status variable, even it fails to uninstall the protocol.\r
+  gBS->UninstallMultipleProtocolInterfaces (\r
+         Instance->Handle,\r
+         &gEfiGraphicsOutputProtocolGuid,\r
+         &Instance->Gop, // Uninstall Graphics Output protocol\r
+         &gEfiDevicePathProtocolGuid,\r
+         &Instance->DevicePath,     // Uninstall device path\r
+         NULL\r
+         );\r
 \r
 EXIT:\r
-       return Status;\r
-\r
+  return Status;\r
 }\r
 \r
-/***************************************\r
- * This function should be called\r
- * on Event: ExitBootServices\r
- * to free up memory, stop the driver\r
- * and uninstall the protocols\r
- ***************************************/\r
+/** This function should be called\r
+  on Event: ExitBootServices\r
+  to free up memory, stop the driver\r
+  and uninstall the protocols\r
+**/\r
 VOID\r
 LcdGraphicsExitBootServicesEvent (\r
   IN EFI_EVENT  Event,\r
   IN VOID       *Context\r
   )\r
 {\r
-       //TODO: Implement me\r
+  // By default, this PCD is FALSE. But if a platform starts a predefined OS\r
+  // that does not use a framebuffer then we might want to disable the display\r
+  // controller to avoid to display corrupted information on the screen.\r
+  if (FeaturePcdGet (PcdGopDisableOnExitBootServices)) {\r
+    // Turn-off the Display controller\r
+    LcdShutdown ();\r
+  }\r
 }\r
 \r
-/***************************************\r
- * GraphicsOutput Protocol function, mapping to\r
- * EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode\r
- ***************************************/\r
+/** GraphicsOutput Protocol function, mapping to\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL.QueryMode\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 LcdGraphicsQueryMode (\r
   IN EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,\r
-       IN UINT32                                  ModeNumber,\r
-       OUT UINTN                                  *SizeOfInfo,\r
-       OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   **Info\r
-       )\r
+  IN UINT32                                  ModeNumber,\r
+  OUT UINTN                                  *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   **Info\r
+  )\r
 {\r
-       EFI_STATUS Status = EFI_SUCCESS;\r
-       LCD_INSTANCE *Instance;\r
+  EFI_STATUS Status = EFI_SUCCESS;\r
+  LCD_INSTANCE *Instance;\r
 \r
-       Instance = LCD_INSTANCE_FROM_GOP_THIS(This);\r
+  Instance = LCD_INSTANCE_FROM_GOP_THIS (This);\r
 \r
   // Setup the hardware if not already done\r
-  if( !mDisplayInitialized ) {\r
-    Status = InitializeDisplay(Instance);\r
-    if (EFI_ERROR(Status)) {\r
+  if (!mDisplayInitialized) {\r
+    Status = InitializeDisplay (Instance);\r
+    if (EFI_ERROR (Status)) {\r
       goto EXIT;\r
     }\r
   }\r
 \r
-       // Error checking\r
-       if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) {\r
-         DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber ));\r
-               Status = EFI_INVALID_PARAMETER;\r
-               goto EXIT;\r
-       }\r
+  // Error checking\r
+  if ((This == NULL) ||\r
+      (Info == NULL) ||\r
+      (SizeOfInfo == NULL) ||\r
+      (ModeNumber >= This->Mode->MaxMode)) {\r
+    DEBUG ((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    goto EXIT;\r
+  }\r
 \r
-       *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
   if (*Info == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto EXIT;\r
   }\r
 \r
-  *SizeOfInfo = sizeofEFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
 \r
-  Status = LcdPlatformQueryMode (ModeNumber,*Info);\r
-  if (EFI_ERROR(Status)) {\r
-    FreePool(*Info);\r
+  Status = LcdPlatformQueryMode (ModeNumber, *Info);\r
+  if (EFI_ERROR (Status)) {\r
+    FreePool (*Info);\r
   }\r
 \r
 EXIT:\r
-       return Status;\r
+  return Status;\r
 }\r
 \r
-/***************************************\r
- * GraphicsOutput Protocol function, mapping to\r
- * EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode\r
- ***************************************/\r
+/** GraphicsOutput Protocol function, mapping to\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode\r
+**/\r
 EFI_STATUS\r
 EFIAPI\r
 LcdGraphicsSetMode (\r
   IN EFI_GRAPHICS_OUTPUT_PROTOCOL   *This,\r
-       IN UINT32                         ModeNumber\r
-       )\r
+  IN UINT32                         ModeNumber\r
+  )\r
 {\r
-       EFI_STATUS                      Status               = EFI_SUCCESS;\r
-       EFI_GRAPHICS_OUTPUT_BLT_PIXEL   FillColour;\r
-       LCD_INSTANCE* Instance;\r
+  EFI_STATUS                      Status = EFI_SUCCESS;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   FillColour;\r
+  LCD_INSTANCE*                   Instance;\r
+  LCD_BPP                         Bpp;\r
 \r
-       Instance = LCD_INSTANCE_FROM_GOP_THIS (This);\r
+  Instance = LCD_INSTANCE_FROM_GOP_THIS (This);\r
 \r
   // Setup the hardware if not already done\r
-  if(!mDisplayInitialized) {\r
+  if (!mDisplayInitialized) {\r
     Status = InitializeDisplay (Instance);\r
-    if (EFI_ERROR(Status)) {\r
+    if (EFI_ERROR (Status)) {\r
       goto EXIT;\r
     }\r
   }\r
 \r
   // Check if this mode is supported\r
-  if( ModeNumber >= This->Mode->MaxMode ) {\r
-    DEBUG((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber ));\r
+  if (ModeNumber >= This->Mode->MaxMode) {\r
+    DEBUG ((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Unsupported mode number %d .\n", ModeNumber));\r
     Status = EFI_UNSUPPORTED;\r
     goto EXIT;\r
   }\r
 \r
-       // Set the oscillator frequency to support the new mode\r
+  // Set the oscillator frequency to support the new mode\r
   Status = LcdPlatformSetMode (ModeNumber);\r
-  if (EFI_ERROR(Status)) {\r
+  if (EFI_ERROR (Status)) {\r
     Status = EFI_DEVICE_ERROR;\r
     goto EXIT;\r
   }\r
 \r
-       // Update the UEFI mode information\r
-       This->Mode->Mode = ModeNumber;\r
-       LcdPlatformQueryMode (ModeNumber,&Instance->ModeInfo);\r
+  // Update the UEFI mode information\r
+  This->Mode->Mode = ModeNumber;\r
+  LcdPlatformQueryMode (ModeNumber, &Instance->ModeInfo);\r
+  Status = LcdPlatformGetBpp (ModeNumber, &Bpp);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "LcdGraphicsSetMode: ERROR - Couldn't get bytes per pixel, status: %r\n", Status));\r
+    goto EXIT;\r
+  }\r
+  This->Mode->FrameBufferSize =  Instance->ModeInfo.VerticalResolution\r
+                                 * Instance->ModeInfo.PixelsPerScanLine\r
+                                 * GetBytesPerPixel (Bpp);\r
 \r
   // Set the hardware to the new mode\r
-       Status = LcdSetMode (ModeNumber);\r
-  if (EFI_ERROR(Status)) {\r
+  Status = LcdSetMode (ModeNumber);\r
+  if (EFI_ERROR (Status)) {\r
     Status = EFI_DEVICE_ERROR;\r
     goto EXIT;\r
   }\r
 \r
-       // The UEFI spec requires that we now clear the visible portions of the output display to black.\r
+  // The UEFI spec requires that we now clear the visible portions of the\r
+  // output display to black.\r
 \r
   // Set the fill colour to black\r
   SetMem (&FillColour, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0);\r
@@ -344,10 +367,11 @@ LcdGraphicsSetMode (
       0,\r
       This->Mode->Info->HorizontalResolution,\r
       This->Mode->Info->VerticalResolution,\r
-      0);\r
+      0\r
+      );\r
 \r
 EXIT:\r
-       return Status;\r
+  return Status;\r
 }\r
 \r
 UINTN\r
@@ -355,7 +379,7 @@ GetBytesPerPixel (
   IN  LCD_BPP       Bpp\r
   )\r
 {\r
-  switch(Bpp) {\r
+  switch (Bpp) {\r
   case LCD_BITS_PER_PIXEL_24:\r
     return 4;\r
 \r