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