]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.c
ShellPkg: Remove trailing white space
[mirror_edk2.git] / ArmPlatformPkg / Library / ArmMaliDp / ArmMaliDp.c
1 /** @file
2
3 ARM Mali DP 500/550/650 display controller driver
4
5 Copyright (c) 2017-2018, Arm Limited. All rights reserved.<BR>
6
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include <Library/DebugLib.h>
18 #include <Library/IoLib.h>
19 #include <Library/LcdHwLib.h>
20 #include <Library/LcdPlatformLib.h>
21 #include <Library/MemoryAllocationLib.h>
22
23 #include "ArmMaliDp.h"
24
25 // CORE_ID of the MALI DP
26 STATIC UINT32 mDpDeviceId;
27
28 /** Disable the graphics layer
29
30 This is done by clearing the EN bit of the LG_CONTROL register.
31 **/
32 STATIC
33 VOID
34 LayerGraphicsDisable (VOID)
35 {
36 MmioAnd32 (DP_BASE + DP_DE_LG_CONTROL, ~DP_DE_LG_ENABLE);
37 }
38
39 /** Enable the graphics layer
40
41 This is done by setting the EN bit of the LG_CONTROL register.
42 **/
43 STATIC
44 VOID
45 LayerGraphicsEnable (VOID)
46 {
47 MmioOr32 (DP_BASE + DP_DE_LG_CONTROL, DP_DE_LG_ENABLE);
48 }
49
50 /** Set the frame address of the graphics layer.
51
52 @param[in] FrameBaseAddress Address of the data buffer to be used as
53 a framebuffer.
54 **/
55 STATIC
56 VOID
57 LayerGraphicsSetFrame (
58 IN CONST EFI_PHYSICAL_ADDRESS FrameBaseAddress
59 )
60 {
61 // Disable the graphics layer.
62 LayerGraphicsDisable ();
63
64 // Set up memory address of the data buffer for graphics layer.
65 // write lower bits of the address.
66 MmioWrite32 (
67 DP_BASE + DP_DE_LG_PTR_LOW,
68 DP_DE_LG_PTR_LOW_MASK & FrameBaseAddress
69 );
70
71 // Write higher bits of the address.
72 MmioWrite32 (
73 DP_BASE + DP_DE_LG_PTR_HIGH,
74 (UINT32)(FrameBaseAddress >> DP_DE_LG_PTR_HIGH_SHIFT)
75 );
76
77 // Enable the graphics layer.
78 LayerGraphicsEnable ();
79 }
80
81 /** Configures various graphics layer characteristics.
82
83 @param[in] UefiGfxPixelFormat This must be either
84 PixelBlueGreenRedReserved8BitPerColor
85 OR
86 PixelRedGreenBlueReserved8BitPerColor
87 @param[in] HRes Horizontal resolution of the graphics layer.
88 @param[in] VRes Vertical resolution of the graphics layer.
89 **/
90 STATIC
91 VOID
92 LayerGraphicsConfig (
93 IN CONST EFI_GRAPHICS_PIXEL_FORMAT UefiGfxPixelFormat,
94 IN CONST UINT32 HRes,
95 IN CONST UINT32 VRes
96 )
97 {
98 UINT32 PixelFormat;
99
100 // Disable the graphics layer before configuring any settings.
101 LayerGraphicsDisable ();
102
103 // Setup graphics layer size.
104 MmioWrite32 (DP_BASE + DP_DE_LG_IN_SIZE, FRAME_IN_SIZE (HRes, VRes));
105
106 // Setup graphics layer composition size.
107 MmioWrite32 (DP_BASE + DP_DE_LG_CMP_SIZE, FRAME_CMP_SIZE (HRes, VRes));
108
109 // Setup memory stride (total visible pixels on a line * 4).
110 MmioWrite32 (DP_BASE + DP_DE_LG_H_STRIDE, (HRes * sizeof (UINT32)));
111
112 // Set the format.
113
114 // In PixelBlueGreenRedReserved8BitPerColor format, byte 0 represents blue,
115 // byte 1 represents green, byte 2 represents red, and byte 3 is reserved
116 // which is equivalent to XRGB format of the DP500/DP550/DP650. Whereas
117 // PixelRedGreenBlueReserved8BitPerColor is equivalent to XBGR of the
118 // DP500/DP550/DP650.
119 if (UefiGfxPixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
120 PixelFormat = (mDpDeviceId == MALIDP_500) ? DP_PIXEL_FORMAT_DP500_XRGB_8888
121 : DP_PIXEL_FORMAT_XRGB_8888;
122 } else {
123 PixelFormat = (mDpDeviceId == MALIDP_500) ? DP_PIXEL_FORMAT_DP500_XBGR_8888
124 : DP_PIXEL_FORMAT_XBGR_8888;
125 }
126
127 MmioWrite32 (DP_BASE + DP_DE_LG_FORMAT, PixelFormat);
128
129 // Enable graphics layer.
130 LayerGraphicsEnable ();
131 }
132
133 /** Configure timing information of the display.
134
135 @param[in] Horizontal Pointer to horizontal timing parameters.
136 (Resolution, Sync, Back porch, Front porch)
137 @param[in] Vertical Pointer to vertical timing parameters.
138 (Resolution, Sync, Back porch, Front porch)
139 **/
140 STATIC
141 VOID
142 SetDisplayEngineTiming (
143 IN CONST SCAN_TIMINGS * CONST Horizontal,
144 IN CONST SCAN_TIMINGS * CONST Vertical
145 )
146 {
147 UINTN RegHIntervals;
148 UINTN RegVIntervals;
149 UINTN RegSyncControl;
150 UINTN RegHVActiveSize;
151
152 if (mDpDeviceId == MALIDP_500) {
153 // MALI DP500 timing registers.
154 RegHIntervals = DP_BASE + DP_DE_DP500_H_INTERVALS;
155 RegVIntervals = DP_BASE + DP_DE_DP500_V_INTERVALS;
156 RegSyncControl = DP_BASE + DP_DE_DP500_SYNC_CONTROL;
157 RegHVActiveSize = DP_BASE + DP_DE_DP500_HV_ACTIVESIZE;
158 } else {
159 // MALI DP550/DP650 timing registers.
160 RegHIntervals = DP_BASE + DP_DE_H_INTERVALS;
161 RegVIntervals = DP_BASE + DP_DE_V_INTERVALS;
162 RegSyncControl = DP_BASE + DP_DE_SYNC_CONTROL;
163 RegHVActiveSize = DP_BASE + DP_DE_HV_ACTIVESIZE;
164 }
165
166 // Horizontal back porch and front porch.
167 MmioWrite32 (
168 RegHIntervals,
169 H_INTERVALS (Horizontal->FrontPorch, Horizontal->BackPorch)
170 );
171
172 // Vertical back porch and front porch.
173 MmioWrite32 (
174 RegVIntervals,
175 V_INTERVALS (Vertical->FrontPorch, Vertical->BackPorch)
176 );
177
178 // Sync control, Horizontal and Vertical sync.
179 MmioWrite32 (
180 RegSyncControl,
181 SYNC_WIDTH (Horizontal->Sync, Vertical->Sync)
182 );
183
184 // Set up Horizontal and Vertical area size.
185 MmioWrite32 (
186 RegHVActiveSize,
187 HV_ACTIVE (Horizontal->Resolution, Vertical->Resolution)
188 );
189 }
190
191 /** Return CORE_ID of the ARM Mali DP.
192
193 @retval 0xFFF No Mali DP found.
194 @retval 0x500 Mali DP core id for DP500.
195 @retval 0x550 Mali DP core id for DP550.
196 @retval 0x650 Mali DP core id for DP650.
197 **/
198 STATIC
199 UINT32
200 ArmMaliDpGetCoreId (
201 )
202 {
203 UINT32 DpCoreId;
204
205 // First check for DP500 as register offset for DP550/DP650 CORE_ID
206 // is beyond 3K/4K register space of the DP500.
207 DpCoreId = MmioRead32 (DP_BASE + DP_DE_DP500_CORE_ID);
208 DpCoreId >>= DP_DE_DP500_CORE_ID_SHIFT;
209
210 if (DpCoreId == MALIDP_500) {
211 return DpCoreId;
212 }
213
214 // Check for DP550 or DP650.
215 DpCoreId = MmioRead32 (DP_BASE + DP_DC_CORE_ID);
216 DpCoreId >>= DP_DC_CORE_ID_SHIFT;
217
218 if ((DpCoreId == MALIDP_550) || (DpCoreId == MALIDP_650)) {
219 return DpCoreId;
220 }
221
222 return MALIDP_NOT_PRESENT;
223 }
224
225 /** Check for presence of MALI.
226
227 This function returns success if the platform implements
228 DP500/DP550/DP650 ARM Mali display processor.
229
230 @retval EFI_SUCCESS DP500/DP550/DP650 display processor found
231 on the platform.
232 @retval EFI_NOT_FOUND DP500/DP550/DP650 display processor not found
233 on the platform.
234 **/
235 EFI_STATUS
236 LcdIdentify (VOID)
237 {
238 DEBUG ((DEBUG_WARN,
239 "Probing ARM Mali DP500/DP550/DP650 at base address 0x%p\n",
240 DP_BASE
241 ));
242
243 if (mDpDeviceId == 0) {
244 mDpDeviceId = ArmMaliDpGetCoreId ();
245 }
246
247 if (mDpDeviceId == MALIDP_NOT_PRESENT) {
248 DEBUG ((DEBUG_WARN, "ARM Mali DP not found...\n"));
249 return EFI_NOT_FOUND;
250 }
251
252 DEBUG ((DEBUG_WARN, "Found ARM Mali DP %x\n", mDpDeviceId));
253 return EFI_SUCCESS;
254 }
255
256 /** Initialize platform display.
257
258 @param[in] FrameBaseAddress Address of the frame buffer.
259
260 @retval EFI_SUCCESS Display initialization successful.
261 @retval !(EFI_SUCCESS) Display initialization failure.
262 **/
263 EFI_STATUS
264 LcdInitialize (
265 IN CONST EFI_PHYSICAL_ADDRESS FrameBaseAddress
266 )
267 {
268 DEBUG ((DEBUG_WARN, "Framebuffer base address = %p\n", FrameBaseAddress));
269
270 if (mDpDeviceId == 0) {
271 mDpDeviceId = ArmMaliDpGetCoreId ();
272 }
273
274 if (mDpDeviceId == MALIDP_NOT_PRESENT) {
275 DEBUG ((DEBUG_ERROR, "ARM Mali DP initialization failed,"
276 "no ARM Mali DP present\n"));
277 return EFI_NOT_FOUND;
278 }
279
280 // We are using graphics layer of the Mali DP as a main framebuffer.
281 LayerGraphicsSetFrame (FrameBaseAddress);
282
283 return EFI_SUCCESS;
284 }
285
286 /** Set ARM Mali DP in cofiguration mode.
287
288 The ARM Mali DP must be in the configuration mode for
289 configuration of the H_INTERVALS, V_INTERVALS, SYNC_CONTROL
290 and HV_ACTIVESIZE.
291 **/
292 STATIC
293 VOID
294 SetConfigurationMode (VOID)
295 {
296 // Request configuration Mode.
297 if (mDpDeviceId == MALIDP_500) {
298 MmioOr32 (DP_BASE + DP_DE_DP500_CONTROL, DP_DE_DP500_CONTROL_CONFIG_REQ);
299 } else {
300 MmioOr32 (DP_BASE + DP_DC_CONTROL, DP_DC_CONTROL_CM_ACTIVE);
301 }
302 }
303
304 /** Set ARM Mali DP in normal mode.
305
306 Normal mode is the main operating mode of the display processor
307 in which display layer data is fetched from framebuffer and
308 displayed.
309 **/
310 STATIC
311 VOID
312 SetNormalMode (VOID)
313 {
314 // Disable configuration Mode.
315 if (mDpDeviceId == MALIDP_500) {
316 MmioAnd32 (DP_BASE + DP_DE_DP500_CONTROL, ~DP_DE_DP500_CONTROL_CONFIG_REQ);
317 } else {
318 MmioAnd32 (DP_BASE + DP_DC_CONTROL, ~DP_DC_CONTROL_CM_ACTIVE);
319 }
320 }
321
322 /** Set the global configuration valid flag.
323
324 Any new configuration parameters written to the display engine are not
325 activated until the global configuration valid flag is set in the
326 CONFIG_VALID register.
327 **/
328 STATIC
329 VOID
330 SetConfigValid (VOID)
331 {
332 if (mDpDeviceId == MALIDP_500) {
333 MmioOr32 (DP_BASE + DP_DP500_CONFIG_VALID, DP_DC_CONFIG_VALID);
334 } else {
335 MmioOr32 (DP_BASE + DP_DC_CONFIG_VALID, DP_DC_CONFIG_VALID);
336 }
337 }
338
339 /** Set requested mode of the display.
340
341 @param[in] ModeNumber Display mode number.
342
343 @retval EFI_SUCCESS Display mode set successful.
344 @retval EFI_DEVICE_ERROR Display mode not found/supported.
345 **/
346 EFI_STATUS
347 LcdSetMode (
348 IN CONST UINT32 ModeNumber
349 )
350 {
351 EFI_STATUS Status;
352 SCAN_TIMINGS *Horizontal;
353 SCAN_TIMINGS *Vertical;
354
355 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo;
356
357 // Get the display mode timings and other relevant information.
358 Status = LcdPlatformGetTimings (
359 ModeNumber,
360 &Horizontal,
361 &Vertical
362 );
363 if (EFI_ERROR (Status)) {
364 ASSERT_EFI_ERROR (Status);
365 return Status;
366 }
367
368 ASSERT (Horizontal != NULL);
369 ASSERT (Vertical != NULL);
370
371 // Get the pixel format information.
372 Status = LcdPlatformQueryMode (ModeNumber, &ModeInfo);
373 if (EFI_ERROR (Status)) {
374 ASSERT_EFI_ERROR (Status);
375 return Status;
376 }
377
378 // Request configuration mode.
379 SetConfigurationMode ();
380
381 // Configure the graphics layer.
382 LayerGraphicsConfig (
383 ModeInfo.PixelFormat,
384 Horizontal->Resolution,
385 Vertical->Resolution
386 );
387
388 // Set the display engine timings.
389 SetDisplayEngineTiming (Horizontal, Vertical);
390
391 // After configuration, set Mali DP in normal mode.
392 SetNormalMode ();
393
394 // Any parameters written to the display engine are not activated until
395 // CONFIG_VALID is set.
396 SetConfigValid ();
397
398 return EFI_SUCCESS;
399 }
400
401 /** This function de-initializes the display.
402
403 **/
404 VOID
405 LcdShutdown (VOID)
406 {
407 // Disable graphics layer.
408 LayerGraphicsDisable ();
409 }