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_frac, uint y, char ch) 86 { 87 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 88 struct udevice *vid = dev->parent; 89 struct video_priv *vid_priv = dev_get_uclass_priv(vid); 90 int pbytes = VNBYTES(vid_priv->bpix); 91 int i, col; 92 int mask = 0x80; 93 void *line; 94 uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT; 95 96 line = vid_priv->fb + (VID_TO_PIXEL(x_frac) + 1) * 97 vid_priv->line_length - (y + 1) * pbytes; 98 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) 99 return -EAGAIN; 100 101 for (col = 0; col < VIDEO_FONT_HEIGHT; col++) { 102 switch (vid_priv->bpix) { 103 #ifdef CONFIG_VIDEO_BPP8 104 case VIDEO_BPP8: { 105 uint8_t *dst = line; 106 107 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { 108 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg 109 : vid_priv->colour_bg; 110 } 111 break; 112 } 113 #endif 114 #ifdef CONFIG_VIDEO_BPP16 115 case VIDEO_BPP16: { 116 uint16_t *dst = line; 117 118 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { 119 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg 120 : vid_priv->colour_bg; 121 } 122 break; 123 } 124 #endif 125 #ifdef CONFIG_VIDEO_BPP32 126 case VIDEO_BPP32: { 127 uint32_t *dst = line; 128 129 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { 130 *dst-- = (pfont[i] & mask) ? vid_priv->colour_fg 131 : vid_priv->colour_bg; 132 } 133 break; 134 } 135 #endif 136 default: 137 return -ENOSYS; 138 } 139 line += vid_priv->line_length; 140 mask >>= 1; 141 } 142 143 return VID_TO_POS(VIDEO_FONT_WIDTH); 144 } 145 146 147 static int console_set_row_2(struct udevice *dev, uint row, int clr) 148 { 149 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 150 void *line; 151 int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize; 152 int i; 153 154 line = vid_priv->fb + vid_priv->ysize * vid_priv->line_length - 155 (row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length; 156 switch (vid_priv->bpix) { 157 #ifdef CONFIG_VIDEO_BPP8 158 case VIDEO_BPP8: { 159 uint8_t *dst = line; 160 161 for (i = 0; i < pixels; i++) 162 *dst++ = clr; 163 break; 164 } 165 #endif 166 #ifdef CONFIG_VIDEO_BPP16 167 case VIDEO_BPP16: { 168 uint16_t *dst = line; 169 170 for (i = 0; i < pixels; i++) 171 *dst++ = clr; 172 break; 173 } 174 #endif 175 #ifdef CONFIG_VIDEO_BPP32 176 case VIDEO_BPP32: { 177 uint32_t *dst = line; 178 179 for (i = 0; i < pixels; i++) 180 *dst++ = clr; 181 break; 182 } 183 #endif 184 default: 185 return -ENOSYS; 186 } 187 188 return 0; 189 } 190 191 static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc, 192 uint count) 193 { 194 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 195 void *dst; 196 void *src; 197 void *end; 198 199 end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length; 200 dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT * 201 vid_priv->line_length; 202 src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT * 203 vid_priv->line_length; 204 memmove(dst, src, VIDEO_FONT_HEIGHT * vid_priv->line_length * count); 205 206 return 0; 207 } 208 209 static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch) 210 { 211 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 212 struct udevice *vid = dev->parent; 213 struct video_priv *vid_priv = dev_get_uclass_priv(vid); 214 int i, row; 215 void *line; 216 217 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) 218 return -EAGAIN; 219 220 line = vid_priv->fb + (vid_priv->ysize - y - 1) * 221 vid_priv->line_length + 222 (vid_priv->xsize - VID_TO_PIXEL(x_frac) - 223 VIDEO_FONT_WIDTH - 1) * VNBYTES(vid_priv->bpix); 224 225 for (row = 0; row < VIDEO_FONT_HEIGHT; row++) { 226 uchar bits = video_fontdata[ch * VIDEO_FONT_HEIGHT + row]; 227 228 switch (vid_priv->bpix) { 229 #ifdef CONFIG_VIDEO_BPP8 230 case VIDEO_BPP8: { 231 uint8_t *dst = line; 232 233 for (i = 0; i < VIDEO_FONT_WIDTH; i++) { 234 *dst-- = (bits & 0x80) ? vid_priv->colour_fg 235 : vid_priv->colour_bg; 236 bits <<= 1; 237 } 238 break; 239 } 240 #endif 241 #ifdef CONFIG_VIDEO_BPP16 242 case VIDEO_BPP16: { 243 uint16_t *dst = line; 244 245 for (i = 0; i < VIDEO_FONT_WIDTH; i++) { 246 *dst-- = (bits & 0x80) ? vid_priv->colour_fg 247 : vid_priv->colour_bg; 248 bits <<= 1; 249 } 250 break; 251 } 252 #endif 253 #ifdef CONFIG_VIDEO_BPP32 254 case VIDEO_BPP32: { 255 uint32_t *dst = line; 256 257 for (i = 0; i < VIDEO_FONT_WIDTH; i++) { 258 *dst-- = (bits & 0x80) ? vid_priv->colour_fg 259 : vid_priv->colour_bg; 260 bits <<= 1; 261 } 262 break; 263 } 264 #endif 265 default: 266 return -ENOSYS; 267 } 268 line -= vid_priv->line_length; 269 } 270 271 return VID_TO_POS(VIDEO_FONT_WIDTH); 272 } 273 274 static int console_set_row_3(struct udevice *dev, uint row, int clr) 275 { 276 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 277 int pbytes = VNBYTES(vid_priv->bpix); 278 void *line; 279 int i, j; 280 281 line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes; 282 for (j = 0; j < vid_priv->ysize; j++) { 283 switch (vid_priv->bpix) { 284 #ifdef CONFIG_VIDEO_BPP8 285 case VIDEO_BPP8: { 286 uint8_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_BPP16 294 case VIDEO_BPP16: { 295 uint16_t *dst = line; 296 297 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) 298 *dst++ = clr; 299 break; 300 } 301 #endif 302 #ifdef CONFIG_VIDEO_BPP32 303 case VIDEO_BPP32: { 304 uint32_t *dst = line; 305 306 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) 307 *dst++ = clr; 308 break; 309 } 310 #endif 311 default: 312 return -ENOSYS; 313 } 314 line += vid_priv->line_length; 315 } 316 317 return 0; 318 } 319 320 static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc, 321 uint count) 322 { 323 struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); 324 void *dst; 325 void *src; 326 int pbytes = VNBYTES(vid_priv->bpix); 327 int j; 328 329 dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes; 330 src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes; 331 332 for (j = 0; j < vid_priv->ysize; j++) { 333 memmove(dst, src, VIDEO_FONT_HEIGHT * pbytes * count); 334 src += vid_priv->line_length; 335 dst += vid_priv->line_length; 336 } 337 338 return 0; 339 } 340 341 static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch) 342 { 343 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 344 struct udevice *vid = dev->parent; 345 struct video_priv *vid_priv = dev_get_uclass_priv(vid); 346 int pbytes = VNBYTES(vid_priv->bpix); 347 int i, col; 348 int mask = 0x80; 349 void *line = vid_priv->fb + 350 (vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1) * 351 vid_priv->line_length + y * pbytes; 352 uchar *pfont = video_fontdata + ch * VIDEO_FONT_HEIGHT; 353 354 if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac) 355 return -EAGAIN; 356 357 for (col = 0; col < VIDEO_FONT_HEIGHT; col++) { 358 switch (vid_priv->bpix) { 359 #ifdef CONFIG_VIDEO_BPP8 360 case VIDEO_BPP8: { 361 uint8_t *dst = line; 362 363 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { 364 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg 365 : vid_priv->colour_bg; 366 } 367 break; 368 } 369 #endif 370 #ifdef CONFIG_VIDEO_BPP16 371 case VIDEO_BPP16: { 372 uint16_t *dst = line; 373 374 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { 375 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg 376 : vid_priv->colour_bg; 377 } 378 break; 379 } 380 #endif 381 #ifdef CONFIG_VIDEO_BPP32 382 case VIDEO_BPP32: { 383 uint32_t *dst = line; 384 385 for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { 386 *dst++ = (pfont[i] & mask) ? vid_priv->colour_fg 387 : vid_priv->colour_bg; 388 } 389 break; 390 } 391 #endif 392 default: 393 return -ENOSYS; 394 } 395 line -= vid_priv->line_length; 396 mask >>= 1; 397 } 398 399 return VID_TO_POS(VIDEO_FONT_WIDTH); 400 } 401 402 403 static int console_probe_2(struct udevice *dev) 404 { 405 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 406 struct udevice *vid_dev = dev->parent; 407 struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); 408 409 vc_priv->x_charsize = VIDEO_FONT_WIDTH; 410 vc_priv->y_charsize = VIDEO_FONT_HEIGHT; 411 vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH; 412 vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT; 413 414 return 0; 415 } 416 417 static int console_probe_1_3(struct udevice *dev) 418 { 419 struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); 420 struct udevice *vid_dev = dev->parent; 421 struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); 422 423 vc_priv->x_charsize = VIDEO_FONT_WIDTH; 424 vc_priv->y_charsize = VIDEO_FONT_HEIGHT; 425 vc_priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH; 426 vc_priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT; 427 vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize); 428 429 return 0; 430 } 431 432 struct vidconsole_ops console_ops_1 = { 433 .putc_xy = console_putc_xy_1, 434 .move_rows = console_move_rows_1, 435 .set_row = console_set_row_1, 436 }; 437 438 struct vidconsole_ops console_ops_2 = { 439 .putc_xy = console_putc_xy_2, 440 .move_rows = console_move_rows_2, 441 .set_row = console_set_row_2, 442 }; 443 444 struct vidconsole_ops console_ops_3 = { 445 .putc_xy = console_putc_xy_3, 446 .move_rows = console_move_rows_3, 447 .set_row = console_set_row_3, 448 }; 449 450 U_BOOT_DRIVER(vidconsole_1) = { 451 .name = "vidconsole1", 452 .id = UCLASS_VIDEO_CONSOLE, 453 .ops = &console_ops_1, 454 .probe = console_probe_1_3, 455 }; 456 457 U_BOOT_DRIVER(vidconsole_2) = { 458 .name = "vidconsole2", 459 .id = UCLASS_VIDEO_CONSOLE, 460 .ops = &console_ops_2, 461 .probe = console_probe_2, 462 }; 463 464 U_BOOT_DRIVER(vidconsole_3) = { 465 .name = "vidconsole3", 466 .id = UCLASS_VIDEO_CONSOLE, 467 .ops = &console_ops_3, 468 .probe = console_probe_1_3, 469 }; 470