* [Qemu-devel] [PATCH 1/3] hw/pl110: Model the PL111 CLCD controller
2011-07-22 15:59 [Qemu-devel] [PATCH 0/3] Add PL111, implement PL110 BGR mode Peter Maydell
@ 2011-07-22 15:59 ` Peter Maydell
2011-07-22 15:59 ` [Qemu-devel] [PATCH 2/3] versatilepb: Implement SYS_CLCD mux control register bits Peter Maydell
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Peter Maydell @ 2011-07-22 15:59 UTC (permalink / raw)
To: qemu-devel; +Cc: patches
Model the PL111 CLCD controller. This is a minor variation
on the PL110; the major programmer visible differences are
support for hardware cursor (unimplemented) and two new
pixel formats.
Since syborg_fb.c borrows the pl11x pixel drawing routines,
we also update it to cope with the new slightly larger array
of function pointers.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/pl110.c | 94 ++++++++++++++++++++++++++++++++++++++---------
hw/pl110_template.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++---
hw/syborg_fb.c | 15 ++++++-
3 files changed, 183 insertions(+), 28 deletions(-)
diff --git a/hw/pl110.c b/hw/pl110.c
index 06d2dfa..f931fb1 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -24,15 +24,25 @@ enum pl110_bppmode
BPP_4,
BPP_8,
BPP_16,
- BPP_32
+ BPP_32,
+ BPP_16_565, /* PL111 only */
+ BPP_12 /* PL111 only */
+};
+
+
+/* The Versatile/PB uses a slightly modified PL110 controller. */
+enum pl110_version
+{
+ PL110,
+ PL110_VERSATILE,
+ PL111
};
typedef struct {
SysBusDevice busdev;
DisplayState *ds;
- /* The Versatile/PB uses a slightly modified PL110 controller. */
- int versatile;
+ int version;
uint32_t timing[4];
uint32_t cr;
uint32_t upbase;
@@ -53,7 +63,7 @@ static const VMStateDescription vmstate_pl110 = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
- VMSTATE_INT32(versatile, pl110_state),
+ VMSTATE_INT32(version, pl110_state),
VMSTATE_UINT32_ARRAY(timing, pl110_state, 4),
VMSTATE_UINT32(cr, pl110_state),
VMSTATE_UINT32(upbase, pl110_state),
@@ -82,6 +92,17 @@ static const unsigned char pl110_versatile_id[] =
#define pl110_versatile_id pl110_id
#endif
+static const unsigned char pl111_id[] = {
+ 0x11, 0x11, 0x24, 0x00, 0x0d, 0xf0, 0x05, 0xb1
+};
+
+/* Indexed by pl110_version */
+static const unsigned char *idregs[] = {
+ pl110_id,
+ pl110_versatile_id,
+ pl111_id
+};
+
#include "pixel_ops.h"
#define BITS 8
@@ -144,12 +165,30 @@ static void pl110_update_display(void *opaque)
if (s->cr & PL110_CR_BGR)
bpp_offset = 0;
else
- bpp_offset = 18;
+ bpp_offset = 24;
+
+ if ((s->version != PL111) && (s->bpp == BPP_16)) {
+ /* The PL110's native 16 bit mode is 5551; however
+ * most boards with a PL110 implement an external
+ * mux which allows bits to be reshuffled to give
+ * 565 format. The mux is typically controlled by
+ * an external system register.
+ * This should be controlled by a GPIO input pin
+ * so boards can wire it up to their register.
+ * For now, force 16 bit to be 565, to match
+ * previous QEMU PL110 model behaviour.
+ *
+ * The PL111 straightforwardly implements both
+ * 5551 and 565 under control of the bpp field
+ * in the LCDControl register.
+ */
+ bpp_offset += (BPP_16_565 - BPP_16);
+ }
if (s->cr & PL110_CR_BEBO)
- fn = fntable[s->bpp + 6 + bpp_offset];
+ fn = fntable[s->bpp + 8 + bpp_offset];
else if (s->cr & PL110_CR_BEPO)
- fn = fntable[s->bpp + 12 + bpp_offset];
+ fn = fntable[s->bpp + 16 + bpp_offset];
else
fn = fntable[s->bpp + bpp_offset];
@@ -167,6 +206,8 @@ static void pl110_update_display(void *opaque)
case BPP_8:
break;
case BPP_16:
+ case BPP_16_565:
+ case BPP_12:
src_width <<= 1;
break;
case BPP_32:
@@ -253,10 +294,7 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
pl110_state *s = (pl110_state *)opaque;
if (offset >= 0xfe0 && offset < 0x1000) {
- if (s->versatile)
- return pl110_versatile_id[(offset - 0xfe0) >> 2];
- else
- return pl110_id[(offset - 0xfe0) >> 2];
+ return idregs[s->version][(offset - 0xfe0) >> 2];
}
if (offset >= 0x200 && offset < 0x400) {
return s->raw_pallette[(offset - 0x200) >> 2];
@@ -275,12 +313,14 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
case 5: /* LCDLPBASE */
return s->lpbase;
case 6: /* LCDIMSC */
- if (s->versatile)
- return s->cr;
+ if (s->version != PL110) {
+ return s->cr;
+ }
return s->int_mask;
case 7: /* LCDControl */
- if (s->versatile)
- return s->int_mask;
+ if (s->version != PL110) {
+ return s->int_mask;
+ }
return s->cr;
case 8: /* LCDRIS */
return s->int_status;
@@ -337,15 +377,17 @@ static void pl110_write(void *opaque, target_phys_addr_t offset,
s->lpbase = val;
break;
case 6: /* LCDIMSC */
- if (s->versatile)
+ if (s->version != PL110) {
goto control;
+ }
imsc:
s->int_mask = val;
pl110_update(s);
break;
case 7: /* LCDControl */
- if (s->versatile)
+ if (s->version != PL110) {
goto imsc;
+ }
control:
s->cr = val;
s->bpp = (val >> 1) & 7;
@@ -393,7 +435,14 @@ static int pl110_init(SysBusDevice *dev)
static int pl110_versatile_init(SysBusDevice *dev)
{
pl110_state *s = FROM_SYSBUS(pl110_state, dev);
- s->versatile = 1;
+ s->version = PL110_VERSATILE;
+ return pl110_init(dev);
+}
+
+static int pl111_init(SysBusDevice *dev)
+{
+ pl110_state *s = FROM_SYSBUS(pl110_state, dev);
+ s->version = PL111;
return pl110_init(dev);
}
@@ -413,10 +462,19 @@ static SysBusDeviceInfo pl110_versatile_info = {
.qdev.no_user = 1,
};
+static SysBusDeviceInfo pl111_info = {
+ .init = pl111_init,
+ .qdev.name = "pl111",
+ .qdev.size = sizeof(pl110_state),
+ .qdev.vmsd = &vmstate_pl110,
+ .qdev.no_user = 1,
+};
+
static void pl110_register_devices(void)
{
sysbus_register_withprop(&pl110_info);
sysbus_register_withprop(&pl110_versatile_info);
+ sysbus_register_withprop(&pl111_info);
}
device_init(pl110_register_devices)
diff --git a/hw/pl110_template.h b/hw/pl110_template.h
index b3c9077..93671f2 100644
--- a/hw/pl110_template.h
+++ b/hw/pl110_template.h
@@ -43,49 +43,61 @@
#include "pl110_template.h"
#undef BORDER
-static drawfn glue(pl110_draw_fn_,BITS)[36] =
+static drawfn glue(pl110_draw_fn_,BITS)[48] =
{
glue(pl110_draw_line1_lblp_bgr,BITS),
glue(pl110_draw_line2_lblp_bgr,BITS),
glue(pl110_draw_line4_lblp_bgr,BITS),
glue(pl110_draw_line8_lblp_bgr,BITS),
- glue(pl110_draw_line16_lblp_bgr,BITS),
+ glue(pl110_draw_line16_555_lblp_bgr,BITS),
glue(pl110_draw_line32_lblp_bgr,BITS),
+ glue(pl110_draw_line16_lblp_bgr,BITS),
+ glue(pl110_draw_line12_lblp_bgr,BITS),
glue(pl110_draw_line1_bbbp_bgr,BITS),
glue(pl110_draw_line2_bbbp_bgr,BITS),
glue(pl110_draw_line4_bbbp_bgr,BITS),
glue(pl110_draw_line8_bbbp_bgr,BITS),
- glue(pl110_draw_line16_bbbp_bgr,BITS),
+ glue(pl110_draw_line16_555_bbbp_bgr,BITS),
glue(pl110_draw_line32_bbbp_bgr,BITS),
+ glue(pl110_draw_line16_bbbp_bgr,BITS),
+ glue(pl110_draw_line12_bbbp_bgr,BITS),
glue(pl110_draw_line1_lbbp_bgr,BITS),
glue(pl110_draw_line2_lbbp_bgr,BITS),
glue(pl110_draw_line4_lbbp_bgr,BITS),
glue(pl110_draw_line8_lbbp_bgr,BITS),
- glue(pl110_draw_line16_lbbp_bgr,BITS),
+ glue(pl110_draw_line16_555_lbbp_bgr,BITS),
glue(pl110_draw_line32_lbbp_bgr,BITS),
+ glue(pl110_draw_line16_lbbp_bgr,BITS),
+ glue(pl110_draw_line12_lbbp_bgr,BITS),
glue(pl110_draw_line1_lblp_rgb,BITS),
glue(pl110_draw_line2_lblp_rgb,BITS),
glue(pl110_draw_line4_lblp_rgb,BITS),
glue(pl110_draw_line8_lblp_rgb,BITS),
- glue(pl110_draw_line16_lblp_rgb,BITS),
+ glue(pl110_draw_line16_555_lblp_rgb,BITS),
glue(pl110_draw_line32_lblp_rgb,BITS),
+ glue(pl110_draw_line16_lblp_rgb,BITS),
+ glue(pl110_draw_line12_lblp_rgb,BITS),
glue(pl110_draw_line1_bbbp_rgb,BITS),
glue(pl110_draw_line2_bbbp_rgb,BITS),
glue(pl110_draw_line4_bbbp_rgb,BITS),
glue(pl110_draw_line8_bbbp_rgb,BITS),
- glue(pl110_draw_line16_bbbp_rgb,BITS),
+ glue(pl110_draw_line16_555_bbbp_rgb,BITS),
glue(pl110_draw_line32_bbbp_rgb,BITS),
+ glue(pl110_draw_line16_bbbp_rgb,BITS),
+ glue(pl110_draw_line12_bbbp_rgb,BITS),
glue(pl110_draw_line1_lbbp_rgb,BITS),
glue(pl110_draw_line2_lbbp_rgb,BITS),
glue(pl110_draw_line4_lbbp_rgb,BITS),
glue(pl110_draw_line8_lbbp_rgb,BITS),
- glue(pl110_draw_line16_lbbp_rgb,BITS),
+ glue(pl110_draw_line16_555_lbbp_rgb,BITS),
glue(pl110_draw_line32_lbbp_rgb,BITS),
+ glue(pl110_draw_line16_lbbp_rgb,BITS),
+ glue(pl110_draw_line12_lbbp_rgb,BITS),
};
#undef BITS
@@ -299,6 +311,82 @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_
}
}
+static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ /* RGB 555 plus an intensity bit (which we ignore) */
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+ LSB = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x1f) << 3;
+ data >>= 5;
+ MSB = (data & 0x1f) << 3;
+ data >>= 5;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+ LSB = (data & 0x1f) << 3;
+ data >>= 5;
+ g = (data & 0x1f) << 3;
+ data >>= 5;
+ MSB = (data & 0x1f) << 3;
+ data >>= 6;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+ width -= 2;
+ src += 4;
+ }
+}
+
+static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+ /* RGB 444 with 4 bits of zeroes at the top of each halfword */
+ uint32_t data;
+ unsigned int r, g, b;
+ while (width > 0) {
+ data = *(uint32_t *)src;
+#ifdef SWAP_WORDS
+ data = bswap32(data);
+#endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+ LSB = (data & 0xf) << 4;
+ data >>= 4;
+ g = (data & 0xf) << 4;
+ data >>= 4;
+ MSB = (data & 0xf) << 4;
+ data >>= 8;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+ LSB = (data & 0xf) << 4;
+ data >>= 4;
+ g = (data & 0xf) << 4;
+ data >>= 4;
+ MSB = (data & 0xf) << 4;
+ data >>= 8;
+ COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+ width -= 2;
+ src += 4;
+ }
+}
+
#undef SWAP_PIXELS
#undef NAME
#undef SWAP_WORDS
diff --git a/hw/syborg_fb.c b/hw/syborg_fb.c
index 7e37364..ae3e0eb 100644
--- a/hw/syborg_fb.c
+++ b/hw/syborg_fb.c
@@ -217,15 +217,24 @@ static void syborg_fb_update_display(void *opaque)
}
if (s->rgb) {
- bpp_offset = 18;
+ bpp_offset = 24;
} else {
bpp_offset = 0;
}
if (s->endian) {
+ bpp_offset += 8;
+ }
+ /* Our bpp constants mostly match the PL110/PL111 but
+ * not for the 16 bit case
+ */
+ switch (s->bpp) {
+ case BPP_SRC_16:
bpp_offset += 6;
+ break;
+ default:
+ bpp_offset += s->bpp;
}
-
- fn = fntable[s->bpp + bpp_offset];
+ fn = fntable[bpp_offset];
if (s->pitch) {
src_width = s->pitch;
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH 2/3] versatilepb: Implement SYS_CLCD mux control register bits
2011-07-22 15:59 [Qemu-devel] [PATCH 0/3] Add PL111, implement PL110 BGR mode Peter Maydell
2011-07-22 15:59 ` [Qemu-devel] [PATCH 1/3] hw/pl110: Model the PL111 CLCD controller Peter Maydell
@ 2011-07-22 15:59 ` Peter Maydell
2011-07-22 15:59 ` [Qemu-devel] [PATCH 3/3] vexpress, realview: Use pl111, not pl110 Peter Maydell
2011-07-26 10:12 ` [Qemu-devel] [PATCH 0/3] Add PL111, implement PL110 BGR mode Peter Maydell
3 siblings, 0 replies; 6+ messages in thread
From: Peter Maydell @ 2011-07-22 15:59 UTC (permalink / raw)
To: qemu-devel; +Cc: patches
On the Versatile PB, PL110 graphics adaptor only natively supports
5551 pixel format; an external mux swaps bits around to allow
RGB565 and BGR565, under the control of bits [1:0] in the SYS_CLCD
system register.
Implement these SYS_CLCD register bits, and use a gpio line to
feed them out of the system register model, across the versatilepb
board and into the pl110 so we can select the right format.
This is necessary as recent Linux versatile kernels default to
programming the CLCD and mux for 16 bit BGR rather than 16 bit RGB.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/arm_sysctl.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
hw/pl110.c | 29 ++++++++++++++++++++++++-----
hw/versatilepb.c | 13 ++++++++++---
3 files changed, 80 insertions(+), 11 deletions(-)
diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 9225b58..d1ea3ef 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -17,6 +17,8 @@
typedef struct {
SysBusDevice busdev;
+ qemu_irq pl110_mux_ctrl;
+
uint32_t sys_id;
uint32_t leds;
uint16_t lockval;
@@ -30,11 +32,12 @@ typedef struct {
uint32_t sys_cfgdata;
uint32_t sys_cfgctrl;
uint32_t sys_cfgstat;
+ uint32_t sys_clcd;
} arm_sysctl_state;
static const VMStateDescription vmstate_arm_sysctl = {
.name = "realview_sysctl",
- .version_id = 2,
+ .version_id = 3,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32(leds, arm_sysctl_state),
@@ -48,6 +51,7 @@ static const VMStateDescription vmstate_arm_sysctl = {
VMSTATE_UINT32_V(sys_cfgdata, arm_sysctl_state, 2),
VMSTATE_UINT32_V(sys_cfgctrl, arm_sysctl_state, 2),
VMSTATE_UINT32_V(sys_cfgstat, arm_sysctl_state, 2),
+ VMSTATE_UINT32_V(sys_clcd, arm_sysctl_state, 3),
VMSTATE_END_OF_LIST()
}
};
@@ -78,6 +82,13 @@ static void arm_sysctl_reset(DeviceState *d)
s->cfgdata2 = 0;
s->flags = 0;
s->resetlevel = 0;
+ if (board_id(s) == BOARD_ID_VEXPRESS) {
+ /* On VExpress this register will RAZ/WI */
+ s->sys_clcd = 0;
+ } else {
+ /* All others: CLCDID 0x1f, indicating VGA */
+ s->sys_clcd = 0x1f00;
+ }
}
static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
@@ -124,7 +135,7 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
case 0x4c: /* FLASH */
return 0;
case 0x50: /* CLCD */
- return 0x1000;
+ return s->sys_clcd;
case 0x54: /* CLCDSER */
return 0;
case 0x58: /* BOOTCS */
@@ -232,7 +243,39 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
/* nothing to do. */
break;
case 0x4c: /* FLASH */
+ break;
case 0x50: /* CLCD */
+ switch (board_id(s)) {
+ case BOARD_ID_PB926:
+ /* On 926 bits 13:8 are R/O, bits 1:0 control
+ * the mux that defines how to interpret the PL110
+ * graphics format, and other bits are r/w but we
+ * don't implement them to do anything.
+ */
+ s->sys_clcd &= 0x3f00;
+ s->sys_clcd |= val & ~0x3f00;
+ qemu_set_irq(s->pl110_mux_ctrl, val & 3);
+ break;
+ case BOARD_ID_EB:
+ /* The EB is the same except that there is no mux since
+ * the EB has a PL111.
+ */
+ s->sys_clcd &= 0x3f00;
+ s->sys_clcd |= val & ~0x3f00;
+ break;
+ case BOARD_ID_PBA8:
+ case BOARD_ID_PBX:
+ /* On PBA8 and PBX bit 7 is r/w and all other bits
+ * are either r/o or RAZ/WI.
+ */
+ s->sys_clcd &= (1 << 7);
+ s->sys_clcd |= val & ~(1 << 7);
+ break;
+ case BOARD_ID_VEXPRESS:
+ default:
+ /* On VExpress this register is unimplemented and will RAZ/WI */
+ break;
+ }
case 0x54: /* CLCDSER */
case 0x64: /* DMAPSR0 */
case 0x68: /* DMAPSR1 */
@@ -334,7 +377,7 @@ static int arm_sysctl_init1(SysBusDevice *dev)
DEVICE_NATIVE_ENDIAN);
sysbus_init_mmio(dev, 0x1000, iomemtype);
qdev_init_gpio_in(&s->busdev.qdev, arm_sysctl_gpio_set, 2);
- /* ??? Save/restore. */
+ qdev_init_gpio_out(&s->busdev.qdev, &s->pl110_mux_ctrl, 1);
return 0;
}
diff --git a/hw/pl110.c b/hw/pl110.c
index f931fb1..1a0145c 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -53,6 +53,7 @@ typedef struct {
int rows;
enum pl110_bppmode bpp;
int invalidate;
+ uint32_t mux_ctrl;
uint32_t pallette[256];
uint32_t raw_pallette[128];
qemu_irq irq;
@@ -60,7 +61,7 @@ typedef struct {
static const VMStateDescription vmstate_pl110 = {
.name = "pl110",
- .version_id = 1,
+ .version_id = 2,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_INT32(version, pl110_state),
@@ -76,6 +77,7 @@ static const VMStateDescription vmstate_pl110 = {
VMSTATE_INT32(invalidate, pl110_state),
VMSTATE_UINT32_ARRAY(pallette, pl110_state, 256),
VMSTATE_UINT32_ARRAY(raw_pallette, pl110_state, 128),
+ VMSTATE_UINT32_V(mux_ctrl, pl110_state, 2),
VMSTATE_END_OF_LIST()
}
};
@@ -173,16 +175,26 @@ static void pl110_update_display(void *opaque)
* mux which allows bits to be reshuffled to give
* 565 format. The mux is typically controlled by
* an external system register.
- * This should be controlled by a GPIO input pin
+ * This is controlled by a GPIO input pin
* so boards can wire it up to their register.
- * For now, force 16 bit to be 565, to match
- * previous QEMU PL110 model behaviour.
*
* The PL111 straightforwardly implements both
* 5551 and 565 under control of the bpp field
* in the LCDControl register.
*/
- bpp_offset += (BPP_16_565 - BPP_16);
+ switch (s->mux_ctrl) {
+ case 3: /* 565 BGR */
+ bpp_offset = (BPP_16_565 - BPP_16);
+ break;
+ case 1: /* 5551 */
+ break;
+ case 0: /* 888; also if we have loaded vmstate from an old version */
+ case 2: /* 565 RGB */
+ default:
+ /* treat as 565 but honour BGR bit */
+ bpp_offset += (BPP_16_565 - BPP_16);
+ break;
+ }
}
if (s->cr & PL110_CR_BEBO)
@@ -416,6 +428,12 @@ static CPUWriteMemoryFunc * const pl110_writefn[] = {
pl110_write
};
+static void pl110_mux_ctrl_set(void *opaque, int line, int level)
+{
+ pl110_state *s = (pl110_state *)opaque;
+ s->mux_ctrl = level;
+}
+
static int pl110_init(SysBusDevice *dev)
{
pl110_state *s = FROM_SYSBUS(pl110_state, dev);
@@ -426,6 +444,7 @@ static int pl110_init(SysBusDevice *dev)
DEVICE_NATIVE_ENDIAN);
sysbus_init_mmio(dev, 0x1000, iomemtype);
sysbus_init_irq(dev, &s->irq);
+ qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
s->ds = graphic_console_init(pl110_update_display,
pl110_invalidate_display,
NULL, NULL, s);
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 46b6a3f..eba0db1 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -180,7 +180,7 @@ static void versatile_init(ram_addr_t ram_size,
qemu_irq *cpu_pic;
qemu_irq pic[32];
qemu_irq sic[32];
- DeviceState *dev;
+ DeviceState *dev, *sysctl;
PCIBus *pci_bus;
NICInfo *nd;
int n;
@@ -198,7 +198,12 @@ static void versatile_init(ram_addr_t ram_size,
/* SDRAM at address zero. */
cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
- arm_sysctl_init(0x10000000, 0x41007004, 0x02000000);
+ sysctl = qdev_create(NULL, "realview_sysctl");
+ qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004);
+ qdev_init_nofail(sysctl);
+ qdev_prop_set_uint32(sysctl, "proc_id", 0x02000000);
+ sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000);
+
cpu_pic = arm_pic_init_cpu(env);
dev = sysbus_create_varargs("pl190", 0x10140000,
cpu_pic[0], cpu_pic[1], NULL);
@@ -250,7 +255,9 @@ static void versatile_init(ram_addr_t ram_size,
/* The versatile/PB actually has a modified Color LCD controller
that includes hardware cursor support from the PL111. */
- sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);
+ dev = sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);
+ /* Wire up the mux control signals from the SYS_CLCD register */
+ qdev_connect_gpio_out(sysctl, 0, qdev_get_gpio_in(dev, 0));
sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL);
sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL);
--
1.7.1
^ permalink raw reply related [flat|nested] 6+ messages in thread