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 qemu_log_mask(LOG_UNIMP, 431 "%s: internal frame buffer unsupported\n", __func__); 432 } 433 if ((s->control[3] & LCCR3_API) && 434 (value & LCCR0_ENB) && !(value & LCCR0_LCDT)) 435 s->status[0] |= LCSR0_ABC; 436 437 s->control[0] = value & 0x07ffffff; 438 pxa2xx_lcdc_int_update(s); 439 440 s->dma_ch[0].up = !!(value & LCCR0_ENB); 441 s->dma_ch[1].up = (s->ovl1c[0] & OVLC1_EN) || (value & LCCR0_SDS); 442 break; 443 444 case LCCR1: 445 s->control[1] = value; 446 break; 447 448 case LCCR2: 449 s->control[2] = value; 450 break; 451 452 case LCCR3: 453 s->control[3] = value & 0xefffffff; 454 s->bpp = LCCR3_BPP(value); 455 break; 456 457 case LCCR4: 458 s->control[4] = value & 0x83ff81ff; 459 break; 460 461 case LCCR5: 462 s->control[5] = value & 0x3f3f3f3f; 463 break; 464 465 case OVL1C1: 466 if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN)) { 467 qemu_log_mask(LOG_UNIMP, "%s: Overlay 1 not supported\n", __func__); 468 } 469 s->ovl1c[0] = value & 0x80ffffff; 470 s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS); 471 break; 472 473 case OVL1C2: 474 s->ovl1c[1] = value & 0x000fffff; 475 break; 476 477 case OVL2C1: 478 if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN)) { 479 qemu_log_mask(LOG_UNIMP, "%s: Overlay 2 not supported\n", __func__); 480 } 481 s->ovl2c[0] = value & 0x80ffffff; 482 s->dma_ch[2].up = !!(value & OVLC1_EN); 483 s->dma_ch[3].up = !!(value & OVLC1_EN); 484 s->dma_ch[4].up = !!(value & OVLC1_EN); 485 break; 486 487 case OVL2C2: 488 s->ovl2c[1] = value & 0x007fffff; 489 break; 490 491 case CCR: 492 if (!(s->ccr & CCR_CEN) && (value & CCR_CEN)) { 493 qemu_log_mask(LOG_UNIMP, 494 "%s: Hardware cursor unimplemented\n", __func__); 495 } 496 s->ccr = value & 0x81ffffe7; 497 s->dma_ch[5].up = !!(value & CCR_CEN); 498 break; 499 500 case CMDCR: 501 s->cmdcr = value & 0xff; 502 break; 503 504 case TRGBR: 505 s->trgbr = value & 0x00ffffff; 506 break; 507 508 case TCR: 509 s->tcr = value & 0x7fff; 510 break; 511 512 case 0x200 ... 0x1000: /* DMA per-channel registers */ 513 ch = (offset - 0x200) >> 4; 514 if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS)) 515 goto fail; 516 517 switch (offset & 0xf) { 518 case DMA_FDADR: 519 s->dma_ch[ch].descriptor = value & 0xfffffff0; 520 break; 521 522 default: 523 goto fail; 524 } 525 break; 526 527 case FBR0: 528 s->dma_ch[0].branch = value & 0xfffffff3; 529 break; 530 case FBR1: 531 s->dma_ch[1].branch = value & 0xfffffff3; 532 break; 533 case FBR2: 534 s->dma_ch[2].branch = value & 0xfffffff3; 535 break; 536 case FBR3: 537 s->dma_ch[3].branch = value & 0xfffffff3; 538 break; 539 case FBR4: 540 s->dma_ch[4].branch = value & 0xfffffff3; 541 break; 542 case FBR5: 543 s->dma_ch[5].branch = value & 0xfffffff3; 544 break; 545 case FBR6: 546 s->dma_ch[6].branch = value & 0xfffffff3; 547 break; 548 549 case BSCNTR: 550 s->bscntr = value & 0xf; 551 break; 552 553 case PRSR: 554 break; 555 556 case LCSR0: 557 s->status[0] &= ~(value & 0xfff); 558 if (value & LCSR0_BER) 559 s->status[0] &= ~LCSR0_BERCH(7); 560 break; 561 562 case LCSR1: 563 s->status[1] &= ~(value & 0x3e3f3f); 564 break; 565 566 default: 567 fail: 568 qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIX "\n", 569 __func__, offset); 570 } 571 } 572 573 static const MemoryRegionOps pxa2xx_lcdc_ops = { 574 .read = pxa2xx_lcdc_read, 575 .write = pxa2xx_lcdc_write, 576 .endianness = DEVICE_NATIVE_ENDIAN, 577 }; 578 579 /* Load new palette for a given DMA channel, convert to internal format */ 580 static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp) 581 { 582 DisplaySurface *surface = qemu_console_surface(s->con); 583 int i, n, format, r, g, b, alpha; 584 uint32_t *dest; 585 uint8_t *src; 586 s->pal_for = LCCR4_PALFOR(s->control[4]); 587 format = s->pal_for; 588 589 switch (bpp) { 590 case pxa_lcdc_2bpp: 591 n = 4; 592 break; 593 case pxa_lcdc_4bpp: 594 n = 16; 595 break; 596 case pxa_lcdc_8bpp: 597 n = 256; 598 break; 599 default: 600 return; 601 } 602 603 src = (uint8_t *) s->dma_ch[ch].pbuffer; 604 dest = (uint32_t *) s->dma_ch[ch].palette; 605 alpha = r = g = b = 0; 606 607 for (i = 0; i < n; i ++) { 608 switch (format) { 609 case 0: /* 16 bpp, no transparency */ 610 alpha = 0; 611 if (s->control[0] & LCCR0_CMS) { 612 r = g = b = *(uint16_t *) src & 0xff; 613 } 614 else { 615 r = (*(uint16_t *) src & 0xf800) >> 8; 616 g = (*(uint16_t *) src & 0x07e0) >> 3; 617 b = (*(uint16_t *) src & 0x001f) << 3; 618 } 619 src += 2; 620 break; 621 case 1: /* 16 bpp plus transparency */ 622 alpha = *(uint32_t *) src & (1 << 24); 623 if (s->control[0] & LCCR0_CMS) 624 r = g = b = *(uint32_t *) src & 0xff; 625 else { 626 r = (*(uint32_t *) src & 0xf80000) >> 16; 627 g = (*(uint32_t *) src & 0x00fc00) >> 8; 628 b = (*(uint32_t *) src & 0x0000f8); 629 } 630 src += 4; 631 break; 632 case 2: /* 18 bpp plus transparency */ 633 alpha = *(uint32_t *) src & (1 << 24); 634 if (s->control[0] & LCCR0_CMS) 635 r = g = b = *(uint32_t *) src & 0xff; 636 else { 637 r = (*(uint32_t *) src & 0xfc0000) >> 16; 638 g = (*(uint32_t *) src & 0x00fc00) >> 8; 639 b = (*(uint32_t *) src & 0x0000fc); 640 } 641 src += 4; 642 break; 643 case 3: /* 24 bpp plus transparency */ 644 alpha = *(uint32_t *) src & (1 << 24); 645 if (s->control[0] & LCCR0_CMS) 646 r = g = b = *(uint32_t *) src & 0xff; 647 else { 648 r = (*(uint32_t *) src & 0xff0000) >> 16; 649 g = (*(uint32_t *) src & 0x00ff00) >> 8; 650 b = (*(uint32_t *) src & 0x0000ff); 651 } 652 src += 4; 653 break; 654 } 655 switch (surface_bits_per_pixel(surface)) { 656 case 8: 657 *dest = rgb_to_pixel8(r, g, b) | alpha; 658 break; 659 case 15: 660 *dest = rgb_to_pixel15(r, g, b) | alpha; 661 break; 662 case 16: 663 *dest = rgb_to_pixel16(r, g, b) | alpha; 664 break; 665 case 24: 666 *dest = rgb_to_pixel24(r, g, b) | alpha; 667 break; 668 case 32: 669 *dest = rgb_to_pixel32(r, g, b) | alpha; 670 break; 671 } 672 dest ++; 673 } 674 } 675 676 static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s, 677 hwaddr addr, int *miny, int *maxy) 678 { 679 DisplaySurface *surface = qemu_console_surface(s->con); 680 int src_width, dest_width; 681 drawfn fn = NULL; 682 if (s->dest_width) 683 fn = s->line_fn[s->transp][s->bpp]; 684 if (!fn) 685 return; 686 687 src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ 688 if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) 689 src_width *= 3; 690 else if (s->bpp > pxa_lcdc_16bpp) 691 src_width *= 4; 692 else if (s->bpp > pxa_lcdc_8bpp) 693 src_width *= 2; 694 695 dest_width = s->xres * s->dest_width; 696 *miny = 0; 697 if (s->invalidated) { 698 framebuffer_update_memory_section(&s->fbsection, s->sysmem, 699 addr, s->yres, src_width); 700 } 701 framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, 702 src_width, dest_width, s->dest_width, 703 s->invalidated, 704 fn, s->dma_ch[0].palette, miny, maxy); 705 } 706 707 static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s, 708 hwaddr addr, int *miny, int *maxy) 709 { 710 DisplaySurface *surface = qemu_console_surface(s->con); 711 int src_width, dest_width; 712 drawfn fn = NULL; 713 if (s->dest_width) 714 fn = s->line_fn[s->transp][s->bpp]; 715 if (!fn) 716 return; 717 718 src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ 719 if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) 720 src_width *= 3; 721 else if (s->bpp > pxa_lcdc_16bpp) 722 src_width *= 4; 723 else if (s->bpp > pxa_lcdc_8bpp) 724 src_width *= 2; 725 726 dest_width = s->yres * s->dest_width; 727 *miny = 0; 728 if (s->invalidated) { 729 framebuffer_update_memory_section(&s->fbsection, s->sysmem, 730 addr, s->yres, src_width); 731 } 732 framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, 733 src_width, s->dest_width, -dest_width, 734 s->invalidated, 735 fn, s->dma_ch[0].palette, 736 miny, maxy); 737 } 738 739 static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s, 740 hwaddr addr, int *miny, int *maxy) 741 { 742 DisplaySurface *surface = qemu_console_surface(s->con); 743 int src_width, dest_width; 744 drawfn fn = NULL; 745 if (s->dest_width) { 746 fn = s->line_fn[s->transp][s->bpp]; 747 } 748 if (!fn) { 749 return; 750 } 751 752 src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ 753 if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) { 754 src_width *= 3; 755 } else if (s->bpp > pxa_lcdc_16bpp) { 756 src_width *= 4; 757 } else if (s->bpp > pxa_lcdc_8bpp) { 758 src_width *= 2; 759 } 760 761 dest_width = s->xres * s->dest_width; 762 *miny = 0; 763 if (s->invalidated) { 764 framebuffer_update_memory_section(&s->fbsection, s->sysmem, 765 addr, s->yres, src_width); 766 } 767 framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, 768 src_width, -dest_width, -s->dest_width, 769 s->invalidated, 770 fn, s->dma_ch[0].palette, miny, maxy); 771 } 772 773 static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, 774 hwaddr addr, int *miny, int *maxy) 775 { 776 DisplaySurface *surface = qemu_console_surface(s->con); 777 int src_width, dest_width; 778 drawfn fn = NULL; 779 if (s->dest_width) { 780 fn = s->line_fn[s->transp][s->bpp]; 781 } 782 if (!fn) { 783 return; 784 } 785 786 src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ 787 if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) { 788 src_width *= 3; 789 } else if (s->bpp > pxa_lcdc_16bpp) { 790 src_width *= 4; 791 } else if (s->bpp > pxa_lcdc_8bpp) { 792 src_width *= 2; 793 } 794 795 dest_width = s->yres * s->dest_width; 796 *miny = 0; 797 if (s->invalidated) { 798 framebuffer_update_memory_section(&s->fbsection, s->sysmem, 799 addr, s->yres, src_width); 800 } 801 framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, 802 src_width, -s->dest_width, dest_width, 803 s->invalidated, 804 fn, s->dma_ch[0].palette, 805 miny, maxy); 806 } 807 808 static void pxa2xx_lcdc_resize(PXA2xxLCDState *s) 809 { 810 int width, height; 811 if (!(s->control[0] & LCCR0_ENB)) 812 return; 813 814 width = LCCR1_PPL(s->control[1]) + 1; 815 height = LCCR2_LPP(s->control[2]) + 1; 816 817 if (width != s->xres || height != s->yres) { 818 if (s->orientation == 90 || s->orientation == 270) { 819 qemu_console_resize(s->con, height, width); 820 } else { 821 qemu_console_resize(s->con, width, height); 822 } 823 s->invalidated = 1; 824 s->xres = width; 825 s->yres = height; 826 } 827 } 828 829 static void pxa2xx_update_display(void *opaque) 830 { 831 PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; 832 hwaddr fbptr; 833 int miny, maxy; 834 int ch; 835 if (!(s->control[0] & LCCR0_ENB)) 836 return; 837 838 pxa2xx_descriptor_load(s); 839 840 pxa2xx_lcdc_resize(s); 841 miny = s->yres; 842 maxy = 0; 843 s->transp = s->dma_ch[2].up || s->dma_ch[3].up; 844 /* Note: With overlay planes the order depends on LCCR0 bit 25. */ 845 for (ch = 0; ch < PXA_LCDDMA_CHANS; ch ++) 846 if (s->dma_ch[ch].up) { 847 if (!s->dma_ch[ch].source) { 848 pxa2xx_dma_ber_set(s, ch); 849 continue; 850 } 851 fbptr = s->dma_ch[ch].source; 852 if (!((fbptr >= PXA2XX_SDRAM_BASE && 853 fbptr <= PXA2XX_SDRAM_BASE + ram_size) || 854 (fbptr >= PXA2XX_INTERNAL_BASE && 855 fbptr <= PXA2XX_INTERNAL_BASE + PXA2XX_INTERNAL_SIZE))) { 856 pxa2xx_dma_ber_set(s, ch); 857 continue; 858 } 859 860 if (s->dma_ch[ch].command & LDCMD_PAL) { 861 cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer, 862 MAX(LDCMD_LENGTH(s->dma_ch[ch].command), 863 sizeof(s->dma_ch[ch].pbuffer))); 864 pxa2xx_palette_parse(s, ch, s->bpp); 865 } else { 866 /* Do we need to reparse palette */ 867 if (LCCR4_PALFOR(s->control[4]) != s->pal_for) 868 pxa2xx_palette_parse(s, ch, s->bpp); 869 870 /* ACK frame start */ 871 pxa2xx_dma_sof_set(s, ch); 872 873 s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy); 874 s->invalidated = 0; 875 876 /* ACK frame completed */ 877 pxa2xx_dma_eof_set(s, ch); 878 } 879 } 880 881 if (s->control[0] & LCCR0_DIS) { 882 /* ACK last frame completed */ 883 s->control[0] &= ~LCCR0_ENB; 884 s->status[0] |= LCSR0_LDD; 885 } 886 887 if (miny >= 0) { 888 switch (s->orientation) { 889 case 0: 890 dpy_gfx_update(s->con, 0, miny, s->xres, maxy - miny + 1); 891 break; 892 case 90: 893 dpy_gfx_update(s->con, miny, 0, maxy - miny + 1, s->xres); 894 break; 895 case 180: 896 maxy = s->yres - maxy - 1; 897 miny = s->yres - miny - 1; 898 dpy_gfx_update(s->con, 0, maxy, s->xres, miny - maxy + 1); 899 break; 900 case 270: 901 maxy = s->yres - maxy - 1; 902 miny = s->yres - miny - 1; 903 dpy_gfx_update(s->con, maxy, 0, miny - maxy + 1, s->xres); 904 break; 905 } 906 } 907 pxa2xx_lcdc_int_update(s); 908 909 qemu_irq_raise(s->vsync_cb); 910 } 911 912 static void pxa2xx_invalidate_display(void *opaque) 913 { 914 PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; 915 s->invalidated = 1; 916 } 917 918 static void pxa2xx_lcdc_orientation(void *opaque, int angle) 919 { 920 PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; 921 922 switch (angle) { 923 case 0: 924 s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot0; 925 break; 926 case 90: 927 s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot90; 928 break; 929 case 180: 930 s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot180; 931 break; 932 case 270: 933 s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_rot270; 934 break; 935 } 936 937 s->orientation = angle; 938 s->xres = s->yres = -1; 939 pxa2xx_lcdc_resize(s); 940 } 941 942 static const VMStateDescription vmstate_dma_channel = { 943 .name = "dma_channel", 944 .version_id = 0, 945 .minimum_version_id = 0, 946 .fields = (VMStateField[]) { 947 VMSTATE_UINT32(branch, struct DMAChannel), 948 VMSTATE_UINT8(up, struct DMAChannel), 949 VMSTATE_BUFFER(pbuffer, struct DMAChannel), 950 VMSTATE_UINT32(descriptor, struct DMAChannel), 951 VMSTATE_UINT32(source, struct DMAChannel), 952 VMSTATE_UINT32(id, struct DMAChannel), 953 VMSTATE_UINT32(command, struct DMAChannel), 954 VMSTATE_END_OF_LIST() 955 } 956 }; 957 958 static int pxa2xx_lcdc_post_load(void *opaque, int version_id) 959 { 960 PXA2xxLCDState *s = opaque; 961 962 s->bpp = LCCR3_BPP(s->control[3]); 963 s->xres = s->yres = s->pal_for = -1; 964 965 return 0; 966 } 967 968 static const VMStateDescription vmstate_pxa2xx_lcdc = { 969 .name = "pxa2xx_lcdc", 970 .version_id = 0, 971 .minimum_version_id = 0, 972 .post_load = pxa2xx_lcdc_post_load, 973 .fields = (VMStateField[]) { 974 VMSTATE_INT32(irqlevel, PXA2xxLCDState), 975 VMSTATE_INT32(transp, PXA2xxLCDState), 976 VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6), 977 VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2), 978 VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2), 979 VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2), 980 VMSTATE_UINT32(ccr, PXA2xxLCDState), 981 VMSTATE_UINT32(cmdcr, PXA2xxLCDState), 982 VMSTATE_UINT32(trgbr, PXA2xxLCDState), 983 VMSTATE_UINT32(tcr, PXA2xxLCDState), 984 VMSTATE_UINT32(liidr, PXA2xxLCDState), 985 VMSTATE_UINT8(bscntr, PXA2xxLCDState), 986 VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0, 987 vmstate_dma_channel, struct DMAChannel), 988 VMSTATE_END_OF_LIST() 989 } 990 }; 991 992 #define BITS 8 993 #include "pxa2xx_template.h" 994 #define BITS 15 995 #include "pxa2xx_template.h" 996 #define BITS 16 997 #include "pxa2xx_template.h" 998 #define BITS 24 999 #include "pxa2xx_template.h" 1000 #define BITS 32 1001 #include "pxa2xx_template.h" 1002 1003 static const GraphicHwOps pxa2xx_ops = { 1004 .invalidate = pxa2xx_invalidate_display, 1005 .gfx_update = pxa2xx_update_display, 1006 }; 1007 1008 PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem, 1009 hwaddr base, qemu_irq irq) 1010 { 1011 PXA2xxLCDState *s; 1012 DisplaySurface *surface; 1013 1014 s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState)); 1015 s->invalidated = 1; 1016 s->irq = irq; 1017 s->sysmem = sysmem; 1018 1019 pxa2xx_lcdc_orientation(s, graphic_rotate); 1020 1021 memory_region_init_io(&s->iomem, NULL, &pxa2xx_lcdc_ops, s, 1022 "pxa2xx-lcd-controller", 0x00100000); 1023 memory_region_add_subregion(sysmem, base, &s->iomem); 1024 1025 s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s); 1026 surface = qemu_console_surface(s->con); 1027 1028 switch (surface_bits_per_pixel(surface)) { 1029 case 0: 1030 s->dest_width = 0; 1031 break; 1032 case 8: 1033 s->line_fn[0] = pxa2xx_draw_fn_8; 1034 s->line_fn[1] = pxa2xx_draw_fn_8t; 1035 s->dest_width = 1; 1036 break; 1037 case 15: 1038 s->line_fn[0] = pxa2xx_draw_fn_15; 1039 s->line_fn[1] = pxa2xx_draw_fn_15t; 1040 s->dest_width = 2; 1041 break; 1042 case 16: 1043 s->line_fn[0] = pxa2xx_draw_fn_16; 1044 s->line_fn[1] = pxa2xx_draw_fn_16t; 1045 s->dest_width = 2; 1046 break; 1047 case 24: 1048 s->line_fn[0] = pxa2xx_draw_fn_24; 1049 s->line_fn[1] = pxa2xx_draw_fn_24t; 1050 s->dest_width = 3; 1051 break; 1052 case 32: 1053 s->line_fn[0] = pxa2xx_draw_fn_32; 1054 s->line_fn[1] = pxa2xx_draw_fn_32t; 1055 s->dest_width = 4; 1056 break; 1057 default: 1058 fprintf(stderr, "%s: Bad color depth\n", __func__); 1059 exit(1); 1060 } 1061 1062 vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s); 1063 1064 return s; 1065 } 1066 1067 void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler) 1068 { 1069 s->vsync_cb = handler; 1070 } 1071