• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2015 Google, Inc
4  * (C) Copyright 2015
5  * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <video.h>
11 #include <video_console.h>
12 #include <video_font.h>		/* Get font data, width and height */
13 
console_set_row_1(struct udevice * dev,uint row,int clr)14 static int console_set_row_1(struct udevice *dev, uint row, int clr)
15 {
16 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
17 	int pbytes = VNBYTES(vid_priv->bpix);
18 	void *line;
19 	int i, j;
20 
21 	line = vid_priv->fb + vid_priv->line_length -
22 		(row + 1) * VIDEO_FONT_HEIGHT * pbytes;
23 	for (j = 0; j < vid_priv->ysize; j++) {
24 		switch (vid_priv->bpix) {
25 		case VIDEO_BPP8:
26 			if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
27 				uint8_t *dst = line;
28 
29 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
30 					*dst++ = clr;
31 				break;
32 			}
33 		case VIDEO_BPP16:
34 			if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
35 				uint16_t *dst = line;
36 
37 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
38 					*dst++ = clr;
39 				break;
40 			}
41 		case VIDEO_BPP32:
42 			if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
43 				uint32_t *dst = line;
44 
45 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
46 					*dst++ = clr;
47 				break;
48 			}
49 		default:
50 			return -ENOSYS;
51 		}
52 		line += vid_priv->line_length;
53 	}
54 
55 	return 0;
56 }
57 
console_move_rows_1(struct udevice * dev,uint rowdst,uint rowsrc,uint count)58 static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
59 			       uint count)
60 {
61 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
62 	void *dst;
63 	void *src;
64 	int pbytes = VNBYTES(vid_priv->bpix);
65 	int j;
66 
67 	dst = vid_priv->fb + vid_priv->line_length -
68 		(rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
69 	src = vid_priv->fb + vid_priv->line_length -
70 		(rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
71 
72 	for (j = 0; j < vid_priv->ysize; j++) {
73 		memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
74 		src += vid_priv->line_length;
75 		dst += vid_priv->line_length;
76 	}
77 
78 	return 0;
79 }
80 
console_putc_xy_1(struct udevice * dev,uint x_frac,uint y,char ch)81 static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
82 {
83 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
84 	struct udevice *vid = dev->parent;
85 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
86 	int pbytes = VNBYTES(vid_priv->bpix);
87 	int i, col;
88 	int mask = 0x80;
89 	void *line;
90 	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
91 
92 	line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) *
93 			vid_priv->line_length - (y + 1) * pbytes;
94 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
95 		return -EAGAIN;
96 
97 	for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
98 		switch (vid_priv->bpix) {
99 		case VIDEO_BPP8:
100 			if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
101 				uint8_t *dst = line;
102 
103 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
104 					*dst-- = (pfont[i] & mask) ?
105 						vid_priv->colour_fg :
106 						vid_priv->colour_bg;
107 				}
108 				break;
109 			}
110 		case VIDEO_BPP16:
111 			if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
112 				uint16_t *dst = line;
113 
114 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
115 					*dst-- = (pfont[i] & mask) ?
116 						vid_priv->colour_fg :
117 						vid_priv->colour_bg;
118 				}
119 				break;
120 			}
121 		case VIDEO_BPP32:
122 			if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
123 				uint32_t *dst = line;
124 
125 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
126 					*dst-- = (pfont[i] & mask) ?
127 						vid_priv->colour_fg :
128 						vid_priv->colour_bg;
129 				}
130 				break;
131 			}
132 		default:
133 			return -ENOSYS;
134 		}
135 		line += vid_priv->line_length;
136 		mask >>= 1;
137 	}
138 
139 	return VID_TO_POS(VIDEO_FONT_WIDTH);
140 }
141 
142 
console_set_row_2(struct udevice * dev,uint row,int clr)143 static int console_set_row_2(struct udevice *dev, uint row, int clr)
144 {
145 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
146 	void *line;
147 	int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
148 	int i;
149 
150 	line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
151 		(row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
152 	switch (vid_priv->bpix) {
153 	case VIDEO_BPP8:
154 		if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
155 			uint8_t *dst = line;
156 
157 			for (i = 0; i < pixels; i++)
158 				*dst++ = clr;
159 			break;
160 		}
161 	case VIDEO_BPP16:
162 		if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
163 			uint16_t *dst = line;
164 
165 			for (i = 0; i < pixels; i++)
166 				*dst++ = clr;
167 			break;
168 		}
169 	case VIDEO_BPP32:
170 		if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
171 			uint32_t *dst = line;
172 
173 			for (i = 0; i < pixels; i++)
174 				*dst++ = clr;
175 			break;
176 		}
177 	default:
178 		return -ENOSYS;
179 	}
180 
181 	return 0;
182 }
183 
console_move_rows_2(struct udevice * dev,uint rowdst,uint rowsrc,uint count)184 static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
185 			       uint count)
186 {
187 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
188 	void *dst;
189 	void *src;
190 	void *end;
191 
192 	end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length;
193 	dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT *
194 		vid_priv->line_length;
195 	src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
196 		vid_priv->line_length;
197 	memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
198 
199 	return 0;
200 }
201 
console_putc_xy_2(struct udevice * dev,uint x_frac,uint y,char ch)202 static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
203 {
204 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
205 	struct udevice *vid = dev->parent;
206 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
207 	int i, row;
208 	void *line;
209 
210 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
211 		return -EAGAIN;
212 
213 	line = vid_priv->fb + (vid_priv->ysize - y - 1) *
214 			vid_priv->line_length +
215 			(vid_priv->xsize - VID_TO_PIXEL(x_frac) -
216 			VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix);
217 
218 	for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
219 		unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
220 		uchar bits = video_fontdata[idx];
221 
222 		switch (vid_priv->bpix) {
223 		case VIDEO_BPP8:
224 			if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
225 				uint8_t *dst = line;
226 
227 				for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
228 					*dst-- = (bits & 0x80) ?
229 						vid_priv->colour_fg :
230 						vid_priv->colour_bg;
231 					bits <<= 1;
232 				}
233 				break;
234 			}
235 		case VIDEO_BPP16:
236 			if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
237 				uint16_t *dst = line;
238 
239 				for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
240 					*dst-- = (bits & 0x80) ?
241 						vid_priv->colour_fg :
242 						vid_priv->colour_bg;
243 					bits <<= 1;
244 				}
245 				break;
246 			}
247 		case VIDEO_BPP32:
248 			if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
249 				uint32_t *dst = line;
250 
251 				for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
252 					*dst-- = (bits & 0x80) ?
253 						vid_priv->colour_fg :
254 						vid_priv->colour_bg;
255 					bits <<= 1;
256 				}
257 				break;
258 			}
259 		default:
260 			return -ENOSYS;
261 		}
262 		line -= vid_priv->line_length;
263 	}
264 
265 	return VID_TO_POS(VIDEO_FONT_WIDTH);
266 }
267 
console_set_row_3(struct udevice * dev,uint row,int clr)268 static int console_set_row_3(struct udevice *dev, uint row, int clr)
269 {
270 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
271 	int pbytes = VNBYTES(vid_priv->bpix);
272 	void *line;
273 	int i, j;
274 
275 	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
276 	for (j = 0; j < vid_priv->ysize; j++) {
277 		switch (vid_priv->bpix) {
278 		case VIDEO_BPP8:
279 			if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
280 				uint8_t *dst = line;
281 
282 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
283 					*dst++ = clr;
284 				break;
285 			}
286 		case VIDEO_BPP16:
287 			if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
288 				uint16_t *dst = line;
289 
290 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
291 					*dst++ = clr;
292 				break;
293 			}
294 		case VIDEO_BPP32:
295 			if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
296 				uint32_t *dst = line;
297 
298 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
299 					*dst++ = clr;
300 				break;
301 			}
302 		default:
303 			return -ENOSYS;
304 		}
305 		line += vid_priv->line_length;
306 	}
307 
308 	return 0;
309 }
310 
console_move_rows_3(struct udevice * dev,uint rowdst,uint rowsrc,uint count)311 static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
312 			       uint count)
313 {
314 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
315 	void *dst;
316 	void *src;
317 	int pbytes = VNBYTES(vid_priv->bpix);
318 	int j;
319 
320 	dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
321 	src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
322 
323 	for (j = 0; j < vid_priv->ysize; j++) {
324 		memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count);
325 		src += vid_priv->line_length;
326 		dst += vid_priv->line_length;
327 	}
328 
329 	return 0;
330 }
331 
console_putc_xy_3(struct udevice * dev,uint x_frac,uint y,char ch)332 static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
333 {
334 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
335 	struct udevice *vid = dev->parent;
336 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
337 	int pbytes = VNBYTES(vid_priv->bpix);
338 	int i, col;
339 	int mask = 0x80;
340 	void *line = vid_priv->fb +
341 		(vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) *
342 		vid_priv->line_length + y * pbytes;
343 	uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
344 
345 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
346 		return -EAGAIN;
347 
348 	for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
349 		switch (vid_priv->bpix) {
350 		case VIDEO_BPP8:
351 			if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
352 				uint8_t *dst = line;
353 
354 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
355 					*dst++ = (pfont[i] & mask) ?
356 						vid_priv->colour_fg :
357 						vid_priv->colour_bg;
358 				}
359 				break;
360 			}
361 		case VIDEO_BPP16:
362 			if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
363 				uint16_t *dst = line;
364 
365 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
366 					*dst++ = (pfont[i] & mask) ?
367 						vid_priv->colour_fg :
368 						vid_priv->colour_bg;
369 				}
370 				break;
371 			}
372 		case VIDEO_BPP32:
373 			if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
374 				uint32_t *dst = line;
375 
376 				for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
377 					*dst++ = (pfont[i] & mask) ?
378 						vid_priv->colour_fg :
379 						vid_priv->colour_bg;
380 				}
381 				break;
382 			}
383 		default:
384 			return -ENOSYS;
385 		}
386 		line -= vid_priv->line_length;
387 		mask >>= 1;
388 	}
389 
390 	return VID_TO_POS(VIDEO_FONT_WIDTH);
391 }
392 
393 
console_probe_2(struct udevice * dev)394 static int console_probe_2(struct udevice *dev)
395 {
396 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
397 	struct udevice *vid_dev = dev->parent;
398 	struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
399 
400 	vc_priv->x_charsize = VIDEO_FONT_WIDTH;
401 	vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
402 	vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
403 	vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
404 
405 	return 0;
406 }
407 
console_probe_1_3(struct udevice * dev)408 static int console_probe_1_3(struct udevice *dev)
409 {
410 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
411 	struct udevice *vid_dev = dev->parent;
412 	struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
413 
414 	vc_priv->x_charsize = VIDEO_FONT_WIDTH;
415 	vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
416 	vc_priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH;
417 	vc_priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT;
418 	vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize);
419 
420 	return 0;
421 }
422 
423 struct vidconsole_ops console_ops_1 = {
424 	.putc_xy	= console_putc_xy_1,
425 	.move_rows	= console_move_rows_1,
426 	.set_row	= console_set_row_1,
427 };
428 
429 struct vidconsole_ops console_ops_2 = {
430 	.putc_xy	= console_putc_xy_2,
431 	.move_rows	= console_move_rows_2,
432 	.set_row	= console_set_row_2,
433 };
434 
435 struct vidconsole_ops console_ops_3 = {
436 	.putc_xy	= console_putc_xy_3,
437 	.move_rows	= console_move_rows_3,
438 	.set_row	= console_set_row_3,
439 };
440 
441 U_BOOT_DRIVER(vidconsole_1) = {
442 	.name	= "vidconsole1",
443 	.id	= UCLASS_VIDEO_CONSOLE,
444 	.ops	= &console_ops_1,
445 	.probe	= console_probe_1_3,
446 };
447 
448 U_BOOT_DRIVER(vidconsole_2) = {
449 	.name	= "vidconsole2",
450 	.id	= UCLASS_VIDEO_CONSOLE,
451 	.ops	= &console_ops_2,
452 	.probe	= console_probe_2,
453 };
454 
455 U_BOOT_DRIVER(vidconsole_3) = {
456 	.name	= "vidconsole3",
457 	.id	= UCLASS_VIDEO_CONSOLE,
458 	.ops	= &console_ops_3,
459 	.probe	= console_probe_1_3,
460 };
461