qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-arm] [RFC PATCH 5/6] zynq_slcr: add uart clock gating and soft res


From: Damien Hedde
Subject: [Qemu-arm] [RFC PATCH 5/6] zynq_slcr: add uart clock gating and soft reset support
Date: Fri, 27 Jul 2018 16:37:24 +0200

Clock gating and reset of uart0 and uart1 is controlled by
UART_CLK_CTRL and UART_RST_CTRL.
Uart0 and uart1 links are kept in properties to allow taking action.

The CLKACT bit in UART_CLK_CTRL is used to driver the clock gating.

In order to implement the reset behavior, which can be hold: when
reset is asserted, device_reset is called on the uart and the clock
is also disabled until reset is deasserted.

Signed-off-by: Damien Hedde <address@hidden>
---
 hw/misc/zynq_slcr.c | 63 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index d6bdd027ef..55dd586066 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -168,6 +168,14 @@ enum {
 #define DDRIOB_LENGTH 14
 };
 
+enum {
+    UART_CLK_CTRL_CLKACT0 = 0x0001,
+    UART_CLK_CTRL_CLKACT1 = 0x0002,
+
+    UART_RST_CTRL_UART0_REF_RST = 0x04,
+    UART_RST_CTRL_UART1_REF_RST = 0x08,
+};
+
 #define ZYNQ_SLCR_MMIO_SIZE     0x1000
 #define ZYNQ_SLCR_NUM_REGS      (ZYNQ_SLCR_MMIO_SIZE / 4)
 
@@ -180,6 +188,9 @@ typedef struct ZynqSLCRState {
     MemoryRegion iomem;
 
     uint32_t regs[ZYNQ_SLCR_NUM_REGS];
+
+    DeviceState *uart0;
+    DeviceState *uart1;
 } ZynqSLCRState;
 
 static void zynq_slcr_reset(DeviceState *d)
@@ -355,6 +366,35 @@ static uint64_t zynq_slcr_read(void *opaque, hwaddr offset,
     return ret;
 }
 
+/*
+ * zynq_slcr_update_clock:
+ * Update a device clock state given its:
+ * + clock enable bit
+ * + reset asserted bit
+ * Since reset cannot be enabled and disabled, the clock is disabled when
+ * reset is asserted
+ */
+static void zynq_slcr_update_clock(DeviceState *dev, bool clken, bool rsten)
+{
+    if (dev) {
+        device_set_clock(dev, clken && !rsten);
+    }
+}
+
+/*
+ * zynq_slcr_update_reset:
+ * Update a device reset state given its:
+ * + reset asserted bit
+ * Also trigger a clock update
+ */
+static void zynq_slcr_update_reset(DeviceState *dev, bool clken, bool rsten)
+{
+    if (dev && rsten) {
+        device_reset(dev);
+    }
+    zynq_slcr_update_clock(dev, clken, rsten);
+}
+
 static void zynq_slcr_write(void *opaque, hwaddr offset,
                           uint64_t val, unsigned size)
 {
@@ -408,6 +448,22 @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
         }
         break;
+    case UART_CLK_CTRL:
+        zynq_slcr_update_clock(s->uart0,
+                s->regs[UART_CLK_CTRL] & UART_CLK_CTRL_CLKACT0,
+                s->regs[UART_RST_CTRL] & UART_RST_CTRL_UART0_REF_RST);
+        zynq_slcr_update_clock(s->uart1,
+                s->regs[UART_CLK_CTRL] & UART_CLK_CTRL_CLKACT1,
+                s->regs[UART_RST_CTRL] & UART_RST_CTRL_UART1_REF_RST);
+        break;
+    case UART_RST_CTRL:
+        zynq_slcr_update_reset(s->uart0,
+                s->regs[UART_CLK_CTRL] & UART_CLK_CTRL_CLKACT0,
+                s->regs[UART_RST_CTRL] & UART_RST_CTRL_UART0_REF_RST);
+        zynq_slcr_update_reset(s->uart1,
+                s->regs[UART_CLK_CTRL] & UART_CLK_CTRL_CLKACT1,
+                s->regs[UART_RST_CTRL] & UART_RST_CTRL_UART1_REF_RST);
+        break;
     }
 }
 
@@ -436,12 +492,19 @@ static const VMStateDescription vmstate_zynq_slcr = {
     }
 };
 
+static Property zynq_slcr_properties[] = {
+    DEFINE_PROP_LINK("uart0", ZynqSLCRState, uart0, TYPE_DEVICE, DeviceState 
*),
+    DEFINE_PROP_LINK("uart1", ZynqSLCRState, uart1, TYPE_DEVICE, DeviceState 
*),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void zynq_slcr_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->vmsd = &vmstate_zynq_slcr;
     dc->reset = zynq_slcr_reset;
+    dc->props = zynq_slcr_properties;
 }
 
 static const TypeInfo zynq_slcr_info = {
-- 
2.18.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]