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