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