#include "sysemu.h"
#include "framebuffer.h"
-struct pxa2xx_lcdc_s {
+struct DMAChannel {
+ target_phys_addr_t branch;
+ uint8_t up;
+ uint8_t palette[1024];
+ uint8_t pbuffer[1024];
+ void (*redraw)(PXA2xxLCDState *s, target_phys_addr_t addr,
+ int *miny, int *maxy);
+
+ target_phys_addr_t descriptor;
+ target_phys_addr_t source;
+ uint32_t id;
+ uint32_t command;
+};
+
+struct PXA2xxLCDState {
qemu_irq irq;
int irqlevel;
uint32_t liidr;
uint8_t bscntr;
- struct {
- target_phys_addr_t branch;
- int up;
- uint8_t palette[1024];
- uint8_t pbuffer[1024];
- void (*redraw)(struct pxa2xx_lcdc_s *s, target_phys_addr_t addr,
- int *miny, int *maxy);
-
- target_phys_addr_t descriptor;
- target_phys_addr_t source;
- uint32_t id;
- uint32_t command;
- } dma_ch[7];
+ struct DMAChannel dma_ch[7];
qemu_irq vsync_cb;
int orientation;
};
-struct __attribute__ ((__packed__)) pxa_frame_descriptor_s {
+typedef struct __attribute__ ((__packed__)) {
uint32_t fdaddr;
uint32_t fsaddr;
uint32_t fidr;
uint32_t ldcmd;
-};
+} PXAFrameDescriptor;
#define LCCR0 0x000 /* LCD Controller Control register 0 */
#define LCCR1 0x004 /* LCD Controller Control register 1 */
#define LDCMD_PAL (1 << 26)
/* Route internal interrupt lines to the global IC */
-static void pxa2xx_lcdc_int_update(struct pxa2xx_lcdc_s *s)
+static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
{
int level = 0;
level |= (s->status[0] & LCSR0_LDD) && !(s->control[0] & LCCR0_LDM);
}
/* Set Branch Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_bs_set(struct pxa2xx_lcdc_s *s, int ch)
+static inline void pxa2xx_dma_bs_set(PXA2xxLCDState *s, int ch)
{
int unmasked;
if (ch == 0) {
}
/* Set Start Of Frame Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_sof_set(struct pxa2xx_lcdc_s *s, int ch)
+static inline void pxa2xx_dma_sof_set(PXA2xxLCDState *s, int ch)
{
int unmasked;
if (!(s->dma_ch[ch].command & LDCMD_SOFINT))
}
/* Set End Of Frame Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_eof_set(struct pxa2xx_lcdc_s *s, int ch)
+static inline void pxa2xx_dma_eof_set(PXA2xxLCDState *s, int ch)
{
int unmasked;
if (!(s->dma_ch[ch].command & LDCMD_EOFINT))
}
/* Set Bus Error Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_ber_set(struct pxa2xx_lcdc_s *s, int ch)
+static inline void pxa2xx_dma_ber_set(PXA2xxLCDState *s, int ch)
{
s->status[0] |= LCSR0_BERCH(ch) | LCSR0_BER;
if (s->irqlevel)
}
/* Set Read Status interrupt high and poke associated registers */
-static inline void pxa2xx_dma_rdst_set(struct pxa2xx_lcdc_s *s)
+static inline void pxa2xx_dma_rdst_set(PXA2xxLCDState *s)
{
s->status[0] |= LCSR0_RDST;
if (s->irqlevel && !(s->control[0] & LCCR0_RDSTM))
}
/* Load new Frame Descriptors from DMA */
-static void pxa2xx_descriptor_load(struct pxa2xx_lcdc_s *s)
+static void pxa2xx_descriptor_load(PXA2xxLCDState *s)
{
- struct pxa_frame_descriptor_s desc;
+ PXAFrameDescriptor desc;
target_phys_addr_t descptr;
int i;
descptr = s->dma_ch[i].descriptor;
if (!(descptr >= PXA2XX_SDRAM_BASE && descptr +
- sizeof(desc) <= PXA2XX_SDRAM_BASE + phys_ram_size))
+ sizeof(desc) <= PXA2XX_SDRAM_BASE + ram_size))
continue;
cpu_physical_memory_read(descptr, (void *)&desc, sizeof(desc));
static uint32_t pxa2xx_lcdc_read(void *opaque, target_phys_addr_t offset)
{
- struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
+ PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
int ch;
switch (offset) {
default:
fail:
- cpu_abort(cpu_single_env,
- "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
}
return 0;
static void pxa2xx_lcdc_write(void *opaque,
target_phys_addr_t offset, uint32_t value)
{
- struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
+ PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
int ch;
switch (offset) {
default:
fail:
- cpu_abort(cpu_single_env,
- "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
+ hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
}
}
-static CPUReadMemoryFunc *pxa2xx_lcdc_readfn[] = {
+static CPUReadMemoryFunc * const pxa2xx_lcdc_readfn[] = {
pxa2xx_lcdc_read,
pxa2xx_lcdc_read,
pxa2xx_lcdc_read
};
-static CPUWriteMemoryFunc *pxa2xx_lcdc_writefn[] = {
+static CPUWriteMemoryFunc * const pxa2xx_lcdc_writefn[] = {
pxa2xx_lcdc_write,
pxa2xx_lcdc_write,
pxa2xx_lcdc_write
};
/* Load new palette for a given DMA channel, convert to internal format */
-static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp)
+static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
{
int i, n, format, r, g, b, alpha;
uint32_t *dest, *src;
}
}
-static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
+static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s,
target_phys_addr_t addr, int *miny, int *maxy)
{
int src_width, dest_width;
- drawfn fn = 0;
+ drawfn fn = NULL;
if (s->dest_width)
fn = s->line_fn[s->transp][s->bpp];
if (!fn)
fn, s->dma_ch[0].palette, miny, maxy);
}
-static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
+static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s,
target_phys_addr_t addr, int *miny, int *maxy)
{
int src_width, dest_width;
- drawfn fn = 0;
+ drawfn fn = NULL;
if (s->dest_width)
fn = s->line_fn[s->transp][s->bpp];
if (!fn)
miny, maxy);
}
-static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s)
+static void pxa2xx_lcdc_resize(PXA2xxLCDState *s)
{
int width, height;
if (!(s->control[0] & LCCR0_ENB))
static void pxa2xx_update_display(void *opaque)
{
- struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
+ PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
target_phys_addr_t fbptr;
int miny, maxy;
int ch;
}
fbptr = s->dma_ch[ch].source;
if (!(fbptr >= PXA2XX_SDRAM_BASE &&
- fbptr <= PXA2XX_SDRAM_BASE + phys_ram_size)) {
+ fbptr <= PXA2XX_SDRAM_BASE + ram_size)) {
pxa2xx_dma_ber_set(s, ch);
continue;
}
if (miny >= 0) {
if (s->orientation)
- dpy_update(s->ds, miny, 0, maxy, s->xres);
+ dpy_update(s->ds, miny, 0, maxy - miny, s->xres);
else
- dpy_update(s->ds, 0, miny, s->xres, maxy);
+ dpy_update(s->ds, 0, miny, s->xres, maxy - miny);
}
pxa2xx_lcdc_int_update(s);
static void pxa2xx_invalidate_display(void *opaque)
{
- struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
+ PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
s->invalidated = 1;
}
static void pxa2xx_lcdc_orientation(void *opaque, int angle)
{
- struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
+ PXA2xxLCDState *s = (PXA2xxLCDState *) opaque;
if (angle) {
s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_vert;
pxa2xx_lcdc_resize(s);
}
-static void pxa2xx_lcdc_save(QEMUFile *f, void *opaque)
-{
- struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
- int i;
-
- qemu_put_be32(f, s->irqlevel);
- qemu_put_be32(f, s->transp);
-
- for (i = 0; i < 6; i ++)
- qemu_put_be32s(f, &s->control[i]);
- for (i = 0; i < 2; i ++)
- qemu_put_be32s(f, &s->status[i]);
- for (i = 0; i < 2; i ++)
- qemu_put_be32s(f, &s->ovl1c[i]);
- for (i = 0; i < 2; i ++)
- qemu_put_be32s(f, &s->ovl2c[i]);
- qemu_put_be32s(f, &s->ccr);
- qemu_put_be32s(f, &s->cmdcr);
- qemu_put_be32s(f, &s->trgbr);
- qemu_put_be32s(f, &s->tcr);
- qemu_put_be32s(f, &s->liidr);
- qemu_put_8s(f, &s->bscntr);
-
- for (i = 0; i < 7; i ++) {
- qemu_put_betl(f, s->dma_ch[i].branch);
- qemu_put_byte(f, s->dma_ch[i].up);
- qemu_put_buffer(f, s->dma_ch[i].pbuffer, sizeof(s->dma_ch[i].pbuffer));
-
- qemu_put_betl(f, s->dma_ch[i].descriptor);
- qemu_put_betl(f, s->dma_ch[i].source);
- qemu_put_be32s(f, &s->dma_ch[i].id);
- qemu_put_be32s(f, &s->dma_ch[i].command);
+static const VMStateDescription vmstate_dma_channel = {
+ .name = "dma_channel",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINTTL(branch, struct DMAChannel),
+ VMSTATE_UINT8(up, struct DMAChannel),
+ VMSTATE_BUFFER(pbuffer, struct DMAChannel),
+ VMSTATE_UINTTL(descriptor, struct DMAChannel),
+ VMSTATE_UINTTL(source, struct DMAChannel),
+ VMSTATE_UINT32(id, struct DMAChannel),
+ VMSTATE_UINT32(command, struct DMAChannel),
+ VMSTATE_END_OF_LIST()
}
-}
+};
-static int pxa2xx_lcdc_load(QEMUFile *f, void *opaque, int version_id)
+static int pxa2xx_lcdc_post_load(void *opaque, int version_id)
{
- struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) 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);
- }
+ PXA2xxLCDState *s = opaque;
s->bpp = LCCR3_BPP(s->control[3]);
s->xres = s->yres = s->pal_for = -1;
return 0;
}
+static const VMStateDescription vmstate_pxa2xx_lcdc = {
+ .name = "pxa2xx_lcdc",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .minimum_version_id_old = 0,
+ .post_load = pxa2xx_lcdc_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(irqlevel, PXA2xxLCDState),
+ VMSTATE_INT32(transp, PXA2xxLCDState),
+ VMSTATE_UINT32_ARRAY(control, PXA2xxLCDState, 6),
+ VMSTATE_UINT32_ARRAY(status, PXA2xxLCDState, 2),
+ VMSTATE_UINT32_ARRAY(ovl1c, PXA2xxLCDState, 2),
+ VMSTATE_UINT32_ARRAY(ovl2c, PXA2xxLCDState, 2),
+ VMSTATE_UINT32(ccr, PXA2xxLCDState),
+ VMSTATE_UINT32(cmdcr, PXA2xxLCDState),
+ VMSTATE_UINT32(trgbr, PXA2xxLCDState),
+ VMSTATE_UINT32(tcr, PXA2xxLCDState),
+ VMSTATE_UINT32(liidr, PXA2xxLCDState),
+ VMSTATE_UINT8(bscntr, PXA2xxLCDState),
+ VMSTATE_STRUCT_ARRAY(dma_ch, PXA2xxLCDState, 7, 0,
+ vmstate_dma_channel, struct DMAChannel),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
#define BITS 8
#include "pxa2xx_template.h"
#define BITS 15
#define BITS 32
#include "pxa2xx_template.h"
-struct pxa2xx_lcdc_s *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
+PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
{
int iomemtype;
- struct pxa2xx_lcdc_s *s;
+ PXA2xxLCDState *s;
- s = (struct pxa2xx_lcdc_s *) qemu_mallocz(sizeof(struct pxa2xx_lcdc_s));
+ s = (PXA2xxLCDState *) qemu_mallocz(sizeof(PXA2xxLCDState));
s->invalidated = 1;
s->irq = irq;
pxa2xx_lcdc_orientation(s, graphic_rotate);
- iomemtype = cpu_register_io_memory(0, pxa2xx_lcdc_readfn,
- pxa2xx_lcdc_writefn, s);
+ iomemtype = cpu_register_io_memory(pxa2xx_lcdc_readfn,
+ pxa2xx_lcdc_writefn, s, DEVICE_NATIVE_ENDIAN);
cpu_register_physical_memory(base, 0x00100000, iomemtype);
s->ds = graphic_console_init(pxa2xx_update_display,
exit(1);
}
- register_savevm("pxa2xx_lcdc", 0, 0,
- pxa2xx_lcdc_save, pxa2xx_lcdc_load, s);
+ vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
return s;
}
-void pxa2xx_lcd_vsync_notifier(struct pxa2xx_lcdc_s *s, qemu_irq handler)
+void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler)
{
s->vsync_cb = handler;
}