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