]>
git.ipfire.org Git - people/ms/u-boot.git/blob - lib/efi_loader/efi_gop.c
2 * EFI application disk support
4 * Copyright (c) 2016 Alexander Graf
6 * SPDX-License-Identifier: GPL-2.0+
11 #include <efi_loader.h>
17 DECLARE_GLOBAL_DATA_PTR
;
19 static const efi_guid_t efi_gop_guid
= EFI_GOP_GUID
;
22 /* Generic EFI object parent class data */
23 struct efi_object parent
;
24 /* EFI Interface callback struct for gop */
26 /* The only mode we support */
27 struct efi_gop_mode_info info
;
28 struct efi_gop_mode mode
;
29 /* Fields we only have acces to during init */
34 static efi_status_t EFIAPI
gop_query_mode(struct efi_gop
*this, u32 mode_number
,
35 unsigned long *size_of_info
,
36 struct efi_gop_mode_info
**info
)
38 struct efi_gop_obj
*gopobj
;
40 EFI_ENTRY("%p, %x, %p, %p", this, mode_number
, size_of_info
, info
);
42 gopobj
= container_of(this, struct efi_gop_obj
, ops
);
43 *size_of_info
= sizeof(gopobj
->info
);
44 *info
= &gopobj
->info
;
46 return EFI_EXIT(EFI_SUCCESS
);
49 static efi_status_t EFIAPI
gop_set_mode(struct efi_gop
*this, u32 mode_number
)
51 EFI_ENTRY("%p, %x", this, mode_number
);
54 return EFI_EXIT(EFI_INVALID_PARAMETER
);
56 return EFI_EXIT(EFI_SUCCESS
);
59 static efi_status_t EFIAPI
gop_blt(struct efi_gop
*this, void *buffer
,
60 unsigned long operation
, unsigned long sx
,
61 unsigned long sy
, unsigned long dx
,
62 unsigned long dy
, unsigned long width
,
63 unsigned long height
, unsigned long delta
)
65 struct efi_gop_obj
*gopobj
= container_of(this, struct efi_gop_obj
, ops
);
66 int i
, j
, line_len16
, line_len32
;
69 EFI_ENTRY("%p, %p, %lx, %lx, %lx, %lx, %lx, %lx, %lx, %lx", this,
70 buffer
, operation
, sx
, sy
, dx
, dy
, width
, height
, delta
);
72 if (operation
!= EFI_BLT_BUFFER_TO_VIDEO
)
73 return EFI_EXIT(EFI_INVALID_PARAMETER
);
76 line_len16
= gopobj
->info
.width
* sizeof(u16
);
77 line_len32
= gopobj
->info
.width
* sizeof(u32
);
79 /* Copy the contents line by line */
81 switch (gopobj
->bpix
) {
82 #ifdef CONFIG_DM_VIDEO
87 for (i
= 0; i
< height
; i
++) {
88 u32
*dest
= fb
+ ((i
+ dy
) * line_len32
) +
90 u32
*src
= buffer
+ ((i
+ sy
) * line_len32
) +
93 /* Same color format, just memcpy */
94 memcpy(dest
, src
, width
* sizeof(u32
));
97 #ifdef CONFIG_DM_VIDEO
102 for (i
= 0; i
< height
; i
++) {
103 u16
*dest
= fb
+ ((i
+ dy
) * line_len16
) +
105 u32
*src
= buffer
+ ((i
+ sy
) * line_len32
) +
108 /* Convert from rgb888 to rgb565 */
109 for (j
= 0; j
< width
; j
++) {
111 dest
[j
] = ((((rgb888
>> (16 + 3)) & 0x1f) << 11) |
112 (((rgb888
>> (8 + 2)) & 0x3f) << 5) |
113 (((rgb888
>> (0 + 3)) & 0x1f) << 0));
119 #ifdef CONFIG_DM_VIDEO
125 return EFI_EXIT(EFI_SUCCESS
);
128 /* This gets called from do_bootefi_exec(). */
129 int efi_gop_register(void)
131 struct efi_gop_obj
*gopobj
;
133 u64 fb_base
, fb_size
;
136 #ifdef CONFIG_DM_VIDEO
137 struct udevice
*vdev
;
139 /* We only support a single video output device for now */
140 if (uclass_first_device(UCLASS_VIDEO
, &vdev
) || !vdev
)
143 struct video_priv
*priv
= dev_get_uclass_priv(vdev
);
145 col
= video_get_xsize(vdev
);
146 row
= video_get_ysize(vdev
);
147 fb_base
= (uintptr_t)priv
->fb
;
148 fb_size
= priv
->fb_size
;
153 bpix
= panel_info
.vl_bpix
;
154 col
= panel_info
.vl_col
;
155 row
= panel_info
.vl_row
;
156 fb_base
= gd
->fb_base
;
157 fb_size
= lcd_get_size(&line_len
);
158 fb
= (void*)gd
->fb_base
;
162 #ifdef CONFIG_DM_VIDEO
171 /* So far, we only work in 16 or 32 bit mode */
175 gopobj
= calloc(1, sizeof(*gopobj
));
177 /* Fill in object data */
178 gopobj
->parent
.protocols
[0].guid
= &efi_gop_guid
;
179 gopobj
->parent
.protocols
[0].protocol_interface
= &gopobj
->ops
;
180 gopobj
->parent
.handle
= &gopobj
->ops
;
181 gopobj
->ops
.query_mode
= gop_query_mode
;
182 gopobj
->ops
.set_mode
= gop_set_mode
;
183 gopobj
->ops
.blt
= gop_blt
;
184 gopobj
->ops
.mode
= &gopobj
->mode
;
186 gopobj
->mode
.max_mode
= 1;
187 gopobj
->mode
.info
= &gopobj
->info
;
188 gopobj
->mode
.info_size
= sizeof(gopobj
->info
);
190 #ifdef CONFIG_DM_VIDEO
191 if (bpix
== VIDEO_BPP32
) {
193 if (bpix
== LCD_COLOR32
) {
195 /* With 32bit color space we can directly expose the fb */
196 gopobj
->mode
.fb_base
= fb_base
;
197 gopobj
->mode
.fb_size
= fb_size
;
200 gopobj
->info
.version
= 0;
201 gopobj
->info
.width
= col
;
202 gopobj
->info
.height
= row
;
203 gopobj
->info
.pixel_format
= EFI_GOT_RGBA8
;
204 gopobj
->info
.pixels_per_scanline
= col
;
209 /* Hook up to the device list */
210 list_add_tail(&gopobj
->parent
.link
, &efi_obj_list
);