qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Philippe Mathieu-Daudé" <f4bug@amsat.org>
To: qemu-devel@nongnu.org
Cc: "Damien Hedde" <damien.hedde@greensocs.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>
Subject: [PATCH-for-5.2 4/4] hw/char/serial: Use the Clock API to feed the UART reference clock
Date: Thu,  6 Aug 2020 15:03:40 +0200	[thread overview]
Message-ID: <20200806130340.17316-5-f4bug@amsat.org> (raw)
In-Reply-To: <20200806130340.17316-1-f4bug@amsat.org>

In the same chipset, UARTs can be clocked at different rate, or the
input clock can be changed at runtime. The Clock API allow us to
propagate such clock rate change to the device.
Let the SerialState have its reference input clock (called 'rclk')
and if not clock is connected to the device, use the currently provided
frequency, to not modify the current code behavior.

Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 include/hw/char/serial.h |  3 +++
 hw/char/serial.c         | 35 ++++++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index 75c71adfd2..1c7a4df2ab 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -31,8 +31,10 @@
 #include "qemu/fifo8.h"
 #include "chardev/char.h"
 #include "hw/sysbus.h"
+#include "hw/clock.h"
 
 #define UART_FIFO_LENGTH    16      /* 16550A Fifo Length */
+#define UART_CLOCK_DIVISOR  16      /* baudrate is input clock / 16 */
 
 typedef struct SerialState {
     DeviceState parent;
@@ -57,6 +59,7 @@ typedef struct SerialState {
     qemu_irq irq;
     CharBackend chr;
     int last_break_enable;
+    Clock *rclk; /* ReceiverClock */
     uint32_t baudbase;
     uint32_t tsr_retry;
     guint watch_tag;
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 2ddc73f255..701c670fd5 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -35,6 +35,7 @@
 #include "qemu/error-report.h"
 #include "trace.h"
 #include "hw/qdev-properties.h"
+#include "hw/qdev-clock.h"
 
 #define UART_LCR_DLAB	0x80	/* Divisor latch access bit */
 
@@ -921,10 +922,36 @@ static int serial_be_change(void *opaque)
     return 0;
 }
 
+/* Change the main reference oscillator frequency. */
+void serial_set_frequency(SerialState *s, uint32_t frequency)
+{
+    s->baudbase = frequency;
+    serial_update_parameters(s);
+}
+
+static void serial_rclk_update(void *opaque)
+{
+    SerialState *s = opaque;
+
+    serial_set_frequency(s, clock_get_hz(s->rclk) / UART_CLOCK_DIVISOR);
+}
+
+static void serial_init(Object *obj)
+{
+    SerialState *s = SERIAL(obj);
+
+    s->rclk = qdev_init_clock_in(DEVICE(obj), "rclk", serial_rclk_update, s);
+}
+
 static void serial_realize(DeviceState *dev, Error **errp)
 {
     SerialState *s = SERIAL(dev);
 
+    /* initialize the frequency in case the clock remains unconnected */
+    if (!clock_get(s->rclk)) {
+        clock_set_hz(s->rclk, s->baudbase);
+    }
+
     s->modem_status_poll = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) serial_update_msl, s);
 
     s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) fifo_timeout_int, s);
@@ -955,13 +982,6 @@ static void serial_unrealize(DeviceState *dev)
     qemu_unregister_reset(serial_reset, s);
 }
 
-/* Change the main reference oscillator frequency. */
-void serial_set_frequency(SerialState *s, uint32_t frequency)
-{
-    s->baudbase = frequency;
-    serial_update_parameters(s);
-}
-
 const MemoryRegionOps serial_io_ops = {
     .read = serial_ioport_read,
     .write = serial_ioport_write,
@@ -994,6 +1014,7 @@ static const TypeInfo serial_info = {
     .name = TYPE_SERIAL,
     .parent = TYPE_DEVICE,
     .instance_size = sizeof(SerialState),
+    .instance_init = serial_init,
     .class_init = serial_class_init,
 };
 
-- 
2.21.3



  parent reply	other threads:[~2020-08-06 13:06 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-06 13:03 [PATCH-for-5.2 0/4] hw/char/serial: Use the Clock API to feed the UART reference clock Philippe Mathieu-Daudé
2020-08-06 13:03 ` [PATCH-for-5.2 1/4] hw/char/serial: Replace commented DPRINTF() by trace event Philippe Mathieu-Daudé
2020-08-12 17:41   ` Richard Henderson
2020-08-06 13:03 ` [PATCH-for-5.2 2/4] hw/char/serial: Remove old DEBUG_SERIAL commented code Philippe Mathieu-Daudé
2020-08-12 17:42   ` Richard Henderson
2020-08-06 13:03 ` [PATCH-for-5.2 3/4] hw/char/serial: Let SerialState have an 'id' field Philippe Mathieu-Daudé
2020-08-12 17:43   ` Richard Henderson
2020-08-06 13:03 ` Philippe Mathieu-Daudé [this message]
2020-08-12 17:46   ` [PATCH-for-5.2 4/4] hw/char/serial: Use the Clock API to feed the UART reference clock Richard Henderson
2020-08-22 20:00 ` [PATCH-for-5.2 0/4] " Philippe Mathieu-Daudé
2020-08-24 15:19   ` Peter Maydell
2020-08-26  9:52     ` Philippe Mathieu-Daudé
2020-09-01 16:54       ` Marc-André Lureau
2020-09-01 17:02 ` Paolo Bonzini
2020-09-02 10:41   ` Philippe Mathieu-Daudé

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=20200806130340.17316-5-f4bug@amsat.org \
    --to=f4bug@amsat.org \
    --cc=damien.hedde@greensocs.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).