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