ArmPlatformPkg/LcdGraphicsOutputDxe: check PrimeCell ID before initializing
[mirror_edk2.git] / ArmPlatformPkg / Drivers / LcdGraphicsOutputDxe / PL111Lcd.c
1 /** @file PL111Lcd.c
2
3 Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
4
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include <Library/IoLib.h>
16 #include <Library/MemoryAllocationLib.h>
17
18 #include <Drivers/PL111Lcd.h>
19
20 #include "LcdGraphicsOutputDxe.h"
21
22 /**********************************************************************
23 *
24 * This file contains all the bits of the PL111 that are
25 * platform independent.
26 *
27 **********************************************************************/
28
29 EFI_STATUS
30 LcdIdentify (
31 VOID
32 )
33 {
34 DEBUG ((EFI_D_WARN, "Probing ID registers at 0x%lx for a PL111\n",
35 PL111_REG_CLCD_PERIPH_ID_0));
36
37 // Check if this is a PL111
38 if (MmioRead8 (PL111_REG_CLCD_PERIPH_ID_0) == PL111_CLCD_PERIPH_ID_0 &&
39 MmioRead8 (PL111_REG_CLCD_PERIPH_ID_1) == PL111_CLCD_PERIPH_ID_1 &&
40 (MmioRead8 (PL111_REG_CLCD_PERIPH_ID_2) & 0xf) == PL111_CLCD_PERIPH_ID_2 &&
41 MmioRead8 (PL111_REG_CLCD_PERIPH_ID_3) == PL111_CLCD_PERIPH_ID_3 &&
42 MmioRead8 (PL111_REG_CLCD_P_CELL_ID_0) == PL111_CLCD_P_CELL_ID_0 &&
43 MmioRead8 (PL111_REG_CLCD_P_CELL_ID_1) == PL111_CLCD_P_CELL_ID_1 &&
44 MmioRead8 (PL111_REG_CLCD_P_CELL_ID_2) == PL111_CLCD_P_CELL_ID_2 &&
45 MmioRead8 (PL111_REG_CLCD_P_CELL_ID_3) == PL111_CLCD_P_CELL_ID_3) {
46 return EFI_SUCCESS;
47 }
48 return EFI_NOT_FOUND;
49 }
50
51 EFI_STATUS
52 LcdInitialize (
53 IN EFI_PHYSICAL_ADDRESS VramBaseAddress
54 )
55 {
56 // Define start of the VRAM. This never changes for any graphics mode
57 MmioWrite32(PL111_REG_LCD_UP_BASE, (UINT32) VramBaseAddress);
58 MmioWrite32(PL111_REG_LCD_LP_BASE, 0); // We are not using a double buffer
59
60 // Disable all interrupts from the PL111
61 MmioWrite32(PL111_REG_LCD_IMSC, 0);
62
63 return EFI_SUCCESS;
64 }
65
66 EFI_STATUS
67 LcdSetMode (
68 IN UINT32 ModeNumber
69 )
70 {
71 EFI_STATUS Status;
72 UINT32 HRes;
73 UINT32 HSync;
74 UINT32 HBackPorch;
75 UINT32 HFrontPorch;
76 UINT32 VRes;
77 UINT32 VSync;
78 UINT32 VBackPorch;
79 UINT32 VFrontPorch;
80 UINT32 LcdControl;
81 LCD_BPP LcdBpp;
82
83 // Set the video mode timings and other relevant information
84 Status = LcdPlatformGetTimings (ModeNumber,
85 &HRes,&HSync,&HBackPorch,&HFrontPorch,
86 &VRes,&VSync,&VBackPorch,&VFrontPorch);
87 ASSERT_EFI_ERROR (Status);
88 if (EFI_ERROR( Status )) {
89 return EFI_DEVICE_ERROR;
90 }
91
92 Status = LcdPlatformGetBpp (ModeNumber,&LcdBpp);
93 ASSERT_EFI_ERROR (Status);
94 if (EFI_ERROR( Status )) {
95 return EFI_DEVICE_ERROR;
96 }
97
98 // Disable the CLCD_LcdEn bit
99 LcdControl = MmioRead32( PL111_REG_LCD_CONTROL);
100 MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl & ~1);
101
102 // Set Timings
103 MmioWrite32 (PL111_REG_LCD_TIMING_0, HOR_AXIS_PANEL(HBackPorch, HFrontPorch, HSync, HRes));
104 MmioWrite32 (PL111_REG_LCD_TIMING_1, VER_AXIS_PANEL(VBackPorch, VFrontPorch, VSync, VRes));
105 MmioWrite32 (PL111_REG_LCD_TIMING_2, CLK_SIG_POLARITY(HRes));
106 MmioWrite32 (PL111_REG_LCD_TIMING_3, 0);
107
108 // PL111_REG_LCD_CONTROL
109 LcdControl = PL111_CTRL_LCD_EN | PL111_CTRL_LCD_BPP(LcdBpp) | PL111_CTRL_LCD_TFT | PL111_CTRL_BGR;
110 MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl);
111
112 // Turn on power to the LCD Panel
113 LcdControl |= PL111_CTRL_LCD_PWR;
114 MmioWrite32(PL111_REG_LCD_CONTROL, LcdControl);
115
116 return EFI_SUCCESS;
117 }
118
119 VOID
120 LcdShutdown (
121 VOID
122 )
123 {
124 // Disable the controller
125 MmioAnd32 (PL111_REG_LCD_CONTROL, ~PL111_CTRL_LCD_EN);
126 }