All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/6] misc ARM device fixes
@ 2011-08-17 23:49 Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 1/6] hw/pl110: Model the PL111 CLCD controller Peter Maydell
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Peter Maydell @ 2011-08-17 23:49 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

This is a pull request for bugfixing patches to various
ARM devboard devices. The patches have all been on the
mailing list for a few weeks without comment; please pull.

thanks
-- PMM

The following changes since commit 8b2a04eeb95212305d3a39170e1c4bc3dbe45e8a:

  scsi: do not overwrite memory on REQUEST SENSE commands with a large buffer (2011-08-16 19:11:51 +0000)

are available in the git repository at:
  git://git.linaro.org/people/pmaydell/qemu-arm.git armhw-for-upstream

Engin AYDOGAN (1):
      hw/stellaris: Add support for RCC2 register

Peter Maydell (5):
      hw/pl110: Model the PL111 CLCD controller
      versatilepb: Implement SYS_CLCD mux control register bits
      vexpress, realview: Use pl111, not pl110
      hw/pl061: Convert to VMState
      hw/pl061.c: Support GPIOAMSEL register

 hw/arm_sysctl.c     |   49 +++++++++++++-
 hw/pl061.c          |  181 ++++++++++++++++++++++++---------------------------
 hw/pl110.c          |  115 +++++++++++++++++++++++++++------
 hw/pl110_template.h |  102 +++++++++++++++++++++++++++--
 hw/realview.c       |    2 +-
 hw/stellaris.c      |   72 +++++++++++++++++++-
 hw/syborg_fb.c      |   15 ++++-
 hw/versatilepb.c    |   13 +++-
 hw/vexpress.c       |    2 +-
 9 files changed, 415 insertions(+), 136 deletions(-)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 1/6] hw/pl110: Model the PL111 CLCD controller
  2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
@ 2011-08-17 23:49 ` Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 2/6] versatilepb: Implement SYS_CLCD mux control register bits Peter Maydell
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2011-08-17 23:49 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

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 62aba17..384eba2 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 d303336..1dce32a 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] 8+ messages in thread

* [Qemu-devel] [PATCH 2/6] versatilepb: Implement SYS_CLCD mux control register bits
  2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 1/6] hw/pl110: Model the PL111 CLCD controller Peter Maydell
@ 2011-08-17 23:49 ` Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 3/6] vexpress, realview: Use pl111, not pl110 Peter Maydell
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2011-08-17 23:49 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

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 fd0c8bc..22c62df 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 384eba2..4ac710a 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 147fe29..49f8f5f 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] 8+ messages in thread

* [Qemu-devel] [PATCH 3/6] vexpress, realview: Use pl111, not pl110
  2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 1/6] hw/pl110: Model the PL111 CLCD controller Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 2/6] versatilepb: Implement SYS_CLCD mux control register bits Peter Maydell
