1 /* SPDX-License-Identifier: MIT */
3 #include <console/console.h>
5 #include <boot/coreboot_tables.h>
6 #include <framebuffer_info.h>
9 #include <commonlib/list.h>
12 struct list_node node
;
13 struct lb_framebuffer fb
;
15 static struct list_node list
;
18 * Allocate a new framebuffer info struct on heap.
19 * Returns NULL on error.
21 static struct fb_info
*fb_new_framebuffer_info(void)
24 ret
= malloc(sizeof(struct fb_info
));
26 memset(ret
, 0, sizeof(struct fb_info
));
32 * Fills a provided framebuffer info struct and adds it to the internal list if it's
33 * valid. Returns NULL on error.
36 fb_add_framebuffer_info_ex(const struct lb_framebuffer
*fb
)
42 if (!fb
|| !fb
->x_resolution
|| !fb
->y_resolution
|| !fb
->bytes_per_line
||
43 !fb
->bits_per_pixel
) {
44 printk(BIOS_ERR
, "%s: Invalid framebuffer data provided\n", __func__
);
48 bpp_mask
= fb
->blue_mask_size
+ fb
->green_mask_size
+ fb
->red_mask_size
+
49 fb
->reserved_mask_size
;
50 if (bpp_mask
> fb
->bits_per_pixel
) {
52 "%s: channel bit mask=%d is greater than BPP=%d ."
53 " This is a driver bug. Framebuffer is invalid.\n",
54 __func__
, bpp_mask
, fb
->bits_per_pixel
);
56 } else if (bpp_mask
!= fb
->bits_per_pixel
) {
58 "%s: channel bit mask=%d and BPP=%d don't match."
59 " This is a driver bug.\n",
60 __func__
, bpp_mask
, fb
->bits_per_pixel
);
63 info
= fb_new_framebuffer_info();
67 printk(BIOS_INFO
, "framebuffer_info: bytes_per_line: %d, bits_per_pixel: %d\n "
68 " x_res x y_res: %d x %d, size: %d at 0x%llx\n",
69 fb
->bytes_per_line
, fb
->bits_per_pixel
, fb
->x_resolution
,
70 fb
->y_resolution
, (fb
->bytes_per_line
* fb
->y_resolution
),
71 fb
->physical_address
);
76 list_insert_after(&info
->node
, &list
);
82 * Allocates a new framebuffer info struct and fills it for 32/24/16bpp framebuffers.
83 * Intended for drivers that only support reporting the current information or have a single
86 * Complex drivers should use fb_add_framebuffer_info_ex() instead.
89 fb_add_framebuffer_info(uintptr_t fb_addr
, uint32_t x_resolution
,
90 uint32_t y_resolution
, uint32_t bytes_per_line
,
91 uint8_t bits_per_pixel
)
93 struct fb_info
*info
= NULL
;
95 switch (bits_per_pixel
) {
98 /* FIXME: 24 BPP might be RGB8 or XRGB8 */
99 /* packed into 4-byte words */
101 const struct lb_framebuffer fb
= {
102 .physical_address
= fb_addr
,
103 .x_resolution
= x_resolution
,
104 .y_resolution
= y_resolution
,
105 .bytes_per_line
= bytes_per_line
,
106 .bits_per_pixel
= bits_per_pixel
,
110 .green_mask_size
= 8,
113 .reserved_mask_pos
= 24,
114 .reserved_mask_size
= 8,
115 .orientation
= LB_FB_ORIENTATION_NORMAL
,
118 info
= fb_add_framebuffer_info_ex(&fb
);
122 /* packed into 2-byte words */
123 const struct lb_framebuffer fb
= {
124 .physical_address
= fb_addr
,
125 .x_resolution
= x_resolution
,
126 .y_resolution
= y_resolution
,
127 .bytes_per_line
= bytes_per_line
,
128 .bits_per_pixel
= 16,
132 .green_mask_size
= 6,
135 .reserved_mask_pos
= 0,
136 .reserved_mask_size
= 0,
137 .orientation
= LB_FB_ORIENTATION_NORMAL
,
139 info
= fb_add_framebuffer_info_ex(&fb
);
143 printk(BIOS_ERR
, "%s: unsupported BPP %d\n", __func__
, bits_per_pixel
);
146 printk(BIOS_ERR
, "%s: failed to add framebuffer info\n", __func__
);
151 void fb_set_orientation(struct fb_info
*info
, enum lb_fb_orientation orientation
)
156 info
->fb
.orientation
= orientation
;
160 * Take an edid, and create a framebuffer.
162 struct fb_info
*fb_new_framebuffer_info_from_edid(const struct edid
*edid
,
165 return fb_add_framebuffer_info(fb_addr
, edid
->x_resolution
, edid
->y_resolution
,
166 edid
->bytes_per_line
, edid
->framebuffer_bits_per_pixel
);
169 int fill_lb_framebuffer(struct lb_framebuffer
*framebuffer
)
173 list_for_each(i
, list
, node
) {
174 //TODO: Add support for advertising all framebuffers in this list
175 *framebuffer
= i
->fb
;