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