qemu/hw/display/pxa2xx_lcd.c
<<
>>
Prefs
   1/*
   2 * Intel XScale PXA255/270 LCDC emulation.
   3 *
   4 * Copyright (c) 2006 Openedhand Ltd.
   5 * Written by Andrzej Zaborowski <balrog@zabor.org>
   6 *
   7 * This code is licensed under the GPLv2.
   8 *
   9 * Contributions after 2012-01-13 are licensed under the terms of the
  10 * GNU GPL, version 2 or (at your option) any later version.
  11 */
  12
  13#include "qemu/osdep.h"
  14#include "hw/hw.h"
  15#include "hw/irq.h"
  16#include "migration/vmstate.h"
  17#include "ui/console.h"
  18#include "hw/arm/pxa.h"
  19#include "ui/pixel_ops.h"
  20/* FIXME: For graphic_rotate. Should probably be done in common code.  */
  21#include "sysemu/sysemu.h"
  22#include "framebuffer.h"
  23
  24struct DMAChannel {
  25    uint32_t branch;
  26    uint8_t up;
  27    uint8_t palette[1024];
  28    uint8_t pbuffer[1024];
  29    void (*redraw)(PXA2xxLCDState *s, hwaddr addr,
  30                   int *miny, int *maxy);
  31
  32    uint32_t descriptor;
  33    uint32_t source;
  34    uint32_t id;
  35    uint32_t command;
  36};
  37
  38struct PXA2xxLCDState {
  39    MemoryRegion *sysmem;
  40    MemoryRegion iomem;
  41    MemoryRegionSection fbsection;
  42    qemu_irq irq;
  43    int irqlevel;
  44
  45    int invalidated;
  46    QemuConsole *con;
  47    drawfn *line_fn[2];
  48    int dest_width;
  49    int xres, yres;
  50    int pal_for;
  51    int transp;
  52    enum {
  53        pxa_lcdc_2bpp = 1,
  54        pxa_lcdc_4bpp = 2,
  55        pxa_lcdc_8bpp = 3,
  56        pxa_lcdc_16bpp = 4,
  57        pxa_lcdc_18bpp = 5,
  58        pxa_lcdc_18pbpp = 6,
  59        pxa_lcdc_19bpp = 7,
  60        pxa_lcdc_19pbpp = 8,
  61        pxa_lcdc_24bpp = 9,
  62        pxa_lcdc_25bpp = 10,
  63    } bpp;
  64
  65    uint32_t control[6];
  66    uint32_t status[2];
  67    uint32_t ovl1c[2];
  68    uint32_t ovl2c[2];
  69    uint32_t ccr;
  70    uint32_t cmdcr;
  71    uint32_t trgbr;
  72    uint32_t tcr;
  73    uint32_t liidr;
  74    uint8_t bscntr;
  75
  76    struct DMAChannel dma_ch[7];
  77
  78    qemu_irq vsync_cb;
  79    int orientation;
  80};
  81
  82typedef struct QEMU_PACKED {
  83    uint32_t fdaddr;
  84    uint32_t fsaddr;
  85    uint32_t fidr;
  86    uint32_t ldcmd;
  87} PXAFrameDescriptor;
  88
  89#define LCCR0   0x000   /* LCD Controller Control register 0 */
  90#define LCCR1   0x004   /* LCD Controller Control register 1 */
  91#define LCCR2   0x008   /* LCD Controller Control register 2 */
  92#define LCCR3   0x00c   /* LCD Controller Control register 3 */
  93#define LCCR4   0x010   /* LCD Controller Control register 4 */
  94#define LCCR5   0x014   /* LCD Controller Control register 5 */
  95
  96#define FBR0    0x020   /* DMA Channel 0 Frame Branch register */
  97#define FBR1    0x024   /* DMA Channel 1 Frame Branch register */
  98#define FBR2    0x028   /* DMA Channel 2 Frame Branch register */
  99#define FBR3    0x02c   /* DMA Channel 3 Frame Branch register */
 100#define FBR4    0x030   /* DMA Channel 4 Frame Branch register */
 101#define FBR5    0x110   /* DMA Channel 5 Frame Branch register */
 102#define FBR6    0x114   /* DMA Channel 6 Frame Branch register */
 103
 104#define LCSR1   0x034   /* LCD Controller Status register 1 */
 105#define LCSR0   0x038   /* LCD Controller Status register 0 */
 106#define LIIDR   0x03c   /* LCD Controller Interrupt ID register */
 107
 108#define TRGBR   0x040   /* TMED RGB Seed register */
 109#define TCR     0x044   /* TMED Control register */
 110
 111#define OVL1C1  0x050   /* Overlay 1 Control register 1 */
 112#define OVL1C2  0x060   /* Overlay 1 Control register 2 */
 113#define OVL2C1  0x070   /* Overlay 2 Control register 1 */
 114#define OVL2C2  0x080   /* Overlay 2 Control register 2 */
 115#define CCR     0x090   /* Cursor Control register */
 116
 117#define CMDCR   0x100   /* Command Control register */
 118#define PRSR    0x104   /* Panel Read Status register */
 119
 120#define PXA_LCDDMA_CHANS        7
 121#define DMA_FDADR               0x00    /* Frame Descriptor Address register */
 122#define DMA_FSADR               0x04    /* Frame Source Address register */
 123#define DMA_FIDR                0x08    /* Frame ID register */
 124#define DMA_LDCMD               0x0c    /* Command register */
 125
 126/* LCD Buffer Strength Control register */
 127#define BSCNTR  0x04000054
 128
 129/* Bitfield masks */
 130#define LCCR0_ENB       (1 << 0)
 131#define LCCR0_CMS       (1 << 1)
 132#define LCCR0_SDS       (1 << 2)
 133#define LCCR0_LDM       (1 << 3)
 134#define LCCR0_SOFM0     (1 << 4)
 135#define LCCR0_IUM       (1 << 5)
 136#define LCCR0_EOFM0     (1 << 6)
 137#define LCCR0_PAS       (1 << 7)
 138#define LCCR0_DPD       (1 << 9)
 139#define LCCR0_DIS       (1 << 10)
 140#define LCCR0_QDM       (1 << 11)
 141#define LCCR0_PDD       (0xff << 12)
 142#define LCCR0_BSM0      (1 << 20)
 143#define LCCR0_OUM       (1 << 21)
 144#define LCCR0_LCDT      (1 << 22)
 145#define LCCR0_RDSTM     (1 << 23)
 146#define LCCR0_CMDIM     (1 << 24)
 147#define LCCR0_OUC       (1 << 25)
 148#define LCCR0_LDDALT    (1 << 26)
 149#define LCCR1_PPL(x)    ((x) & 0x3ff)
 150#define LCCR2_LPP(x)    ((x) & 0x3ff)
 151#define LCCR3_API       (15 << 16)
 152#define LCCR3_BPP(x)    ((((x) >> 24) & 7) | (((x) >> 26) & 8))
 153#define LCCR3_PDFOR(x)  (((x) >> 30) & 3)
 154#define LCCR4_K1(x)     (((x) >> 0) & 7)
 155#define LCCR4_K2(x)     (((x) >> 3) & 7)
 156#define LCCR4_K3(x)     (((x) >> 6) & 7)
 157#define LCCR4_PALFOR(x) (((x) >> 15) & 3)
 158#define LCCR5_SOFM(ch)  (1 << (ch - 1))
 159#define LCCR5_EOFM(ch)  (1 << (ch + 7))
 160#define LCCR5_BSM(ch)   (1 << (ch + 15))
 161#define LCCR5_IUM(ch)   (1 << (ch + 23))
 162#define OVLC1_EN        (1 << 31)
 163#define CCR_CEN         (1 << 31)
 164#define FBR_BRA         (1 << 0)
 165#define FBR_BINT        (1 << 1)
 166#define FBR_SRCADDR     (0xfffffff << 4)
 167#define LCSR0_LDD       (1 << 0)
 168#define LCSR0_SOF0      (1 << 1)
 169#define LCSR0_BER       (1 << 2)
 170#define LCSR0_ABC       (1 << 3)
 171#define LCSR0_IU0       (1 << 4)
 172#define LCSR0_IU1       (1 << 5)
 173#define LCSR0_OU        (1 << 6)
 174#define LCSR0_QD        (1 << 7)
 175#define LCSR0_EOF0      (1 << 8)
 176#define LCSR0_BS0       (1 << 9)
 177#define LCSR0_SINT      (1 << 10)
 178#define LCSR0_RDST      (1 << 11)
 179#define LCSR0_CMDINT    (1 << 12)
 180#define LCSR0_BERCH(x)  (((x) & 7) << 28)
 181#define LCSR1_SOF(ch)   (1 << (ch - 1))
 182#define LCSR1_EOF(ch)   (1 << (ch + 7))
 183#define LCSR1_BS(ch)    (1 << (ch + 15))
 184#define LCSR1_IU(ch)    (1 << (ch + 23))
 185#define LDCMD_LENGTH(x) ((x) & 0x001ffffc)
 186#define LDCMD_EOFINT    (1 << 21)
 187#define LDCMD_SOFINT    (1 << 22)
 188#define LDCMD_PAL       (1 << 26)
 189
 190/* Route internal interrupt lines to the global IC */
 191static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
 192{
 193    int level = 0;
 194    level |= (s->status[0] & LCSR0_LDD)    && !(s->control[0] & LCCR0_LDM);
 195    level |= (s->status[0] & LCSR0_SOF0)   && !(s->control[0] & LCCR0_SOFM0);
 196    level |= (s->status[0] & LCSR0_IU0)    && !(s->control[0] & LCCR0_IUM);
 197    level |= (s->status[0] & LCSR0_IU1)    && !(s->control[5] & LCCR5_IUM(1));
 198    level |= (s->status[0] & LCSR0_OU)     && !(s->control[0] & LCCR0_OUM);
 199    level |= (s->status[0] & LCSR0_QD)     && !(s->control[0] & LCCR0_QDM);
 200    level |= (s->status[0] & LCSR0_EOF0)   && !(s->control[0] & LCCR0_EOFM0);
 201    level |= (s->status[0] & LCSR0_BS0)    && !(s->control[0] & LCCR0_BSM0);
 202    level |= (s->status[0] & LCSR0_RDST)   && !(s->control[0] & LCCR0_RDSTM);
 203    level |= (s->status[0] & LCSR0_CMDINT) && !(s->control[0] & LCCR0_CMDIM);
 204    level |= (s->status[1] & ~s->control[5]);
 205
 206    qemu_set_irq(s->irq, !!level);
 207    s->irqlevel = level;
 208}
 209
 210/* Set Branch Status interrupt high and poke associated registers */
 211static inline void pxa2xx_dma_bs_set(PXA2xxLCDState *s, int ch)
 212{
 213    int unmasked;
 214    if (ch == 0) {
 215        s->status[0] |= LCSR0_BS0;
 216        unmasked = !(s->control[0] & LCCR0_BSM0);
 217    } else {
 218        s->status[1] |= LCSR1_BS(ch);
 219        unmasked = !(s->control[5] & LCCR5_BSM(ch));
 220    }
 221
 222    if (unmasked) {
 223        if (s->irqlevel)
 224            s->status[0] |= LCSR0_SINT;
 225        else
 226            s->liidr = s->dma_ch[ch].id;
 227    }
 228}
 229
 230/* Set Start Of Frame Status interrupt high and poke associated registers */
 231static inline void pxa2xx_dma_sof_set(PXA2xxLCDState *s, int ch)
 232{
 233    int unmasked;
 234    if (!(s->dma_ch[ch].command & LDCMD_SOFINT))
 235        return;
 236
 237    if (ch == 0) {
 238        s->status[0] |= LCSR0_SOF0;
 239        unmasked = !(s->control[0] & LCCR0_SOFM0);
 240    } else {
 241        s->status[1] |= LCSR1_SOF(ch);
 242        unmasked = !(s->control[5] & LCCR5_SOFM(ch));
 243    }
 244
 245    if (unmasked) {
 246        if (s->irqlevel)
 247            s->status[0] |= LCSR0_SINT;
 248        else
 249            s->liidr = s->dma_ch[ch].id;
 250    }
 251}
 252
 253/* Set End Of Frame Status interrupt high and poke associated registers */
 254static inline void pxa2xx_dma_eof_set(PXA2xxLCDState *s, int ch)
 255{
 256    int unmasked;
 257    if (!(s->dma_ch[ch].command & LDCMD_EOFINT))
 258        return;
 259
 260    if (ch == 0) {
 261        s->status[0] |= LCSR0_EOF0;
 262        unmasked = !(s->control[0] & LCCR0_EOFM0);
 263    } else {
 264        s->status[1] |= LCSR1_EOF(ch);
 265        unmasked = !(s->control[5] & LCCR5_EOFM(ch));
 266    }
 267
 268    if (unmasked) {
 269        if (s->irqlevel)
 270            s->status[0] |= LCSR0_SINT;
 271        else
 272            s->liidr = s->dma_ch[ch].id;
 273    }
 274}
 275
 276/* Set Bus Error Status interrupt high and poke associated registers */
 277static inline void pxa2xx_dma_ber_set(PXA2xxLCDState *s, int ch)
 278{
 279    s->status[0] |= LCSR0_BERCH(ch) | LCSR0_BER;
 280    if (s->irqlevel)
 281        s->status[0] |= LCSR0_SINT;
 282    else
 283        s->liidr = s->dma_ch[ch].id;
 284}
 285
 286/* Load new Frame Descriptors from DMA */
 287static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
 288{
 289    PXAFrameDescriptor desc;
 290    hwaddr descptr;
 291    int i;
 292
 293    for (i = 0; i < PXA_LCDDMA_CHANS; i ++) {
 294        s->dma_ch[i].source = 0;
 295
 296        if (!s->dma_ch[i].up)
 297            continue;
 298
 299        if (s->dma_ch[i].branch & FBR_BRA) {
 300            descptr = s->dma_ch[i].branch & FBR_SRCADDR;
 301            if (s->dma_ch[i].branch & FBR_BINT)
 302                pxa2xx_dma_bs_set(s, i);
 303            s->dma_ch[i].branch &= ~FBR_BRA;
 304        } else
 305            descptr = s->dma_ch[i].descriptor;
 306
 307        if (!((descptr >= PXA2XX_SDRAM_BASE && descptr +
 308                 sizeof(desc) <= PXA2XX_SDRAM_BASE + ram_size) ||
 309                (descptr >= PXA2XX_INTERNAL_BASE && descptr + sizeof(desc) <=
 310                 PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
 311            continue;
 312        }
 313
 314        cpu_physical_memory_read(descptr, &desc, sizeof(desc));
 315        s->dma_ch[i].descriptor = le32_to_cpu(desc.fdaddr);
 316        s->dma_ch[i].source = le32_to_cpu(desc.fsaddr);
 317        s->dma_ch[i].id = le32_to_cpu(desc.fidr);
 318        s->dma_ch[i].command = le32_to_cpu(desc.ldcmd);
 319    }
 320}
 321
 322static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset,
 323                                 unsigned size)
 324{
 325    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
 326    int ch;
 327
 328    switch (offset) {
 329    case LCCR0:
 330        return s->control[0];
 331    case LCCR1:
 332        return s->control[1];
 333    case LCCR2:
 334        return s->control[2];
 335    case LCCR3:
 336        return s->control[3];
 337    case LCCR4:
 338        return s->control[4];
 339    case LCCR5:
 340        return s->control[5];
 341
 342    case OVL1C1:
 343        return s->ovl1c[0];
 344    case OVL1C2:
 345        return s->ovl1c[1];
 346    case OVL2C1:
 347        return s->ovl2c[0];
 348    case OVL2C2:
 349        return s->ovl2c[1];
 350
 351    case CCR:
 352        return s->ccr;
 353
 354    case CMDCR:
 355        return s->cmdcr;
 356
 357    case TRGBR:
 358        return s->trgbr;
 359    case TCR:
 360        return s->tcr;
 361
 362    case 0x200 ... 0x1000:      /* DMA per-channel registers */
 363        ch = (offset - 0x200) >> 4;
 364        if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
 365            goto fail;
 366
 367        switch (offset & 0xf) {
 368        case DMA_FDADR:
 369            return s->dma_ch[ch].descriptor;
 370        case DMA_FSADR:
 371            return s->dma_ch[ch].source;
 372        case DMA_FIDR:
 373            return s->dma_ch[ch].id;
 374        case DMA_LDCMD:
 375            return s->dma_ch[ch].command;
 376        default:
 377            goto fail;
 378        }
 379
 380    case FBR0:
 381        return s->dma_ch[0].branch;
 382    case FBR1:
 383        return s->dma_ch[1].branch;
 384    case FBR2:
 385        return s->dma_ch[2].branch;
 386    case FBR3:
 387        return s->dma_ch[3].branch;
 388    case FBR4:
 389        return s->dma_ch[4].branch;
 390    case FBR5:
 391        return s->dma_ch[5].branch;
 392    case FBR6:
 393        return s->dma_ch[6].branch;
 394
 395    case BSCNTR:
 396        return s->bscntr;
 397
 398    case PRSR:
 399        return 0;
 400
 401    case LCSR0:
 402        return s->status[0];
 403    case LCSR1:
 404        return s->status[1];
 405    case LIIDR:
 406        return s->liidr;
 407
 408    default:
 409    fail:
 410        hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
 411    }
 412
 413    return 0;
 414}
 415
 416static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
 417                              uint64_t value, unsigned size)
 418{
 419    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
 420    int ch;
 421
 422    switch (offset) {
 423    case LCCR0:
 424        /* ACK Quick Disable done */
 425        if ((s->control[0] & LCCR0_ENB) && !(value & LCCR0_ENB))
 426            s->status[0] |= LCSR0_QD;
 427
 428        if (!(s->control[0] & LCCR0_LCDT) && (value & LCCR0_LCDT))
 429            printf("%s: internal frame buffer unsupported\n", __func__);
 430
 431        if ((s->control[3] & LCCR3_API) &&
 432                (value & LCCR0_ENB) && !(value & LCCR0_LCDT))
 433            s->status[0] |= LCSR0_ABC;
 434
 435        s->control[0] = value & 0x07ffffff;
 436        pxa2xx_lcdc_int_update(s);
 437
 438        s->dma_ch[0].up = !!(value & LCCR0_ENB);
 439        s->dma_ch[1].up = (s->ovl1c[0] & OVLC1_EN) || (value & LCCR0_SDS);
 440        break;
 441
 442    case LCCR1:
 443        s->control[1] = value;
 444        break;
 445
 446    case LCCR2:
 447        s->control[2] = value;
 448        break;
 449
 450    case LCCR3:
 451        s->control[3] = value & 0xefffffff;
 452        s->bpp = LCCR3_BPP(value);
 453        break;
 454
 455    case LCCR4:
 456        s->control[4] = value & 0x83ff81ff;
 457        break;
 458
 459    case LCCR5:
 460        s->control[5] = value & 0x3f3f3f3f;
 461        break;
 462
 463    case OVL1C1:
 464        if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN))
 465            printf("%s: Overlay 1 not supported\n", __func__);
 466
 467        s->ovl1c[0] = value & 0x80ffffff;
 468        s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS);
 469        break;
 470
 471    case OVL1C2:
 472        s->ovl1c[1] = value & 0x000fffff;
 473        break;
 474
 475    case OVL2C1:
 476        if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN))
 477            printf("%s: Overlay 2 not supported\n", __func__);
 478
 479        s->ovl2c[0] = value & 0x80ffffff;
 480        s->dma_ch[2].up = !!(value & OVLC1_EN);
 481        s->dma_ch[3].up = !!(value & OVLC1_EN);
 482        s->dma_ch[4].up = !!(value & OVLC1_EN);
 483        break;
 484
 485    case OVL2C2:
 486        s->ovl2c[1] = value & 0x007fffff;
 487        break;
 488
 489    case CCR:
 490        if (!(s->ccr & CCR_CEN) && (value & CCR_CEN))
 491            printf("%s: Hardware cursor unimplemented\n", __func__);
 492
 493        s->ccr = value & 0x81ffffe7;
 494        s->dma_ch[5].up = !!(value & CCR_CEN);
 495        break;
 496
 497    case CMDCR:
 498        s->cmdcr = value & 0xff;
 499        break;
 500
 501    case TRGBR:
 502        s->trgbr = value & 0x00ffffff;
 503        break;
 504
 505    case TCR:
 506        s->tcr = value & 0x7fff;
 507        break;
 508
 509    case 0x200 ... 0x1000:      /* DMA per-channel registers */
 510        ch = (offset - 0x200) >> 4;
 511        if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
 512            goto fail;
 513
 514        switch (offset & 0xf) {
 515        case DMA_FDADR:
 516            s->dma_ch[ch].descriptor = value & 0xfffffff0;
 517            break;
 518
 519        default:
 520            goto fail;
 521        }
 522        break;
 523
 524    case FBR0:
 525        s->dma_ch[0].branch = value & 0xfffffff3;
 526        break;
 527    case FBR1:
 528        s->dma_ch[1].branch = value & 0xfffffff3;
 529        break;
 530    case FBR2:
 531        s->dma_ch[2].branch = value & 0xfffffff3;
 532        break;
 533    case FBR3:
 534        s->dma_ch[3].branch = value & 0xfffffff3;
 535        break;
 536    case FBR4:
 537        s->dma_ch[4].branch = value & 0xfffffff3;
 538        break;
 539    case FBR5:
 540        s->dma_ch[5].branch = value & 0xfffffff3;
 541        break;
 542    case FBR6:
 543        s->dma_ch[6].branch = value & 0xfffffff3;
 544        break;
 545
 546    case BSCNTR:
 547        s->bscntr = value & 0xf;
 548        break;
 549
 550    case PRSR:
 551        break;
 552
 553    case LCSR0:
 554        s->status[0] &= ~(value & 0xfff);
 555        if (value & LCSR0_BER)
 556            s->status[0] &= ~LCSR0_BERCH(7);
 557        break;
 558
 559    case LCSR1:
 560        s->status[1] &= ~(value & 0x3e3f3f);
 561        break;
 562
 563    default:
 564    fail:
 565        hw_error("%s: Bad offset " REG_FMT "\n", __func__, offset);
 566    }
 567}
 568
 569static const MemoryRegionOps pxa2xx_lcdc_ops = {
 570    .read = pxa2xx_lcdc_read,
 571    .write = pxa2xx_lcdc_write,
 572    .endianness = DEVICE_NATIVE_ENDIAN,
 573};
 574
 575/* Load new palette for a given DMA channel, convert to internal format */
 576static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
 577{
 578    DisplaySurface *surface = qemu_console_surface(s->con);
 579    int i, n, format, r, g, b, alpha;
 580    uint32_t *dest;
 581    uint8_t *src;
 582    s->pal_for = LCCR4_PALFOR(s->control[4]);
 583    format = s->pal_for;
 584
 585    switch (bpp) {
 586    case pxa_lcdc_2bpp:
 587        n = 4;
 588        break;
 589    case pxa_lcdc_4bpp:
 590        n = 16;
 591        break;
 592    case pxa_lcdc_8bpp:
 593        n = 256;
 594        break;
 595    default:
 596        format = 0;
 597        return;
 598    }
 599
 600    src = (uint8_t *) s->dma_ch[ch].pbuffer;
 601    dest = (uint32_t *) s->dma_ch[ch].palette;
 602    alpha = r = g = b = 0;
 603
 604    for (i = 0; i < n; i ++) {
 605        switch (format) {
 606        case 0: /* 16 bpp, no transparency */
 607            alpha = 0;
 608            if (s->control[0] & LCCR0_CMS) {
 609                r = g = b = *(uint16_t *) src & 0xff;
 610            }
 611            else {
 612                r = (*(uint16_t *) src & 0xf800) >> 8;
 613                g = (*(uint16_t *) src & 0x07e0) >> 3;
 614                b = (*(uint16_t *) src & 0x001f) << 3;
 615            }
 616            src += 2;
 617            break;
 618        case 1: /* 16 bpp plus transparency */
 619            alpha = *(uint32_t *) src & (1 << 24);
 620            if (s->control[0] & LCCR0_CMS)
 621                r = g = b = *(uint32_t *) src & 0xff;
 622            else {
 623                r = (*(uint32_t *) src & 0xf80000) >> 16;
 624                g = (*(uint32_t *) src & 0x00fc00) >> 8;
 625                b = (*(uint32_t *) src & 0x0000f8);
 626            }
 627            src += 4;
 628            break;
 629        case 2: /* 18 bpp plus transparency */
 630            alpha = *(uint32_t *) src & (1 << 24);
 631            if (s->control[0] & LCCR0_CMS)
 632                r = g = b = *(uint32_t *) src & 0xff;
 633            else {
 634                r = (*(uint32_t *) src & 0xfc0000) >> 16;
 635                g = (*(uint32_t *) src & 0x00fc00) >> 8;
 636                b = (*(uint32_t *) src & 0x0000fc);
 637            }
 638            src += 4;
 639            break;
 640        case 3: /* 24 bpp plus transparency */
 641            alpha = *(uint32_t *) src & (1 << 24);
 642            if (s->control[0] & LCCR0_CMS)
 643                r = g = b = *(uint32_t *) src & 0xff;
 644            else {
 645                r = (*(uint32_t *) src & 0xff0000) >> 16;
 646                g = (*(uint32_t *) src & 0x00ff00) >> 8;
 647                b = (*(uint32_t *) src & 0x0000ff);
 648            }
 649            src += 4;
 650            break;
 651        }
 652        switch (surface_bits_per_pixel(surface)) {
 653        case 8:
 654            *dest = rgb_to_pixel8(r, g, b) | alpha;
 655            break;
 656        case 15:
 657            *dest = rgb_to_pixel15(r, g, b) | alpha;
 658            break;
 659        case 16:
 660            *dest = rgb_to_pixel16(r, g, b) | alpha;
 661            break;
 662        case 24:
 663            *dest = rgb_to_pixel24(r, g, b) | alpha;
 664            break;
 665        case 32:
 666            *dest = rgb_to_pixel32(r, g, b) | alpha;
 667            break;
 668        }
 669        dest ++;
 670    }
 671}
 672
 673static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
 674                hwaddr addr, int *miny, int *maxy)
 675{
 676    DisplaySurface *surface = qemu_console_surface(s->con);
 677    int src_width, dest_width;
 678    drawfn fn = NULL;
 679    if (s->dest_width)
 680        fn = s->line_fn[s->transp][s->bpp];
 681    if (!fn)
 682        return;
 683
 684    src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
 685    if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
 686        src_width *= 3;
 687    else if (s->bpp > pxa_lcdc_16bpp)
 688        src_width *= 4;
 689    else if (s->bpp > pxa_lcdc_8bpp)
 690        src_width *= 2;
 691
 692    dest_width = s->xres * s->dest_width;
 693    *miny = 0;
 694    if (s->invalidated) {
 695        framebuffer_update_memory_section(&s->fbsection, s->sysmem,
 696                                          addr, s->yres, src_width);
 697    }
 698    framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
 699                               src_width, dest_width, s->dest_width,
 700                               s->invalidated,
 701                               fn, s->dma_ch[0].palette, miny, maxy);
 702}
 703
 704static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
 705               hwaddr addr, int *miny, int *maxy)
 706{
 707    DisplaySurface *surface = qemu_console_surface(s->con);
 708    int src_width, dest_width;
 709    drawfn fn = NULL;
 710    if (s->dest_width)
 711        fn = s->line_fn[s->transp][s->bpp];
 712    if (!fn)
 713        return;
 714
 715    src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
 716    if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
 717        src_width *= 3;
 718    else if (s->bpp > pxa_lcdc_16bpp)
 719        src_width *= 4;
 720    else if (s->bpp > pxa_lcdc_8bpp)
 721        src_width *= 2;
 722
 723    dest_width = s->yres * s->dest_width;
 724    *miny = 0;
 725    if (s->invalidated) {
 726        framebuffer_update_memory_section(&s->fbsection, s->sysmem,
 727                                          addr, s->yres, src_width);
 728    }
 729    framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
 730                               src_width, s->dest_width, -dest_width,
 731                               s->invalidated,
 732                               fn, s->dma_ch[0].palette,
 733                               miny, maxy);
 734}
 735
 736static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
 737                hwaddr addr, int *miny, int *maxy)
 738{
 739    DisplaySurface *surface = qemu_console_surface(s->con);
 740    int src_width, dest_width;
 741    drawfn fn = NULL;
 742    if (s->dest_width) {
 743        fn = s->line_fn[s->transp][s->bpp];
 744    }
 745    if (!fn) {
 746        return;
 747    }
 748
 749    src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
 750    if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
 751        src_width *= 3;
 752    } else if (s->bpp > pxa_lcdc_16bpp) {
 753        src_width *= 4;
 754    } else if (s->bpp > pxa_lcdc_8bpp) {
 755        src_width *= 2;
 756    }
 757
 758    dest_width = s->xres * s->dest_width;
 759    *miny = 0;
 760    if (s->invalidated) {
 761        framebuffer_update_memory_section(&s->fbsection, s->sysmem,
 762                                          addr, s->yres, src_width);
 763    }
 764    framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
 765                               src_width, -dest_width, -s->dest_width,
 766                               s->invalidated,
 767                               fn, s->dma_ch[0].palette, miny, maxy);
 768}
 769
 770static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
 771               hwaddr addr, int *miny, int *maxy)
 772{
 773    DisplaySurface *surface = qemu_console_surface(s->con);
 774    int src_width, dest_width;
 775    drawfn fn = NULL;
 776    if (s->dest_width) {
 777        fn = s->line_fn[s->transp][s->bpp];
 778    }
 779    if (!fn) {
 780        return;
 781    }
 782
 783    src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
 784    if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
 785        src_width *= 3;
 786    } else if (s->bpp > pxa_lcdc_16bpp) {
 787        src_width *= 4;
 788    } else if (s->bpp > pxa_lcdc_8bpp) {
 789        src_width *= 2;
 790    }
 791
 792    dest_width = s->yres * s->dest_width;
 793    *miny = 0;
 794    if (s->invalidated) {
 795        framebuffer_update_memory_section(&s->fbsection, s->sysmem,
 796                                          addr, s->yres, src_width);
 797    }
 798    framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
 799                               src_width, -s->dest_width, dest_width,
 800                               s->invalidated,
 801                               fn, s->dma_ch[0].palette,
 802                               miny, maxy);
 803}
 804
 805static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
 806{
 807    int width, height;
 808    if (!(s->control[0] & LCCR0_ENB))
 809        return;
 810
 811    width = LCCR1_PPL(s->control[1]) + 1;
 812    height = LCCR2_LPP(s->control[2]) + 1;
 813
 814    if (width != s->xres || height != s->yres) {
 815        if (s->orientation == 90 || s->orientation == 270) {
 816            qemu_console_resize(s->con, height, width);
 817        } else {
 818            qemu_console_resize(s->con, width, height);
 819        }
 820        s->invalidated = 1;
 821        s->xres = width;
 822        s->yres = height;
 823    }
 824}
 825
 826static void pxa2xx_update_display(void *opaque)
 827{
 828    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
 829    hwaddr fbptr;
 830    int miny, maxy;
 831    int ch;
 832    if (!(s->control[0] & LCCR0_ENB))
 833        return;
 834
 835    pxa2xx_descriptor_load(s);
 836
 837    pxa2xx_lcdc_resize(s);
 838    miny = s->yres;
 839    maxy = 0;
 840    s->transp = s->dma_ch[2].up || s->dma_ch[3].up;
 841    /* Note: With overlay planes the order depends on LCCR0 bit 25.  */
 842    for (ch = 0; ch < PXA_LCDDMA_CHANS; ch ++)
 843        if (s->dma_ch[ch].up) {
 844            if (!s->dma_ch[ch].source) {
 845                pxa2xx_dma_ber_set(s, ch);
 846                continue;
 847            }
 848            fbptr = s->dma_ch[ch].source;
 849            if (!((fbptr >= PXA2XX_SDRAM_BASE &&
 850                     fbptr <= PXA2XX_SDRAM_BASE + ram_size) ||
 851                    (fbptr >= PXA2XX_INTERNAL_BASE &&
 852                     fbptr <= PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
 853                pxa2xx_dma_ber_set(s, ch);
 854                continue;
 855            }
 856
 857            if (s->dma_ch[ch].command & LDCMD_PAL) {
 858                cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
 859                    MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
 860                        sizeof(s->dma_ch[ch].pbuffer)));
 861                pxa2xx_palette_parse(s, ch, s->bpp);
 862            } else {
 863                /* Do we need to reparse palette */
 864                if (LCCR4_PALFOR(s->control[4]) != s->pal_for)
 865                    pxa2xx_palette_parse(s, ch, s->bpp);
 866
 867                /* ACK frame start */
 868                pxa2xx_dma_sof_set(s, ch);
 869
 870                s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
 871                s->invalidated = 0;
 872
 873                /* ACK frame completed */
 874                pxa2xx_dma_eof_set(s, ch);
 875            }
 876        }
 877
 878    if (s->control[0] & LCCR0_DIS) {
 879        /* ACK last frame completed */
 880        s->control[0] &= ~LCCR0_ENB;
 881        s->status[0] |= LCSR0_LDD;
 882    }
 883
 884    if (miny >= 0) {
 885        switch (s->orientation) {
 886        case 0:
 887            dpy_gfx_update(s->con, 0, miny, s->xres, maxy - miny + 1);
 888            break;
 889        case 90:
 890            dpy_gfx_update(s->con, miny, 0, maxy - miny + 1, s->xres);
 891            break;
 892        case 180:
 893            maxy = s->yres - maxy - 1;
 894            miny = s->yres - miny - 1;
 895            dpy_gfx_update(s->con, 0, maxy, s->xres, miny - maxy + 1);
 896            break;
 897        case 270:
 898            maxy = s->yres - maxy - 1;
 899            miny = s->yres - miny - 1;
 900            dpy_gfx_update(s->con, maxy, 0, miny - maxy + 1, s->xres);
 901            break;
 902        }
 903    }
 904    pxa2xx_lcdc_int_update(s);
 905
 906    qemu_irq_raise(s->vsync_cb);
 907}
 908
 909static void pxa2xx_invalidate_display(void *opaque)
 910{
 911    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
 912    s->invalidated = 1;
 913}
 914
 915static void pxa2xx_lcdc_orientation(void *opaque, int angle)
 916{
 917    PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
 918
 919    switch (angle) {
 920    case 0:
 921        s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0;
 922        break;
 923    case 90:
 924        s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90;
 925        break;
 926    case 180:
 927        s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180;
 928        break;
 929    case 270:
 930        s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270;
 931        break;
 932    }
 933
 934    s->orientation = angle;
 935    s->xres = s->yres = -1;
 936    pxa2xx_lcdc_resize(s);
 937}
 938
 939static const VMStateDescription vmstate_dma_channel = {
 940    .name = "dma_channel",
 941    .version_id = 0,
 942    .minimum_version_id = 0,
 943    .fields = (VMStateField[]) {
 944        VMSTATE_UINT32(branch, struct DMAChannel),
 945        VMSTATE_UINT8(up, struct DMAChannel),
 946        VMSTATE_BUFFER(pbuffer, struct DMAChannel),
 947        VMSTATE_UINT32(descriptor, struct DMAChannel),
 948        VMSTATE_UINT32(source, struct DMAChannel),
 949        VMSTATE_UINT32(id, struct DMAChannel),
 950        VMSTATE_UINT32(command, struct DMAChannel),
 951        VMSTATE_END_OF_LIST()
 952    }
 953};
 954
 955static int pxa2xx_lcdc_post_load(void *opaque, int version_id)
 956{
 957    PXA2xxLCDState *s = opaque;
 958
 959    s->bpp = LCCR3_BPP(s->control[3]);
 960    s->xres = s->yres = s->pal_for = -1;
 961
 962    return 0;
 963}
 964
 965static const VMStateDescription vmstate_pxa2xx_lcdc = {
 966    .name = "pxa2xx_lcdc",
 967    .version_id = 0,
 968    .minimum_version_id = 0,
 969    .post_load = pxa2xx_lcdc_post_load,
 970    .fields = (VMStateField[]) {
 971        VMSTATE_INT32(irqlevel, PXA2xxLCDState),
 972        VMSTATE_INT32(transp, PXA2xxLCDState),
 973        VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6),
 974        VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2),
 975        VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2),
 976        VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2),
 977        VMSTATE_UINT32(ccr, PXA2xxLCDState),
 978        VMSTATE_UINT32(cmdcr, PXA2xxLCDState),
 979        VMSTATE_UINT32(trgbr, PXA2xxLCDState),
 980        VMSTATE_UINT32(tcr, PXA2xxLCDState),
 981        VMSTATE_UINT32(liidr, PXA2xxLCDState),
 982        VMSTATE_UINT8(bscntr, PXA2xxLCDState),
 983        VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0,
 984                             vmstate_dma_channel, struct DMAChannel),
 985        VMSTATE_END_OF_LIST()
 986    }
 987};
 988
 989#define BITS 8
 990#include "pxa2xx_template.h"
 991#define BITS 15
 992#include "pxa2xx_template.h"
 993#define BITS 16
 994#include "pxa2xx_template.h"
 995#define BITS 24
 996#include "pxa2xx_template.h"
 997#define BITS 32
 998#include "pxa2xx_template.h"
 999
