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