ArmMaliDp.c 11 KB

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