Home | History | Annotate | Download | only in HdLcdArmVExpressLib
      1 /**
      2 
      3   Copyright (c) 2012, ARM Ltd. All rights reserved.
      4 
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <PiDxe.h>
     16 
     17 #include <Library/ArmPlatformSysConfigLib.h>
     18 #include <Library/IoLib.h>
     19 #include <Library/PcdLib.h>
     20 #include <Library/DebugLib.h>
     21 #include <Library/LcdPlatformLib.h>
     22 #include <Library/MemoryAllocationLib.h>
     23 #include <Library/UefiBootServicesTableLib.h>
     24 
     25 #include <Protocol/Cpu.h>
     26 #include <Protocol/EdidDiscovered.h>
     27 #include <Protocol/EdidActive.h>
     28 
     29 #include <ArmPlatform.h>
     30 
     31 typedef struct {
     32   UINT32                     Mode;
     33   UINT32                     HorizontalResolution;
     34   UINT32                     VerticalResolution;
     35   LCD_BPP                    Bpp;
     36   UINT32                     OscFreq;
     37 
     38   // These are used by HDLCD
     39   UINT32                     HSync;
     40   UINT32                     HBackPorch;
     41   UINT32                     HFrontPorch;
     42   UINT32                     VSync;
     43   UINT32                     VBackPorch;
     44   UINT32                     VFrontPorch;
     45 } LCD_RESOLUTION;
     46 
     47 
     48 LCD_RESOLUTION mResolutions[] = {
     49   { // Mode 0 : VGA : 640 x 480 x 24 bpp
     50     VGA, VGA_H_RES_PIXELS, VGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, VGA_OSC_FREQUENCY,
     51     VGA_H_SYNC, VGA_H_BACK_PORCH, VGA_H_FRONT_PORCH,
     52     VGA_V_SYNC, VGA_V_BACK_PORCH, VGA_V_FRONT_PORCH
     53   },
     54   { // Mode 1 : SVGA : 800 x 600 x 24 bpp
     55     SVGA, SVGA_H_RES_PIXELS, SVGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, SVGA_OSC_FREQUENCY,
     56     SVGA_H_SYNC, SVGA_H_BACK_PORCH, SVGA_H_FRONT_PORCH,
     57     SVGA_V_SYNC, SVGA_V_BACK_PORCH, SVGA_V_FRONT_PORCH
     58   },
     59   { // Mode 2 : XGA : 1024 x 768 x 24 bpp
     60     XGA, XGA_H_RES_PIXELS, XGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, XGA_OSC_FREQUENCY,
     61     XGA_H_SYNC, XGA_H_BACK_PORCH, XGA_H_FRONT_PORCH,
     62     XGA_V_SYNC, XGA_V_BACK_PORCH, XGA_V_FRONT_PORCH
     63   },
     64   { // Mode 3 : SXGA : 1280 x 1024 x 24 bpp
     65     SXGA, SXGA_H_RES_PIXELS, SXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (SXGA_OSC_FREQUENCY/2),
     66     SXGA_H_SYNC, SXGA_H_BACK_PORCH, SXGA_H_FRONT_PORCH,
     67     SXGA_V_SYNC, SXGA_V_BACK_PORCH, SXGA_V_FRONT_PORCH
     68   },
     69   { // Mode 4 : UXGA : 1600 x 1200 x 24 bpp
     70     UXGA, UXGA_H_RES_PIXELS, UXGA_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (UXGA_OSC_FREQUENCY/2),
     71     UXGA_H_SYNC, UXGA_H_BACK_PORCH, UXGA_H_FRONT_PORCH,
     72     UXGA_V_SYNC, UXGA_V_BACK_PORCH, UXGA_V_FRONT_PORCH
     73   },
     74   { // Mode 5 : HD : 1920 x 1080 x 24 bpp
     75     HD, HD_H_RES_PIXELS, HD_V_RES_PIXELS, LCD_BITS_PER_PIXEL_24, (HD_OSC_FREQUENCY/2),
     76     HD_H_SYNC, HD_H_BACK_PORCH, HD_H_FRONT_PORCH,
     77     HD_V_SYNC, HD_V_BACK_PORCH, HD_V_FRONT_PORCH
     78   }
     79 };
     80 
     81 EFI_EDID_DISCOVERED_PROTOCOL  mEdidDiscovered = {
     82   0,
     83   NULL
     84 };
     85 
     86 EFI_EDID_ACTIVE_PROTOCOL      mEdidActive = {
     87   0,
     88   NULL
     89 };
     90 
     91 EFI_STATUS
     92 LcdPlatformInitializeDisplay (
     93   IN EFI_HANDLE   Handle
     94   )
     95 {
     96   EFI_STATUS  Status;
     97 
     98   // Set the FPGA multiplexer to select the video output from the motherboard or the daughterboard
     99   Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE);
    100   if (EFI_ERROR(Status)) {
    101     return Status;
    102   }
    103 
    104   // Install the EDID Protocols
    105   Status = gBS->InstallMultipleProtocolInterfaces (
    106     &Handle,
    107     &gEfiEdidDiscoveredProtocolGuid,  &mEdidDiscovered,
    108     &gEfiEdidActiveProtocolGuid,      &mEdidActive,
    109     NULL
    110   );
    111 
    112   return Status;
    113 }
    114 
    115 EFI_STATUS
    116 LcdPlatformGetVram (
    117   OUT EFI_PHYSICAL_ADDRESS*  VramBaseAddress,
    118   OUT UINTN*                 VramSize
    119   )
    120 {
    121   EFI_STATUS              Status;
    122   EFI_CPU_ARCH_PROTOCOL  *Cpu;
    123   EFI_ALLOCATE_TYPE       AllocationType;
    124 
    125   // Set the vram size
    126   *VramSize = LCD_VRAM_SIZE;
    127 
    128   *VramBaseAddress = (EFI_PHYSICAL_ADDRESS)LCD_VRAM_CORE_TILE_BASE;
    129 
    130   // Allocate the VRAM from the DRAM so that nobody else uses it.
    131   if (*VramBaseAddress == 0) {
    132     AllocationType = AllocateAnyPages;
    133   } else {
    134     AllocationType = AllocateAddress;
    135   }
    136   Status = gBS->AllocatePages (AllocationType, EfiBootServicesData, EFI_SIZE_TO_PAGES(((UINTN)LCD_VRAM_SIZE)), VramBaseAddress);
    137   if (EFI_ERROR(Status)) {
    138     return Status;
    139   }
    140 
    141   // Ensure the Cpu architectural protocol is already installed
    142   Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
    143   ASSERT_EFI_ERROR(Status);
    144 
    145   // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.
    146   Status = Cpu->SetMemoryAttributes (Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);
    147   ASSERT_EFI_ERROR(Status);
    148   if (EFI_ERROR(Status)) {
    149     gBS->FreePool (VramBaseAddress);
    150     return Status;
    151   }
    152 
    153   return EFI_SUCCESS;
    154 }
    155 
    156 UINT32
    157 LcdPlatformGetMaxMode (
    158   VOID
    159   )
    160 {
    161   //
    162   // The following line will report correctly the total number of graphics modes
    163   // that could be supported by the graphics driver:
    164   //
    165   return (sizeof(mResolutions) / sizeof(LCD_RESOLUTION));
    166 }
    167 
    168 EFI_STATUS
    169 LcdPlatformSetMode (
    170   IN UINT32                         ModeNumber
    171   )
    172 {
    173   EFI_STATUS            Status;
    174 
    175   if (ModeNumber >= LcdPlatformGetMaxMode ()) {
    176     return EFI_INVALID_PARAMETER;
    177   }
    178 
    179   // Set the video mode oscillator
    180   do {
    181     Status = ArmPlatformSysConfigSetDevice (SYS_CFG_OSC_SITE1, PcdGet32(PcdHdLcdVideoModeOscId), mResolutions[ModeNumber].OscFreq);
    182   } while (Status == EFI_TIMEOUT);
    183   if (EFI_ERROR(Status)) {
    184     ASSERT_EFI_ERROR (Status);
    185     return Status;
    186   }
    187 
    188   // Set the DVI into the new mode
    189   do {
    190     Status = ArmPlatformSysConfigSet (SYS_CFG_DVIMODE, mResolutions[ModeNumber].Mode);
    191   } while (Status == EFI_TIMEOUT);
    192   if (EFI_ERROR(Status)) {
    193     ASSERT_EFI_ERROR (Status);
    194     return Status;
    195   }
    196 
    197   // Set the multiplexer
    198   Status = ArmPlatformSysConfigSet (SYS_CFG_MUXFPGA, ARM_VE_DAUGHTERBOARD_1_SITE);
    199   if (EFI_ERROR(Status)) {
    200     ASSERT_EFI_ERROR (Status);
    201     return Status;
    202   }
    203 
    204   return Status;
    205 }
    206 
    207 EFI_STATUS
    208 LcdPlatformQueryMode (
    209   IN  UINT32                                ModeNumber,
    210   OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info
    211   )
    212 {
    213   if (ModeNumber >= LcdPlatformGetMaxMode ()) {
    214     return EFI_INVALID_PARAMETER;
    215   }
    216 
    217   Info->Version = 0;
    218   Info->HorizontalResolution = mResolutions[ModeNumber].HorizontalResolution;
    219   Info->VerticalResolution = mResolutions[ModeNumber].VerticalResolution;
    220   Info->PixelsPerScanLine = mResolutions[ModeNumber].HorizontalResolution;
    221 
    222   switch (mResolutions[ModeNumber].Bpp) {
    223     case LCD_BITS_PER_PIXEL_24:
    224       Info->PixelFormat                   = PixelRedGreenBlueReserved8BitPerColor;
    225       Info->PixelInformation.RedMask      = LCD_24BPP_RED_MASK;
    226       Info->PixelInformation.GreenMask    = LCD_24BPP_GREEN_MASK;
    227       Info->PixelInformation.BlueMask     = LCD_24BPP_BLUE_MASK;
    228       Info->PixelInformation.ReservedMask = LCD_24BPP_RESERVED_MASK;
    229       break;
    230 
    231     case LCD_BITS_PER_PIXEL_16_555:
    232     case LCD_BITS_PER_PIXEL_16_565:
    233     case LCD_BITS_PER_PIXEL_12_444:
    234     case LCD_BITS_PER_PIXEL_8:
    235     case LCD_BITS_PER_PIXEL_4:
    236     case LCD_BITS_PER_PIXEL_2:
    237     case LCD_BITS_PER_PIXEL_1:
    238     default:
    239       // These are not supported
    240       ASSERT(FALSE);
    241       break;
    242   }
    243 
    244   return EFI_SUCCESS;
    245 }
    246 
    247 EFI_STATUS
    248 LcdPlatformGetTimings (
    249   IN  UINT32                              ModeNumber,
    250   OUT UINT32*                             HRes,
    251   OUT UINT32*                             HSync,
    252   OUT UINT32*                             HBackPorch,
    253   OUT UINT32*                             HFrontPorch,
    254   OUT UINT32*                             VRes,
    255   OUT UINT32*                             VSync,
    256   OUT UINT32*                             VBackPorch,
    257   OUT UINT32*                             VFrontPorch
    258   )
    259 {
    260   if (ModeNumber >= LcdPlatformGetMaxMode ()) {
    261     return EFI_INVALID_PARAMETER;
    262   }
    263 
    264   *HRes           = mResolutions[ModeNumber].HorizontalResolution;
    265   *HSync          = mResolutions[ModeNumber].HSync;
    266   *HBackPorch     = mResolutions[ModeNumber].HBackPorch;
    267   *HFrontPorch    = mResolutions[ModeNumber].HFrontPorch;
    268   *VRes           = mResolutions[ModeNumber].VerticalResolution;
    269   *VSync          = mResolutions[ModeNumber].VSync;
    270   *VBackPorch     = mResolutions[ModeNumber].VBackPorch;
    271   *VFrontPorch    = mResolutions[ModeNumber].VFrontPorch;
    272 
    273   return EFI_SUCCESS;
    274 }
    275 
    276 EFI_STATUS
    277 LcdPlatformGetBpp (
    278   IN  UINT32                              ModeNumber,
    279   OUT LCD_BPP  *                          Bpp
    280   )
    281 {
    282   if (ModeNumber >= LcdPlatformGetMaxMode ()) {
    283     return EFI_INVALID_PARAMETER;
    284   }
    285 
    286   *Bpp = mResolutions[ModeNumber].Bpp;
    287 
    288   return EFI_SUCCESS;
    289 }
    290