summaryrefslogtreecommitdiff
path: root/hw/pl110.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-04-09 01:32:52 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-04-09 01:32:52 +0000
commitcdbdb648b7c2867f0bb7dce27efb1986f770dedb (patch)
treef838b39e8f30e4872a792638e532d8ac8db6fbfc /hw/pl110.c
parent95219897ff4e6d0502b920c521fccc612ad913dd (diff)
ARM Versatile Platform Baseboard emulation.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1804 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/pl110.c')
-rw-r--r--hw/pl110.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/hw/pl110.c b/hw/pl110.c
index 839f103b1..09352e742 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -1,7 +1,7 @@
/*
* Arm PrimeCell PL110 Color LCD Controller
*
- * Copyright (c) 2005 CodeSourcery, LLC.
+ * Copyright (c) 2005-2006 CodeSourcery.
* Written by Paul Brook
*
* This code is licenced under the GNU LGPL
@@ -27,6 +27,8 @@ enum pl110_bppmode
typedef struct {
uint32_t base;
DisplayState *ds;
+ /* The Versatile/PB uses a slightly modified PL110 controller. */
+ int versatile;
void *pic;
uint32_t timing[4];
uint32_t cr;
@@ -46,6 +48,15 @@ typedef struct {
static const unsigned char pl110_id[] =
{ 0x10, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
+/* The Arm documentation (DDI0224C) says the CLDC on the Versatile board
+ has a different ID. However Linux only looks for the normal ID. */
+#if 0
+static const unsigned char pl110_versatile_id[] =
+{ 0x93, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
+#else
+#define pl110_versatile_id pl110_id
+#endif
+
static inline uint32_t rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
{
return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
@@ -101,7 +112,7 @@ static void pl110_update_display(void *opaque)
int src_width;
uint8_t *dest;
uint8_t *src;
- int first, last;
+ int first, last = 0;
int dirty, new_dirty;
int i;
@@ -269,7 +280,10 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
offset -= s->base;
if (offset >= 0xfe0 && offset < 0x1000) {
- return pl110_id[(offset - 0xfe0) >> 2];
+ if (s->versatile)
+ return pl110_versatile_id[(offset - 0xfe0) >> 2];
+ else
+ return pl110_id[(offset - 0xfe0) >> 2];
}
if (offset >= 0x200 && offset < 0x400) {
return s->raw_pallette[(offset - 0x200) >> 2];
@@ -347,10 +361,16 @@ static void pl110_write(void *opaque, target_phys_addr_t offset,
s->lpbase = val;
break;
case 6: /* LCDIMSC */
+ if (s->versatile)
+ goto control;
+ imsc:
s->int_mask = val;
pl110_update(s);
break;
case 7: /* LCDControl */
+ if (s->versatile)
+ goto imsc;
+ control:
s->cr = val;
s->bpp = (val >> 1) & 7;
if (pl110_enabled(s)) {
@@ -390,6 +410,7 @@ void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq,
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
s->base = base;
s->ds = ds;
+ s->versatile = versatile;
s->pic = pic;
s->irq = irq;
graphic_console_init(ds, pl110_update_display, pl110_invalidate_display,