]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPlatformPkg/ArmVExpressPkg/Library/PL111LcdArmVExpressLib/PL111LcdArmVExpress.c
ArmPlatformPkg/PL111LcdArmVExpressLib: use write-combine mapping for VRAM
[mirror_edk2.git] / ArmPlatformPkg / ArmVExpressPkg / Library / PL111LcdArmVExpressLib / PL111LcdArmVExpress.c
index 6ae5da99975e62387a8c7d9ddddd3c3ecef5d060..3f3ceb3d2fa82f614e0c6dac8455c117745cf3a6 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>\r
+  Copyright (c) 2011-2015, 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
 #include <Library/IoLib.h>\r
 #include <Library/PcdLib.h>\r
 #include <Library/DebugLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
 #include <Library/LcdPlatformLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 \r
-#include <Protocol/Cpu.h>\r
+#include <Protocol/EdidDiscovered.h>\r
+#include <Protocol/EdidActive.h>\r
 \r
 #include <ArmPlatform.h>\r
 \r
-#define PL111_CLCD_SITE ARM_VE_DAUGHTERBOARD_1_SITE\r
-\r
 typedef struct {\r
   UINT32                     Mode;\r
   UINT32                     HorizontalResolution;\r
@@ -43,94 +43,119 @@ typedef struct {
 \r
 \r
 LCD_RESOLUTION mResolutions[] = {\r
-    { // Mode 0 : VGA : 640 x 480 x 24 bpp\r
-        VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY,\r
-        VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
-        VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 1 : SVGA : 800 x 600 x 24 bpp\r
-        SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY,\r
-        SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
-        SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 2 : XGA : 1024 x 768 x 24 bpp\r
-        XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY,\r
-        XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
-        XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp\r
-        SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2),\r
-        SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH,\r
-        SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp\r
-        UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2),\r
-        UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH,\r
-        UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 5 : HD : 1920 x 1080 x 24 bpp\r
-        HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2),\r
-        HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH,\r
-        HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH\r
-    },\r
-    { // Mode 6 : VGA : 640 x 480 x 16 bpp (565 Mode)\r
-        VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, VGA_OSC_FREQUENCY,\r
-        VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
-        VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 7 : SVGA : 800 x 600 x 16 bpp (565 Mode)\r
-        SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, SVGA_OSC_FREQUENCY,\r
-        SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
-        SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 8 : XGA : 1024 x 768 x 16 bpp (565 Mode)\r
-        XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, XGA_OSC_FREQUENCY,\r
-        XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
-        XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 9 : VGA : 640 x 480 x 15 bpp\r
-        VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, VGA_OSC_FREQUENCY,\r
-        VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
-        VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 10 : SVGA : 800 x 600 x 15 bpp\r
-        SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, SVGA_OSC_FREQUENCY,\r
-        SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
-        SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 11 : XGA : 1024 x 768 x 15 bpp\r
-        XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, XGA_OSC_FREQUENCY,\r
-        XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
-        XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 12 : XGA : 1024 x 768 x 15 bpp - All the timing info is derived from Linux Kernel Driver Settings\r
-        XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, 63500000,\r
-        XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
-        XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 13 : VGA : 640 x 480 x 12 bpp (444 Mode)\r
-        VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, VGA_OSC_FREQUENCY,\r
-        VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
-        VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 14 : SVGA : 800 x 600 x 12 bpp (444 Mode)\r
-        SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, SVGA_OSC_FREQUENCY,\r
-        SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
-        SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
-    },\r
-    { // Mode 15 : XGA : 1024 x 768 x 12 bpp (444 Mode)\r
-        XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, XGA_OSC_FREQUENCY,\r
-        XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
-        XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
-    }\r
+  { // Mode 0 : VGA : 640 x 480 x 24 bpp\r
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY,\r
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 1 : SVGA : 800 x 600 x 24 bpp\r
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY,\r
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 2 : XGA : 1024 x 768 x 24 bpp\r
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY,\r
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp\r
+      SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2),\r
+      SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH,\r
+      SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp\r
+      UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2),\r
+      UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH,\r
+      UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 5 : HD : 1920 x 1080 x 24 bpp\r
+      HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2),\r
+      HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH,\r
+      HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH\r
+  },\r
+  { // Mode 6 : VGA : 640 x 480 x 16 bpp (565 Mode)\r
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, VGA_OSC_FREQUENCY,\r
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 7 : SVGA : 800 x 600 x 16 bpp (565 Mode)\r
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, SVGA_OSC_FREQUENCY,\r
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 8 : XGA : 1024 x 768 x 16 bpp (565 Mode)\r
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_565, XGA_OSC_FREQUENCY,\r
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 9 : VGA : 640 x 480 x 15 bpp\r
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, VGA_OSC_FREQUENCY,\r
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 10 : SVGA : 800 x 600 x 15 bpp\r
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, SVGA_OSC_FREQUENCY,\r
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 11 : XGA : 1024 x 768 x 15 bpp\r
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, XGA_OSC_FREQUENCY,\r
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 12 : XGA : 1024 x 768 x 15 bpp - All the timing info is derived from Linux Kernel Driver Settings\r
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_16_555, 63500000,\r
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 13 : VGA : 640 x 480 x 12 bpp (444 Mode)\r
+      VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, VGA_OSC_FREQUENCY,\r
+      VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,\r
+      VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 14 : SVGA : 800 x 600 x 12 bpp (444 Mode)\r
+      SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, SVGA_OSC_FREQUENCY,\r
+      SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,\r
+      SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH\r
+  },\r
+  { // Mode 15 : XGA : 1024 x 768 x 12 bpp (444 Mode)\r
+      XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_12_444, XGA_OSC_FREQUENCY,\r
+      XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,\r
+      XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH\r
+  }\r
 };\r
 \r
