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