qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

pxa2xx_lcd.c (41547B)


      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 "qemu/log.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 #include "hw/boards.h"
     21 /* FIXME: For graphic_rotate. Should probably be done in common code.  */
     22 #include "sysemu/sysemu.h"
     23 #include "framebuffer.h"
     24 
     25 struct DMAChannel {
     26     uint32_t branch;
     27     uint8_t up;
     28     uint8_t palette[1024];
     29     uint8_t pbuffer[1024];
     30     void (*redraw)(PXA2xxLCDState *s, hwaddr addr,
     31                    int *miny, int *maxy);
     32 
     33     uint32_t descriptor;
     34     uint32_t source;
     35     uint32_t id;
     36     uint32_t command;
     37 };
     38 
     39 struct PXA2xxLCDState {
     40     MemoryRegion *sysmem;
     41     MemoryRegion iomem;
     42     MemoryRegionSection fbsection;
     43     qemu_irq irq;
     44     int irqlevel;
     45 
     46     int invalidated;
     47     QemuConsole *con;
     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 
     82 typedef 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 /* Size of a pixel in the QEMU UI output surface, in bytes */
    191 #define DEST_PIXEL_WIDTH 4
    192 
    193 /* Line drawing code to handle the various possible guest pixel formats */
    194 
    195 # define SKIP_PIXEL(to) do { to += deststep; } while (0)
    196 # define COPY_PIXEL(to, from)    \
    197     do {                         \
    198         *(uint32_t *) to = from; \
    199         SKIP_PIXEL(to);          \
    200     } while (0)
    201 
    202 #if HOST_BIG_ENDIAN
    203 # define SWAP_WORDS 1
    204 #endif
    205 
    206 #define FN_2(x) FN(x + 1) FN(x)
    207 #define FN_4(x) FN_2(x + 2) FN_2(x)
    208 
    209 static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
    210                               int width, int deststep)
    211 {
    212     uint32_t *palette = opaque;
    213     uint32_t data;
    214     while (width > 0) {
    215         data = *(uint32_t *) src;
    216 #define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
    217 #ifdef SWAP_WORDS
    218         FN_4(12)
    219         FN_4(8)
    220         FN_4(4)
    221         FN_4(0)
    222 #else
    223         FN_4(0)
    224         FN_4(4)
    225         FN_4(8)
    226         FN_4(12)
    227 #endif
    228 #undef FN
    229         width -= 16;
    230         src += 4;
    231     }
    232 }
    233 
    234 static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
    235                               int width, int deststep)
    236 {
    237     uint32_t *palette = opaque;
    238     uint32_t data;
    239     while (width > 0) {
    240         data = *(uint32_t *) src;
    241 #define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
    242 #ifdef SWAP_WORDS
    243         FN_2(6)
    244         FN_2(4)
    245         FN_2(2)
    246         FN_2(0)
    247 #else
    248         FN_2(0)
    249         FN_2(2)
    250         FN_2(4)
    251         FN_2(6)
    252 #endif
    253 #undef FN
    254         width -= 8;
    255         src += 4;
    256     }
    257 }
    258 
    259 static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
    260                               int width, int deststep)
    261 {
    262     uint32_t *palette = opaque;
    263     uint32_t data;
    264     while (width > 0) {
    265         data = *(uint32_t *) src;
    266 #define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
    267 #ifdef SWAP_WORDS
    268         FN(24)
    269         FN(16)
    270         FN(8)
    271         FN(0)
    272 #else
    273         FN(0)
    274         FN(8)
    275         FN(16)
    276         FN(24)
    277 #endif
    278 #undef FN
    279         width -= 4;
    280         src += 4;
    281     }
    282 }
    283 
    284 static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
    285                                int width, int deststep)
    286 {
    287     uint32_t data;
    288     unsigned int r, g, b;
    289     while (width > 0) {
    290         data = *(uint32_t *) src;
    291 #ifdef SWAP_WORDS
    292         data = bswap32(data);
    293 #endif
    294         b = (data & 0x1f) << 3;
    295         data >>= 5;
    296         g = (data & 0x3f) << 2;
    297         data >>= 6;
    298         r = (data & 0x1f) << 3;
    299         data >>= 5;
    300         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    301         b = (data & 0x1f) << 3;
    302         data >>= 5;
    303         g = (data & 0x3f) << 2;
    304         data >>= 6;
    305         r = (data & 0x1f) << 3;
    306         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    307         width -= 2;
    308         src += 4;
    309     }
    310 }
    311 
    312 static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
    313                                 int width, int deststep)
    314 {
    315     uint32_t data;
    316     unsigned int r, g, b;
    317     while (width > 0) {
    318         data = *(uint32_t *) src;
    319 #ifdef SWAP_WORDS
    320         data = bswap32(data);
    321 #endif
    322         b = (data & 0x1f) << 3;
    323         data >>= 5;
    324         g = (data & 0x1f) << 3;
    325         data >>= 5;
    326         r = (data & 0x1f) << 3;
    327         data >>= 5;
    328         if (data & 1) {
    329             SKIP_PIXEL(dest);
    330         } else {
    331             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    332         }
    333         data >>= 1;
    334         b = (data & 0x1f) << 3;
    335         data >>= 5;
    336         g = (data & 0x1f) << 3;
    337         data >>= 5;
    338         r = (data & 0x1f) << 3;
    339         data >>= 5;
    340         if (data & 1) {
    341             SKIP_PIXEL(dest);
    342         } else {
    343             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    344         }
    345         width -= 2;
    346         src += 4;
    347     }
    348 }
    349 
    350 static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
    351                                int width, int deststep)
    352 {
    353     uint32_t data;
    354     unsigned int r, g, b;
    355     while (width > 0) {
    356         data = *(uint32_t *) src;
    357 #ifdef SWAP_WORDS
    358         data = bswap32(data);
    359 #endif
    360         b = (data & 0x3f) << 2;
    361         data >>= 6;
    362         g = (data & 0x3f) << 2;
    363         data >>= 6;
    364         r = (data & 0x3f) << 2;
    365         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    366         width -= 1;
    367         src += 4;
    368     }
    369 }
    370 
    371 /* The wicked packed format */
    372 static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
    373                                 int width, int deststep)
    374 {
    375     uint32_t data[3];
    376     unsigned int r, g, b;
    377     while (width > 0) {
    378         data[0] = *(uint32_t *) src;
    379         src += 4;
    380         data[1] = *(uint32_t *) src;
    381         src += 4;
    382         data[2] = *(uint32_t *) src;
    383         src += 4;
    384 #ifdef SWAP_WORDS
    385         data[0] = bswap32(data[0]);
    386         data[1] = bswap32(data[1]);
    387         data[2] = bswap32(data[2]);
    388 #endif
    389         b = (data[0] & 0x3f) << 2;
    390         data[0] >>= 6;
    391         g = (data[0] & 0x3f) << 2;
    392         data[0] >>= 6;
    393         r = (data[0] & 0x3f) << 2;
    394         data[0] >>= 12;
    395         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    396         b = (data[0] & 0x3f) << 2;
    397         data[0] >>= 6;
    398         g = ((data[1] & 0xf) << 4) | (data[0] << 2);
    399         data[1] >>= 4;
    400         r = (data[1] & 0x3f) << 2;
    401         data[1] >>= 12;
    402         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    403         b = (data[1] & 0x3f) << 2;
    404         data[1] >>= 6;
    405         g = (data[1] & 0x3f) << 2;
    406         data[1] >>= 6;
    407         r = ((data[2] & 0x3) << 6) | (data[1] << 2);
    408         data[2] >>= 8;
    409         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    410         b = (data[2] & 0x3f) << 2;
    411         data[2] >>= 6;
    412         g = (data[2] & 0x3f) << 2;
    413         data[2] >>= 6;
    414         r = data[2] << 2;
    415         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    416         width -= 4;
    417     }
    418 }
    419 
    420 static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
    421                                int width, int deststep)
    422 {
    423     uint32_t data;
    424     unsigned int r, g, b;
    425     while (width > 0) {
    426         data = *(uint32_t *) src;
    427 #ifdef SWAP_WORDS
    428         data = bswap32(data);
    429 #endif
    430         b = (data & 0x3f) << 2;
    431         data >>= 6;
    432         g = (data & 0x3f) << 2;
    433         data >>= 6;
    434         r = (data & 0x3f) << 2;
    435         data >>= 6;
    436         if (data & 1) {
    437             SKIP_PIXEL(dest);
    438         } else {
    439             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    440         }
    441         width -= 1;
    442         src += 4;
    443     }
    444 }
    445 
    446 /* The wicked packed format */
    447 static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
    448                                 int width, int deststep)
    449 {
    450     uint32_t data[3];
    451     unsigned int r, g, b;
    452     while (width > 0) {
    453         data[0] = *(uint32_t *) src;
    454         src += 4;
    455         data[1] = *(uint32_t *) src;
    456         src += 4;
    457         data[2] = *(uint32_t *) src;
    458         src += 4;
    459 # ifdef SWAP_WORDS
    460         data[0] = bswap32(data[0]);
    461         data[1] = bswap32(data[1]);
    462         data[2] = bswap32(data[2]);
    463 # endif
    464         b = (data[0] & 0x3f) << 2;
    465         data[0] >>= 6;
    466         g = (data[0] & 0x3f) << 2;
    467         data[0] >>= 6;
    468         r = (data[0] & 0x3f) << 2;
    469         data[0] >>= 6;
    470         if (data[0] & 1) {
    471             SKIP_PIXEL(dest);
    472         } else {
    473             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    474         }
    475         data[0] >>= 6;
    476         b = (data[0] & 0x3f) << 2;
    477         data[0] >>= 6;
    478         g = ((data[1] & 0xf) << 4) | (data[0] << 2);
    479         data[1] >>= 4;
    480         r = (data[1] & 0x3f) << 2;
    481         data[1] >>= 6;
    482         if (data[1] & 1) {
    483             SKIP_PIXEL(dest);
    484         } else {
    485             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    486         }
    487         data[1] >>= 6;
    488         b = (data[1] & 0x3f) << 2;
    489         data[1] >>= 6;
    490         g = (data[1] & 0x3f) << 2;
    491         data[1] >>= 6;
    492         r = ((data[2] & 0x3) << 6) | (data[1] << 2);
    493         data[2] >>= 2;
    494         if (data[2] & 1) {
    495             SKIP_PIXEL(dest);
    496         } else {
    497             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    498         }
    499         data[2] >>= 6;
    500         b = (data[2] & 0x3f) << 2;
    501         data[2] >>= 6;
    502         g = (data[2] & 0x3f) << 2;
    503         data[2] >>= 6;
    504         r = data[2] << 2;
    505         data[2] >>= 6;
    506         if (data[2] & 1) {
    507             SKIP_PIXEL(dest);
    508         } else {
    509             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    510         }
    511         width -= 4;
    512     }
    513 }
    514 
    515 static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
    516                                int width, int deststep)
    517 {
    518     uint32_t data;
    519     unsigned int r, g, b;
    520     while (width > 0) {
    521         data = *(uint32_t *) src;
    522 #ifdef SWAP_WORDS
    523         data = bswap32(data);
    524 #endif
    525         b = data & 0xff;
    526         data >>= 8;
    527         g = data & 0xff;
    528         data >>= 8;
    529         r = data & 0xff;
    530         COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    531         width -= 1;
    532         src += 4;
    533     }
    534 }
    535 
    536 static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
    537                                 int width, int deststep)
    538 {
    539     uint32_t data;
    540     unsigned int r, g, b;
    541     while (width > 0) {
    542         data = *(uint32_t *) src;
    543 #ifdef SWAP_WORDS
    544         data = bswap32(data);
    545 #endif
    546         b = (data & 0x7f) << 1;
    547         data >>= 7;
    548         g = data & 0xff;
    549         data >>= 8;
    550         r = data & 0xff;
    551         data >>= 8;
    552         if (data & 1) {
    553             SKIP_PIXEL(dest);
    554         } else {
    555             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    556         }
    557         width -= 1;
    558         src += 4;
    559     }
    560 }
    561 
    562 static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
    563                                int width, int deststep)
    564 {
    565     uint32_t data;
    566     unsigned int r, g, b;
    567     while (width > 0) {
    568         data = *(uint32_t *) src;
    569 #ifdef SWAP_WORDS
    570         data = bswap32(data);
    571 #endif
    572         b = data & 0xff;
    573         data >>= 8;
    574         g = data & 0xff;
    575         data >>= 8;
    576         r = data & 0xff;
    577         data >>= 8;
    578         if (data & 1) {
    579             SKIP_PIXEL(dest);
    580         } else {
    581             COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
    582         }
    583         width -= 1;
    584         src += 4;
    585     }
    586 }
    587 
    588 /* Overlay planes disabled, no transparency */
    589 static drawfn pxa2xx_draw_fn_32[16] = {
    590     [0 ... 0xf]       = NULL,
    591     [pxa_lcdc_2bpp]   = pxa2xx_draw_line2,
    592     [pxa_lcdc_4bpp]   = pxa2xx_draw_line4,
    593     [pxa_lcdc_8bpp]   = pxa2xx_draw_line8,
    594     [pxa_lcdc_16bpp]  = pxa2xx_draw_line16,
    595     [pxa_lcdc_18bpp]  = pxa2xx_draw_line18,
    596     [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
    597     [pxa_lcdc_24bpp]  = pxa2xx_draw_line24,
    598 };
    599 
    600 /* Overlay planes enabled, transparency used */
    601 static drawfn pxa2xx_draw_fn_32t[16] = {
    602     [0 ... 0xf]       = NULL,
    603     [pxa_lcdc_4bpp]   = pxa2xx_draw_line4,
    604     [pxa_lcdc_8bpp]   = pxa2xx_draw_line8,
    605     [pxa_lcdc_16bpp]  = pxa2xx_draw_line16t,
    606     [pxa_lcdc_19bpp]  = pxa2xx_draw_line19,
    607     [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
    608     [pxa_lcdc_24bpp]  = pxa2xx_draw_line24t,
    609     [pxa_lcdc_25bpp]  = pxa2xx_draw_line25,
    610 };
    611 
    612 #undef COPY_PIXEL
    613 #undef SKIP_PIXEL
    614 
    615 #ifdef SWAP_WORDS
    616 # undef SWAP_WORDS
    617 #endif
    618 
    619 /* Route internal interrupt lines to the global IC */
    620 static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
    621 {
    622     int level = 0;
    623     level |= (s->status[0] & LCSR0_LDD)    && !(s->control[0] & LCCR0_LDM);
    624     level |= (s->status[0] & LCSR0_SOF0)   && !(s->control[0] & LCCR0_SOFM0);
    625     level |= (s->status[0] & LCSR0_IU0)    && !(s->control[0] & LCCR0_IUM);
    626     level |= (s->status[0] & LCSR0_IU1)    && !(s->control[5] & LCCR5_IUM(1));
    627     level |= (s->status[0] & LCSR0_OU)     && !(s->control[0] & LCCR0_OUM);
    628     level |= (s->status[0] & LCSR0_QD)     && !(s->control[0] & LCCR0_QDM);
    629     level |= (s->status[0] & LCSR0_EOF0)   && !(s->control[0] & LCCR0_EOFM0);
    630     level |= (s->status[0] & LCSR0_BS0)    && !(s->control[0] & LCCR0_BSM0);
    631     level |= (s->status[0] & LCSR0_RDST)   && !(s->control[0] & LCCR0_RDSTM);
    632     level |= (s->status[0] & LCSR0_CMDINT) && !(s->control[0] & LCCR0_CMDIM);
    633     level |= (s->status[1] & ~s->control[5]);
    634 
    635     qemu_set_irq(s->irq, !!level);
    636     s->irqlevel = level;
    637 }
    638 
    639 /* Set Branch Status interrupt high and poke associated registers */
    640 static inline void pxa2xx_dma_bs_set(PXA2xxLCDState *s, int ch)
    641 {
    642     int unmasked;
    643     if (ch == 0) {
    644         s->status[0] |= LCSR0_BS0;
    645         unmasked = !(s->control[0] & LCCR0_BSM0);
    646     } else {
    647         s->status[1] |= LCSR1_BS(ch);
    648         unmasked = !(s->control[5] & LCCR5_BSM(ch));
    649     }
    650 
    651     if (unmasked) {
    652         if (s->irqlevel)
    653             s->status[0] |= LCSR0_SINT;
    654         else
    655             s->liidr = s->dma_ch[ch].id;
    656     }
    657 }
    658 
    659 /* Set Start Of Frame Status interrupt high and poke associated registers */
    660 static inline void pxa2xx_dma_sof_set(PXA2xxLCDState *s, int ch)
    661 {
    662     int unmasked;
    663     if (!(s->dma_ch[ch].command & LDCMD_SOFINT))
    664         return;
    665 
    666     if (ch == 0) {
    667         s->status[0] |= LCSR0_SOF0;
    668         unmasked = !(s->control[0] & LCCR0_SOFM0);
    669     } else {
    670         s->status[1] |= LCSR1_SOF(ch);
    671         unmasked = !(s->control[5] & LCCR5_SOFM(ch));
    672     }
    673 
    674     if (unmasked) {
    675         if (s->irqlevel)
    676             s->status[0] |= LCSR0_SINT;
    677         else
    678             s->liidr = s->dma_ch[ch].id;
    679     }
    680 }
    681 
    682 /* Set End Of Frame Status interrupt high and poke associated registers */
    683 static inline void pxa2xx_dma_eof_set(PXA2xxLCDState *s, int ch)
    684 {
    685     int unmasked;
    686     if (!(s->dma_ch[ch].command & LDCMD_EOFINT))
    687         return;
    688 
    689     if (ch == 0) {
    690         s->status[0] |= LCSR0_EOF0;
    691         unmasked = !(s->control[0] & LCCR0_EOFM0);
    692     } else {
    693         s->status[1] |= LCSR1_EOF(ch);
    694         unmasked = !(s->control[5] & LCCR5_EOFM(ch));
    695     }
    696 
    697     if (unmasked) {
    698         if (s->irqlevel)
    699             s->status[0] |= LCSR0_SINT;
    700         else
    701             s->liidr = s->dma_ch[ch].id;
    702     }
    703 }
    704 
    705 /* Set Bus Error Status interrupt high and poke associated registers */
    706 static inline void pxa2xx_dma_ber_set(PXA2xxLCDState *s, int ch)
    707 {
    708     s->status[0] |= LCSR0_BERCH(ch) | LCSR0_BER;
    709     if (s->irqlevel)
    710         s->status[0] |= LCSR0_SINT;
    711     else
    712         s->liidr = s->dma_ch[ch].id;
    713 }
    714 
    715 /* Load new Frame Descriptors from DMA */
    716 static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
    717 {
    718     PXAFrameDescriptor desc;
    719     hwaddr descptr;
    720     int i;
    721 
    722     for (i = 0; i < PXA_LCDDMA_CHANS; i ++) {
    723         s->dma_ch[i].source = 0;
    724 
    725         if (!s->dma_ch[i].up)
    726             continue;
    727 
    728         if (s->dma_ch[i].branch & FBR_BRA) {
    729             descptr = s->dma_ch[i].branch & FBR_SRCADDR;
    730             if (s->dma_ch[i].branch & FBR_BINT)
    731                 pxa2xx_dma_bs_set(s, i);
    732             s->dma_ch[i].branch &= ~FBR_BRA;
    733         } else
    734             descptr = s->dma_ch[i].descriptor;
    735 
    736         if (!((descptr >= PXA2XX_SDRAM_BASE && descptr +
    737                  sizeof(desc) <= PXA2XX_SDRAM_BASE + current_machine->ram_size) ||
    738                 (descptr >= PXA2XX_INTERNAL_BASE && descptr + sizeof(desc) <=
    739                  PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
    740             continue;
    741         }
    742 
    743         cpu_physical_memory_read(descptr, &desc, sizeof(desc));
    744         s->dma_ch[i].descriptor = le32_to_cpu(desc.fdaddr);
    745         s->dma_ch[i].source = le32_to_cpu(desc.fsaddr);
    746         s->dma_ch[i].id = le32_to_cpu(desc.fidr);
    747         s->dma_ch[i].command = le32_to_cpu(desc.ldcmd);
    748     }
    749 }
    750 
    751 static uint64_t pxa2xx_lcdc_read(void *opaque, hwaddr offset,
    752                                  unsigned size)
    753 {
    754     PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
    755     int ch;
    756 
    757     switch (offset) {
    758     case LCCR0:
    759         return s->control[0];
    760     case LCCR1:
    761         return s->control[1];
    762     case LCCR2:
    763         return s->control[2];
    764     case LCCR3:
    765         return s->control[3];
    766     case LCCR4:
    767         return s->control[4];
    768     case LCCR5:
    769         return s->control[5];
    770 
    771     case OVL1C1:
    772         return s->ovl1c[0];
    773     case OVL1C2:
    774         return s->ovl1c[1];
    775     case OVL2C1:
    776         return s->ovl2c[0];
    777     case OVL2C2:
    778         return s->ovl2c[1];
    779 
    780     case CCR:
    781         return s->ccr;
    782 
    783     case CMDCR:
    784         return s->cmdcr;
    785 
    786     case TRGBR:
    787         return s->trgbr;
    788     case TCR:
    789         return s->tcr;
    790 
    791     case 0x200 ... 0x1000:      /* DMA per-channel registers */
    792         ch = (offset - 0x200) >> 4;
    793         if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
    794             goto fail;
    795 
    796         switch (offset & 0xf) {
    797         case DMA_FDADR:
    798             return s->dma_ch[ch].descriptor;
    799         case DMA_FSADR:
    800             return s->dma_ch[ch].source;
    801         case DMA_FIDR:
    802             return s->dma_ch[ch].id;
    803         case DMA_LDCMD:
    804             return s->dma_ch[ch].command;
    805         default:
    806             goto fail;
    807         }
    808 
    809     case FBR0:
    810         return s->dma_ch[0].branch;
    811     case FBR1:
    812         return s->dma_ch[1].branch;
    813     case FBR2:
    814         return s->dma_ch[2].branch;
    815     case FBR3:
    816         return s->dma_ch[3].branch;
    817     case FBR4:
    818         return s->dma_ch[4].branch;
    819     case FBR5:
    820         return s->dma_ch[5].branch;
    821     case FBR6:
    822         return s->dma_ch[6].branch;
    823 
    824     case BSCNTR:
    825         return s->bscntr;
    826 
    827     case PRSR:
    828         return 0;
    829 
    830     case LCSR0:
    831         return s->status[0];
    832     case LCSR1:
    833         return s->status[1];
    834     case LIIDR:
    835         return s->liidr;
    836 
    837     default:
    838     fail:
    839         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
    840                       __func__, offset);
    841     }
    842 
    843     return 0;
    844 }
    845 
    846 static void pxa2xx_lcdc_write(void *opaque, hwaddr offset,
    847                               uint64_t value, unsigned size)
    848 {
    849     PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
    850     int ch;
    851 
    852     switch (offset) {
    853     case LCCR0:
    854         /* ACK Quick Disable done */
    855         if ((s->control[0] & LCCR0_ENB) && !(value & LCCR0_ENB))
    856             s->status[0] |= LCSR0_QD;
    857 
    858         if (!(s->control[0] & LCCR0_LCDT) && (value & LCCR0_LCDT)) {
    859             qemu_log_mask(LOG_UNIMP,
    860                           "%s: internal frame buffer unsupported\n", __func__);
    861         }
    862         if ((s->control[3] & LCCR3_API) &&
    863                 (value & LCCR0_ENB) && !(value & LCCR0_LCDT))
    864             s->status[0] |= LCSR0_ABC;
    865 
    866         s->control[0] = value & 0x07ffffff;
    867         pxa2xx_lcdc_int_update(s);
    868 
    869         s->dma_ch[0].up = !!(value & LCCR0_ENB);
    870         s->dma_ch[1].up = (s->ovl1c[0] & OVLC1_EN) || (value & LCCR0_SDS);
    871         break;
    872 
    873     case LCCR1:
    874         s->control[1] = value;
    875         break;
    876 
    877     case LCCR2:
    878         s->control[2] = value;
    879         break;
    880 
    881     case LCCR3:
    882         s->control[3] = value & 0xefffffff;
    883         s->bpp = LCCR3_BPP(value);
    884         break;
    885 
    886     case LCCR4:
    887         s->control[4] = value & 0x83ff81ff;
    888         break;
    889 
    890     case LCCR5:
    891         s->control[5] = value & 0x3f3f3f3f;
    892         break;
    893 
    894     case OVL1C1:
    895         if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN)) {
    896             qemu_log_mask(LOG_UNIMP, "%s: Overlay 1 not supported\n", __func__);
    897         }
    898         s->ovl1c[0] = value & 0x80ffffff;
    899         s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS);
    900         break;
    901 
    902     case OVL1C2:
    903         s->ovl1c[1] = value & 0x000fffff;
    904         break;
    905 
    906     case OVL2C1:
    907         if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN)) {
    908             qemu_log_mask(LOG_UNIMP, "%s: Overlay 2 not supported\n", __func__);
    909         }
    910         s->ovl2c[0] = value & 0x80ffffff;
    911         s->dma_ch[2].up = !!(value & OVLC1_EN);
    912         s->dma_ch[3].up = !!(value & OVLC1_EN);
    913         s->dma_ch[4].up = !!(value & OVLC1_EN);
    914         break;
    915 
    916     case OVL2C2:
    917         s->ovl2c[1] = value & 0x007fffff;
    918         break;
    919 
    920     case CCR:
    921         if (!(s->ccr & CCR_CEN) && (value & CCR_CEN)) {
    922             qemu_log_mask(LOG_UNIMP,
    923                           "%s: Hardware cursor unimplemented\n", __func__);
    924         }
    925         s->ccr = value & 0x81ffffe7;
    926         s->dma_ch[5].up = !!(value & CCR_CEN);
    927         break;
    928 
    929     case CMDCR:
    930         s->cmdcr = value & 0xff;
    931         break;
    932 
    933     case TRGBR:
    934         s->trgbr = value & 0x00ffffff;
    935         break;
    936 
    937     case TCR:
    938         s->tcr = value & 0x7fff;
    939         break;
    940 
    941     case 0x200 ... 0x1000:      /* DMA per-channel registers */
    942         ch = (offset - 0x200) >> 4;
    943         if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS))
    944             goto fail;
    945 
    946         switch (offset & 0xf) {
    947         case DMA_FDADR:
    948             s->dma_ch[ch].descriptor = value & 0xfffffff0;
    949             break;
    950 
    951         default:
    952             goto fail;
    953         }
    954         break;
    955 
    956     case FBR0:
    957         s->dma_ch[0].branch = value & 0xfffffff3;
    958         break;
    959     case FBR1:
    960         s->dma_ch[1].branch = value & 0xfffffff3;
    961         break;
    962     case FBR2:
    963         s->dma_ch[2].branch = value & 0xfffffff3;
    964         break;
    965     case FBR3:
    966         s->dma_ch[3].branch = value & 0xfffffff3;
    967         break;
    968     case FBR4:
    969         s->dma_ch[4].branch = value & 0xfffffff3;
    970         break;
    971     case FBR5:
    972         s->dma_ch[5].branch = value & 0xfffffff3;
    973         break;
    974     case FBR6:
    975         s->dma_ch[6].branch = value & 0xfffffff3;
    976         break;
    977 
    978     case BSCNTR:
    979         s->bscntr = value & 0xf;
    980         break;
    981 
    982     case PRSR:
    983         break;
    984 
    985     case LCSR0:
    986         s->status[0] &= ~(value & 0xfff);
    987         if (value & LCSR0_BER)
    988             s->status[0] &= ~LCSR0_BERCH(7);
    989         break;
    990 
    991     case LCSR1:
    992         s->status[1] &= ~(value & 0x3e3f3f);
    993         break;
    994 
    995     default:
    996     fail:
    997         qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n",
    998                       __func__, offset);
    999     }
   1000 }
   1001 
   1002 static const MemoryRegionOps pxa2xx_lcdc_ops = {
   1003     .read = pxa2xx_lcdc_read,
   1004     .write = pxa2xx_lcdc_write,
   1005     .endianness = DEVICE_NATIVE_ENDIAN,
   1006 };
   1007 
   1008 /* Load new palette for a given DMA channel, convert to internal format */
   1009 static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
   1010 {
   1011     DisplaySurface *surface = qemu_console_surface(s->con);
   1012     int i, n, format, r, g, b, alpha;
   1013     uint32_t *dest;
   1014     uint8_t *src;
   1015     s->pal_for = LCCR4_PALFOR(s->control[4]);
   1016     format = s->pal_for;
   1017 
   1018     switch (bpp) {
   1019     case pxa_lcdc_2bpp:
   1020         n = 4;
   1021         break;
   1022     case pxa_lcdc_4bpp:
   1023         n = 16;
   1024         break;
   1025     case pxa_lcdc_8bpp:
   1026         n = 256;
   1027         break;
   1028     default:
   1029         return;
   1030     }
   1031 
   1032     src = (uint8_t *) s->dma_ch[ch].pbuffer;
   1033     dest = (uint32_t *) s->dma_ch[ch].palette;
   1034     alpha = r = g = b = 0;
   1035 
   1036     for (i = 0; i < n; i ++) {
   1037         switch (format) {
   1038         case 0: /* 16 bpp, no transparency */
   1039             alpha = 0;
   1040             if (s->control[0] & LCCR0_CMS) {
   1041                 r = g = b = *(uint16_t *) src & 0xff;
   1042             }
   1043             else {
   1044                 r = (*(uint16_t *) src & 0xf800) >> 8;
   1045                 g = (*(uint16_t *) src & 0x07e0) >> 3;
   1046                 b = (*(uint16_t *) src & 0x001f) << 3;
   1047             }
   1048             src += 2;
   1049             break;
   1050         case 1: /* 16 bpp plus transparency */
   1051             alpha = *(uint32_t *) src & (1 << 24);
   1052             if (s->control[0] & LCCR0_CMS)
   1053                 r = g = b = *(uint32_t *) src & 0xff;
   1054             else {
   1055                 r = (*(uint32_t *) src & 0xf80000) >> 16;
   1056                 g = (*(uint32_t *) src & 0x00fc00) >> 8;
   1057                 b = (*(uint32_t *) src & 0x0000f8);
   1058             }
   1059             src += 4;
   1060             break;
   1061         case 2: /* 18 bpp plus transparency */
   1062             alpha = *(uint32_t *) src & (1 << 24);
   1063             if (s->control[0] & LCCR0_CMS)
   1064                 r = g = b = *(uint32_t *) src & 0xff;
   1065             else {
   1066                 r = (*(uint32_t *) src & 0xfc0000) >> 16;
   1067                 g = (*(uint32_t *) src & 0x00fc00) >> 8;
   1068                 b = (*(uint32_t *) src & 0x0000fc);
   1069             }
   1070             src += 4;
   1071             break;
   1072         case 3: /* 24 bpp plus transparency */
   1073             alpha = *(uint32_t *) src & (1 << 24);
   1074             if (s->control[0] & LCCR0_CMS)
   1075                 r = g = b = *(uint32_t *) src & 0xff;
   1076             else {
   1077                 r = (*(uint32_t *) src & 0xff0000) >> 16;
   1078                 g = (*(uint32_t *) src & 0x00ff00) >> 8;
   1079                 b = (*(uint32_t *) src & 0x0000ff);
   1080             }
   1081             src += 4;
   1082             break;
   1083         }
   1084         switch (surface_bits_per_pixel(surface)) {
   1085         case 8:
   1086             *dest = rgb_to_pixel8(r, g, b) | alpha;
   1087             break;
   1088         case 15:
   1089             *dest = rgb_to_pixel15(r, g, b) | alpha;
   1090             break;
   1091         case 16:
   1092             *dest = rgb_to_pixel16(r, g, b) | alpha;
   1093             break;
   1094         case 24:
   1095             *dest = rgb_to_pixel24(r, g, b) | alpha;
   1096             break;
   1097         case 32:
   1098             *dest = rgb_to_pixel32(r, g, b) | alpha;
   1099             break;
   1100         }
   1101         dest ++;
   1102     }
   1103 }
   1104 
   1105 static inline drawfn pxa2xx_drawfn(PXA2xxLCDState *s)
   1106 {
   1107     if (s->transp) {
   1108         return pxa2xx_draw_fn_32t[s->bpp];
   1109     } else {
   1110         return pxa2xx_draw_fn_32[s->bpp];
   1111     }
   1112 }
   1113 
   1114 static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
   1115                 hwaddr addr, int *miny, int *maxy)
   1116 {
   1117     DisplaySurface *surface = qemu_console_surface(s->con);
   1118     int src_width, dest_width;
   1119     drawfn fn = pxa2xx_drawfn(s);
   1120     if (!fn)
   1121         return;
   1122 
   1123     src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
   1124     if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
   1125         src_width *= 3;
   1126     else if (s->bpp > pxa_lcdc_16bpp)
   1127         src_width *= 4;
   1128     else if (s->bpp > pxa_lcdc_8bpp)
   1129         src_width *= 2;
   1130 
   1131     dest_width = s->xres * DEST_PIXEL_WIDTH;
   1132     *miny = 0;
   1133     if (s->invalidated) {
   1134         framebuffer_update_memory_section(&s->fbsection, s->sysmem,
   1135                                           addr, s->yres, src_width);
   1136     }
   1137     framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
   1138                                src_width, dest_width, DEST_PIXEL_WIDTH,
   1139                                s->invalidated,
   1140                                fn, s->dma_ch[0].palette, miny, maxy);
   1141 }
   1142 
   1143 static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
   1144                hwaddr addr, int *miny, int *maxy)
   1145 {
   1146     DisplaySurface *surface = qemu_console_surface(s->con);
   1147     int src_width, dest_width;
   1148     drawfn fn = pxa2xx_drawfn(s);
   1149     if (!fn)
   1150         return;
   1151 
   1152     src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
   1153     if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
   1154         src_width *= 3;
   1155     else if (s->bpp > pxa_lcdc_16bpp)
   1156         src_width *= 4;
   1157     else if (s->bpp > pxa_lcdc_8bpp)
   1158         src_width *= 2;
   1159 
   1160     dest_width = s->yres * DEST_PIXEL_WIDTH;
   1161     *miny = 0;
   1162     if (s->invalidated) {
   1163         framebuffer_update_memory_section(&s->fbsection, s->sysmem,
   1164                                           addr, s->yres, src_width);
   1165     }
   1166     framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
   1167                                src_width, DEST_PIXEL_WIDTH, -dest_width,
   1168                                s->invalidated,
   1169                                fn, s->dma_ch[0].palette,
   1170                                miny, maxy);
   1171 }
   1172 
   1173 static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
   1174                 hwaddr addr, int *miny, int *maxy)
   1175 {
   1176     DisplaySurface *surface = qemu_console_surface(s->con);
   1177     int src_width, dest_width;
   1178     drawfn fn = pxa2xx_drawfn(s);
   1179     if (!fn) {
   1180         return;
   1181     }
   1182 
   1183     src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
   1184     if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
   1185         src_width *= 3;
   1186     } else if (s->bpp > pxa_lcdc_16bpp) {
   1187         src_width *= 4;
   1188     } else if (s->bpp > pxa_lcdc_8bpp) {
   1189         src_width *= 2;
   1190     }
   1191 
   1192     dest_width = s->xres * DEST_PIXEL_WIDTH;
   1193     *miny = 0;
   1194     if (s->invalidated) {
   1195         framebuffer_update_memory_section(&s->fbsection, s->sysmem,
   1196                                           addr, s->yres, src_width);
   1197     }
   1198     framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
   1199                                src_width, -dest_width, -DEST_PIXEL_WIDTH,
   1200                                s->invalidated,
   1201                                fn, s->dma_ch[0].palette, miny, maxy);
   1202 }
   1203 
   1204 static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
   1205                hwaddr addr, int *miny, int *maxy)
   1206 {
   1207     DisplaySurface *surface = qemu_console_surface(s->con);
   1208     int src_width, dest_width;
   1209     drawfn fn = pxa2xx_drawfn(s);
   1210     if (!fn) {
   1211         return;
   1212     }
   1213 
   1214     src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
   1215     if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) {
   1216         src_width *= 3;
   1217     } else if (s->bpp > pxa_lcdc_16bpp) {
   1218         src_width *= 4;
   1219     } else if (s->bpp > pxa_lcdc_8bpp) {
   1220         src_width *= 2;
   1221     }
   1222 
   1223     dest_width = s->yres * DEST_PIXEL_WIDTH;
   1224     *miny = 0;
   1225     if (s->invalidated) {
   1226         framebuffer_update_memory_section(&s->fbsection, s->sysmem,
   1227                                           addr, s->yres, src_width);
   1228     }
   1229     framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
   1230                                src_width, -DEST_PIXEL_WIDTH, dest_width,
   1231                                s->invalidated,
   1232                                fn, s->dma_ch[0].palette,
   1233                                miny, maxy);
   1234 }
   1235 
   1236 static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
   1237 {
   1238     int width, height;
   1239     if (!(s->control[0] & LCCR0_ENB))
   1240         return;
   1241 
   1242     width = LCCR1_PPL(s->control[1]) + 1;
   1243     height = LCCR2_LPP(s->control[2]) + 1;
   1244 
   1245     if (width != s->xres || height != s->yres) {
   1246         if (s->orientation == 90 || s->orientation == 270) {
   1247             qemu_console_resize(s->con, height, width);
   1248         } else {
   1249             qemu_console_resize(s->con, width, height);
   1250         }
   1251         s->invalidated = 1;
   1252         s->xres = width;
   1253         s->yres = height;
   1254     }
   1255 }
   1256 
   1257 static void pxa2xx_update_display(void *opaque)
   1258 {
   1259     PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
   1260     hwaddr fbptr;
   1261     int miny, maxy;
   1262     int ch;
   1263     if (!(s->control[0] & LCCR0_ENB))
   1264         return;
   1265 
   1266     pxa2xx_descriptor_load(s);
   1267 
   1268     pxa2xx_lcdc_resize(s);
   1269     miny = s->yres;
   1270     maxy = 0;
   1271     s->transp = s->dma_ch[2].up || s->dma_ch[3].up;
   1272     /* Note: With overlay planes the order depends on LCCR0 bit 25.  */
   1273     for (ch = 0; ch < PXA_LCDDMA_CHANS; ch ++)
   1274         if (s->dma_ch[ch].up) {
   1275             if (!s->dma_ch[ch].source) {
   1276                 pxa2xx_dma_ber_set(s, ch);
   1277                 continue;
   1278             }
   1279             fbptr = s->dma_ch[ch].source;
   1280             if (!((fbptr >= PXA2XX_SDRAM_BASE &&
   1281                      fbptr <= PXA2XX_SDRAM_BASE + current_machine->ram_size) ||
   1282                     (fbptr >= PXA2XX_INTERNAL_BASE &&
   1283                      fbptr <= PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) {
   1284                 pxa2xx_dma_ber_set(s, ch);
   1285                 continue;
   1286             }
   1287 
   1288             if (s->dma_ch[ch].command & LDCMD_PAL) {
   1289                 cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
   1290                     MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
   1291                         sizeof(s->dma_ch[ch].pbuffer)));
   1292                 pxa2xx_palette_parse(s, ch, s->bpp);
   1293             } else {
   1294                 /* Do we need to reparse palette */
   1295                 if (LCCR4_PALFOR(s->control[4]) != s->pal_for)
   1296                     pxa2xx_palette_parse(s, ch, s->bpp);
   1297 
   1298                 /* ACK frame start */
   1299                 pxa2xx_dma_sof_set(s, ch);
   1300 
   1301                 s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
   1302                 s->invalidated = 0;
   1303 
   1304                 /* ACK frame completed */
   1305                 pxa2xx_dma_eof_set(s, ch);
   1306             }
   1307         }
   1308 
   1309     if (s->control[0] & LCCR0_DIS) {
   1310         /* ACK last frame completed */
   1311         s->control[0] &= ~LCCR0_ENB;
   1312         s->status[0] |= LCSR0_LDD;
   1313     }
   1314 
   1315     if (miny >= 0) {
   1316         switch (s->orientation) {
   1317         case 0:
   1318             dpy_gfx_update(s->con, 0, miny, s->xres, maxy - miny + 1);
   1319             break;
   1320         case 90:
   1321             dpy_gfx_update(s->con, miny, 0, maxy - miny + 1, s->xres);
   1322             break;
   1323         case 180:
   1324             maxy = s->yres - maxy - 1;
   1325             miny = s->yres - miny - 1;
   1326             dpy_gfx_update(s->con, 0, maxy, s->xres, miny - maxy + 1);
   1327             break;
   1328         case 270:
   1329             maxy = s->yres - maxy - 1;
   1330             miny = s->yres - miny - 1;
   1331             dpy_gfx_update(s->con, maxy, 0, miny - maxy + 1, s->xres);
   1332             break;
   1333         }
   1334     }
   1335     pxa2xx_lcdc_int_update(s);
   1336 
   1337     qemu_irq_raise(s->vsync_cb);
   1338 }
   1339 
   1340 static void pxa2xx_invalidate_display(void *opaque)
   1341 {
   1342     PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
   1343     s->invalidated = 1;
   1344 }
   1345 
   1346 static void pxa2xx_lcdc_orientation(void *opaque, int angle)
   1347 {
   1348     PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
   1349 
   1350     switch (angle) {
   1351     case 0:
   1352         s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0;
   1353         break;
   1354     case 90:
   1355         s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90;
   1356         break;
   1357     case 180:
   1358         s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180;
   1359         break;
   1360     case 270:
   1361         s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270;
   1362         break;
   1363     }
   1364 
   1365     s->orientation = angle;
   1366     s->xres = s->yres = -1;
   1367     pxa2xx_lcdc_resize(s);
   1368 }
   1369 
   1370 static const VMStateDescription vmstate_dma_channel = {
   1371     .name = "dma_channel",
   1372     .version_id = 0,
   1373     .minimum_version_id = 0,
   1374     .fields = (VMStateField[]) {
   1375         VMSTATE_UINT32(branch, struct DMAChannel),
   1376         VMSTATE_UINT8(up, struct DMAChannel),
   1377         VMSTATE_BUFFER(pbuffer, struct DMAChannel),
   1378         VMSTATE_UINT32(descriptor, struct DMAChannel),
   1379         VMSTATE_UINT32(source, struct DMAChannel),
   1380         VMSTATE_UINT32(id, struct DMAChannel),
   1381         VMSTATE_UINT32(command, struct DMAChannel),
   1382         VMSTATE_END_OF_LIST()
   1383     }
   1384 };
   1385 
   1386 static int pxa2xx_lcdc_post_load(void *opaque, int version_id)
   1387 {
   1388     PXA2xxLCDState *s = opaque;
   1389 
   1390     s->bpp = LCCR3_BPP(s->control[3]);
   1391     s->xres = s->yres = s->pal_for = -1;
   1392 
   1393     return 0;
   1394 }
   1395 
   1396 static const VMStateDescription vmstate_pxa2xx_lcdc = {
   1397     .name = "pxa2xx_lcdc",
   1398     .version_id = 0,
   1399     .minimum_version_id = 0,
   1400     .post_load = pxa2xx_lcdc_post_load,
   1401     .fields = (VMStateField[]) {
   1402         VMSTATE_INT32(irqlevel, PXA2xxLCDState),
   1403         VMSTATE_INT32(transp, PXA2xxLCDState),
   1404         VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6),
   1405         VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2),
   1406         VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2),
   1407         VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2),
   1408         VMSTATE_UINT32(ccr, PXA2xxLCDState),
   1409         VMSTATE_UINT32(cmdcr, PXA2xxLCDState),
   1410         VMSTATE_UINT32(trgbr, PXA2xxLCDState),
   1411         VMSTATE_UINT32(tcr, PXA2xxLCDState),
   1412         VMSTATE_UINT32(liidr, PXA2xxLCDState),
   1413         VMSTATE_UINT8(bscntr, PXA2xxLCDState),
   1414         VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0,
   1415                              vmstate_dma_channel, struct DMAChannel),
   1416         VMSTATE_END_OF_LIST()
   1417     }
   1418 };
   1419 
   1420 static const GraphicHwOps pxa2xx_ops = {
   1421     .invalidate  = pxa2xx_invalidate_display,
   1422     .gfx_update  = pxa2xx_update_display,
   1423 };
   1424 
   1425 PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
   1426                                  hwaddr base, qemu_irq irq)
   1427 {
   1428     PXA2xxLCDState *s;
   1429 
   1430     s = g_new0(PXA2xxLCDState, 1);
   1431     s->invalidated = 1;
   1432     s->irq = irq;
   1433     s->sysmem = sysmem;
   1434 
   1435     pxa2xx_lcdc_orientation(s, graphic_rotate);
   1436 
   1437     memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s,
   1438                           "pxa2xx-lcd-controller", 0x00100000);
   1439     memory_region_add_subregion(sysmem, base, &s->iomem);
   1440 
   1441     s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
   1442 
   1443     vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
   1444 
   1445     return s;
   1446 }
   1447 
   1448 void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler)
   1449 {
   1450     s->vsync_cb = handler;
   1451 }