Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit 90366e8

Browse files
jeremy-compostellabuildslave
authored andcommitted
drivers/gop: Graphical Output Protocol taking over pipe A surface 1
This driver creates a Graphical Output Protocol based on the pipe A surface 1 assuming it has been approprietly setup by the BIOS (ABL). It reads back the resolution information and the surface address directly from the registers. Change-Id: Ib893935964204faa4278a85dabceba21b3f8bc30 Tracked-On: https://jira.devtools.intel.com/browse/OAM-75934 Signed-off-by: Jeremy Compostella <[email protected]> Reviewed-on: https://android.intel.com:443/655387
1 parent c90a10b commit 90366e8

File tree

3 files changed

+353
-0
lines changed

3 files changed

+353
-0
lines changed

drivers/gop/gop.c

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
/*
2+
* Copyright (c) 2018, Intel Corporation
3+
* All rights reserved.
4+
*
5+
* Authors: Jérémy Compostella <[email protected]>
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
*
11+
* * Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
* * Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer
15+
* in the documentation and/or other materials provided with the
16+
* distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29+
* OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
#include <interface.h>
33+
#include <efiwrapper.h>
34+
#include <string.h>
35+
#include <ewlib.h>
36+
#include <pci/pci.h>
37+
#include <arch/io.h>
38+
#include <hwconfig.h>
39+
40+
#include "gop.h"
41+
42+
typedef struct gop {
43+
EFI_GRAPHICS_OUTPUT_PROTOCOL prot;
44+
pcidev_t dev;
45+
uint8_t *fb;
46+
size_t pipe;
47+
} gop_t;
48+
49+
static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
50+
static EFI_HANDLE gop_handle;
51+
static gop_t *gop;
52+
53+
static EFI_GRAPHICS_OUTPUT_MODE_INFORMATION info = {
54+
.Version = 1,
55+
.PixelFormat = PixelRedGreenBlueReserved8BitPerColor
56+
};
57+
58+
static EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE mode = {
59+
.MaxMode = 1,
60+
.Info = &info,
61+
.SizeOfInfo = sizeof(info)
62+
};
63+
64+
static EFIAPI EFI_STATUS
65+
query_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
66+
UINT32 ModeNumber,
67+
UINTN *SizeOfInfo,
68+
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info)
69+
{
70+
if (!This || ModeNumber != 0 || !SizeOfInfo || !Info)
71+
return EFI_INVALID_PARAMETER;
72+
73+
*SizeOfInfo = sizeof(info);
74+
*Info = &info;
75+
76+
return EFI_SUCCESS;
77+
}
78+
79+
#define PIPE_NUMBER 3
80+
#define PIPE_OFFSET 0x1000
81+
#define PLANE_SIZE 0x70190
82+
#define PLANE_SURF 0x7019C
83+
#define PLANE_CTL 0x70180
84+
#define PLANE_CTL_ORDER_RGBX (1 << 20)
85+
86+
/*
87+
* It assumes that the BIOS (ABL) configured the monitors and setup
88+
* Surface 1 of PIPE A appropriately. The two following function are
89+
* reading back register set by the BIOS to determine the surface
90+
* resolution and surface address.
91+
*
92+
* Registers information are available on 01.org in:
93+
* - intel-gfx-prm-osrc-skl-vol02c-commandreference-registers-part1.pdf
94+
* - intel-gfx-prm-osrc-skl-vol02c-commandreference-registers-part2.pdf
95+
*/
96+
static void get_resolution(pcidev_t dev, UINT32 *width, UINT32 *height,
97+
size_t *pipe)
98+
{
99+
uint32_t mmio, size;
100+
size_t i;
101+
102+
mmio = pci_read_config32(dev, 0x10) & ~0xf;
103+
for (i = 0; i < PIPE_NUMBER; i++) {
104+
uint32_t offset = i * PIPE_OFFSET;
105+
size = read32((void *)mmio + PLANE_SIZE + offset);
106+
if (!size)
107+
continue;
108+
*pipe = i;
109+
*width = (size & 0xffff) + 1;
110+
*height = (size >> 16) + 1;
111+
return;
112+
}
113+
}
114+
115+
static uint8_t *get_framebuffer(pcidev_t dev, size_t pipe)
116+
{
117+
uint32_t mmio, gmaddr, surf;
118+
119+
mmio = pci_read_config32(dev, 0x10) & ~0xf;
120+
surf = read32((void *)(mmio + PLANE_SURF + pipe * PIPE_OFFSET));
121+
gmaddr = pci_read_config32(dev, 0x18) & ~0xf;
122+
123+
return (uint8_t *)(gmaddr + surf);
124+
}
125+
126+
static void set_efi_color_order(pcidev_t dev)
127+
{
128+
uint32_t mmio, ctl, surf;
129+
size_t i;
130+
131+
mmio = pci_read_config32(dev, 0x10) & ~0xf;
132+
for (i = 0; i < PIPE_NUMBER; i++) {
133+
uint32_t offset = i * PIPE_OFFSET;
134+
ctl = read32((void *)(mmio + PLANE_CTL + offset));
135+
if (ctl & PLANE_CTL_ORDER_RGBX) {
136+
write32((void *)(mmio + PLANE_CTL + offset),
137+
ctl & ~PLANE_CTL_ORDER_RGBX);
138+
surf = read32((void *)(mmio + PLANE_SURF + offset));
139+
write32((void *)(mmio + PLANE_SURF + offset), surf);
140+
}
141+
}
142+
}
143+
144+
static EFIAPI EFI_STATUS
145+
set_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
146+
UINT32 ModeNumber)
147+
{
148+
if (!This || (gop_t *)This != gop || ModeNumber != 0)
149+
return EFI_INVALID_PARAMETER;
150+
151+
gop->fb = get_framebuffer(gop->dev, gop->pipe);
152+
set_efi_color_order(gop->dev);
153+
return gop->fb ? EFI_SUCCESS : EFI_DEVICE_ERROR;
154+
}
155+
156+
static void fill_buffer(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *color,
157+
UINTN destx,
158+
UINTN desty,
159+
UINTN width,
160+
UINTN height)
161+
{
162+
size_t x, y;
163+
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *data;
164+
165+
data = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)gop->fb;
166+
for (y = desty; y < desty + height; y++) {
167+
UINTN cur_y = y * info.HorizontalResolution;
168+
for (x = destx; x < destx + width; x++)
169+
data[cur_y + x] = *color;
170+
}
171+
}
172+
173+
static void copy_to_buffer(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buffer,
174+
UINTN srcx,
175+
UINTN srcy,
176+
UINTN destx,
177+
UINTN desty,
178+
UINTN width,
179+
UINTN height)
180+
{
181+
size_t i, y, sy;
182+
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *data, *dst, *src;
183+
184+
data = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)gop->fb;
185+
for (y = desty, sy = srcy; y < desty + height; y++, sy++) {
186+
dst = &data[y * info.HorizontalResolution + destx];
187+
src = &buffer[sy * width + srcx];
188+
for (i = 0; i < width; i++)
189+
dst[i] = src[i];
190+
}
191+
}
192+
193+
static EFIAPI EFI_STATUS
194+
blt(EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
195+
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
196+
EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
197+
UINTN SourceX,
198+
UINTN SourceY,
199+
UINTN DestinationX,
200+
UINTN DestinationY,
201+
UINTN Width,
202+
UINTN Height,
203+
__attribute__((__unused__)) UINTN Delta)
204+
{
205+
if (!This || (gop_t *)This != gop || !BltBuffer)
206+
return EFI_INVALID_PARAMETER;
207+
208+
if (DestinationX + Width > info.HorizontalResolution ||
209+
DestinationY + Height > info.VerticalResolution)
210+
return EFI_INVALID_PARAMETER;
211+
212+
if (!gop->fb)
213+
return EFI_NOT_STARTED;
214+
215+
switch (BltOperation) {
216+
case EfiBltVideoFill:
217+
fill_buffer(BltBuffer, DestinationX, DestinationY,
218+
Width, Height);
219+
break;
220+
221+
case EfiBltBufferToVideo:
222+
copy_to_buffer(BltBuffer, SourceX, SourceY,
223+
DestinationX, DestinationY,
224+
Width, Height);
225+
break;
226+
227+
default:
228+
return EFI_UNSUPPORTED;
229+
}
230+
231+
return EFI_SUCCESS;
232+
}
233+
234+
static struct supported_device {
235+
u16 vid;
236+
u16 did;
237+
} SUPPORTED_DEVICES[] ={
238+
{ .vid = 0x8086, .did = VGA_PID },
239+
{ .vid = 0x8086, .did = VGA_PID2 },
240+
};
241+
242+
static EFI_STATUS gop_init(EFI_SYSTEM_TABLE *st)
243+
{
244+
static gop_t gop_default = {
245+
.prot = {
246+
.QueryMode = query_mode,
247+
.SetMode = set_mode,
248+
.Blt = blt,
249+
.Mode = &mode
250+
}
251+
};
252+
pcidev_t pci_dev = 0;
253+
size_t i;
254+
255+
if (!st)
256+
return EFI_INVALID_PARAMETER;
257+
258+
if (gop_handle)
259+
return EFI_ALREADY_STARTED;
260+
261+
for (i = 0; i < ARRAY_SIZE(SUPPORTED_DEVICES); i++)
262+
if (pci_find_device(SUPPORTED_DEVICES[i].vid,
263+
SUPPORTED_DEVICES[i].did,
264+
&pci_dev))
265+
break;
266+
267+
if (!pci_dev)
268+
return EFI_UNSUPPORTED;
269+
270+
gop_default.dev = pci_dev;
271+
get_resolution(pci_dev, &info.HorizontalResolution,
272+
&info.VerticalResolution,
273+
&gop_default.pipe);
274+
275+
/* If the BIOS has not programmed any surface, silently
276+
disable the Graphical Output Protocol. */
277+
if (!info.HorizontalResolution || !info.VerticalResolution)
278+
return EFI_SUCCESS;
279+
280+
return interface_init(st, &gop_guid, &gop_handle,
281+
&gop_default, sizeof(gop_default),
282+
(void **)&gop);
283+
}
284+
285+
static EFI_STATUS gop_exit(EFI_SYSTEM_TABLE *st)
286+
{
287+
EFI_STATUS ret;
288+
289+
if (!st)
290+
return EFI_INVALID_PARAMETER;
291+
292+
if (!gop_handle)
293+
return EFI_SUCCESS;
294+
295+
ret = interface_free(st, &gop_guid, gop_handle);
296+
if (EFI_ERROR(ret))
297+
return ret;
298+
299+
gop = NULL;
300+
gop_handle = NULL;
301+
302+
return EFI_SUCCESS;
303+
}
304+
305+
ewdrv_t gop_drv = {
306+
.name = "gop",
307+
.description = "Graphics Output Protocol",
308+
.init = gop_init,
309+
.exit = gop_exit
310+
};

drivers/gop/gop.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2018, Intel Corporation
3+
* All rights reserved.
4+
*
5+
* Author: Jérémy Compostella <[email protected]>
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
*
11+
* * Redistributions of source code must retain the above copyright
12+
* notice, this list of conditions and the following disclaimer.
13+
* * Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer
15+
* in the documentation and/or other materials provided with the
16+
* distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27+
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29+
* OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
#ifndef _GOP_H_
33+
#define _GOP_H_
34+
35+
#include <ewdrv.h>
36+
37+
extern ewdrv_t gop_drv;
38+
39+
#endif /* _GOP_H_ */

include/hardware/hw_broxton.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,9 @@
5858
/* TCO base address for Gordon peak */
5959
#define TCOBASE (0x00000460)
6060

61+
/* APL HD Graphics 505 */
62+
#define VGA_PID 0x5a84
63+
#define VGA_PID2 0x5a85
64+
6165
#endif /* __HW_BROXTON__ */
6266

0 commit comments

Comments
 (0)