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