xref: /qemu/hw/display/pxa2xx_lcd.c (revision a976a99a)
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 }
1452