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->xsize;
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_frac, uint y,
75 				  char ch)
76 {
77 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
78 	struct udevice *vid = dev->parent;
79 	struct video_priv *vid_priv = dev_get_uclass_priv(vid);
80 	int i, row;
81 	void *line = vid_priv->fb + y * vid_priv->line_length +
82 		VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
83 
84 	if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
85 		return -EAGAIN;
86 
87 	for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
88 		uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row];
89 
90 		switch (vid_priv->bpix) {
91 #ifdef CONFIG_VIDEO_BPP8
92 		case VIDEO_BPP8: {
93 			uint8_t *dst = line;
94 
95 			for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
96 				*dst++ = (bits & 0x80) ? vid_priv->colour_fg
97 					: vid_priv->colour_bg;
98 				bits <<= 1;
99 			}
100 			break;
101 		}
102 #endif
103 #ifdef CONFIG_VIDEO_BPP16
104 		case VIDEO_BPP16: {
105 			uint16_t *dst = line;
106 
107 			for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
108 				*dst++ = (bits & 0x80) ? vid_priv->colour_fg
109 					: vid_priv->colour_bg;
110 				bits <<= 1;
111 			}
112 			break;
113 		}
114 #endif
115 #ifdef CONFIG_VIDEO_BPP32
116 		case VIDEO_BPP32: {
117 			uint32_t *dst = line;
118 
119 			for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
120 				*dst++ = (bits & 0x80) ? vid_priv->colour_fg
121 					: vid_priv->colour_bg;
122 				bits <<= 1;
123 			}
124 			break;
125 		}
126 #endif
127 		default:
128 			return -ENOSYS;
129 		}
130 		line += vid_priv->line_length;
131 	}
132 
133 	return VID_TO_POS(VIDEO_FONT_WIDTH);
134 }
135 
136 static int console_normal_probe(struct udevice *dev)
137 {
138 	struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
139 	struct udevice *vid_dev = dev->parent;
140 	struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
141 
142 	vc_priv->x_charsize = VIDEO_FONT_WIDTH;
143 	vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
144 	vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
145 	vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
146 
147 	return 0;
148 }
149 
150 struct vidconsole_ops console_normal_ops = {
151 	.putc_xy	= console_normal_putc_xy,
152 	.move_rows	= console_normal_move_rows,
153 	.set_row	= console_normal_set_row,
154 };
155 
156 U_BOOT_DRIVER(vidconsole_normal) = {
157 	.name	= "vidconsole0",
158 	.id	= UCLASS_VIDEO_CONSOLE,
159 	.ops	= &console_normal_ops,
160 	.probe	= console_normal_probe,
161 };
162