1000static const GraphicHwOps pxa2xx_ops = {
1001    .invalidate  = pxa2xx_invalidate_display,
1002    .gfx_update  = pxa2xx_update_display,
1003};
1004
1005PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
1006                                 hwaddr base, qemu_irq irq)
1007{
1008    PXA2xxLCDState *s;
1009    DisplaySurface *surface;
1010
1011    s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState));
1012    s->invalidated = 1;
1013    s->irq = irq;
1014    s->sysmem = sysmem;
1015
1016    pxa2xx_lcdc_orientation(s, graphic_rotate);
1017
1018    memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s,
1019                          "pxa2xx-lcd-controller", 0x00100000);
1020    memory_region_add_subregion(sysmem, base, &s->iomem);
1021
1022    s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
1023    surface = qemu_console_surface(s->con);
1024
1025    switch (surface_bits_per_pixel(surface)) {
1026    case 0:
1027        s->dest_width = 0;
1028        break;
1029    case 8:
1030        s->line_fn[0] = pxa2xx_draw_fn_8;
1031        s->line_fn[1] = pxa2xx_draw_fn_8t;
1032        s->dest_width = 1;
1033        break;
1034    case 15:
1035        s->line_fn[0] = pxa2xx_draw_fn_15;
1036        s->line_fn[1] = pxa2xx_draw_fn_15t;
1037        s->dest_width = 2;
1038        break;
1039    case 16:
1040        s->line_fn[0] = pxa2xx_draw_fn_16;
1041        s->line_fn[1] = pxa2xx_draw_fn_16t;
1042        s->dest_width = 2;
1043        break;
1044    case 24:
1045        s->line_fn[0] = pxa2xx_draw_fn_24;
1046        s->line_fn[1] = pxa2xx_draw_fn_24t;
1047        s->dest_width = 3;
1048        break;
1049    case 32:
1050        s->line_fn[0] = pxa2xx_draw_fn_32;
1051        s->line_fn[1] = pxa2xx_draw_fn_32t;
1052        s->dest_width = 4;
1053        break;
1054    default:
1055        fprintf(stderr, "%s: Bad color depth\n", __func__);
1056        exit(1);
1057    }
1058
1059    vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
1060
1061    return s;
1062}
1063
1064void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler)
1065{
1066    s->vsync_cb = handler;
1067}
1068