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