@ 2011-08-17 23:49 ` Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 4/6] hw/pl061: Convert to VMState Peter Maydell
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2011-08-17 23:49 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

The Versatile Express, Realview EB, PBX A9 and PB A8 boards all
use a PL111 for their graphics, not a PL110. Now we model the
PL111, use it on these board models.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/realview.c |    2 +-
 hw/vexpress.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/realview.c b/hw/realview.c
index 94ab900..549bb15 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -251,7 +251,7 @@ static void realview_init(ram_addr_t ram_size,
     sysbus_create_simple("pl061", 0x10014000, pic[7]);
     gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]);
 
-    sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]);
+    sysbus_create_simple("pl111", 0x10020000, pic[23]);
 
     dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);
     /* Wire up MMC card detect and read-only signals. These have
diff --git a/hw/vexpress.c b/hw/vexpress.c
index 9ffd332..c9766dd 100644
--- a/hw/vexpress.c
+++ b/hw/vexpress.c
@@ -150,7 +150,7 @@ static void vexpress_a9_init(ram_addr_t ram_size,
     /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
 
     /* 0x10020000 PL111 CLCD (daughterboard) */
-    sysbus_create_simple("pl110", 0x10020000, pic[44]);
+    sysbus_create_simple("pl111", 0x10020000, pic[44]);
 
     /* 0x10060000 AXI RAM */
     /* 0x100e0000 PL341 Dynamic Memory Controller */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 4/6] hw/pl061: Convert to VMState
  2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
                   ` (2 preceding siblings ...)
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 3/6] vexpress, realview: Use pl111, not pl110 Peter Maydell
@ 2011-08-17 23:49 ` Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 5/6] hw/pl061.c: Support GPIOAMSEL register Peter Maydell
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2011-08-17 23:49 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

Convert the PL061 to VMState. We choose to widen the struct members
to uint32_t rather than the other two options of breaking migration
compatibility or using vmstate hacks to read/write a 32 bit value
into an 8 bit struct field.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/pl061.c |  174 +++++++++++++++++++++++++++---------------------------------
 1 files changed, 79 insertions(+), 95 deletions(-)

diff --git a/hw/pl061.c b/hw/pl061.c
index 79e5c53..27de824 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -30,31 +30,60 @@ static const uint8_t pl061_id_luminary[12] =
 
 typedef struct {
     SysBusDevice busdev;
-    int locked;
-    uint8_t data;
-    uint8_t old_data;
-    uint8_t dir;
-    uint8_t isense;
-    uint8_t ibe;
-    uint8_t iev;
-    uint8_t im;
-    uint8_t istate;
-    uint8_t afsel;
-    uint8_t dr2r;
-    uint8_t dr4r;
-    uint8_t dr8r;
-    uint8_t odr;
-    uint8_t pur;
-    uint8_t pdr;
-    uint8_t slr;
-    uint8_t den;
-    uint8_t cr;
-    uint8_t float_high;
+    uint32_t locked;
+    uint32_t data;
+    uint32_t old_data;
+    uint32_t dir;
+    uint32_t isense;
+    uint32_t ibe;
+    uint32_t iev;
+    uint32_t im;
+    uint32_t istate;
+    uint32_t afsel;
+    uint32_t dr2r;
+    uint32_t dr4r;
+    uint32_t dr8r;
+    uint32_t odr;
+    uint32_t pur;
+    uint32_t pdr;
+    uint32_t slr;
+    uint32_t den;
+    uint32_t cr;
+    uint32_t float_high;
     qemu_irq irq;
     qemu_irq out[8];
     const unsigned char *id;
 } pl061_state;
 
+static const VMStateDescription vmstate_pl061 = {
+    .name = "pl061",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(locked, pl061_state),
+        VMSTATE_UINT32(data, pl061_state),
+        VMSTATE_UINT32(old_data, pl061_state),
+        VMSTATE_UINT32(dir, pl061_state),
+        VMSTATE_UINT32(isense, pl061_state),
+        VMSTATE_UINT32(ibe, pl061_state),
+        VMSTATE_UINT32(iev, pl061_state),
+        VMSTATE_UINT32(im, pl061_state),
+        VMSTATE_UINT32(istate, pl061_state),
+        VMSTATE_UINT32(afsel, pl061_state),
+        VMSTATE_UINT32(dr2r, pl061_state),
+        VMSTATE_UINT32(dr4r, pl061_state),
+        VMSTATE_UINT32(dr8r, pl061_state),
+        VMSTATE_UINT32(odr, pl061_state),
+        VMSTATE_UINT32(pur, pl061_state),
+        VMSTATE_UINT32(pdr, pl061_state),
+        VMSTATE_UINT32(slr, pl061_state),
+        VMSTATE_UINT32(den, pl061_state),
+        VMSTATE_UINT32(cr, pl061_state),
+        VMSTATE_UINT32(float_high, pl061_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static void pl061_update(pl061_state *s)
 {
     uint8_t changed;
@@ -148,19 +177,19 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
     }
     switch (offset) {
     case 0x400: /* Direction */
-        s->dir = value;
+        s->dir = value & 0xff;
         break;
     case 0x404: /* Interrupt sense */
-        s->isense = value;
+        s->isense = value & 0xff;
         break;
     case 0x408: /* Interrupt both edges */
-        s->ibe = value;
+        s->ibe = value & 0xff;
         break;
     case 0x40c: /* Interrupt event */
-        s->iev = value;
+        s->iev = value & 0xff;
         break;
     case 0x410: /* Interrupt mask */
-        s->im = value;
+        s->im = value & 0xff;
         break;
     case 0x41c: /* Interrupt clear */
         s->istate &= ~value;
@@ -170,35 +199,35 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
         s->afsel = (s->afsel & ~mask) | (value & mask);
         break;
     case 0x500: /* 2mA drive */
-        s->dr2r = value;
+        s->dr2r = value & 0xff;
         break;
     case 0x504: /* 4mA drive */
-        s->dr4r = value;
+        s->dr4r = value & 0xff;
         break;
     case 0x508: /* 8mA drive */
-        s->dr8r = value;
+        s->dr8r = value & 0xff;
         break;
     case 0x50c: /* Open drain */
-        s->odr = value;
+        s->odr = value & 0xff;
         break;
     case 0x510: /* Pull-up */
-        s->pur = value;
+        s->pur = value & 0xff;
         break;
     case 0x514: /* Pull-down */
-        s->pdr = value;
+        s->pdr = value & 0xff;
         break;
     case 0x518: /* Slew rate control */
-        s->slr = value;
+        s->slr = value & 0xff;
         break;
     case 0x51c: /* Digital enable */
-        s->den = value;
+        s->den = value & 0xff;
         break;
     case 0x520: /* Lock */
         s->locked = (value != 0xacce551);
         break;
     case 0x524: /* Commit */
         if (!s->locked)
-            s->cr = value;
+            s->cr = value & 0xff;
         break;
     default:
         hw_error("pl061_write: Bad offset %x\n", (int)offset);
@@ -238,62 +267,6 @@ static CPUWriteMemoryFunc * const pl061_writefn[] = {
    pl061_write
 };
 
-static void pl061_save(QEMUFile *f, void *opaque)
-{
-    pl061_state *s = (pl061_state *)opaque;
-
-    qemu_put_be32(f, s->locked);
-    qemu_put_be32(f, s->data);
-    qemu_put_be32(f, s->old_data);
-    qemu_put_be32(f, s->dir);
-    qemu_put_be32(f, s->isense);
-    qemu_put_be32(f, s->ibe);
-    qemu_put_be32(f, s->iev);
-    qemu_put_be32(f, s->im);
-    qemu_put_be32(f, s->istate);
-    qemu_put_be32(f, s->afsel);
-    qemu_put_be32(f, s->dr2r);
-    qemu_put_be32(f, s->dr4r);
-    qemu_put_be32(f, s->dr8r);
-    qemu_put_be32(f, s->odr);
-    qemu_put_be32(f, s->pur);
-    qemu_put_be32(f, s->pdr);
-    qemu_put_be32(f, s->slr);
-    qemu_put_be32(f, s->den);
-    qemu_put_be32(f, s->cr);
-    qemu_put_be32(f, s->float_high);
-}
-
-static int pl061_load(QEMUFile *f, void *opaque, int version_id)
-{
-    pl061_state *s = (pl061_state *)opaque;
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->locked = qemu_get_be32(f);
-    s->data = qemu_get_be32(f);
-    s->old_data = qemu_get_be32(f);
-    s->dir = qemu_get_be32(f);
-    s->isense = qemu_get_be32(f);
-    s->ibe = qemu_get_be32(f);
-    s->iev = qemu_get_be32(f);
-    s->im = qemu_get_be32(f);
-    s->istate = qemu_get_be32(f);
-    s->afsel = qemu_get_be32(f);
-    s->dr2r = qemu_get_be32(f);
-    s->dr4r = qemu_get_be32(f);
-    s->dr8r = qemu_get_be32(f);
-    s->odr = qemu_get_be32(f);
-    s->pur = qemu_get_be32(f);
-    s->pdr = qemu_get_be32(f);
-    s->slr = qemu_get_be32(f);
-    s->den = qemu_get_be32(f);
-    s->cr = qemu_get_be32(f);
-    s->float_high = qemu_get_be32(f);
-
-    return 0;
-}
-
 static int pl061_init(SysBusDevice *dev, const unsigned char *id)
 {
     int iomemtype;
@@ -307,7 +280,6 @@ static int pl061_init(SysBusDevice *dev, const unsigned char *id)
     qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8);
     qdev_init_gpio_out(&dev->qdev, s->out, 8);
     pl061_reset(s);
-    register_savevm(&dev->qdev, "pl061_gpio", -1, 1, pl061_save, pl061_load, s);
     return 0;
 }
 
@@ -321,12 +293,24 @@ static int pl061_init_arm(SysBusDevice *dev)
     return pl061_init(dev, pl061_id);
 }
 
+static SysBusDeviceInfo pl061_info = {
+    .init = pl061_init_arm,
+    .qdev.name = "pl061",
+    .qdev.size = sizeof(pl061_state),
+    .qdev.vmsd = &vmstate_pl061,
+};
+
+static SysBusDeviceInfo pl061_luminary_info = {
+    .init = pl061_init_luminary,
+    .qdev.name = "pl061_luminary",
+    .qdev.size = sizeof(pl061_state),
+    .qdev.vmsd = &vmstate_pl061,
+};
+
 static void pl061_register_devices(void)
 {
-    sysbus_register_dev("pl061", sizeof(pl061_state),
-                        pl061_init_arm);
-    sysbus_register_dev("pl061_luminary", sizeof(pl061_state),
-                        pl061_init_luminary);
+    sysbus_register_withprop(&pl061_info);
+    sysbus_register_withprop(&pl061_luminary_info);
 }
 
 device_init(pl061_register_devices)
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 5/6] hw/pl061.c: Support GPIOAMSEL register
  2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
                   ` (3 preceding siblings ...)
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 4/6] hw/pl061: Convert to VMState Peter Maydell
@ 2011-08-17 23:49 ` Peter Maydell
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 6/6] hw/stellaris: Add support for RCC2 register Peter Maydell
  2011-08-21 23:39 ` [Qemu-devel] [PULL 0/6] misc ARM device fixes Anthony Liguori
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2011-08-17 23:49 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

