1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright 2020 Toomas Soome
5 * Copyright 2020 RackTop Systems, Inc.
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 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31#ifndef _GFX_FB_H
32#define	_GFX_FB_H
33
34#include <sys/font.h>
35#include <teken.h>
36#include <stdbool.h>
37#include <machine/metadata.h>
38#include <pnglite.h>
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#define	EDID_MAGIC	{ 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }
45
46struct edid_header {
47	uint8_t header[8];	/* fixed header pattern */
48	uint16_t manufacturer_id;
49	uint16_t product_code;
50	uint32_t serial_number;
51	uint8_t week_of_manufacture;
52	uint8_t year_of_manufacture;
53	uint8_t version;
54	uint8_t revision;
55};
56
57struct edid_basic_display_parameters {
58	uint8_t video_input_parameters;
59	uint8_t max_horizontal_image_size;
60	uint8_t max_vertical_image_size;
61	uint8_t display_gamma;
62	uint8_t supported_features;
63};
64
65struct edid_chromaticity_coordinates {
66	uint8_t red_green_lo;
67	uint8_t blue_white_lo;
68	uint8_t red_x_hi;
69	uint8_t red_y_hi;
70	uint8_t green_x_hi;
71	uint8_t green_y_hi;
72	uint8_t blue_x_hi;
73	uint8_t blue_y_hi;
74	uint8_t white_x_hi;
75	uint8_t white_y_hi;
76};
77
78struct edid_detailed_timings {
79	uint16_t pixel_clock;
80	uint8_t horizontal_active_lo;
81	uint8_t horizontal_blanking_lo;
82	uint8_t horizontal_hi;
83	uint8_t vertical_active_lo;
84	uint8_t vertical_blanking_lo;
85	uint8_t vertical_hi;
86	uint8_t horizontal_sync_offset_lo;
87	uint8_t horizontal_sync_pulse_width_lo;
88	uint8_t vertical_sync_lo;
89	uint8_t sync_hi;
90	uint8_t horizontal_image_size_lo;
91	uint8_t vertical_image_size_lo;
92	uint8_t image_size_hi;
93	uint8_t horizontal_border;
94	uint8_t vertical_border;
95	uint8_t features;
96};
97
98struct vesa_edid_info {
99	struct edid_header header;
100	struct edid_basic_display_parameters display;
101#define	EDID_FEATURE_PREFERRED_TIMING_MODE	(1 << 1)
102	struct edid_chromaticity_coordinates chromaticity;
103	uint8_t established_timings_1;
104	uint8_t established_timings_2;
105	uint8_t manufacturer_reserved_timings;
106	uint16_t standard_timings[8];
107	struct edid_detailed_timings detailed_timings[4];
108	uint8_t number_of_extensions;
109	uint8_t checksum;
110} __packed;
111
112extern struct vesa_edid_info *edid_info;
113
114#define	STD_TIMINGS	8
115#define	DET_TIMINGS	4
116
117#define	HSIZE(x)	(((x & 0xff) + 31) * 8)
118#define	RATIO(x)	((x & 0xC000) >> 14)
119#define	RATIO1_1	0
120/* EDID Ver. 1.3 redefined this */
121#define	RATIO16_10	RATIO1_1
122#define	RATIO4_3	1
123#define	RATIO5_4	2
124#define	RATIO16_9	3
125
126/*
127 * Number of pixels and lines is 12-bit int, valid values 0-4095.
128 */
129#define	EDID_MAX_PIXELS	4095
130#define	EDID_MAX_LINES	4095
131
132#define	GET_EDID_INFO_WIDTH(edid_info, timings_num) \
133    ((edid_info)->detailed_timings[(timings_num)].horizontal_active_lo | \
134    (((uint32_t)(edid_info)->detailed_timings[(timings_num)].horizontal_hi & \
135    0xf0) << 4))
136
137#define	GET_EDID_INFO_HEIGHT(edid_info, timings_num) \
138    ((edid_info)->detailed_timings[(timings_num)].vertical_active_lo | \
139    (((uint32_t)(edid_info)->detailed_timings[(timings_num)].vertical_hi & \
140    0xf0) << 4))
141
142struct resolution {
143	uint32_t width;
144	uint32_t height;
145	TAILQ_ENTRY(resolution) next;
146};
147
148typedef TAILQ_HEAD(edid_resolution, resolution) edid_res_list_t;
149
150struct vesa_flat_panel_info {
151	uint16_t HSize;			/* Horizontal Size in Pixels */
152	uint16_t VSize;			/* Vertical Size in Lines */
153	uint16_t FPType;		/* Flat Panel Type */
154	uint8_t RedBPP;			/* Red Bits Per Primary */
155	uint8_t GreenBPP;		/* Green Bits Per Primary */
156	uint8_t BlueBPP;		/* Blue Bits Per Primary */
157	uint8_t ReservedBPP;		/* Reserved Bits Per Primary */
158	uint32_t RsvdOffScrnMemSize;	/* Size in KB of Offscreen Memory */
159	uint32_t RsvdOffScrnMemPtr; /* Pointer to reserved offscreen memory */
160	uint8_t Reserved[14];		/* remainder of FPInfo */
161} __packed;
162
163#define	COLOR_FORMAT_VGA 0
164#define	COLOR_FORMAT_RGB 1
165#define	NCOLORS	16
166#define	NCMAP	256
167extern uint32_t cmap[NCMAP];
168
169/*
170 * VT_FB_MAX_WIDTH and VT_FB_MAX_HEIGHT are dimensions from where
171 * we will not auto select smaller font than 8x16.
172 * See also sys/dev/vt/vt.h
173 */
174#ifndef VT_FB_MAX_WIDTH
175#define	VT_FB_MAX_WIDTH		4096
176#endif
177#ifndef VT_FB_MAX_HEIGHT
178#define	VT_FB_MAX_HEIGHT	2400
179#endif
180
181enum FB_TYPE {
182	FB_TEXT = -1,
183	FB_GOP,
184	FB_UGA,
185	FB_VBE
186};
187
188enum COLOR_TYPE {
189	CT_INDEXED,
190	CT_RGB
191};
192
193struct gen_fb {
194	uint64_t	fb_addr;
195	uint64_t	fb_size;
196	uint32_t	fb_height;
197	uint32_t	fb_width;
198	uint32_t	fb_stride;
199	uint32_t	fb_mask_red;
200	uint32_t	fb_mask_green;
201	uint32_t	fb_mask_blue;
202	uint32_t	fb_mask_reserved;
203	uint32_t	fb_bpp;
204};
205
206typedef struct teken_gfx {
207	enum FB_TYPE	tg_fb_type;
208	enum COLOR_TYPE tg_ctype;
209	unsigned	tg_mode;
210	teken_t		tg_teken;		/* Teken core */
211	teken_pos_t	tg_cursor;		/* Where cursor was drawn */
212	bool		tg_cursor_visible;
213	uint8_t		*tg_cursor_image;	/* Memory for cursor */
214	size_t		tg_cursor_size;
215	teken_pos_t	tg_tp;			/* Terminal dimensions */
216	teken_pos_t	tg_origin;		/* Point of origin in pixels */
217	uint8_t		*tg_glyph;		/* Memory for glyph */
218	size_t		tg_glyph_size;
219	struct vt_font	tg_font;
220	struct gen_fb	tg_fb;
221	teken_funcs_t	*tg_functions;
222	void		*tg_private;
223	bool		tg_kernel_supported;	/* Loaded kernel is supported */
224} teken_gfx_t;
225
226extern font_list_t fonts;
227extern teken_gfx_t gfx_state;
228
229typedef enum {
230	GfxFbBltVideoFill,
231	GfxFbBltVideoToBltBuffer,
232	GfxFbBltBufferToVideo,
233	GfxFbBltVideoToVideo,
234	GfxFbBltOperationMax,
235} GFXFB_BLT_OPERATION;
236
237int gfxfb_blt(void *, GFXFB_BLT_OPERATION, uint32_t, uint32_t,
238    uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
239
240int generate_cons_palette(uint32_t *, int, uint32_t, int, uint32_t, int,
241    uint32_t, int);
242bool console_update_mode(bool);
243void setup_font(teken_gfx_t *, teken_unit_t, teken_unit_t);
244uint8_t *font_lookup(const struct vt_font *, teken_char_t,
245    const teken_attr_t *);
246void bios_text_font(bool);
247
248/* teken callbacks. */
249tf_cursor_t gfx_fb_cursor;
250tf_putchar_t gfx_fb_putchar;
251tf_fill_t gfx_fb_fill;
252tf_copy_t gfx_fb_copy;
253tf_param_t gfx_fb_param;
254
255/* Screen buffer element */
256struct text_pixel {
257	teken_char_t c;
258	teken_attr_t a;
259};
260
261extern const int cons_to_vga_colors[NCOLORS];
262
263/* Screen buffer to track changes on the terminal screen. */
264extern struct text_pixel *screen_buffer;
265bool is_same_pixel(struct text_pixel *, struct text_pixel *);
266
267bool gfx_get_edid_resolution(struct vesa_edid_info *, edid_res_list_t *);
268void gfx_framework_init(void);
269void gfx_fb_cons_display(uint32_t, uint32_t, uint32_t, uint32_t, void *);
270void gfx_fb_setpixel(uint32_t, uint32_t);
271void gfx_fb_drawrect(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
272void gfx_term_drawrect(uint32_t, uint32_t, uint32_t, uint32_t);
273void gfx_fb_line(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
274void gfx_fb_bezier(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t,
275	uint32_t);
276
277#define	FL_PUTIMAGE_BORDER	0x1
278#define	FL_PUTIMAGE_NOSCROLL	0x2
279#define	FL_PUTIMAGE_DEBUG	0x80
280
281int gfx_fb_putimage(png_t *, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
282bool gfx_parse_mode_str(char *, int *, int *, int *);
283void term_image_display(teken_gfx_t *, const teken_rect_t *);
284
285void reset_font_flags(void);
286
287#ifdef __cplusplus
288}
289#endif
290
291#endif /* _GFX_FB_H */
292