]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/Library/HdLcd/HdLcd.c
ArmPlatformPkg: PCD to swap red/blue format for HDLCD
[mirror_edk2.git] / ArmPlatformPkg / Library / HdLcd / HdLcd.c
1 /** @file
2 This file contains the platform independent parts of HdLcd
3
4 Copyright (c) 2011-2018, ARM Ltd. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include <Library/DebugLib.h>
17 #include <Library/IoLib.h>
18 #include <Library/LcdHwLib.h>
19 #include <Library/LcdPlatformLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/PcdLib.h>
22
23 #include "HdLcd.h"
24
25 #define BYTES_PER_PIXEL 4
26
27 /** Initialize display.
28
29 @param[in] VramBaseAddress Address of the framebuffer.
30
31 @retval EFI_SUCCESS Display initialization successful.
32 **/
33 EFI_STATUS
34 LcdInitialize (
35 IN EFI_PHYSICAL_ADDRESS VramBaseAddress
36 )
37 {
38 // Disable the controller
39 MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE);
40
41 // Disable all interrupts
42 MmioWrite32 (HDLCD_REG_INT_MASK, 0);
43
44 // Define start of the VRAM. This never changes for any graphics mode
45 MmioWrite32 (HDLCD_REG_FB_BASE, (UINT32)VramBaseAddress);
46
47 // Setup various registers that never change
48 MmioWrite32 (HDLCD_REG_BUS_OPTIONS, (4 << 8) | HDLCD_BURST_8);
49
50 MmioWrite32 (HDLCD_REG_POLARITIES, HDLCD_DEFAULT_POLARITIES);
51
52 MmioWrite32 (
53 HDLCD_REG_PIXEL_FORMAT,
54 HDLCD_LITTLE_ENDIAN | HDLCD_4BYTES_PER_PIXEL
55 );
56
57 return EFI_SUCCESS;
58 }
59
60 /** Set requested mode of the display.
61
62 @param[in] ModeNumber Display mode number.
63
64 @retval EFI_SUCCESS Display mode set successfully.
65 @retval !(EFI_SUCCESS) Other errors.
66 **/
67 EFI_STATUS
68 LcdSetMode (
69 IN UINT32 ModeNumber
70 )
71 {
72 EFI_STATUS Status;
73 SCAN_TIMINGS *Horizontal;
74 SCAN_TIMINGS *Vertical;
75
76 EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
77
78 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;
79
80 // Set the video mode timings and other relevant information
81 Status = LcdPlatformGetTimings (
82 ModeNumber,
83 &Horizontal,
84 &Vertical
85 );
86 if (EFI_ERROR (Status)) {
87 ASSERT_EFI_ERROR (Status);
88 return Status;
89 }
90
91 ASSERT (Horizontal != NULL);
92 ASSERT (Vertical != NULL);
93
94 // Get the pixel format information.
95 Status = LcdPlatformQueryMode (ModeNumber, &ModeInfo);
96 if (EFI_ERROR (Status)) {
97 ASSERT_EFI_ERROR (Status);
98 return Status;
99 }
100
101 // By default PcdArmHdLcdSwapBlueRedSelect is set to false
102 // However on the Juno platform HW lines for BLUE and RED are swapped
103 // Therefore PcdArmHdLcdSwapBlueRedSelect is set to TRUE for the Juno platform
104 PixelFormat = FixedPcdGetBool (PcdArmHdLcdSwapBlueRedSelect)
105 ? PixelRedGreenBlueReserved8BitPerColor
106 : PixelBlueGreenRedReserved8BitPerColor;
107
108 if (ModeInfo.PixelFormat == PixelFormat) {
109 MmioWrite32 (HDLCD_REG_RED_SELECT, (8 << 8) | 16);
110 MmioWrite32 (HDLCD_REG_BLUE_SELECT, (8 << 8) | 0);
111 } else {
112 MmioWrite32 (HDLCD_REG_BLUE_SELECT, (8 << 8) | 16);
113 MmioWrite32 (HDLCD_REG_RED_SELECT, (8 << 8) | 0);
114 }
115
116 MmioWrite32 (HDLCD_REG_GREEN_SELECT, (8 << 8) | 8);
117
118 // Disable the controller
119 MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE);
120
121 // Update the frame buffer information with the new settings
122 MmioWrite32 (
123 HDLCD_REG_FB_LINE_LENGTH,
124 Horizontal->Resolution * BYTES_PER_PIXEL
125 );
126
127 MmioWrite32 (
128 HDLCD_REG_FB_LINE_PITCH,
129 Horizontal->Resolution * BYTES_PER_PIXEL
130 );
131
132 MmioWrite32 (HDLCD_REG_FB_LINE_COUNT, Vertical->Resolution - 1);
133
134 // Set the vertical timing information
135 MmioWrite32 (HDLCD_REG_V_SYNC, Vertical->Sync);
136 MmioWrite32 (HDLCD_REG_V_BACK_PORCH, Vertical->BackPorch);
137 MmioWrite32 (HDLCD_REG_V_DATA, Vertical->Resolution - 1);
138 MmioWrite32 (HDLCD_REG_V_FRONT_PORCH, Vertical->FrontPorch);
139
140 // Set the horizontal timing information
141 MmioWrite32 (HDLCD_REG_H_SYNC, Horizontal->Sync);
142 MmioWrite32 (HDLCD_REG_H_BACK_PORCH, Horizontal->BackPorch);
143 MmioWrite32 (HDLCD_REG_H_DATA, Horizontal->Resolution - 1);
144 MmioWrite32 (HDLCD_REG_H_FRONT_PORCH, Horizontal->FrontPorch);
145
146 // Enable the controller
147 MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_ENABLE);
148
149 return EFI_SUCCESS;
150 }
151
152 /** De-initializes the display.
153 **/
154 VOID
155 LcdShutdown (
156 VOID
157 )
158 {
159 // Disable the controller
160 MmioWrite32 (HDLCD_REG_COMMAND, HDLCD_DISABLE);
161 }
162
163 /** Check for presence of HDLCD.
164
165 @retval EFI_SUCCESS Returns success if platform implements a HDLCD
166 controller.
167 @retval EFI_NOT_FOUND HDLCD display controller not found on the
168 platform.
169 **/
170 EFI_STATUS
171 LcdIdentify (
172 VOID
173 )
174 {
175 if ((MmioRead32 (HDLCD_REG_VERSION) >> 16) == HDLCD_PRODUCT_ID) {
176 return EFI_SUCCESS;
177 }
178
179 return EFI_NOT_FOUND;
180 }