All of lore.kernel.org
 help / color / mirror / Atom feed
From: Damien Hedde <damien.hedde@greensocs.com>
To: qemu-devel@nongnu.org
Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org,
	marc.burton@greensocs.com, alistair@alistair23.me,
	qemu-arm@nongnu.org, Damien Hedde <damien.hedde@greensocs.com>,
	marcandre.lureau@redhat.com, pbonzini@redhat.com,
	philmd@redhat.com, luc.michel@greensocs.com
Subject: [Qemu-devel] [RFC PATCH v2 09/12] convert cadence_uart to 3-phases reset
Date: Tue,  4 Jun 2019 18:25:23 +0200	[thread overview]
Message-ID: <20190604162526.10655-10-damien.hedde@greensocs.com> (raw)
In-Reply-To: <20190604162526.10655-1-damien.hedde@greensocs.com>

Split the existing reset procedure into 3 phases.
Test the resetting flag to discard register accesses
and character reception.
Also adds a active high reset io.

Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
---
 hw/char/cadence_uart.c | 81 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 77 insertions(+), 4 deletions(-)

diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index fbdbd463bb..27e1c70678 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -38,6 +38,18 @@
     #define DB_PRINT(...)
 #endif
 
+#define CADENCE_UART_CLASS(class) \
+    OBJECT_CLASS_CHECK(CadenceUartClass, (class), TYPE_CADENCE_UART)
+#define CADENCE_UART_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(CadenceUartClass, (obj), TYPE_CADENCE_UART)
+
+typedef struct CadenceUartClass {
+    /*< private >*/
+    SysBusDeviceClass parent_class;
+
+    struct ResettablePhases parent_reset_phases;
+} CadenceUartClass;
+
 #define UART_SR_INTR_RTRIG     0x00000001
 #define UART_SR_INTR_REMPTY    0x00000002
 #define UART_SR_INTR_RFUL      0x00000004
@@ -222,6 +234,10 @@ static int uart_can_receive(void *opaque)
     int ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
     uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
 
+    if (device_is_resetting((DeviceState *) opaque)) {
+        return 0;
+    }
+
     if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
         ret = MIN(ret, CADENCE_UART_RX_FIFO_SIZE - s->rx_count);
     }
@@ -337,6 +353,10 @@ static void uart_receive(void *opaque, const uint8_t *buf, int size)
     CadenceUARTState *s = opaque;
     uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
 
+    if (device_is_resetting((DeviceState *) opaque)) {
+        return;
+    }
+
     if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
         uart_write_rx_fifo(opaque, buf, size);
     }
@@ -350,6 +370,10 @@ static void uart_event(void *opaque, int event)
     CadenceUARTState *s = opaque;
     uint8_t buf = '\0';
 
+    if (device_is_resetting((DeviceState *) opaque)) {
+        return;
+    }
+
     if (event == CHR_EVENT_BREAK) {
         uart_write_rx_fifo(opaque, &buf, 1);
     }
