57
56
uint8_t palette[1024];
58
57
uint8_t pbuffer[1024];
59
void (*redraw)(struct pxa2xx_lcdc_s *s, uint8_t *fb,
58
void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
60
59
int *miny, int *maxy);
62
61
target_phys_addr_t descriptor;
178
177
#define LDCMD_PAL (1 << 26)
180
179
/* Route internal interrupt lines to the global IC */
181
static void pxa2xx_lcdc_int_update(struct pxa2xx_lcdc_s *s)
180
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
184
183
level |= (s->status[0] & LCSR0_LDD) && !(s->control[0] & LCCR0_LDM);
220
219
/* Set Start Of Frame Status interrupt high and poke associated registers */
221
static inline void pxa2xx_dma_sof_set(struct pxa2xx_lcdc_s *s, int ch)
220
static inline void pxa2xx_dma_sof_set(PXA2xxLCDState *s, int ch)
224
223
if (!(s->dma_ch[ch].command & LDCMD_SOFINT))
243
242
/* Set End Of Frame Status interrupt high and poke associated registers */
244
static inline void pxa2xx_dma_eof_set(struct pxa2xx_lcdc_s *s, int ch)
243
static inline void pxa2xx_dma_eof_set(PXA2xxLCDState *s, int ch)
247
246
if (!(s->dma_ch[ch].command & LDCMD_EOFINT))
266
265
/* Set Bus Error Status interrupt high and poke associated registers */
267
static inline void pxa2xx_dma_ber_set(struct pxa2xx_lcdc_s *s, int ch)
266
static inline void pxa2xx_dma_ber_set(PXA2xxLCDState *s, int ch)
269
268
s->status[0] |= LCSR0_BERCH(ch) | LCSR0_BER;
276
275
/* Set Read Status interrupt high and poke associated registers */
277
static inline void pxa2xx_dma_rdst_set(struct pxa2xx_lcdc_s *s)
276
static inline void pxa2xx_dma_rdst_set(PXA2xxLCDState *s)
279
278
s->status[0] |= LCSR0_RDST;
280
279
if (s->irqlevel && !(s->control[0] & LCCR0_RDSTM))
284
283
/* Load new Frame Descriptors from DMA */
285
static void pxa2xx_descriptor_load(struct pxa2xx_lcdc_s *s)
284
static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
287
struct pxa_frame_descriptor_s *desc[PXA_LCDDMA_CHANS];
286
PXAFrameDescriptor desc;
288
287
target_phys_addr_t descptr;
291
290
for (i = 0; i < PXA_LCDDMA_CHANS; i ++) {
293
291
s->dma_ch[i].source = 0;
295
293
if (!s->dma_ch[i].up)
304
302
descptr = s->dma_ch[i].descriptor;
306
304
if (!(descptr >= PXA2XX_SDRAM_BASE && descptr +
307
sizeof(*desc[i]) <= PXA2XX_SDRAM_BASE + phys_ram_size))
305
sizeof(desc) <= PXA2XX_SDRAM_BASE + ram_size))
310
descptr -= PXA2XX_SDRAM_BASE;
311
desc[i] = (struct pxa_frame_descriptor_s *) (phys_ram_base + descptr);
312
s->dma_ch[i].descriptor = desc[i]->fdaddr;
313
s->dma_ch[i].source = desc[i]->fsaddr;
314
s->dma_ch[i].id = desc[i]->fidr;
315
s->dma_ch[i].command = desc[i]->ldcmd;
308
cpu_physical_memory_read(descptr, (void *)&desc, sizeof(desc));
309
s->dma_ch[i].descriptor = tswap32(desc.fdaddr);
310
s->dma_ch[i].source = tswap32(desc.fsaddr);
311
s->dma_ch[i].id = tswap32(desc.fidr);
312
s->dma_ch[i].command = tswap32(desc.ldcmd);
319
316
static uint32_t pxa2xx_lcdc_read(void *opaque, target_phys_addr_t offset)
321
struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
318
PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
324
321
switch (offset) {
406
cpu_abort(cpu_single_env,
407
"%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
403
hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
413
409
static void pxa2xx_lcdc_write(void *opaque,
414
410
target_phys_addr_t offset, uint32_t value)
416
struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
412
PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
419
415
switch (offset) {
562
cpu_abort(cpu_single_env,
563
"%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
558
hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
579
574
/* Load new palette for a given DMA channel, convert to internal format */
580
static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp)
575
static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
582
577
int i, n, format, r, g, b, alpha;
583
578
uint32_t *dest, *src;
671
static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
672
uint8_t *fb, int *miny, int *maxy)
666
static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s,
667
target_phys_addr_t addr, int *miny, int *maxy)
674
int y, src_width, dest_width, dirty[2];
676
ram_addr_t x, addr, new_addr, start, end;
669
int src_width, dest_width;
678
671
if (s->dest_width)
679
672
fn = s->line_fn[s->transp][s->bpp];
684
676
src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
685
677
if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
689
681
else if (s->bpp > pxa_lcdc_8bpp)
692
dest = ds_get_data(s->ds);
693
684
dest_width = s->xres * s->dest_width;
695
addr = (ram_addr_t) (fb - phys_ram_base);
696
start = addr + s->yres * src_width;
698
dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
699
for (y = 0; y < s->yres; y ++) {
700
new_addr = addr + src_width;
701
for (x = addr + TARGET_PAGE_SIZE; x < new_addr;
702
x += TARGET_PAGE_SIZE) {
703
dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
704
dirty[0] |= dirty[1];
706
if (dirty[0] || s->invalidated) {
707
fn((uint32_t *) s->dma_ch[0].palette,
708
dest, src, s->xres, s->dest_width);
724
cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
686
framebuffer_update_display(s->ds,
687
addr, s->xres, s->yres,
688
src_width, dest_width, s->dest_width,
690
fn, s->dma_ch[0].palette, miny, maxy);
727
static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
728
uint8_t *fb, int *miny, int *maxy)
693
static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s,
694
target_phys_addr_t addr, int *miny, int *maxy)
730
int y, src_width, dest_width, dirty[2];
732
ram_addr_t x, addr, new_addr, start, end;
696
int src_width, dest_width;
734
698
if (s->dest_width)
735
699
fn = s->line_fn[s->transp][s->bpp];
740
703
src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
741
704
if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
748
711
dest_width = s->yres * s->dest_width;
749
dest = ds_get_data(s->ds) + dest_width * (s->xres - 1);
751
addr = (ram_addr_t) (fb - phys_ram_base);
752
start = addr + s->yres * src_width;
754
x = addr + TARGET_PAGE_SIZE;
755
dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG);
756
for (y = 0; y < s->yres; y ++) {
757
new_addr = addr + src_width;
758
for (; x < new_addr; x += TARGET_PAGE_SIZE) {
759
dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
760
dirty[0] |= dirty[1];
762
if (dirty[0] || s->invalidated) {
763
fn((uint32_t *) s->dma_ch[0].palette,
764
dest, src, s->xres, -dest_width);
776
dest += s->dest_width;
780
cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
713
framebuffer_update_display(s->ds,
714
addr, s->xres, s->yres,
715
src_width, s->dest_width, -dest_width,
717
fn, s->dma_ch[0].palette,
783
static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s)
721
static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
785
723
int width, height;
786
724
if (!(s->control[0] & LCCR0_ENB))
826
763
fbptr = s->dma_ch[ch].source;
827
764
if (!(fbptr >= PXA2XX_SDRAM_BASE &&
828
fbptr <= PXA2XX_SDRAM_BASE + phys_ram_size)) {
765
fbptr <= PXA2XX_SDRAM_BASE + ram_size)) {
829
766
pxa2xx_dma_ber_set(s, ch);
832
fbptr -= PXA2XX_SDRAM_BASE;
833
fb = phys_ram_base + fbptr;
835
770
if (s->dma_ch[ch].command & LDCMD_PAL) {
836
memcpy(s->dma_ch[ch].pbuffer, fb,
837
MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
838
sizeof(s->dma_ch[ch].pbuffer)));
771
cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
772
MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
773
sizeof(s->dma_ch[ch].pbuffer)));
839
774
pxa2xx_palette_parse(s, ch, s->bpp);
841
776
/* Do we need to reparse palette */
845
780
/* ACK frame start */
846
781
pxa2xx_dma_sof_set(s, ch);
848
s->dma_ch[ch].redraw(s, fb, &miny, &maxy);
783
s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
849
784
s->invalidated = 0;
851
786
/* ACK frame completed */
859
794
s->status[0] |= LCSR0_LDD;
863
dpy_update(s->ds, miny, 0, maxy, s->xres);
865
dpy_update(s->ds, 0, miny, s->xres, maxy);
799
dpy_update(s->ds, miny, 0, maxy, s->xres);
801
dpy_update(s->ds, 0, miny, s->xres, maxy);
866
803
pxa2xx_lcdc_int_update(s);
868
805
qemu_irq_raise(s->vsync_cb);
882
819
static void pxa2xx_lcdc_orientation(void *opaque, int angle)
884
struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
821
PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
887
824
s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_vert;
897
834
static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque)
899
struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
836
PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
902
839
qemu_put_be32(f, s->irqlevel);
932
869
static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
934
struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
871
PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
937
874
s->irqlevel = qemu_get_be32(f);
981
918
#include "pxa2xx_template.h"
983
struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
920
PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
986
struct pxa2xx_lcdc_s *s;
988
s = (struct pxa2xx_lcdc_s *) qemu_mallocz(sizeof(struct pxa2xx_lcdc_s));
925
s = (PXA2xxLCDState *) qemu_mallocz(sizeof(PXA2xxLCDState));
989
926
s->invalidated = 1;
992
929
pxa2xx_lcdc_orientation(s, graphic_rotate);
994
iomemtype = cpu_register_io_memory(0, pxa2xx_lcdc_readfn,
931
iomemtype = cpu_register_io_memory(pxa2xx_lcdc_readfn,
995
932
pxa2xx_lcdc_writefn, s);
996
933
cpu_register_physical_memory(base, 0x00100000, iomemtype);