/* * pxafb_var_to_lccr3(): * Convert a bits per pixel value to the correct bit pattern for LCCR3 * * NOTE: for PXA27x with overlays support, the LCCR3_PDFOR_x bits have an * implication of the acutal use of transparency bit, which we handle it * here separatedly. See PXA27x Developer's Manual, Section <<7.4.6 Pixel * Formats>> for the valid combination of PDFOR, PAL_FOR for various BPP. * * Transparency for palette pixel formats is not supported at the moment. */ static uint32_t pxafb_var_to_lccr3(struct fb_info *info) { int bpp = pxafb_var_to_bpp(info); uint32_t lccr3; if (bpp < 0) return 0; lccr3 = LCCR3_BPP(bpp); switch (var_to_depth(info)) { case 16: lccr3 |= info->transp.length ? LCCR3_PDFOR_3 : 0; break; case 18: lccr3 |= LCCR3_PDFOR_3; break; case 24: lccr3 |= info->transp.length ? LCCR3_PDFOR_2 : LCCR3_PDFOR_3; break; case 19: case 25: lccr3 |= LCCR3_PDFOR_0; break; } return lccr3; }
static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id) { PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; int i; s->irqlevel = qemu_get_be32(f); s->transp = qemu_get_be32(f); for (i = 0; i < 6; i ++) qemu_get_be32s(f, &s->control[i]); for (i = 0; i < 2; i ++) qemu_get_be32s(f, &s->status[i]); for (i = 0; i < 2; i ++) qemu_get_be32s(f, &s->ovl1c[i]); for (i = 0; i < 2; i ++) qemu_get_be32s(f, &s->ovl2c[i]); qemu_get_be32s(f, &s->ccr); qemu_get_be32s(f, &s->cmdcr); qemu_get_be32s(f, &s->trgbr); qemu_get_be32s(f, &s->tcr); qemu_get_be32s(f, &s->liidr); qemu_get_8s(f, &s->bscntr); for (i = 0; i < 7; i ++) { s->dma_ch[i].branch = qemu_get_betl(f); s->dma_ch[i].up = qemu_get_byte(f); qemu_get_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer)); s->dma_ch[i].descriptor = qemu_get_betl(f); s->dma_ch[i].source = qemu_get_betl(f); qemu_get_be32s(f, &s->dma_ch[i].id); qemu_get_be32s(f, &s->dma_ch[i].command); } s->bpp = LCCR3_BPP(s->control[3]); s->xres = s->yres = s->pal_for = -1; return 0; }
static void pxa2xx_lcdc_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; int ch; switch (offset) { case LCCR0: /* ACK Quick Disable done */ if ((s->control[0] & LCCR0_ENB) && !(value & LCCR0_ENB)) s->status[0] |= LCSR0_QD; if (!(s->control[0] & LCCR0_LCDT) && (value & LCCR0_LCDT)) printf("%s: internal frame buffer unsupported\n", __FUNCTION__); if ((s->control[3] & LCCR3_API) && (value & LCCR0_ENB) && !(value & LCCR0_LCDT)) s->status[0] |= LCSR0_ABC; s->control[0] = value & 0x07ffffff; pxa2xx_lcdc_int_update(s); s->dma_ch[0].up = !!(value & LCCR0_ENB); s->dma_ch[1].up = (s->ovl1c[0] & OVLC1_EN) || (value & LCCR0_SDS); break; case LCCR1: s->control[1] = value; break; case LCCR2: s->control[2] = value; break; case LCCR3: s->control[3] = value & 0xefffffff; s->bpp = LCCR3_BPP(value); break; case LCCR4: s->control[4] = value & 0x83ff81ff; break; case LCCR5: s->control[5] = value & 0x3f3f3f3f; break; case OVL1C1: if (!(s->ovl1c[0] & OVLC1_EN) && (value & OVLC1_EN)) printf("%s: Overlay 1 not supported\n", __FUNCTION__); s->ovl1c[0] = value & 0x80ffffff; s->dma_ch[1].up = (value & OVLC1_EN) || (s->control[0] & LCCR0_SDS); break; case OVL1C2: s->ovl1c[1] = value & 0x000fffff; break; case OVL2C1: if (!(s->ovl2c[0] & OVLC1_EN) && (value & OVLC1_EN)) printf("%s: Overlay 2 not supported\n", __FUNCTION__); s->ovl2c[0] = value & 0x80ffffff; s->dma_ch[2].up = !!(value & OVLC1_EN); s->dma_ch[3].up = !!(value & OVLC1_EN); s->dma_ch[4].up = !!(value & OVLC1_EN); break; case OVL2C2: s->ovl2c[1] = value & 0x007fffff; break; case CCR: if (!(s->ccr & CCR_CEN) && (value & CCR_CEN)) printf("%s: Hardware cursor unimplemented\n", __FUNCTION__); s->ccr = value & 0x81ffffe7; s->dma_ch[5].up = !!(value & CCR_CEN); break; case CMDCR: s->cmdcr = value & 0xff; break; case TRGBR: s->trgbr = value & 0x00ffffff; break; case TCR: s->tcr = value & 0x7fff; break; case 0x200 ... 0x1000: /* DMA per-channel registers */ ch = (offset - 0x200) >> 4; if (!(ch >= 0 && ch < PXA_LCDDMA_CHANS)) goto fail; switch (offset & 0xf) { case DMA_FDADR: s->dma_ch[ch].descriptor = value & 0xfffffff0; break; default: goto fail; } break; case FBR0: s->dma_ch[0].branch = value & 0xfffffff3; break; case FBR1: s->dma_ch[1].branch = value & 0xfffffff3; break; case FBR2: s->dma_ch[2].branch = value & 0xfffffff3; break; case FBR3: s->dma_ch[3].branch = value & 0xfffffff3; break; case FBR4: s->dma_ch[4].branch = value & 0xfffffff3; break; case FBR5: s->dma_ch[5].branch = value & 0xfffffff3; break; case FBR6: s->dma_ch[6].branch = value & 0xfffffff3; break; case BSCNTR: s->bscntr = value & 0xf; break; case PRSR: break; case LCSR0: s->status[0] &= ~(value & 0xfff); if (value & LCSR0_BER) s->status[0] &= ~LCSR0_BERCH(7); break; case LCSR1: s->status[1] &= ~(value & 0x3e3f3f); break; default: fail: hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset); } }