+EFI_EDID_DISCOVERED_PROTOCOL  mEdidDiscovered = {\r
+  0,\r
+  NULL\r
+};\r
+\r
+EFI_EDID_ACTIVE_PROTOCOL      mEdidActive = {\r
+  0,\r
+  NULL\r
+};\r
+\r
+\r
 EFI_STATUS\r
 LcdPlatformInitializeDisplay (\r
-  VOID\r
-  ) {\r
+  IN EFI_HANDLE   Handle\r
+  )\r
+{\r
+  EFI_STATUS  Status;\r
+\r
   // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard\r
-  return ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE);\r
+  Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, PL111_CLCD_SITE);\r
+  if (!EFI_ERROR(Status)) {\r
+    // Install the EDID Protocols\r
+    Status = gBS->InstallMultipleProtocolInterfaces(\r
+      &Handle,\r
+      &gEfiEdidDiscoveredProtocolGuid,  &mEdidDiscovered,\r
+      &gEfiEdidActiveProtocolGuid,      &mEdidActive,\r
+      NULL\r
+    );\r
+  }\r
+\r
+  return Status;\r
 }\r
 \r
 EFI_STATUS\r
@@ -140,7 +165,8 @@ LcdPlatformGetVram (
   )\r
 {\r
   EFI_STATUS              Status;\r
-  EFI_CPU_ARCH_PROTOCOL  *Cpu;\r
+\r
+  Status = EFI_SUCCESS;\r
 \r
   // Is it on the motherboard or on the daughterboard?\r
   switch(PL111_CLCD_SITE) {\r
@@ -160,15 +186,12 @@ LcdPlatformGetVram (
       return Status;\r
     }\r
 \r
-    // Ensure the Cpu architectural protocol is already installed\r
-    Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);\r
-    ASSERT_EFI_ERROR(Status);\r
-\r
-    // Mark the VRAM as un-cachable. The VRAM is inside the DRAM, which is cachable.\r
-    Status = Cpu->SetMemoryAttributes(Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);\r
+    // Mark the VRAM as write-combining. The VRAM is inside the DRAM, which is cacheable.\r
+    Status = gDS->SetMemorySpaceAttributes (*VramBaseAddress, *VramSize,\r
+                    EFI_MEMORY_WC);\r
     ASSERT_EFI_ERROR(Status);\r
     if (EFI_ERROR(Status)) {\r
-      gBS->FreePool(VramBaseAddress);\r
+      gBS->FreePages (*VramBaseAddress, EFI_SIZE_TO_PAGES(*VramSize));\r
       return Status;\r
     }\r
     break;\r
@@ -195,7 +218,7 @@ LcdPlatformGetMaxMode (
   // This could be because the specific implementation of PL111 has certain limitations.\r
 \r
   // Set the maximum mode allowed\r
-  return (PcdGet32(PcdPL111MaxMode));\r
+  return (PcdGet32(PcdPL111LcdMaxMode));\r
 }\r
 \r
 EFI_STATUS\r
@@ -207,6 +230,7 @@ LcdPlatformSetMode (
   UINT32                LcdSite;\r
   UINT32                OscillatorId;\r
   SYS_CONFIG_FUNCTION   Function;\r
+  UINT32                SysId;\r
 \r
   if (ModeNumber >= LcdPlatformGetMaxMode ()) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -221,7 +245,7 @@ LcdPlatformSetMode (
     break;\r
   case ARM_VE_DAUGHTERBOARD_1_SITE:\r
     Function = SYS_CFG_OSC_SITE1;\r
-    OscillatorId = PL111_CLCD_CORE_TILE_VIDEO_MODE_OSC_ID;\r
+    OscillatorId = (UINT32)PcdGet32(PcdPL111LcdVideoModeOscId);\r
     break;\r
   default:\r
     return EFI_UNSUPPORTED;\r
@@ -234,11 +258,21 @@ LcdPlatformSetMode (
     return Status;\r
   }\r
 \r
-  // Set the DVI into the new mode\r
-  Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);\r
-  if (EFI_ERROR(Status)) {\r
-    ASSERT_EFI_ERROR (Status);\r
-    return Status;\r
+  // The FVP foundation model does not have an LCD.\r
+  // On the FVP models the GIC variant in encoded in bits [15:12].\r
+  // Note: The DVI Mode is not modelled by RTSM or FVP models.\r
+  SysId = MmioRead32 (ARM_VE_SYS_ID_REG);\r
+  if (SysId != ARM_RTSM_SYS_ID) {\r
+    // Take out the FVP GIC variant to reduce the permutations.\r
+    SysId &= ~ARM_FVP_SYS_ID_VARIANT_MASK;\r
+    if (SysId != ARM_FVP_BASE_BOARD_SYS_ID) {\r
+      // Set the DVI into the new mode\r
+      Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);\r
+      if (EFI_ERROR(Status)) {\r
+        ASSERT_EFI_ERROR (Status);\r
+        return Status;\r
+      }\r
+    }\r
   }\r
 \r
   // Set the multiplexer\r