@@ -382,6 +406,10 @@ static void uart_write(void *opaque, hwaddr offset,
 {
     CadenceUARTState *s = opaque;
 
+    if (device_is_resetting((DeviceState *)opaque)) {
+        return;
+    }
+
     DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
     offset >>= 2;
     if (offset >= CADENCE_UART_R_MAX) {
@@ -440,6 +468,10 @@ static uint64_t uart_read(void *opaque, hwaddr offset,
     CadenceUARTState *s = opaque;
     uint32_t c = 0;
 
+    if (device_is_resetting((DeviceState *)opaque)) {
+        return 0;
+    }
+
     offset >>= 2;
     if (offset >= CADENCE_UART_R_MAX) {
         c = 0;
@@ -459,9 +491,14 @@ static const MemoryRegionOps uart_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void cadence_uart_reset(DeviceState *dev)
+static void cadence_uart_reset_init(Object *obj, bool cold)
 {
-    CadenceUARTState *s = CADENCE_UART(dev);
+    CadenceUARTState *s = CADENCE_UART(obj);
+    CadenceUartClass *cc = CADENCE_UART_GET_CLASS(obj);
+
+    if (cc->parent_reset_phases.init) {
+        cc->parent_reset_phases.init(obj, cold);
+    }
 
     s->r[R_CR] = 0x00000128;
     s->r[R_IMR] = 0;
@@ -470,6 +507,28 @@ static void cadence_uart_reset(DeviceState *dev)
     s->r[R_BRGR] = 0x0000028B;
     s->r[R_BDIV] = 0x0000000F;
     s->r[R_TTRIG] = 0x00000020;
+}
+
+static void cadence_uart_reset_hold(Object *obj)
+{
+    CadenceUARTState *s = CADENCE_UART(obj);
+    CadenceUartClass *cc = CADENCE_UART_GET_CLASS(obj);
+
+    if (cc->parent_reset_phases.hold) {
+        cc->parent_reset_phases.hold(obj);
+    }
+
+    qemu_set_irq(s->irq, 0);
+}
+
+static void cadence_uart_reset_exit(Object *obj)
+{
+    CadenceUARTState *s = CADENCE_UART(obj);
+    CadenceUartClass *cc = CADENCE_UART_GET_CLASS(obj);
+
+    if (cc->parent_reset_phases.exit) {
+        cc->parent_reset_phases.exit(obj);
+    }
 
     uart_rx_reset(s);
     uart_tx_reset(s);
@@ -498,6 +557,8 @@ static void cadence_uart_init(Object *obj)
     sysbus_init_irq(sbd, &s->irq);
 
     s->char_tx_time = (NANOSECONDS_PER_SECOND / 9600) * 10;
+
+    qdev_init_warm_reset_gpio(DEVICE(obj), "rst", DEVICE_ACTIVE_HIGH);
 }
 
 static int cadence_uart_post_load(void *opaque, int version_id)
@@ -532,6 +593,10 @@ static const VMStateDescription vmstate_cadence_uart = {
         VMSTATE_UINT32(rx_wpos, CadenceUARTState),
         VMSTATE_TIMER_PTR(fifo_trigger_handle, CadenceUARTState),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (const VMStateDescription * []) {
+        &device_vmstate_reset,
+        NULL
     }
 };
 
@@ -543,12 +608,19 @@ static Property cadence_uart_properties[] = {
 static void cadence_uart_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
+    ResettableClass *rc = RESETTABLE_CLASS(klass);
+    CadenceUartClass *cc = CADENCE_UART_CLASS(klass);
 
     dc->realize = cadence_uart_realize;
     dc->vmsd = &vmstate_cadence_uart;
-    dc->reset = cadence_uart_reset;
     dc->props = cadence_uart_properties;
-  }
+
+    resettable_class_set_parent_reset_phases(rc,
+                                             cadence_uart_reset_init,
+                                             cadence_uart_reset_hold,
+                                             cadence_uart_reset_exit,
+                                             &cc->parent_reset_phases);
+}
 
 static const TypeInfo cadence_uart_info = {
     .name          = TYPE_CADENCE_UART,
@@ -556,6 +628,7 @@ static const TypeInfo cadence_uart_info = {
     .instance_size = sizeof(CadenceUARTState),
     .instance_init = cadence_uart_init,
     .class_init    = cadence_uart_class_init,
+    .class_size = sizeof(CadenceUartClass),
 };
 
 static void cadence_uart_register_types(void)
-- 
2.21.0



  parent reply	other threads:[~2019-06-04 16:39 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-04 16:25 [Qemu-devel] [RFC PATCH v2 00/12] Multi-phase reset Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 01/12] Create Resettable QOM interface Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 02/12] add device_legacy_reset function to do the transition with device_reset Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 03/12] replace all occurences of device_reset by device_legacy_reset Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 04/12] make Device and Bus Resettable Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 05/12] Add function to control reset with gpio inputs Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 06/12] add vmstate description for device reset state Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 07/12] add doc about Resettable interface Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 08/12] hw/misc/zynq_slcr: use standard register definition Damien Hedde
2019-06-04 16:25 ` Damien Hedde [this message]
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 10/12] Convert zynq's slcr to 3-phases reset Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 11/12] Add uart reset support in zynq_slcr Damien Hedde
2019-06-04 16:25 ` [Qemu-devel] [RFC PATCH v2 12/12] Connect the uart reset gpios in the zynq platform Damien Hedde
2019-06-18 16:13 ` [Qemu-devel] [RFC PATCH v2 00/12] Multi-phase reset Peter Maydell
2019-06-27  9:13   ` Damien Hedde

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190604162526.10655-10-damien.hedde@greensocs.com \
    --to=damien.hedde@greensocs.com \
    --cc=alistair@alistair23.me \
    --cc=edgar.iglesias@xilinx.com \
    --cc=luc.michel@greensocs.com \
    --cc=marc.burton@greensocs.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.