3 ARM Mali DP 500/550/650 display controller driver
5 Copyright (c) 2017-2018, Arm Limited. All rights reserved.<BR>
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
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.
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>
23 #include "ArmMaliDp.h"
25 // CORE_ID of the MALI DP
26 STATIC UINT32 mDpDeviceId
;
28 /** Disable the graphics layer
30 This is done by clearing the EN bit of the LG_CONTROL register.
34 LayerGraphicsDisable (VOID
)
36 MmioAnd32 (DP_BASE
+ DP_DE_LG_CONTROL
, ~DP_DE_LG_ENABLE
);
39 /** Enable the graphics layer
41 This is done by setting the EN bit of the LG_CONTROL register.
45 LayerGraphicsEnable (VOID
)
47 MmioOr32 (DP_BASE
+ DP_DE_LG_CONTROL
, DP_DE_LG_ENABLE
);
50 /** Set the frame address of the graphics layer.
52 @param[in] FrameBaseAddress Address of the data buffer to be used as
57 LayerGraphicsSetFrame (
58 IN CONST EFI_PHYSICAL_ADDRESS FrameBaseAddress
61 // Disable the graphics layer.
62 LayerGraphicsDisable ();
64 // Set up memory address of the data buffer for graphics layer.
65 // write lower bits of the address.
67 DP_BASE
+ DP_DE_LG_PTR_LOW
,
68 DP_DE_LG_PTR_LOW_MASK
& FrameBaseAddress
71 // Write higher bits of the address.
73 DP_BASE
+ DP_DE_LG_PTR_HIGH
,
74 (UINT32
)(FrameBaseAddress
>> DP_DE_LG_PTR_HIGH_SHIFT
)
77 // Enable the graphics layer.
78 LayerGraphicsEnable ();
81 /** Configures various graphics layer characteristics.
83 @param[in] UefiGfxPixelFormat This must be either
84 PixelBlueGreenRedReserved8BitPerColor
86 PixelRedGreenBlueReserved8BitPerColor
87 @param[in] HRes Horizontal resolution of the graphics layer.
88 @param[in] VRes Vertical resolution of the graphics layer.
93 IN CONST EFI_GRAPHICS_PIXEL_FORMAT UefiGfxPixelFormat
,
100 // Disable the graphics layer before configuring any settings.
101 LayerGraphicsDisable ();
103 // Setup graphics layer size.
104 MmioWrite32 (DP_BASE
+ DP_DE_LG_IN_SIZE
, FRAME_IN_SIZE (HRes
, VRes
));
106 // Setup graphics layer composition size.
107 MmioWrite32 (DP_BASE
+ DP_DE_LG_CMP_SIZE
, FRAME_CMP_SIZE (HRes
, VRes
));
109 // Setup memory stride (total visible pixels on a line * 4).
110 MmioWrite32 (DP_BASE
+ DP_DE_LG_H_STRIDE
, (HRes
* sizeof (UINT32
)));
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
;
123 PixelFormat
= (mDpDeviceId
== MALIDP_500
) ? DP_PIXEL_FORMAT_DP500_XBGR_8888
124 : DP_PIXEL_FORMAT_XBGR_8888
;
127 MmioWrite32 (DP_BASE
+ DP_DE_LG_FORMAT
, PixelFormat
);
129 // Enable graphics layer.
130 LayerGraphicsEnable ();
133 /** Configure timing information of the display.
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)
142 SetDisplayEngineTiming (
143 IN CONST SCAN_TIMINGS
* CONST Horizontal
,
144 IN CONST SCAN_TIMINGS
* CONST Vertical
149 UINTN RegSyncControl
;
150 UINTN RegHVActiveSize
;
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
;
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
;
166 // Horizontal back porch and front porch.
169 H_INTERVALS (Horizontal
->FrontPorch
, Horizontal
->BackPorch
)
172 // Vertical back porch and front porch.
175 V_INTERVALS (Vertical
->FrontPorch
, Vertical
->BackPorch
)
178 // Sync control, Horizontal and Vertical sync.
181 SYNC_WIDTH (Horizontal
->Sync
, Vertical
->Sync
)
184 // Set up Horizontal and Vertical area size.
187 HV_ACTIVE (Horizontal
->Resolution
, Vertical
->Resolution
)
191 /** Return CORE_ID of the ARM Mali DP.
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.
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
;
210 if (DpCoreId
== MALIDP_500
) {
214 // Check for DP550 or DP650.
215 DpCoreId
= MmioRead32 (DP_BASE
+ DP_DC_CORE_ID
);
216 DpCoreId
>>= DP_DC_CORE_ID_SHIFT
;
218 if ((DpCoreId
== MALIDP_550
) || (DpCoreId
== MALIDP_650
)) {
222 return MALIDP_NOT_PRESENT
;
225 /** Check for presence of MALI.
227 This function returns success if the platform implements
228 DP500/DP550/DP650 ARM Mali display processor.
230 @retval EFI_SUCCESS DP500/DP550/DP650 display processor found
232 @retval EFI_NOT_FOUND DP500/DP550/DP650 display processor not found
239 "Probing ARM Mali DP500/DP550/DP650 at base address 0x%p\n",
243 if (mDpDeviceId
== 0) {
244 mDpDeviceId
= ArmMaliDpGetCoreId ();
247 if (mDpDeviceId
== MALIDP_NOT_PRESENT
) {
248 DEBUG ((DEBUG_WARN
, "ARM Mali DP not found...\n"));
249 return EFI_NOT_FOUND
;
252 DEBUG ((DEBUG_WARN
, "Found ARM Mali DP %x\n", mDpDeviceId
));
256 /** Initialize platform display.
258 @param[in] FrameBaseAddress Address of the frame buffer.
260 @retval EFI_SUCCESS Display initialization successful.
261 @retval !(EFI_SUCCESS) Display initialization failure.
265 IN CONST EFI_PHYSICAL_ADDRESS FrameBaseAddress
268 DEBUG ((DEBUG_WARN
, "Framebuffer base address = %p\n", FrameBaseAddress
));
270 if (mDpDeviceId
== 0) {
271 mDpDeviceId
= ArmMaliDpGetCoreId ();
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
;
280 // We are using graphics layer of the Mali DP as a main framebuffer.
281 LayerGraphicsSetFrame (FrameBaseAddress
);
286 /** Set ARM Mali DP in cofiguration mode.
288 The ARM Mali DP must be in the configuration mode for
289 configuration of the H_INTERVALS, V_INTERVALS, SYNC_CONTROL
294 SetConfigurationMode (VOID
)
296 // Request configuration Mode.
297 if (mDpDeviceId
== MALIDP_500
) {
298 MmioOr32 (DP_BASE
+ DP_DE_DP500_CONTROL
, DP_DE_DP500_CONTROL_CONFIG_REQ
);
300 MmioOr32 (DP_BASE
+ DP_DC_CONTROL
, DP_DC_CONTROL_CM_ACTIVE
);
304 /** Set ARM Mali DP in normal mode.
306 Normal mode is the main operating mode of the display processor
307 in which display layer data is fetched from framebuffer and
314 // Disable configuration Mode.
315 if (mDpDeviceId
== MALIDP_500
) {
316 MmioAnd32 (DP_BASE
+ DP_DE_DP500_CONTROL
, ~DP_DE_DP500_CONTROL_CONFIG_REQ
);
318 MmioAnd32 (DP_BASE
+ DP_DC_CONTROL
, ~DP_DC_CONTROL_CM_ACTIVE
);
322 /** Set the global configuration valid flag.
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.
330 SetConfigValid (VOID
)
332 if (mDpDeviceId
== MALIDP_500
) {
333 MmioOr32 (DP_BASE
+ DP_DP500_CONFIG_VALID
, DP_DC_CONFIG_VALID
);
335 MmioOr32 (DP_BASE
+ DP_DC_CONFIG_VALID
, DP_DC_CONFIG_VALID
);
339 /** Set requested mode of the display.
341 @param[in] ModeNumber Display mode number.
343 @retval EFI_SUCCESS Display mode set successful.
344 @retval EFI_DEVICE_ERROR Display mode not found/supported.
348 IN CONST UINT32 ModeNumber
352 SCAN_TIMINGS
*Horizontal
;
353 SCAN_TIMINGS
*Vertical
;
355 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInfo
;
357 // Get the display mode timings and other relevant information.
358 Status
= LcdPlatformGetTimings (
363 if (EFI_ERROR (Status
)) {
364 ASSERT_EFI_ERROR (Status
);
368 ASSERT (Horizontal
!= NULL
);
369 ASSERT (Vertical
!= NULL
);
371 // Get the pixel format information.
372 Status
= LcdPlatformQueryMode (ModeNumber
, &ModeInfo
);
373 if (EFI_ERROR (Status
)) {
374 ASSERT_EFI_ERROR (Status
);
378 // Request configuration mode.
379 SetConfigurationMode ();
381 // Configure the graphics layer.
382 LayerGraphicsConfig (
383 ModeInfo
.PixelFormat
,
384 Horizontal
->Resolution
,
388 // Set the display engine timings.
389 SetDisplayEngineTiming (Horizontal
, Vertical
);
391 // After configuration, set Mali DP in normal mode.
394 // Any parameters written to the display engine are not activated until
395 // CONFIG_VALID is set.
401 /** This function de-initializes the display.
407 // Disable graphics layer.
408 LayerGraphicsDisable ();