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