uboot/drivers/video/console_rotate.c
<<
>>
Prefs
   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
  15static 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
  62static 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
  85static 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
 147static 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
 191static 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
 209static 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
 274static 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
 320static 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
 341static 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
 403static 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
 417static 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
 432struct 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
 438struct 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
 444struct 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
 450U_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
 457U_BOOT_DRIVER(vidconsole_2) = {
 458        .name   = "vidconsole2",
 459        .id     = UCLASS_VIDEO_CONSOLE,
 460        .ops    = &console_ops_2,
 461        .probe  = console_probe_2,
 462};
 463
 464U_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