1 /*
2  * Copyright (c) 2015 Google, Inc
3  * (C) Copyright 2001-2015
4  * DENX Software Engineering -- wd@denx.de
5  * Compulab Ltd - http://compulab.co.il/
6  * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
7  *
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 
11 #include <common.h>
12 #include <dm.h>
13 #include <video.h>
14 #include <video_console.h>
15 #include <video_font.h>		/* Get font data, width and height */
16 
17 static int console_normal_set_row(struct udevice *dev, uint row, int clr)
18 {
19 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
20 	void *line;
21 	int pixels = VIDEO_FONT_HEIGHT * vid_priv->line_length;
22 	int i;
23 
24 	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
25 	switch (vid_priv->bpix) {
26 #ifdef CONFIG_VIDEO_BPP8
27 	case VIDEO_BPP8: {
28 		uint8_t *dst = line;
29 
30 		for (i = 0; i < pixels; i++)
31 			*dst++ = clr;
32 		break;
33 	}
34 #endif
35 #ifdef CONFIG_VIDEO_BPP16
36 	case VIDEO_BPP16: {
37 		uint16_t *dst = line;
38 
39 		for (i = 0; i < pixels; i++)
40 			*dst++ = clr;
41 		break;
42 	}
43 #endif
44 #ifdef CONFIG_VIDEO_BPP32
45 	case VIDEO_BPP32: {
46 		uint32_t *dst = line;
47 
48 		for (i = 0; i < pixels; i++)
49 			*dst++ = clr;
50 		break;
51 	}
52 #endif
53 	default:
54 		return -ENOSYS;
55 	}
56 
57 	return 0;
58 }
59 
60 static int console_normal_move_rows(struct udevice *dev, uint rowdst,
61 				     uint rowsrc, uint count)
62 {
63 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
64 	void *dst;
65 	void *src;
66 
67 	dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
68 	src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
69 	memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
70 
71 	return 0;
72 }
73 
74 static int console_normal_putc_xy(struct udevice *dev, uint x, uint y, char ch)
75 {
76 	struct udevice *vid = dev->parent;
77 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
78 	int i, row;
79 	void *line = vid_priv->fb + y * vid_priv->line_length +
80 		x * VNBYTES(vid_priv->bpix);
81 
82 	for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
83 		uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
84 
85 		switch (vid_priv->bpix) {
86 #ifdef CONFIG_VIDEO_BPP8
87 		case VIDEO_BPP8: {
88 			uint8_t *dst = line;
89 
90 			for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
91 				*dst++ = (bits & 0x80) ? vid_priv->colour_fg
92 					: vid_priv->colour_bg;
93 				bits <<= 1;
94 			}
95 			break;
96 		}
97 #endif
98 #ifdef CONFIG_VIDEO_BPP16
99 		case VIDEO_BPP16: {
100 			uint16_t *dst = line;
101 
102 			for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
103 				*dst++ = (bits & 0x80) ? vid_priv->colour_fg
104 					: vid_priv->colour_bg;
105 				bits <<= 1;
106 			}
107 			break;
108 		}
109 #endif
110 #ifdef CONFIG_VIDEO_BPP32
111 		case VIDEO_BPP32: {
112 			uint32_t *dst = line;
113 
114 			for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
115 				*dst++ = (bits & 0x80) ? vid_priv->colour_fg
116 					: vid_priv->colour_bg;
117 				bits <<= 1;
118 			}
119 			break;
120 		}
121 #endif
122 		default:
123 			return -ENOSYS;
124 		}
125 		line += vid_priv->line_length;
126 	}
127 
128 	return 0;
129 }
130 
131 struct vidconsole_ops console_normal_ops = {
132 	.putc_xy	= console_normal_putc_xy,
133 	.move_rows	= console_normal_move_rows,
134 	.set_row	= console_normal_set_row,
135 };
136 
137 U_BOOT_DRIVER(vidconsole_normal) = {
138 	.name	= "vidconsole0",
139 	.id	= UCLASS_VIDEO_CONSOLE,
140 	.ops	= &console_normal_ops,
141 };
142