Support the GPIOAMSEL register found on some Stellaris boards.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/pl061.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/hw/pl061.c b/hw/pl061.c
index 27de824..d13746c 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -50,6 +50,7 @@ typedef struct {
     uint32_t den;
     uint32_t cr;
     uint32_t float_high;
+    uint32_t amsel;
     qemu_irq irq;
     qemu_irq out[8];
     const unsigned char *id;
@@ -57,7 +58,7 @@ typedef struct {
 
 static const VMStateDescription vmstate_pl061 = {
     .name = "pl061",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(locked, pl061_state),
@@ -80,6 +81,7 @@ static const VMStateDescription vmstate_pl061 = {
         VMSTATE_UINT32(den, pl061_state),
         VMSTATE_UINT32(cr, pl061_state),
         VMSTATE_UINT32(float_high, pl061_state),
+        VMSTATE_UINT32_V(amsel, pl061_state, 2),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -157,6 +159,8 @@ static uint32_t pl061_read(void *opaque, target_phys_addr_t offset)
         return s->locked;
     case 0x524: /* Commit */
         return s->cr;
+    case 0x528: /* Analog mode select */
+        return s->amsel;
     default:
         hw_error("pl061_read: Bad offset %x\n", (int)offset);
         return 0;
@@ -229,6 +233,9 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
         if (!s->locked)
             s->cr = value & 0xff;
         break;
+    case 0x528:
+        s->amsel = value & 0xff;
+        break;
     default:
         hw_error("pl061_write: Bad offset %x\n", (int)offset);
     }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [PATCH 6/6] hw/stellaris: Add support for RCC2 register
  2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
                   ` (4 preceding siblings ...)
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 5/6] hw/pl061.c: Support GPIOAMSEL register Peter Maydell
@ 2011-08-17 23:49 ` Peter Maydell
  2011-08-21 23:39 ` [Qemu-devel] [PULL 0/6] misc ARM device fixes Anthony Liguori
  6 siblings, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2011-08-17 23:49 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

From: Engin AYDOGAN <engin@bzzzt.biz>

Add support for the RCC2 register on Fury class devices.
Based on a patch by Vijay Kumar.

Signed-off-by: Engin AYDOGAN <engin@bzzzt.biz>
[Peter Maydell: fixed comment typos, minor cleanup of unreachable code]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/stellaris.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 68 insertions(+), 4 deletions(-)

diff --git a/hw/stellaris.c b/hw/stellaris.c
index a280930..70db99f 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -332,6 +332,7 @@ typedef struct {
     uint32_t int_mask;
     uint32_t resc;
     uint32_t rcc;
+    uint32_t rcc2;
     uint32_t rcgc[3];
     uint32_t scgc[3];
     uint32_t dcgc[3];
@@ -386,6 +387,32 @@ static uint32_t pllcfg_fury[16] = {
     0xb11c /* 8.192 Mhz */
 };
 
+#define DID0_VER_MASK        0x70000000
+#define DID0_VER_0           0x00000000
+#define DID0_VER_1           0x10000000
+
+#define DID0_CLASS_MASK      0x00FF0000
+#define DID0_CLASS_SANDSTORM 0x00000000
+#define DID0_CLASS_FURY      0x00010000
+
+static int ssys_board_class(const ssys_state *s)
+{
+    uint32_t did0 = s->board->did0;
+    switch (did0 & DID0_VER_MASK) {
+    case DID0_VER_0:
+        return DID0_CLASS_SANDSTORM;
+    case DID0_VER_1:
+        switch (did0 & DID0_CLASS_MASK) {
+        case DID0_CLASS_SANDSTORM:
+        case DID0_CLASS_FURY:
+            return did0 & DID0_CLASS_MASK;
+        }
+        /* for unknown classes, fall through */
+    default:
+        hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
+    }
+}
+
 static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
 {
     ssys_state *s = (ssys_state *)opaque;
@@ -429,12 +456,18 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
         {
             int xtal;
             xtal = (s->rcc >> 6) & 0xf;
-            if (s->board->did0 & (1 << 16)) {
+            switch (ssys_board_class(s)) {
+            case DID0_CLASS_FURY:
                 return pllcfg_fury[xtal];
-            } else {
+            case DID0_CLASS_SANDSTORM:
                 return pllcfg_sandstorm[xtal];
+            default:
+                hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
+                return 0;
             }
         }
+    case 0x070: /* RCC2 */
+        return s->rcc2;
     case 0x100: /* RCGC0 */
         return s->rcgc[0];
     case 0x104: /* RCGC1 */
@@ -467,9 +500,21 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
     }
 }
 
+static bool ssys_use_rcc2(ssys_state *s)
+{
+    return (s->rcc2 >> 31) & 0x1;
+}
+
+/*
+ * Caculate the sys. clock period in ms.
+ */
 static void ssys_calculate_system_clock(ssys_state *s)
 {
-    system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
+    if (ssys_use_rcc2(s)) {
+        system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
+    } else {
+        system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
+    }
 }
 
 static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
@@ -505,6 +550,18 @@ static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
         s->rcc = value;
         ssys_calculate_system_clock(s);
         break;
+    case 0x070: /* RCC2 */
+        if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
+            break;
+        }
+
+        if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
+            /* PLL enable.  */
+            s->int_status |= (1 << 6);
+        }
+        s->rcc2 = value;
+        ssys_calculate_system_clock(s);
+        break;
     case 0x100: /* RCGC0 */
         s->rcgc[0] = value;
         break;
@@ -562,6 +619,12 @@ static void ssys_reset(void *opaque)
 
     s->pborctl = 0x7ffd;
     s->rcc = 0x078e3ac0;
+
+    if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
+        s->rcc2 = 0;
+    } else {
+        s->rcc2 = 0x07802810;
+    }
     s->rcgc[0] = 1;
     s->scgc[0] = 1;
     s->dcgc[0] = 1;
@@ -578,7 +641,7 @@ static int stellaris_sys_post_load(void *opaque, int version_id)
 
 static const VMStateDescription vmstate_stellaris_sys = {
     .name = "stellaris_sys",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .post_load = stellaris_sys_post_load,
@@ -589,6 +652,7 @@ static const VMStateDescription vmstate_stellaris_sys = {
         VMSTATE_UINT32(int_status, ssys_state),
         VMSTATE_UINT32(resc, ssys_state),
         VMSTATE_UINT32(rcc, ssys_state),
+        VMSTATE_UINT32_V(rcc2, ssys_state, 2),
         VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
         VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
         VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [PULL 0/6] misc ARM device fixes
  2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
                   ` (5 preceding siblings ...)
  2011-08-17 23:49 ` [Qemu-devel] [PATCH 6/6] hw/stellaris: Add support for RCC2 register Peter Maydell
@ 2011-08-21 23:39 ` Anthony Liguori
  6 siblings, 0 replies; 8+ messages in thread
From: Anthony Liguori @ 2011-08-21 23:39 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

On 08/17/2011 06:49 PM, Peter Maydell wrote:
> This is a pull request for bugfixing patches to various
> ARM devboard devices. The patches have all been on the
> mailing list for a few weeks without comment; please pull.

Pulled.  Thanks.

Regards,

Anthony Liguori

>
> thanks
> -- PMM
>
> The following changes since commit 8b2a04eeb95212305d3a39170e1c4bc3dbe45e8a:
>
>    scsi: do not overwrite memory on REQUEST SENSE commands with a large buffer (2011-08-16 19:11:51 +0000)
>
> are available in the git repository at:
>    git://git.linaro.org/people/pmaydell/qemu-arm.git armhw-for-upstream
>
> Engin AYDOGAN (1):
>        hw/stellaris: Add support for RCC2 register
>
> Peter Maydell (5):
>        hw/pl110: Model the PL111 CLCD controller
>        versatilepb: Implement SYS_CLCD mux control register bits
>        vexpress, realview: Use pl111, not pl110
>        hw/pl061: Convert to VMState
>        hw/pl061.c: Support GPIOAMSEL register
>
>   hw/arm_sysctl.c     |   49 +++++++++++++-
>   hw/pl061.c          |  181 ++++++++++++++++++++++++---------------------------
>   hw/pl110.c          |  115 +++++++++++++++++++++++++++------
>   hw/pl110_template.h |  102 +++++++++++++++++++++++++++--
>   hw/realview.c       |    2 +-
>   hw/stellaris.c      |   72 +++++++++++++++++++-
>   hw/syborg_fb.c      |   15 ++++-
>   hw/versatilepb.c    |   13 +++-
>   hw/vexpress.c       |    2 +-
>   9 files changed, 415 insertions(+), 136 deletions(-)
>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-08-21 23:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-17 23:49 [Qemu-devel] [PULL 0/6] misc ARM device fixes Peter Maydell
2011-08-17 23:49 ` [Qemu-devel] [PATCH 1/6] hw/pl110: Model the PL111 CLCD controller Peter Maydell
2011-08-17 23:49 ` [Qemu-devel] [PATCH 2/6] versatilepb: Implement SYS_CLCD mux control register bits Peter Maydell
2011-08-17 23:49 ` [Qemu-devel] [PATCH 3/6] vexpress, realview: Use pl111, not pl110 Peter Maydell
2011-08-17 23:49 ` [Qemu-devel] [PATCH 4/6] hw/pl061: Convert to VMState Peter Maydell
2011-08-17 23:49 ` [Qemu-devel] [PATCH 5/6] hw/pl061.c: Support GPIOAMSEL register Peter Maydell
2011-08-17 23:49 ` [Qemu-devel] [PATCH 6/6] hw/stellaris: Add support for RCC2 register Peter Maydell
2011-08-21 23:39 ` [Qemu-devel] [PULL 0/6] misc ARM device fixes Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.