From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491310085191.28002121252678; Tue, 2 Oct 2018 07:41:50 -0700 (PDT) Received: from localhost ([::1]:44036 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lrw-0001S5-Mx for importer@patchew.org; Tue, 02 Oct 2018 10:41:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46603) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmw-0005Hu-65 for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004Q6-Ho for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:36 -0400 Received: from greensocs.com ([193.104.36.180]:53820) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lcy-0004L1-CD; Tue, 02 Oct 2018 10:26:25 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 49EDD442ADA; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yc7q8NE8idDN; Tue, 2 Oct 2018 16:26:04 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 5403F442AEC; Tue, 2 Oct 2018 16:26:04 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id E1481442AE7; Tue, 2 Oct 2018 16:26:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=SjTuGKi1/V1teMZEtop/VVZ2j005PNFl3339+t7F7B8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=mL7tTloMi2ODKZQI33SQEnEFeSb/vU7unCxa8JBSzZGxpCejjgnhbR72KMyIv+qpk 9ahAqYkKpc6k6B1zxYKokJROcliLTr5HYBaY32w2GYQP5/zinJJ+P+mMsvG+qRTu7M fONp0To/pH3xO4zWm/7cTqA1ei1KSzA280j+8yFA= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=A5kNiJnr; dkim=pass (1024-bit key) header.d=greensocs.com header.b=A5kNiJnr DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490364; bh=SjTuGKi1/V1teMZEtop/VVZ2j005PNFl3339+t7F7B8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=A5kNiJnrQpPNHuqptNkAO+SIyKWKhd1q6IdDXQo/UB7MYmi8aFPsL6opJLJjAiLEo qAiGDtXpO2nYxZ0Uj3i5BU9f+9QsFXDs60dZgrQxFlg80KzwYVSmSXUfGDRClJT41U f9oxlbodo/DE/LrxBYpH7G8MBV7HRheCgeQtRdQc= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490364; bh=SjTuGKi1/V1teMZEtop/VVZ2j005PNFl3339+t7F7B8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=A5kNiJnrQpPNHuqptNkAO+SIyKWKhd1q6IdDXQo/UB7MYmi8aFPsL6opJLJjAiLEo qAiGDtXpO2nYxZ0Uj3i5BU9f+9QsFXDs60dZgrQxFlg80KzwYVSmSXUfGDRClJT41U f9oxlbodo/DE/LrxBYpH7G8MBV7HRheCgeQtRdQc= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:35 +0200 Message-Id: <20181002142443.30976-2-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 1/9] hw/core/clock-port: introduce clock port objects X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Introduce clock port objects: ClockIn and ClockOut. Theses ports may be used to distribute a clock from a object to several other objects. The ClockIn object contains the current state of the clock: the frequency. A ClockIn may be connected to a ClockOut so that it receives update, through the callback, whenever the Clockout is updated using the ClockOut's set function. This is based on the original work of Frederic Konrad. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- Makefile.objs | 1 + include/hw/clock-port.h | 136 ++++++++++++++++++++++++++++++++++ hw/core/clock-port.c | 159 ++++++++++++++++++++++++++++++++++++++++ hw/core/Makefile.objs | 1 + hw/core/trace-events | 7 ++ 5 files changed, 304 insertions(+) create mode 100644 include/hw/clock-port.h create mode 100644 hw/core/clock-port.c create mode 100644 hw/core/trace-events diff --git a/Makefile.objs b/Makefile.objs index ce9c79235e..b29747075f 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -210,6 +210,7 @@ trace-events-subdirs +=3D hw/audio trace-events-subdirs +=3D hw/block trace-events-subdirs +=3D hw/block/dataplane trace-events-subdirs +=3D hw/char +trace-events-subdirs +=3D hw/core trace-events-subdirs +=3D hw/display trace-events-subdirs +=3D hw/dma trace-events-subdirs +=3D hw/hppa diff --git a/include/hw/clock-port.h b/include/hw/clock-port.h new file mode 100644 index 0000000000..8266549350 --- /dev/null +++ b/include/hw/clock-port.h @@ -0,0 +1,136 @@ +#ifndef CLOCK_PORT_H +#define CLOCK_PORT_H + +#include "qom/object.h" +#include "hw/qdev-core.h" +#include "qemu/queue.h" +#include "migration/vmstate.h" + +#define TYPE_CLOCK_IN "clock-in" +#define CLOCK_IN(obj) OBJECT_CHECK(ClockIn, (obj), TYPE_CLOCK_IN) +#define TYPE_CLOCK_OUT "clock-out" +#define CLOCK_OUT(obj) OBJECT_CHECK(ClockOut, (obj), TYPE_CLOCK_OUT) + +typedef void ClockCallback(void *opaque); + +typedef struct ClockOut ClockOut; +typedef struct ClockIn ClockIn; + +struct ClockIn { + /*< private >*/ + Object parent_obj; + /*< private >*/ + uint64_t frequency; + char *canonical_path; /* clock path cache */ + ClockOut *driver; /* clock output controlling this clock */ + ClockCallback *callback; /* local callback */ + void *callback_opaque; /* opaque argument for the callback */ + QLIST_ENTRY(ClockIn) sibling; /* entry in a followers list */ +}; + +struct ClockOut { + /*< private >*/ + Object parent_obj; + /*< private >*/ + char *canonical_path; /* clock path cache */ + QLIST_HEAD(, ClockIn) followers; /* list of registered clocks */ +}; + +extern const VMStateDescription vmstate_clockin; + +/* + * vmstate description entry to be added in device vmsd. + */ +#define VMSTATE_CLOCKIN(_field, _state) \ + VMSTATE_CLOCKIN_V(_field, _state, 0) +#define VMSTATE_CLOCKIN_V(_field, _state, _version) \ + VMSTATE_STRUCT_POINTER_V(_field, _state, _version, vmstate_clockin, Cl= ockIn) + +/** + * clock_out_setup_canonical_path: + * @clk: clock + * + * compute the canonical path of the clock (used by log messages) + */ +void clock_out_setup_canonical_path(ClockOut *clk); + +/** + * clock_in_setup_canonical_path: + * @clk: clock + * + * compute the canonical path of the clock (used by log messages) + */ +void clock_in_setup_canonical_path(ClockIn *clk); + +/** + * clock_add_callback: + * @clk: the clock to register the callback into + * @cb: the callback function + * @opaque: the argument to the callback + * + * Register a callback called on every clock update. + */ +void clock_set_callback(ClockIn *clk, ClockCallback *cb, void *opaque); + +/** + * clock_clear_callback: + * @clk: the clock to delete the callback from + * + * Unregister the callback registered with clock_set_callback. + */ +void clock_clear_callback(ClockIn *clk); + +/** + * clock_init_frequency: + * @clk: the clock to initialize. + * @freq: the clock's frequency in Hz or 0 if unclocked. + * + * Initialize the local cached frequency value of @clk to @freq. + * Note: this function must only be called during device inititialization + * or migration. + */ +void clock_init_frequency(ClockIn *clk, uint64_t freq); + +/** + * clock_connect: + * @clkin: the drived clock. + * @clkout: the driving clock. + * + * Setup @clkout to drive @clkin: Any @clkout update will be propagated + * to @clkin. + */ +void clock_connect(ClockIn *clkin, ClockOut *clkout); + +/** + * clock_set_frequency: + * @clk: the clock to update. + * @freq: the new clock's frequency in Hz or 0 if unclocked. + * + * Update the @clk to the new @freq. + * This change will be propagated through registered clock inputs. + */ +void clock_set_frequency(ClockOut *clk, uint64_t freq); + +/** + * clock_get_frequency: + * @clk: the clk to fetch the clock + * + * @return: the current frequency of @clk in Hz. If @clk is NULL, return 0. + */ +static inline uint64_t clock_get_frequency(const ClockIn *clk) +{ + return clk ? clk->frequency : 0; +} + +/** + * clock_is_enabled: + * @clk: a clock state + * + * @return: true if the clock is running. If @clk is NULL return false. + */ +static inline bool clock_is_enabled(const ClockIn *clk) +{ + return clock_get_frequency(clk) !=3D 0; +} + +#endif /* CLOCK_PORT_H */ diff --git a/hw/core/clock-port.c b/hw/core/clock-port.c new file mode 100644 index 0000000000..25bab0fbed --- /dev/null +++ b/hw/core/clock-port.c @@ -0,0 +1,159 @@ +/* + * Clock inputs and outputs + * + * Copyright GreenSocs 2016-2018 + * + * Authors: + * Frederic Konrad + * Damien Hedde + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/module.h" +#include "hw/clock-port.h" +#include "hw/qdev-core.h" +#include "migration/vmstate.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "trace.h" + +const VMStateDescription vmstate_clockin =3D { + .name =3D "clockin", + .version_id =3D 0, + .minimum_version_id =3D 0, + .fields =3D (VMStateField[]) { + VMSTATE_UINT64(frequency, ClockIn), + VMSTATE_END_OF_LIST() + } +}; + +#define CLOCK_PATH(_clk) (_clk->canonical_path) + +void clock_out_setup_canonical_path(ClockOut *clk) +{ + g_free(clk->canonical_path); + clk->canonical_path =3D object_get_canonical_path(OBJECT(clk)); +} + +void clock_in_setup_canonical_path(ClockIn *clk) +{ + g_free(clk->canonical_path); + clk->canonical_path =3D object_get_canonical_path(OBJECT(clk)); +} + +void clock_set_callback(ClockIn *clk, ClockCallback *cb, void *opaque) +{ + assert(clk); + + clk->callback =3D cb; + clk->callback_opaque =3D opaque; +} + +void clock_init_frequency(ClockIn *clk, uint64_t freq) +{ + assert(clk); + + clk->frequency =3D freq; +} + +void clock_clear_callback(ClockIn *clk) +{ + clock_set_callback(clk, NULL, NULL); +} + +void clock_connect(ClockIn *clkin, ClockOut *clkout) +{ + assert(clkin && clkin->driver =3D=3D NULL); + assert(clkout); + + trace_clock_connect(CLOCK_PATH(clkin), CLOCK_PATH(clkout)); + + QLIST_INSERT_HEAD(&clkout->followers, clkin, sibling); + clkin->driver =3D clkout; +} + +static void clock_disconnect(ClockIn *clk) +{ + if (clk->driver =3D=3D NULL) { + return; + } + + trace_clock_disconnect(CLOCK_PATH(clk)); + + clk->driver =3D NULL; + QLIST_REMOVE(clk, sibling); +} + +void clock_set_frequency(ClockOut *clk, uint64_t freq) +{ + ClockIn *follower; + trace_clock_update(CLOCK_PATH(clk), freq); + + QLIST_FOREACH(follower, &clk->followers, sibling) { + trace_clock_propagate(CLOCK_PATH(clk), CLOCK_PATH(follower)); + if (follower->frequency !=3D freq) { + follower->frequency =3D freq; + if (follower->callback) { + follower->callback(follower->callback_opaque); + } + } + } +} + +static void clock_out_initfn(Object *obj) +{ + ClockOut *clk =3D CLOCK_OUT(obj); + + QLIST_INIT(&clk->followers); +} + +static void clock_out_finalizefn(Object *obj) +{ + ClockOut *clk =3D CLOCK_OUT(obj); + ClockIn *follower, *next; + + /* clear our list of followers */ + QLIST_FOREACH_SAFE(follower, &clk->followers, sibling, next) { + clock_disconnect(follower); + } + + g_free(clk->canonical_path); + clk->canonical_path =3D NULL; +} + +static void clock_in_finalizefn(Object *obj) +{ + ClockIn *clk =3D CLOCK_IN(obj); + + /* remove us from driver's followers list */ + clock_disconnect(clk); + + g_free(clk->canonical_path); + clk->canonical_path =3D NULL; +} + +static const TypeInfo clock_out_info =3D { + .name =3D TYPE_CLOCK_OUT, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(ClockOut), + .instance_init =3D clock_out_initfn, + .instance_finalize =3D clock_out_finalizefn, +}; + +static const TypeInfo clock_in_info =3D { + .name =3D TYPE_CLOCK_IN, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(ClockIn), + .instance_finalize =3D clock_in_finalizefn, +}; + +static void clock_register_types(void) +{ + type_register_static(&clock_in_info); + type_register_static(&clock_out_info); +} + +type_init(clock_register_types) diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index eb88ca979e..f7102121f4 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -6,6 +6,7 @@ common-obj-$(CONFIG_SOFTMMU) +=3D fw-path-provider.o # irq.o needed for qdev GPIO handling: common-obj-y +=3D irq.o common-obj-y +=3D hotplug.o +common-obj-y +=3D clock-port.o common-obj-$(CONFIG_SOFTMMU) +=3D nmi.o =20 common-obj-$(CONFIG_EMPTY_SLOT) +=3D empty_slot.o diff --git a/hw/core/trace-events b/hw/core/trace-events new file mode 100644 index 0000000000..d4880ec138 --- /dev/null +++ b/hw/core/trace-events @@ -0,0 +1,7 @@ +# See docs/devel/tracing.txt for syntax documentation. + +# hw/core/clock-port.c +clock_connect(const char *clk, const char *driver) "'%s' drived-by '%s'" +clock_disconnect(const char *clk) "'%s'" +clock_update(const char *clk, uint64_t freq) "'%s' frequency %" PRIu64 "Hz" +clock_propagate(const char *clko, const char *clki) "'%s' =3D> '%s'" --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491139520884.0915755934391; Tue, 2 Oct 2018 07:38:59 -0700 (PDT) Received: from localhost ([::1]:44019 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lp2-0007OU-Ro for importer@patchew.org; Tue, 02 Oct 2018 10:38:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46817) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmn-0005Jj-MF for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004Q1-Gl for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:37 -0400 Received: from greensocs.com ([193.104.36.180]:53816) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Ld9-0004Kz-8Z; Tue, 02 Oct 2018 10:26:31 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 13427442AFF; Tue, 2 Oct 2018 16:26:07 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bsD2aumRFfpu; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id B5BF2442AED; Tue, 2 Oct 2018 16:26:04 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 55599442AE7; Tue, 2 Oct 2018 16:26:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490367; bh=W368a874LLn3wLZ0ssLjyDwxQKF21HbKz4tSIYNoBNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=f9F5H1XGRNIhraILjBGUQJdJiSUXw3i5Se/7cI44HYWT0griEQd5yrizC+qXEhIdT 5Bm9zt1uVUsGc6xvGtVNpP+pyHzbqFbcmR1o/Xih64ioMqJzyaRIBbwJ9uyhoNT0Xn bEeax0OG/lKXdkBd0w60LMNafWyhqCvjzESaE5wg= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=ax2IQLwP; dkim=pass (1024-bit key) header.d=greensocs.com header.b=ax2IQLwP DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490364; bh=W368a874LLn3wLZ0ssLjyDwxQKF21HbKz4tSIYNoBNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ax2IQLwPsJndXD0kUMaoqrxUImvC87i1XxxTIPu2IdsRfCEtlIa/9oXZ8coN26wrW X/ZBtS90kLbdH7s4RwUEedZSb/p1QMmfu4SaoTsXGw+to8NjFcFHdzTQE6A5CB7IhR 4KlAesA5Yv07iLX380Wc0A+RQmEXJi4CW+c4Y6+4= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490364; bh=W368a874LLn3wLZ0ssLjyDwxQKF21HbKz4tSIYNoBNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ax2IQLwPsJndXD0kUMaoqrxUImvC87i1XxxTIPu2IdsRfCEtlIa/9oXZ8coN26wrW X/ZBtS90kLbdH7s4RwUEedZSb/p1QMmfu4SaoTsXGw+to8NjFcFHdzTQE6A5CB7IhR 4KlAesA5Yv07iLX380Wc0A+RQmEXJi4CW+c4Y6+4= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:36 +0200 Message-Id: <20181002142443.30976-3-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 2/9] qdev: add clock input&output support to devices. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add functions to easily add input or output clocks to a device. The clock port objects are added as children of the device. A function allows to connect two clocks together. It should be called by some toplevel to make a connection between 2 (sub-)devices. Also add a function which forwards a port to another device. This function allows, in the case of device composition, to expose a sub-device clock port as its own clock port. This is really an alias: when forwarding an input, only one callback can be registered on it since there is only one Clockin object behind all aliases. This is based on the original work of Frederic Konrad. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/qdev-clock.h | 62 ++++++++++++++++++ include/hw/qdev-core.h | 14 ++++ include/hw/qdev.h | 1 + hw/core/qdev-clock.c | 140 ++++++++++++++++++++++++++++++++++++++++ hw/core/qdev.c | 29 +++++++++ hw/core/Makefile.objs | 2 +- 6 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 include/hw/qdev-clock.h create mode 100644 hw/core/qdev-clock.c diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h new file mode 100644 index 0000000000..d76aa9f479 --- /dev/null +++ b/include/hw/qdev-clock.h @@ -0,0 +1,62 @@ +#ifndef QDEV_CLOCK_H +#define QDEV_CLOCK_H + +#include "hw/clock-port.h" +#include "hw/qdev-core.h" +#include "qapi/error.h" + +/** + * qdev_init_clock_in: + * @dev: the device in which to add a clock + * @name: the name of the clock (can't be NULL). + * @callback: optional callback to be called on update or NULL. + * @opaque: argument for the callback + * @returns: a pointer to the newly added clock + * + * Add a input clock to device @dev as a clock named @name. + * This adds a child<> property. + * The callback will be called with @dev as opaque parameter. + */ +ClockIn *qdev_init_clock_in(DeviceState *dev, const char *name, + ClockCallback *callback, void *opaque); + +/** + * qdev_init_clock_out: + * @dev: the device to add a clock to + * @name: the name of the clock (can't be NULL). + * @callback: optional callback to be called on update or NULL. + * @returns: a pointer to the newly added clock + * + * Add a output clock to device @dev as a clock named @name. + * This adds a child<> property. + */ +ClockOut *qdev_init_clock_out(DeviceState *dev, const char *name); + +/** + * qdev_pass_clock: + * @dev: the device to forward the clock to + * @name: the name of the clock to be added (can't be NULL) + * @container: the device which already has the clock + * @cont_name: the name of the clock in the container device + * + * Add a clock @name to @dev which forward to the clock @cont_name in @con= tainer + */ +void qdev_pass_clock(DeviceState *dev, const char *name, + DeviceState *container, const char *cont_name); + +/** + * qdev_connect_clock: + * @dev: the drived clock device. + * @name: the drived clock name. + * @driver: the driving clock device. + * @driver_name: the driving clock name. + * @errp: error report + * + * Setup @driver_name output clock of @driver to drive @name input clock of + * @dev. Errors are trigerred if clock does not exists + */ +void qdev_connect_clock(DeviceState *dev, const char *name, + DeviceState *driver, const char *driver_name, + Error **errp); + +#endif /* QDEV_CLOCK_H */ diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index f1fd0f8736..e6014d3a41 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -127,6 +127,19 @@ struct NamedGPIOList { QLIST_ENTRY(NamedGPIOList) node; }; =20 +typedef struct NamedClockList NamedClockList; + +typedef struct ClockIn ClockIn; +typedef struct ClockOut ClockOut; + +struct NamedClockList { + char *name; + bool forward; + ClockIn *in; + ClockOut *out; + QLIST_ENTRY(NamedClockList) node; +}; + /** * DeviceState: * @realized: Indicates whether the device has been fully constructed. @@ -147,6 +160,7 @@ struct DeviceState { int hotplugged; BusState *parent_bus; QLIST_HEAD(, NamedGPIOList) gpios; + QLIST_HEAD(, NamedClockList) clocks; QLIST_HEAD(, BusState) child_bus; int num_child_bus; int instance_id_alias; diff --git a/include/hw/qdev.h b/include/hw/qdev.h index 5cb8b080a6..b031da7b41 100644 --- a/include/hw/qdev.h +++ b/include/hw/qdev.h @@ -4,5 +4,6 @@ #include "hw/hw.h" #include "hw/qdev-core.h" #include "hw/qdev-properties.h" +#include "hw/qdev-clock.h" =20 #endif diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c new file mode 100644 index 0000000000..f0e4839aed --- /dev/null +++ b/hw/core/qdev-clock.c @@ -0,0 +1,140 @@ +/* + * Device's clock + * + * Copyright GreenSocs 2016-2018 + * + * Authors: + * Frederic Konrad + * Damien Hedde + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qom/object.h" +#include "hw/qdev-clock.h" +#include "qapi/error.h" + +static NamedClockList *qdev_init_clocklist(DeviceState *dev, const char *n= ame, + bool forward) +{ + NamedClockList *ncl; + + /* + * The clock path will be computed by the device's realize function ca= ll. + * This is required to ensure the clock's canonical path is right and = log + * messages are meaningfull. + */ + assert(name); + assert(!dev->realized); + + ncl =3D g_malloc0(sizeof(*ncl)); + ncl->name =3D g_strdup(name); + ncl->forward =3D forward; + + QLIST_INSERT_HEAD(&dev->clocks, ncl, node); + return ncl; +} + +ClockOut *qdev_init_clock_out(DeviceState *dev, const char *name) +{ + NamedClockList *ncl; + Object *clk; + + ncl =3D qdev_init_clocklist(dev, name, false); + + clk =3D object_new(TYPE_CLOCK_OUT); + + /* will fail if name already exists */ + object_property_add_child(OBJECT(dev), name, clk, &error_abort); + object_unref(clk); /* remove the initial ref made by object_new */ + + ncl->out =3D CLOCK_OUT(clk); + return ncl->out; +} + +ClockIn *qdev_init_clock_in(DeviceState *dev, const char *name, + ClockCallback *callback, void *opaque) +{ + NamedClockList *ncl; + Object *clk; + + ncl =3D qdev_init_clocklist(dev, name, false); + + clk =3D object_new(TYPE_CLOCK_IN); + /* + * the ref initialized by object_new will be cleared during dev finali= ze. + * It allows us to safely remove the callback. + */ + + /* will fail if name already exists */ + object_property_add_child(OBJECT(dev), name, clk, &error_abort); + + ncl->in =3D CLOCK_IN(clk); + if (callback) { + clock_set_callback(ncl->in, callback, opaque); + } + return ncl->in; +} + +static NamedClockList *qdev_get_clocklist(DeviceState *dev, const char *na= me) +{ + NamedClockList *ncl; + + QLIST_FOREACH(ncl, &dev->clocks, node) { + if (strcmp(name, ncl->name) =3D=3D 0) { + return ncl; + } + } + + return NULL; +} + +void qdev_pass_clock(DeviceState *dev, const char *name, + DeviceState *container, const char *cont_name) +{ + NamedClockList *original_ncl, *ncl; + Object **clk; + + assert(container && cont_name); + + original_ncl =3D qdev_get_clocklist(container, cont_name); + assert(original_ncl); /* clock must exist in origin */ + + ncl =3D qdev_init_clocklist(dev, name, true); + + if (ncl->out) { + clk =3D (Object **)&ncl->out; + } else { + clk =3D (Object **)&ncl->in; + } + + /* will fail if name already exists */ + object_property_add_link(OBJECT(dev), name, object_get_typename(*clk), + clk, NULL, OBJ_PROP_LINK_STRONG, &error_abort); +} + +void qdev_connect_clock(DeviceState *dev, const char *name, + DeviceState *driver, const char *driver_name, + Error **errp) +{ + NamedClockList *ncl, *drv_ncl; + + assert(dev && name); + assert(driver && driver_name); + + ncl =3D qdev_get_clocklist(dev, name); + if (!ncl || !ncl->in) { + error_setg(errp, "no input clock '%s' in device", name); + return; + } + + drv_ncl =3D qdev_get_clocklist(driver, driver_name); + if (!drv_ncl || !drv_ncl->out) { + error_setg(errp, "no output clock '%s' in driver", driver_name); + return; + } + + clock_connect(ncl->in , drv_ncl->out); +} diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 529b82de18..c48edf180f 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -790,6 +790,7 @@ static void device_set_realized(Object *obj, bool value= , Error **errp) DeviceClass *dc =3D DEVICE_GET_CLASS(dev); HotplugHandler *hotplug_ctrl; BusState *bus; + NamedClockList *clk; Error *local_err =3D NULL; bool unattached_parent =3D false; static int unattached_count; @@ -846,6 +847,15 @@ static void device_set_realized(Object *obj, bool valu= e, Error **errp) */ g_free(dev->canonical_path); dev->canonical_path =3D object_get_canonical_path(OBJECT(dev)); + QLIST_FOREACH(clk, &dev->clocks, node) { + if (clk->forward) { + continue; + } else if (clk->in !=3D NULL) { + clock_in_setup_canonical_path(clk->in); + } else { + clock_out_setup_canonical_path(clk->out); + } + } =20 if (qdev_get_vmsd(dev)) { if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev)= , dev, @@ -972,6 +982,7 @@ static void device_initfn(Object *obj) (Object **)&dev->parent_bus, NULL, 0, &error_abort); QLIST_INIT(&dev->gpios); + QLIST_INIT(&dev->clocks); } =20 static void device_post_init(Object *obj) @@ -983,6 +994,7 @@ static void device_post_init(Object *obj) static void device_finalize(Object *obj) { NamedGPIOList *ngl, *next; + NamedClockList *clk, *clk_next; =20 DeviceState *dev =3D DEVICE(obj); =20 @@ -996,6 +1008,23 @@ static void device_finalize(Object *obj) */ } =20 + QLIST_FOREACH_SAFE(clk, &dev->clocks, node, clk_next) { + QLIST_REMOVE(clk, node); + if (!clk->forward && clk->in) { + /* + * if this clock is not forwarded, clk->in & clk->out are chil= d of + * dev. + * At this point the properties and associated reference are + * already deleted but we kept a ref on clk->in to ensure we + * don't have a lost callback to a deleted device somewhere. + */ + clock_clear_callback(clk->in); + object_unref(OBJECT(clk->in)); + } + g_free(clk->name); + g_free(clk); + } + /* Only send event if the device had been completely realized */ if (dev->pending_deleted_event) { g_assert(dev->canonical_path); diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index f7102121f4..fc0505e716 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -1,5 +1,5 @@ # core qdev-related obj files, also used by *-user: -common-obj-y +=3D qdev.o qdev-properties.o +common-obj-y +=3D qdev.o qdev-properties.o qdev-clock.o common-obj-y +=3D bus.o reset.o common-obj-$(CONFIG_SOFTMMU) +=3D qdev-fw.o common-obj-$(CONFIG_SOFTMMU) +=3D fw-path-provider.o --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491494024526.9555504939515; Tue, 2 Oct 2018 07:44:54 -0700 (PDT) Received: from localhost ([::1]:44055 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lun-00042s-DE for importer@patchew.org; Tue, 02 Oct 2018 10:44:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46555) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmw-0005FG-7W for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004QB-IL for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:35 -0400 Received: from greensocs.com ([193.104.36.180]:53815) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Ld9-0004Ky-E2; Tue, 02 Oct 2018 10:26:31 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 328B8442AEC; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DmLwSbXdySxe; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 28BED442AF9; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id B6AC7442AF8; Tue, 2 Oct 2018 16:26:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490366; bh=FABDGza8O8IXXcL2AXTXajpC14NFz8iYXb5Sqj8mK8U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=I2mDQ/VPJeKkVbDyj/oHDbhy0Q54iQeSsTKfc4f2zaPtAOBAc5ryPZTsgPwOxRb81 EbfYhwCjmPYB+YjVtS66gjRe0mCRwuJUhCYrf32h4WyrrlxHqQBEyyti7r3/oCOAVK m1yFDbiyU++tqXknBcd4LCRk1oNueRobQO/kQ7A8= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=GyuUaZGz; dkim=pass (1024-bit key) header.d=greensocs.com header.b=GyuUaZGz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=FABDGza8O8IXXcL2AXTXajpC14NFz8iYXb5Sqj8mK8U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=GyuUaZGzGGN5LtxLmojGJCqLPAXqnePxt5aa0MMAFF0tCKGYstoeGtiBNnzbO7o7Y l/28kGlQIld7E/QTOLkao2t6n4PsTP3WXUW3mI8d++GAbHvE2sk8qc2UIocqJ/lhoX 091KDL4KsZUg1MkIU4yCW1+SSGJ2HgSIUnWBoHgQ= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=FABDGza8O8IXXcL2AXTXajpC14NFz8iYXb5Sqj8mK8U=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=GyuUaZGzGGN5LtxLmojGJCqLPAXqnePxt5aa0MMAFF0tCKGYstoeGtiBNnzbO7o7Y l/28kGlQIld7E/QTOLkao2t6n4PsTP3WXUW3mI8d++GAbHvE2sk8qc2UIocqJ/lhoX 091KDL4KsZUg1MkIU4yCW1+SSGJ2HgSIUnWBoHgQ= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:37 +0200 Message-Id: <20181002142443.30976-4-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 3/9] qdev-monitor: print the device's clock with info qtree X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This prints the clocks attached to a DeviceState when using "info qtree" mo= nitor command. For every clock, it displays the direction, the name and if the clock is forwarded. For input clock, it displays also the frequency. This is based on the original work of Frederic Konrad. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- qdev-monitor.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/qdev-monitor.c b/qdev-monitor.c index 61e0300991..8c39a3a65b 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -682,6 +682,7 @@ static void qdev_print(Monitor *mon, DeviceState *dev, = int indent) ObjectClass *class; BusState *child; NamedGPIOList *ngl; + NamedClockList *clk; =20 qdev_printf("dev: %s, id \"%s\"\n", object_get_typename(OBJECT(dev)), dev->id ? dev->id : ""); @@ -696,6 +697,17 @@ static void qdev_print(Monitor *mon, DeviceState *dev,= int indent) ngl->num_out); } } + QLIST_FOREACH(clk, &dev->clocks, node) { + if (clk->out) { + qdev_printf("clock-out%s \"%s\"\n", + clk->forward ? " (fw)" : "", + clk->name); + } else { + qdev_printf("clock-in%s \"%s\" freq=3D%" PRIu64 "Hz\n", + clk->forward ? " (fw)" : "", + clk->name, clock_get_frequency(clk->in)); + } + } class =3D object_get_class(OBJECT(dev)); do { qdev_print_props(mon, dev, DEVICE_CLASS(class)->props, indent); --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491503829858.2251933787078; Tue, 2 Oct 2018 07:45:03 -0700 (PDT) Received: from localhost ([::1]:44056 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Luy-0004CM-Un for importer@patchew.org; Tue, 02 Oct 2018 10:44:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46825) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmw-0005Kf-7H for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004QL-LV for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:35 -0400 Received: from greensocs.com ([193.104.36.180]:53819) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Ld9-0004L0-C3; Tue, 02 Oct 2018 10:26:31 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 0D1BCC7AC5; Tue, 2 Oct 2018 16:26:08 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nedi4oqLr3lv; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id A9BD0442AF8; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 24E41442AE7; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490368; bh=hfBPiWf3ZL4pT347LbsUbQ915KOAggttZcOgqcVYycs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=S5C/yARp6sbzYiPmKWH904uFdaULGLR3XPoDyrmfu4YRjY5U2FRxAscGqMMdXzoWq 88vEhbvk+V73dW9tGkMQOINnMIripGsSsbebnPLCASLLw1n0v7ux+1pYbjJ3Rjrhmu RXoLE9Wirv/DdCUSeCNf76muama9SSknpFZGPYO4= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=bSjz8aJP; dkim=pass (1024-bit key) header.d=greensocs.com header.b=bSjz8aJP DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=hfBPiWf3ZL4pT347LbsUbQ915KOAggttZcOgqcVYycs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bSjz8aJPTPYj/m0e1Rf8yO1mS4CQDPRO2ABo1q7Qn1Y3Ca4YBqbvE+fE8uLU+d62b ZW1LAuYQt0D0PTpJ095jT8wgvuT154bzC4gSMdk2wYzMOGM+8EDMNL4YcKzibec1Cn R7sa4flfYJm9zDoWlPx+rrix4cS90izeD7Qy0SAU= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=hfBPiWf3ZL4pT347LbsUbQ915KOAggttZcOgqcVYycs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bSjz8aJPTPYj/m0e1Rf8yO1mS4CQDPRO2ABo1q7Qn1Y3Ca4YBqbvE+fE8uLU+d62b ZW1LAuYQt0D0PTpJ095jT8wgvuT154bzC4gSMdk2wYzMOGM+8EDMNL4YcKzibec1Cn R7sa4flfYJm9zDoWlPx+rrix4cS90izeD7Qy0SAU= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:38 +0200 Message-Id: <20181002142443.30976-5-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 4/9] qdev-clock: introduce an init array to ease the device construction X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Introduce a function and macro helpers to setup several clocks in a device from a static array description. An element of the array describes the clock (name and direction) as well as the related callback and an optional offset to store the created object pointer in the device state structure. The array must be terminated by a special element QDEV_CLOCK_END. This is based on the original work of Frederic Konrad. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/qdev-clock.h | 67 +++++++++++++++++++++++++++++++++++++++++ hw/core/qdev-clock.c | 26 ++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h index d76aa9f479..fba907dee2 100644 --- a/include/hw/qdev-clock.h +++ b/include/hw/qdev-clock.h @@ -59,4 +59,71 @@ void qdev_connect_clock(DeviceState *dev, const char *na= me, DeviceState *driver, const char *driver_name, Error **errp); =20 +/** + * ClockInitElem: + * @name: name of the clock (can't be NULL) + * @output: indicates whether the clock is input or output + * @callback: for inputs, optional callback to be called on clock's update + * with device as opaque + * @offset: optional offset to store the clock pointer in device'state + * structure (0 means unused) + */ +struct ClockPortInitElem { + const char *name; + bool output; + ClockCallback *callback; + size_t offset; +}; + +#define clock_offset_value(_type, _devstate, _field) \ + (offsetof(_devstate, _field) + \ + type_check(_type *, typeof_field(_devstate, _field))) + +#define QDEV_CLOCK(_output, _type, _devstate, _field, _callback) { \ + .name =3D (stringify(_field)), \ + .output =3D _output, \ + .callback =3D _callback, \ + .offset =3D clock_offset_value(_type, _devstate, _field), \ +} + +/** + * QDEV_CLOCK_(IN|OUT): + * @_devstate: structure type. @dev argument of qdev_init_clocks below mus= t be + * a pointer to that same type. + * @_field: a field in @_devstate (must be ClockIn* or ClockOut*) + * @_callback: (for input only) callback (or NULL) to be called with the d= evice + * state as argument + * + * The name of the clock will be derived from @_field + */ +#define QDEV_CLOCK_IN(_devstate, _field, _callback) \ + QDEV_CLOCK(false, ClockIn, _devstate, _field, _callback) + +#define QDEV_CLOCK_OUT(_devstate, _field) \ + QDEV_CLOCK(true, ClockOut, _devstate, _field, NULL) + +/** + * QDEV_CLOCK_IN_NOFIELD: + * @_name: name of the clock + * @_callback: callback (or NULL) to be called with the device state as ar= gument + */ +#define QDEV_CLOCK_IN_NOFIELD(_name, _callback) { \ + .name =3D _name, \ + .output =3D false, \ + .callback =3D _callback, \ + .offset =3D 0, \ +} + +#define QDEV_CLOCK_END { .name =3D NULL } + +typedef struct ClockPortInitElem ClockPortInitArray[]; + +/** + * qdev_init_clocks: + * @dev: the device to add clocks + * @clocks: a QDEV_CLOCK_END-terminated array which contains the + * clocks information. + */ +void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks); + #endif /* QDEV_CLOCK_H */ diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c index f0e4839aed..08afe3983d 100644 --- a/hw/core/qdev-clock.c +++ b/hw/core/qdev-clock.c @@ -138,3 +138,29 @@ void qdev_connect_clock(DeviceState *dev, const char *= name, =20 clock_connect(ncl->in , drv_ncl->out); } + +void qdev_init_clocks(DeviceState *dev, const ClockPortInitArray clocks) +{ + const struct ClockPortInitElem *elem; + + assert(dev); + assert(clocks); + + for (elem =3D &clocks[0]; elem->name !=3D NULL; elem++) { + /* offset cannot be inside the DeviceState part */ + assert(elem->offset =3D=3D 0 || elem->offset > sizeof(DeviceState)= ); + if (elem->output) { + ClockOut *clk; + clk =3D qdev_init_clock_out(dev, elem->name); + if (elem->offset) { + *(ClockOut **)(((void *) dev) + elem->offset) =3D clk; + } + } else { + ClockIn *clk; + clk =3D qdev_init_clock_in(dev, elem->name, elem->callback, de= v); + if (elem->offset) { + *(ClockIn **)(((void *) dev) + elem->offset) =3D clk; + } + } + } +} --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491139308617.2977660876868; Tue, 2 Oct 2018 07:38:59 -0700 (PDT) Received: from localhost ([::1]:44021 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lp3-0007Oh-DV for importer@patchew.org; Tue, 02 Oct 2018 10:38:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46555) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmo-0005FG-8b for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004QW-MZ for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:37 -0400 Received: from greensocs.com ([193.104.36.180]:53912) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7LdA-0004NR-4w; Tue, 02 Oct 2018 10:26:32 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 30B5B442AFD; Tue, 2 Oct 2018 16:26:08 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id X9DHJz8u4MPG; Tue, 2 Oct 2018 16:26:07 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 05509442AE7; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 94F9C442AEC; Tue, 2 Oct 2018 16:26:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490368; bh=5hEvNX90SokMK9PbyoKGxS0APN8VtL8lmcUwytaGsG0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=R+3tWROOucd/xvoOTFlNHBNcRDLHBtEtVDKz7R9uoao3kDR7D4NcnOlsPYDzttvhx XF0X/KaPb/m75Dy0eUdySElJk6ZGEQn6yEdODwEmEDNUrC9ITuk6fVvvleA05sdFpI WA3f7A+/Q2Ffci45cgviM7I0wIeJg1aRuF6qRg4Y= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=kCn4QJq0; dkim=pass (1024-bit key) header.d=greensocs.com header.b=5T+1b0Ws DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490366; bh=5hEvNX90SokMK9PbyoKGxS0APN8VtL8lmcUwytaGsG0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=kCn4QJq0xr9djIDbeJk7HzeI2pe54V9soBz/XVJMZsSWzNMhRiDXIXOAna3wfSg2z YM1QRk/+JK/WmzR1k3vt5SvKoe/elPp6aADbd7pCGmA3zi+L4LatTcpp+Szv61vlOy KoybwY/CRgFaNm9blH4/Kp4fUy+xmY7lA3KCYBrM= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490365; bh=5hEvNX90SokMK9PbyoKGxS0APN8VtL8lmcUwytaGsG0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=5T+1b0WsDjdEl8C9hbQfVj0Hi5vJtUDlmVKYZI2+FBERL7x0Fq2bl5d+RrAL3aDCl 4+XWRnUs4GU+E8+2utUq/Nfe0DCoAo9TILz0c8yWzwgCEQqvRAoJJ6Q3pQwaixv00G Kx4EvwYYjLDZgZp6XGnxq6UWygxbqSheVDT1+I4A= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:39 +0200 Message-Id: <20181002142443.30976-6-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 5/9] docs/clocks: add device's clock documentation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 3 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add the documentation about the clock inputs and outputs in devices. This is based on the original work of Frederic Konrad. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- docs/devel/clock.txt | 163 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 docs/devel/clock.txt diff --git a/docs/devel/clock.txt b/docs/devel/clock.txt new file mode 100644 index 0000000000..6dd8abdee6 --- /dev/null +++ b/docs/devel/clock.txt @@ -0,0 +1,163 @@ + +What are device's clocks +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Clocks are ports representing input and output clocks of a device. They ar= e QOM +objects developed for the purpose of modeling the distribution of clocks in +QEMU. + +This allows us to model the clock distribution of a platform and detect +configuration errors in the clock tree such as badly configured PLL, clock +source selection or disabled clock. + +The objects are CLOCK_IN for the input and CLOCK_OUT for the output. + +The clock value: ClockState +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D + +The ClockState is the structure carried by the CLOCK_OUT and CLOCK_IN obje= cts. +It contains one integer field representing the frequency of the clock in H= ertz. + +It only simulates the clock by transmitting the frequency value and +doesn't model the signal itself such as pin toggle or duty cycle. +The special value 0 as a frequency is legal and represent the clock being +inactive or gated. + +Adding clocks to a device +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D + +Adding clocks to a device must be done during the init phase of the Device +object. + +To add an input clock to a device, the function qdev_init_clock_in must be= used. +It takes the name, a callback, and an opaque parameter for the clock. +Output is more simple, only the name is required. Typically: +qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback, dev); +qdev_init_clock_out(DEVICE(dev), "clk-out"); + +Both functions return the created CLOCK_IN/OUT pointer, which should be sa= ved +in the device's state structure. + +Theses objects will be automatically deleted by the qom reference mechanis= m. + +Note that it is possible to create a static array describing clock inputs = and +outputs. The function qdev_init_clocks must be called with the array as +parameters to initialize the clocks: it has the same behaviour as calling = the +qdev_init_clock/out for each clock in the array. + +Unconnected input clocks +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Unconnected input clocks have a default frequency value of 0. It means the +clock will be considered as disabled. If this is not the wanted behaviour, +clock_init_frequency should be called on the ClockIn object during device = init. +For example: +clk =3D qdev_init_clock_in(DEVICE(dev), "clk-in", clk_in_callback, dev); +clock_init_frequency(clk, 100 * 1000 * 1000); // init value is 100Mhz + +Forwarding clocks +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Sometimes, one needs to forward, or inherit, a clock from another device. +Typically, when doing device composition, a device might expose a sub-devi= ce's +clock without interfering with it. +The function qdev_pass_clock can be used to achieve this behaviour. Note, = that +it is possible to expose the clock under a different name. This works for = both +inputs or outputs. + +For example, if device B is a child of device A, device_a_instance_init may +do something like this: +void device_a_instance_init(Object *obj) +{ + AState *A =3D DEVICE_A(obj); + BState *B; + [...] /* create B object as child of A */ + qdev_pass_clock(A, "b_clk", B, "clk"); + /* + * Now A has a clock "b_clk" which forwards to + * the "clk" of its child B. + */ +} + +This function does not returns any clock object. It is not possible to add +a callback on a forwarded input clock. + +Connecting two clocks together +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D + +Let's say we have 2 devices A and B. A has an output clock named "clkout" = and B +has an input clock named "clkin". + +The clocks are connected together using the function qdev_connect_clock: +qdev_connect_clock(B, "clkin", A, "clkout", &error_abort); +The device which has the input must be the first argument. + +It is possible to connect several input clocks to the same output. Every +input callback will be called when the output changes. + +It is not possible to disconnect a clock or to change the clock connection +after it is done. + +Changing a clock output +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +A device can change its outputs using the clock_set function. It will trig= ger +updates on any connected inputs. + +For example, let's say that we have an output clock "clkout" and we have a +pointer to it in the device state because we did the following in init pha= se: +dev->clkout =3D qdev_init_clock_out(DEVICE(dev), "clkout"); + +Then at any time, it is possible to change the clock value by doing: +clock_set_frequency(dev->clkout, 1000 * 1000 * 1000); /* 1Mhz */ + +Callback on input clock change +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D + +Here is an example of an input callback: +void clock_callback(void *opaque) { + MyDeviceState *s =3D (MyDeviceState *) opaque; + /* + * opaque may not be the device state pointer, but most probably it is. + * (It depends on what is given to the qdev_init_clock_in function) + */ + + /* do something with the new frequency */ + fprintf(stdout, "device new frequency is %" PRIu64 "Hz\n", + clock_get_frequency(dev->my_clk_input)); +} + +The state argument needs only to be copied if the device needs to use the = value +later: the state pointer argument of the pointer will not be valid anymore +after the end of the function. + +Migration +=3D=3D=3D=3D=3D=3D=3D=3D=3D + +Only the CLOCK_IN object has a state. CLOCK_OUT frequency should not be set +in migration post_load. + +In case the frequency of in input clock is needed for a device's migration, +this state must be migrated. The VMSTATE_CLOCKIN macro defines an entry to +be added in a vmstate description. + +For example, if a device has a clock input and the device state looks like: +MyDeviceState { + DeviceState parent_obj; + ClockIn *clk; +}; + +Then, to add the clock frequency to the device's migrated state, the vmsta= te +description is: +VMStateDescription my_device_vmstate =3D { + .name =3D "my_device", + .fields =3D (VMStateField[]) { + VMSTATE_CLOCKIN(clk, MyDeviceState), + VMSTATE_END_OF_LIST() + } +}; + +When adding a input clock support to an existing device, you must care abo= ut +migration compatibility. To this end, you can use the clock_init_frequency= in +a pre_load function to setup a default value in case the source vm does not +migrate the frequency. --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491139578223.15923817134603; Tue, 2 Oct 2018 07:38:59 -0700 (PDT) Received: from localhost ([::1]:44020 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lp2-0007OX-EO for importer@patchew.org; Tue, 02 Oct 2018 10:38:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46603) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmo-0005Hu-7i for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdD-0004R0-Fl for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:37 -0400 Received: from greensocs.com ([193.104.36.180]:53911) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7LdA-0004NQ-8C; Tue, 02 Oct 2018 10:26:32 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 36851442AE7; Tue, 2 Oct 2018 16:26:09 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HfcPr8OI72qM; Tue, 2 Oct 2018 16:26:08 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 92048442AFC; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 06E61442AFB; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490369; bh=1i5eXwsDYOm8S969FRbqSB1HGmhdp58XohD/nI9qNnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=eXW/5O82F0HlJgMZcRYySODUgamBX5IpH1UzRY3FaOvgi6182vJf3vzfiNWezRsR7 J10ebYhcOWOCE3pFQIbXVaqYwMs10YkjEitmY4bbsrNkLww2/1WuRtnpDBYb3pSFvP VdyiNi5jn/cp+x91+DSvmQmztbP2OLDjXlzcBFH4= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=VIoyF2o1; dkim=pass (1024-bit key) header.d=greensocs.com header.b=VIoyF2o1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490366; bh=1i5eXwsDYOm8S969FRbqSB1HGmhdp58XohD/nI9qNnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=VIoyF2o1iDueQhYCV48VUjwh0GOYq0i0t80sj9FZMI1nSmVNsMOgrOz5hgITE/x1N CaHR6B63m4S/V9mhqKU2ky4ncJzqp5QhmjV9UtKBWEAdDwyG5IJaK8BlX2kjiamI4O 7bKM19N8ar2J8VCc1Os5LiLhRIYxKwwptKrrfl4U= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490366; bh=1i5eXwsDYOm8S969FRbqSB1HGmhdp58XohD/nI9qNnA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=VIoyF2o1iDueQhYCV48VUjwh0GOYq0i0t80sj9FZMI1nSmVNsMOgrOz5hgITE/x1N CaHR6B63m4S/V9mhqKU2ky4ncJzqp5QhmjV9UtKBWEAdDwyG5IJaK8BlX2kjiamI4O 7bKM19N8ar2J8VCc1Os5LiLhRIYxKwwptKrrfl4U= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:40 +0200 Message-Id: <20181002142443.30976-7-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 6/9] hw/misc/zynq_slcr: use standard register definition X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Replace the zynq_slcr registers enum and macros using the hw/registerfields.h macros. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Alistair Francis --- hw/misc/zynq_slcr.c | 468 ++++++++++++++++++++++---------------------- 1 file changed, 234 insertions(+), 234 deletions(-) diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c index d6bdd027ef..baa13d1316 100644 --- a/hw/misc/zynq_slcr.c +++ b/hw/misc/zynq_slcr.c @@ -20,6 +20,7 @@ #include "hw/sysbus.h" #include "sysemu/sysemu.h" #include "qemu/log.h" +#include "hw/registerfields.h" =20 #ifndef ZYNQ_SLCR_ERR_DEBUG #define ZYNQ_SLCR_ERR_DEBUG 0 @@ -35,138 +36,135 @@ #define XILINX_LOCK_KEY 0x767b #define XILINX_UNLOCK_KEY 0xdf0d =20 -#define R_PSS_RST_CTRL_SOFT_RST 0x1 +REG32(SCL, 0x000) +REG32(LOCK, 0x004) +REG32(UNLOCK, 0x008) +REG32(LOCKSTA, 0x00c) =20 -enum { - SCL =3D 0x000 / 4, - LOCK, - UNLOCK, - LOCKSTA, +REG32(ARM_PLL_CTRL, 0x100) +REG32(DDR_PLL_CTRL, 0x104) +REG32(IO_PLL_CTRL, 0x108) +REG32(PLL_STATUS, 0x10c) +REG32(ARM_PLL_CFG, 0x110) +REG32(DDR_PLL_CFG, 0x114) +REG32(IO_PLL_CFG, 0x118) =20 - ARM_PLL_CTRL =3D 0x100 / 4, - DDR_PLL_CTRL, - IO_PLL_CTRL, - PLL_STATUS, - ARM_PLL_CFG, - DDR_PLL_CFG, - IO_PLL_CFG, - - ARM_CLK_CTRL =3D 0x120 / 4, - DDR_CLK_CTRL, - DCI_CLK_CTRL, - APER_CLK_CTRL, - USB0_CLK_CTRL, - USB1_CLK_CTRL, - GEM0_RCLK_CTRL, - GEM1_RCLK_CTRL, - GEM0_CLK_CTRL, - GEM1_CLK_CTRL, - SMC_CLK_CTRL, - LQSPI_CLK_CTRL, - SDIO_CLK_CTRL, - UART_CLK_CTRL, - SPI_CLK_CTRL, - CAN_CLK_CTRL, - CAN_MIOCLK_CTRL, - DBG_CLK_CTRL, - PCAP_CLK_CTRL, - TOPSW_CLK_CTRL, +REG32(ARM_CLK_CTRL, 0x120) +REG32(DDR_CLK_CTRL, 0x124) +REG32(DCI_CLK_CTRL, 0x128) +REG32(APER_CLK_CTRL, 0x12c) +REG32(USB0_CLK_CTRL, 0x130) +REG32(USB1_CLK_CTRL, 0x134) +REG32(GEM0_RCLK_CTRL, 0x138) +REG32(GEM1_RCLK_CTRL, 0x13c) +REG32(GEM0_CLK_CTRL, 0x140) +REG32(GEM1_CLK_CTRL, 0x144) +REG32(SMC_CLK_CTRL, 0x148) +REG32(LQSPI_CLK_CTRL, 0x14c) +REG32(SDIO_CLK_CTRL, 0x150) +REG32(UART_CLK_CTRL, 0x154) +REG32(SPI_CLK_CTRL, 0x158) +REG32(CAN_CLK_CTRL, 0x15c) +REG32(CAN_MIOCLK_CTRL, 0x160) +REG32(DBG_CLK_CTRL, 0x164) +REG32(PCAP_CLK_CTRL, 0x168) +REG32(TOPSW_CLK_CTRL, 0x16c) =20 #define FPGA_CTRL_REGS(n, start) \ - FPGA ## n ## _CLK_CTRL =3D (start) / 4, \ - FPGA ## n ## _THR_CTRL, \ - FPGA ## n ## _THR_CNT, \ - FPGA ## n ## _THR_STA, - FPGA_CTRL_REGS(0, 0x170) - FPGA_CTRL_REGS(1, 0x180) - FPGA_CTRL_REGS(2, 0x190) - FPGA_CTRL_REGS(3, 0x1a0) - - BANDGAP_TRIP =3D 0x1b8 / 4, - PLL_PREDIVISOR =3D 0x1c0 / 4, - CLK_621_TRUE, - - PSS_RST_CTRL =3D 0x200 / 4, - DDR_RST_CTRL, - TOPSW_RESET_CTRL, - DMAC_RST_CTRL, - USB_RST_CTRL, - GEM_RST_CTRL, - SDIO_RST_CTRL, - SPI_RST_CTRL, - CAN_RST_CTRL, - I2C_RST_CTRL, - UART_RST_CTRL, - GPIO_RST_CTRL, - LQSPI_RST_CTRL, - SMC_RST_CTRL, - OCM_RST_CTRL, - FPGA_RST_CTRL =3D 0x240 / 4, - A9_CPU_RST_CTRL, - - RS_AWDT_CTRL =3D 0x24c / 4, - RST_REASON, - - REBOOT_STATUS =3D 0x258 / 4, - BOOT_MODE, - - APU_CTRL =3D 0x300 / 4, - WDT_CLK_SEL, - - TZ_DMA_NS =3D 0x440 / 4, - TZ_DMA_IRQ_NS, - TZ_DMA_PERIPH_NS, - - PSS_IDCODE =3D 0x530 / 4, - - DDR_URGENT =3D 0x600 / 4, - DDR_CAL_START =3D 0x60c / 4, - DDR_REF_START =3D 0x614 / 4, - DDR_CMD_STA, - DDR_URGENT_SEL, - DDR_DFI_STATUS, - - MIO =3D 0x700 / 4, + REG32(FPGA ## n ## _CLK_CTRL, (start)) \ + REG32(FPGA ## n ## _THR_CTRL, (start) + 0x4)\ + REG32(FPGA ## n ## _THR_CNT, (start) + 0x8)\ + REG32(FPGA ## n ## _THR_STA, (start) + 0xc) +FPGA_CTRL_REGS(0, 0x170) +FPGA_CTRL_REGS(1, 0x180) +FPGA_CTRL_REGS(2, 0x190) +FPGA_CTRL_REGS(3, 0x1a0) + +REG32(BANDGAP_TRIP, 0x1b8) +REG32(PLL_PREDIVISOR, 0x1c0) +REG32(CLK_621_TRUE, 0x1c4) + +REG32(PSS_RST_CTRL, 0x200) + FIELD(PSS_RST_CTRL, SOFT_RST, 0, 1) +REG32(DDR_RST_CTRL, 0x204) +REG32(TOPSW_RESET_CTRL, 0x208) +REG32(DMAC_RST_CTRL, 0x20c) +REG32(USB_RST_CTRL, 0x210) +REG32(GEM_RST_CTRL, 0x214) +REG32(SDIO_RST_CTRL, 0x218) +REG32(SPI_RST_CTRL, 0x21c) +REG32(CAN_RST_CTRL, 0x220) +REG32(I2C_RST_CTRL, 0x224) +REG32(UART_RST_CTRL, 0x228) +REG32(GPIO_RST_CTRL, 0x22c) +REG32(LQSPI_RST_CTRL, 0x230) +REG32(SMC_RST_CTRL, 0x234) +REG32(OCM_RST_CTRL, 0x238) +REG32(FPGA_RST_CTRL, 0x240) +REG32(A9_CPU_RST_CTRL, 0x244) + +REG32(RS_AWDT_CTRL, 0x24c) +REG32(RST_REASON, 0x250) + +REG32(REBOOT_STATUS, 0x258) +REG32(BOOT_MODE, 0x25c) + +REG32(APU_CTRL, 0x300) +REG32(WDT_CLK_SEL, 0x304) + +REG32(TZ_DMA_NS, 0x440) +REG32(TZ_DMA_IRQ_NS, 0x444) +REG32(TZ_DMA_PERIPH_NS, 0x448) + +REG32(PSS_IDCODE, 0x530) + +REG32(DDR_URGENT, 0x600) +REG32(DDR_CAL_START, 0x60c) +REG32(DDR_REF_START, 0x614) +REG32(DDR_CMD_STA, 0x618) +REG32(DDR_URGENT_SEL, 0x61c) +REG32(DDR_DFI_STATUS, 0x620) + +REG32(MIO, 0x700) #define MIO_LENGTH 54 =20 - MIO_LOOPBACK =3D 0x804 / 4, - MIO_MST_TRI0, - MIO_MST_TRI1, +REG32(MIO_LOOPBACK, 0x804) +REG32(MIO_MST_TRI0, 0x808) +REG32(MIO_MST_TRI1, 0x80c) =20 - SD0_WP_CD_SEL =3D 0x830 / 4, - SD1_WP_CD_SEL, +REG32(SD0_WP_CD_SEL, 0x830) +REG32(SD1_WP_CD_SEL, 0x834) =20 - LVL_SHFTR_EN =3D 0x900 / 4, - OCM_CFG =3D 0x910 / 4, +REG32(LVL_SHFTR_EN, 0x900) +REG32(OCM_CFG, 0x910) =20 - CPU_RAM =3D 0xa00 / 4, +REG32(CPU_RAM, 0xa00) =20 - IOU =3D 0xa30 / 4, +REG32(IOU, 0xa30) =20 - DMAC_RAM =3D 0xa50 / 4, +REG32(DMAC_RAM, 0xa50) =20 - AFI0 =3D 0xa60 / 4, - AFI1 =3D AFI0 + 3, - AFI2 =3D AFI1 + 3, - AFI3 =3D AFI2 + 3, +REG32(AFI0, 0xa60) +REG32(AFI1, 0xa6c) +REG32(AFI2, 0xa78) +REG32(AFI3, 0xa84) #define AFI_LENGTH 3 =20 - OCM =3D 0xa90 / 4, +REG32(OCM, 0xa90) =20 - DEVCI_RAM =3D 0xaa0 / 4, +REG32(DEVCI_RAM, 0xaa0) =20 - CSG_RAM =3D 0xab0 / 4, +REG32(CSG_RAM, 0xab0) =20 - GPIOB_CTRL =3D 0xb00 / 4, - GPIOB_CFG_CMOS18, - GPIOB_CFG_CMOS25, - GPIOB_CFG_CMOS33, - GPIOB_CFG_HSTL =3D 0xb14 / 4, - GPIOB_DRVR_BIAS_CTRL, +REG32(GPIOB_CTRL, 0xb00) +REG32(GPIOB_CFG_CMOS18, 0xb04) +REG32(GPIOB_CFG_CMOS25, 0xb08) +REG32(GPIOB_CFG_CMOS33, 0xb0c) +REG32(GPIOB_CFG_HSTL, 0xb14) +REG32(GPIOB_DRVR_BIAS_CTRL, 0xb18) =20 - DDRIOB =3D 0xb40 / 4, +REG32(DDRIOB, 0xb40) #define DDRIOB_LENGTH 14 -}; =20 #define ZYNQ_SLCR_MMIO_SIZE 0x1000 #define ZYNQ_SLCR_NUM_REGS (ZYNQ_SLCR_MMIO_SIZE / 4) @@ -189,150 +187,152 @@ static void zynq_slcr_reset(DeviceState *d) =20 DB_PRINT("RESET\n"); =20 - s->regs[LOCKSTA] =3D 1; + s->regs[R_LOCKSTA] =3D 1; /* 0x100 - 0x11C */ - s->regs[ARM_PLL_CTRL] =3D 0x0001A008; - s->regs[DDR_PLL_CTRL] =3D 0x0001A008; - s->regs[IO_PLL_CTRL] =3D 0x0001A008; - s->regs[PLL_STATUS] =3D 0x0000003F; - s->regs[ARM_PLL_CFG] =3D 0x00014000; - s->regs[DDR_PLL_CFG] =3D 0x00014000; - s->regs[IO_PLL_CFG] =3D 0x00014000; + s->regs[R_ARM_PLL_CTRL] =3D 0x0001A008; + s->regs[R_DDR_PLL_CTRL] =3D 0x0001A008; + s->regs[R_IO_PLL_CTRL] =3D 0x0001A008; + s->regs[R_PLL_STATUS] =3D 0x0000003F; + s->regs[R_ARM_PLL_CFG] =3D 0x00014000; + s->regs[R_DDR_PLL_CFG] =3D 0x00014000; + s->regs[R_IO_PLL_CFG] =3D 0x00014000; =20 /* 0x120 - 0x16C */ - s->regs[ARM_CLK_CTRL] =3D 0x1F000400; - s->regs[DDR_CLK_CTRL] =3D 0x18400003; - s->regs[DCI_CLK_CTRL] =3D 0x01E03201; - s->regs[APER_CLK_CTRL] =3D 0x01FFCCCD; - s->regs[USB0_CLK_CTRL] =3D s->regs[USB1_CLK_CTRL] =3D 0x00101941; - s->regs[GEM0_RCLK_CTRL] =3D s->regs[GEM1_RCLK_CTRL] =3D 0x00000001; - s->regs[GEM0_CLK_CTRL] =3D s->regs[GEM1_CLK_CTRL] =3D 0x00003C01; - s->regs[SMC_CLK_CTRL] =3D 0x00003C01; - s->regs[LQSPI_CLK_CTRL] =3D 0x00002821; - s->regs[SDIO_CLK_CTRL] =3D 0x00001E03; - s->regs[UART_CLK_CTRL] =3D 0x00003F03; - s->regs[SPI_CLK_CTRL] =3D 0x00003F03; - s->regs[CAN_CLK_CTRL] =3D 0x00501903; - s->regs[DBG_CLK_CTRL] =3D 0x00000F03; - s->regs[PCAP_CLK_CTRL] =3D 0x00000F01; + s->regs[R_ARM_CLK_CTRL] =3D 0x1F000400; + s->regs[R_DDR_CLK_CTRL] =3D 0x18400003; + s->regs[R_DCI_CLK_CTRL] =3D 0x01E03201; + s->regs[R_APER_CLK_CTRL] =3D 0x01FFCCCD; + s->regs[R_USB0_CLK_CTRL] =3D s->regs[R_USB1_CLK_CTRL] =3D 0x00101941; + s->regs[R_GEM0_RCLK_CTRL] =3D s->regs[R_GEM1_RCLK_CTRL] =3D 0x00000001; + s->regs[R_GEM0_CLK_CTRL] =3D s->regs[R_GEM1_CLK_CTRL] =3D 0x00003C01; + s->regs[R_SMC_CLK_CTRL] =3D 0x00003C01; + s->regs[R_LQSPI_CLK_CTRL] =3D 0x00002821; + s->regs[R_SDIO_CLK_CTRL] =3D 0x00001E03; + s->regs[R_UART_CLK_CTRL] =3D 0x00003F03; + s->regs[R_SPI_CLK_CTRL] =3D 0x00003F03; + s->regs[R_CAN_CLK_CTRL] =3D 0x00501903; + s->regs[R_DBG_CLK_CTRL] =3D 0x00000F03; + s->regs[R_PCAP_CLK_CTRL] =3D 0x00000F01; =20 /* 0x170 - 0x1AC */ - s->regs[FPGA0_CLK_CTRL] =3D s->regs[FPGA1_CLK_CTRL] =3D s->regs[FPGA2_= CLK_CTRL] - =3D s->regs[FPGA3_CLK_CTRL] =3D 0x00101800; - s->regs[FPGA0_THR_STA] =3D s->regs[FPGA1_THR_STA] =3D s->regs[FPGA2_TH= R_STA] - =3D s->regs[FPGA3_THR_STA] =3D 0x00010000; + s->regs[R_FPGA0_CLK_CTRL] =3D s->regs[R_FPGA1_CLK_CTRL] + =3D s->regs[R_FPGA2_CLK_CTRL] + =3D s->regs[R_FPGA3_CLK_CTRL] =3D 0x00101800; + s->regs[R_FPGA0_THR_STA] =3D s->regs[R_FPGA1_THR_STA] + =3D s->regs[R_FPGA2_THR_STA] + =3D s->regs[R_FPGA3_THR_STA] =3D 0x00010000; =20 /* 0x1B0 - 0x1D8 */ - s->regs[BANDGAP_TRIP] =3D 0x0000001F; - s->regs[PLL_PREDIVISOR] =3D 0x00000001; - s->regs[CLK_621_TRUE] =3D 0x00000001; + s->regs[R_BANDGAP_TRIP] =3D 0x0000001F; + s->regs[R_PLL_PREDIVISOR] =3D 0x00000001; + s->regs[R_CLK_621_TRUE] =3D 0x00000001; =20 /* 0x200 - 0x25C */ - s->regs[FPGA_RST_CTRL] =3D 0x01F33F0F; - s->regs[RST_REASON] =3D 0x00000040; + s->regs[R_FPGA_RST_CTRL] =3D 0x01F33F0F; + s->regs[R_RST_REASON] =3D 0x00000040; =20 - s->regs[BOOT_MODE] =3D 0x00000001; + s->regs[R_BOOT_MODE] =3D 0x00000001; =20 /* 0x700 - 0x7D4 */ for (i =3D 0; i < 54; i++) { - s->regs[MIO + i] =3D 0x00001601; + s->regs[R_MIO + i] =3D 0x00001601; } for (i =3D 2; i <=3D 8; i++) { - s->regs[MIO + i] =3D 0x00000601; + s->regs[R_MIO + i] =3D 0x00000601; } =20 - s->regs[MIO_MST_TRI0] =3D s->regs[MIO_MST_TRI1] =3D 0xFFFFFFFF; + s->regs[R_MIO_MST_TRI0] =3D s->regs[R_MIO_MST_TRI1] =3D 0xFFFFFFFF; =20 - s->regs[CPU_RAM + 0] =3D s->regs[CPU_RAM + 1] =3D s->regs[CPU_RAM + 3] - =3D s->regs[CPU_RAM + 4] =3D s->regs[CPU_RAM + 7] - =3D 0x00010101; - s->regs[CPU_RAM + 2] =3D s->regs[CPU_RAM + 5] =3D 0x01010101; - s->regs[CPU_RAM + 6] =3D 0x00000001; + s->regs[R_CPU_RAM + 0] =3D s->regs[R_CPU_RAM + 1] =3D s->regs[R_CPU_RA= M + 3] + =3D s->regs[R_CPU_RAM + 4] =3D s->regs[R_CPU_RA= M + 7] + =3D 0x00010101; + s->regs[R_CPU_RAM + 2] =3D s->regs[R_CPU_RAM + 5] =3D 0x01010101; + s->regs[R_CPU_RAM + 6] =3D 0x00000001; =20 - s->regs[IOU + 0] =3D s->regs[IOU + 1] =3D s->regs[IOU + 2] =3D s->regs= [IOU + 3] - =3D 0x09090909; - s->regs[IOU + 4] =3D s->regs[IOU + 5] =3D 0x00090909; - s->regs[IOU + 6] =3D 0x00000909; + s->regs[R_IOU + 0] =3D s->regs[R_IOU + 1] =3D s->regs[R_IOU + 2] + =3D s->regs[R_IOU + 3] =3D 0x09090909; + s->regs[R_IOU + 4] =3D s->regs[R_IOU + 5] =3D 0x00090909; + s->regs[R_IOU + 6] =3D 0x00000909; =20 - s->regs[DMAC_RAM] =3D 0x00000009; + s->regs[R_DMAC_RAM] =3D 0x00000009; =20 - s->regs[AFI0 + 0] =3D s->regs[AFI0 + 1] =3D 0x09090909; - s->regs[AFI1 + 0] =3D s->regs[AFI1 + 1] =3D 0x09090909; - s->regs[AFI2 + 0] =3D s->regs[AFI2 + 1] =3D 0x09090909; - s->regs[AFI3 + 0] =3D s->regs[AFI3 + 1] =3D 0x09090909; - s->regs[AFI0 + 2] =3D s->regs[AFI1 + 2] =3D s->regs[AFI2 + 2] - =3D s->regs[AFI3 + 2] =3D 0x00000909; + s->regs[R_AFI0 + 0] =3D s->regs[R_AFI0 + 1] =3D 0x09090909; + s->regs[R_AFI1 + 0] =3D s->regs[R_AFI1 + 1] =3D 0x09090909; + s->regs[R_AFI2 + 0] =3D s->regs[R_AFI2 + 1] =3D 0x09090909; + s->regs[R_AFI3 + 0] =3D s->regs[R_AFI3 + 1] =3D 0x09090909; + s->regs[R_AFI0 + 2] =3D s->regs[R_AFI1 + 2] =3D s->regs[R_AFI2 + 2] + =3D s->regs[R_AFI3 + 2] =3D 0x00000909; =20 - s->regs[OCM + 0] =3D 0x01010101; - s->regs[OCM + 1] =3D s->regs[OCM + 2] =3D 0x09090909; + s->regs[R_OCM + 0] =3D 0x01010101; + s->regs[R_OCM + 1] =3D s->regs[R_OCM + 2] =3D 0x09090909; =20 - s->regs[DEVCI_RAM] =3D 0x00000909; - s->regs[CSG_RAM] =3D 0x00000001; + s->regs[R_DEVCI_RAM] =3D 0x00000909; + s->regs[R_CSG_RAM] =3D 0x00000001; =20 - s->regs[DDRIOB + 0] =3D s->regs[DDRIOB + 1] =3D s->regs[DDRIOB + 2] - =3D s->regs[DDRIOB + 3] =3D 0x00000e00; - s->regs[DDRIOB + 4] =3D s->regs[DDRIOB + 5] =3D s->regs[DDRIOB + 6] - =3D 0x00000e00; - s->regs[DDRIOB + 12] =3D 0x00000021; + s->regs[R_DDRIOB + 0] =3D s->regs[R_DDRIOB + 1] =3D s->regs[R_DDRIOB += 2] + =3D s->regs[R_DDRIOB + 3] =3D 0x00000e00; + s->regs[R_DDRIOB + 4] =3D s->regs[R_DDRIOB + 5] =3D s->regs[R_DDRIOB += 6] + =3D 0x00000e00; + s->regs[R_DDRIOB + 12] =3D 0x00000021; } =20 =20 static bool zynq_slcr_check_offset(hwaddr offset, bool rnw) { switch (offset) { - case LOCK: - case UNLOCK: - case DDR_CAL_START: - case DDR_REF_START: + case R_LOCK: + case R_UNLOCK: + case R_DDR_CAL_START: + case R_DDR_REF_START: return !rnw; /* Write only */ - case LOCKSTA: - case FPGA0_THR_STA: - case FPGA1_THR_STA: - case FPGA2_THR_STA: - case FPGA3_THR_STA: - case BOOT_MODE: - case PSS_IDCODE: - case DDR_CMD_STA: - case DDR_DFI_STATUS: - case PLL_STATUS: + case R_LOCKSTA: + case R_FPGA0_THR_STA: + case R_FPGA1_THR_STA: + case R_FPGA2_THR_STA: + case R_FPGA3_THR_STA: + case R_BOOT_MODE: + case R_PSS_IDCODE: + case R_DDR_CMD_STA: + case R_DDR_DFI_STATUS: + case R_PLL_STATUS: return rnw;/* read only */ - case SCL: - case ARM_PLL_CTRL ... IO_PLL_CTRL: - case ARM_PLL_CFG ... IO_PLL_CFG: - case ARM_CLK_CTRL ... TOPSW_CLK_CTRL: - case FPGA0_CLK_CTRL ... FPGA0_THR_CNT: - case FPGA1_CLK_CTRL ... FPGA1_THR_CNT: - case FPGA2_CLK_CTRL ... FPGA2_THR_CNT: - case FPGA3_CLK_CTRL ... FPGA3_THR_CNT: - case BANDGAP_TRIP: - case PLL_PREDIVISOR: - case CLK_621_TRUE: - case PSS_RST_CTRL ... A9_CPU_RST_CTRL: - case RS_AWDT_CTRL: - case RST_REASON: - case REBOOT_STATUS: - case APU_CTRL: - case WDT_CLK_SEL: - case TZ_DMA_NS ... TZ_DMA_PERIPH_NS: - case DDR_URGENT: - case DDR_URGENT_SEL: - case MIO ... MIO + MIO_LENGTH - 1: - case MIO_LOOPBACK ... MIO_MST_TRI1: - case SD0_WP_CD_SEL: - case SD1_WP_CD_SEL: - case LVL_SHFTR_EN: - case OCM_CFG: - case CPU_RAM: - case IOU: - case DMAC_RAM: - case AFI0 ... AFI3 + AFI_LENGTH - 1: - case OCM: - case DEVCI_RAM: - case CSG_RAM: - case GPIOB_CTRL ... GPIOB_CFG_CMOS33: - case GPIOB_CFG_HSTL: - case GPIOB_DRVR_BIAS_CTRL: - case DDRIOB ... DDRIOB + DDRIOB_LENGTH - 1: + case R_SCL: + case R_ARM_PLL_CTRL ... R_IO_PLL_CTRL: + case R_ARM_PLL_CFG ... R_IO_PLL_CFG: + case R_ARM_CLK_CTRL ... R_TOPSW_CLK_CTRL: + case R_FPGA0_CLK_CTRL ... R_FPGA0_THR_CNT: + case R_FPGA1_CLK_CTRL ... R_FPGA1_THR_CNT: + case R_FPGA2_CLK_CTRL ... R_FPGA2_THR_CNT: + case R_FPGA3_CLK_CTRL ... R_FPGA3_THR_CNT: + case R_BANDGAP_TRIP: + case R_PLL_PREDIVISOR: + case R_CLK_621_TRUE: + case R_PSS_RST_CTRL ... R_A9_CPU_RST_CTRL: + case R_RS_AWDT_CTRL: + case R_RST_REASON: + case R_REBOOT_STATUS: + case R_APU_CTRL: + case R_WDT_CLK_SEL: + case R_TZ_DMA_NS ... R_TZ_DMA_PERIPH_NS: + case R_DDR_URGENT: + case R_DDR_URGENT_SEL: + case R_MIO ... R_MIO + MIO_LENGTH - 1: + case R_MIO_LOOPBACK ... R_MIO_MST_TRI1: + case R_SD0_WP_CD_SEL: + case R_SD1_WP_CD_SEL: + case R_LVL_SHFTR_EN: + case R_OCM_CFG: + case R_CPU_RAM: + case R_IOU: + case R_DMAC_RAM: + case R_AFI0 ... R_AFI3 + AFI_LENGTH - 1: + case R_OCM: + case R_DEVCI_RAM: + case R_CSG_RAM: + case R_GPIOB_CTRL ... R_GPIOB_CFG_CMOS33: + case R_GPIOB_CFG_HSTL: + case R_GPIOB_DRVR_BIAS_CTRL: + case R_DDRIOB ... R_DDRIOB + DDRIOB_LENGTH - 1: return true; default: return false; @@ -370,24 +370,24 @@ static void zynq_slcr_write(void *opaque, hwaddr offs= et, } =20 switch (offset) { - case SCL: - s->regs[SCL] =3D val & 0x1; + case R_SCL: + s->regs[R_SCL] =3D val & 0x1; return; - case LOCK: + case R_LOCK: if ((val & 0xFFFF) =3D=3D XILINX_LOCK_KEY) { DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <=3D 0x%x\n", (int)off= set, (unsigned)val & 0xFFFF); - s->regs[LOCKSTA] =3D 1; + s->regs[R_LOCKSTA] =3D 1; } else { DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <=3D 0x%x\n", (int)offset, (unsigned)val & 0xFFFF); } return; - case UNLOCK: + case R_UNLOCK: if ((val & 0xFFFF) =3D=3D XILINX_UNLOCK_KEY) { DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <=3D 0x%x\n", (int)o= ffset, (unsigned)val & 0xFFFF); - s->regs[LOCKSTA] =3D 0; + s->regs[R_LOCKSTA] =3D 0; } else { DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <=3D 0x%x\= n", (int)offset, (unsigned)val & 0xFFFF); @@ -395,7 +395,7 @@ static void zynq_slcr_write(void *opaque, hwaddr offset, return; } =20 - if (s->regs[LOCKSTA]) { + if (s->regs[R_LOCKSTA]) { qemu_log_mask(LOG_GUEST_ERROR, "SCLR registers are locked. Unlock them first\n"); return; @@ -403,8 +403,8 @@ static void zynq_slcr_write(void *opaque, hwaddr offset, s->regs[offset] =3D val; =20 switch (offset) { - case PSS_RST_CTRL: - if (val & R_PSS_RST_CTRL_SOFT_RST) { + case R_PSS_RST_CTRL: + if (FIELD_EX32(val, PSS_RST_CTRL, SOFT_RST)) { qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); } break; --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491683541912.2951280674173; Tue, 2 Oct 2018 07:48:03 -0700 (PDT) Received: from localhost ([::1]:44081 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lxy-0006hl-Co for importer@patchew.org; Tue, 02 Oct 2018 10:48:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46875) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmw-0005M2-6a for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004QG-Jl for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:36 -0400 Received: from greensocs.com ([193.104.36.180]:53911) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Ld9-0004NQ-BH; Tue, 02 Oct 2018 10:26:31 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 20EF8442AFE; Tue, 2 Oct 2018 16:26:09 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HsvnHnJSm217; Tue, 2 Oct 2018 16:26:08 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id E5632442AFB; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 84E28442AF5; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490369; bh=VvrCjrQ6nDV4DTsIfLOBQX1PCDnPhRmn/LhGmHMbJEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=fQRT3732GoxBZYYZh/R8xpjWmB7Nz/bHhvtMYq+4LD8mQvHcGrqlmDt/J0WBXOgzU mnC5YrdVglK7unRoIJJC0t6PIo/wi68J+KlzXjNec7vN+YFg/flbHT4RkNrlAcPuGc c0Poq9MQkHZp7OSe6PgPcB8gh2ze4tCHThDZCRUQ= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=AOZMrePj; dkim=pass (1024-bit key) header.d=greensocs.com header.b=AOZMrePj DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490366; bh=VvrCjrQ6nDV4DTsIfLOBQX1PCDnPhRmn/LhGmHMbJEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=AOZMrePjCy+fQAKA5ITOt0Kh7+3q1hToOMY/DAk9GKphRzh0FmgyULzJaH0u1KiUi TW6Bot2R0DVOEHdTS8iUrnTM1QUVXeZen2q6Q00oIpkdMqhAPTP9bdB7lyBfk9vC2R gflDx28yETYluTylnaUHwO8K8NlRHeXuYK7Hjz9s= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490366; bh=VvrCjrQ6nDV4DTsIfLOBQX1PCDnPhRmn/LhGmHMbJEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=AOZMrePjCy+fQAKA5ITOt0Kh7+3q1hToOMY/DAk9GKphRzh0FmgyULzJaH0u1KiUi TW6Bot2R0DVOEHdTS8iUrnTM1QUVXeZen2q6Q00oIpkdMqhAPTP9bdB7lyBfk9vC2R gflDx28yETYluTylnaUHwO8K8NlRHeXuYK7Hjz9s= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:41 +0200 Message-Id: <20181002142443.30976-8-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 7/9] hw/misc/zynq_slcr: add clock generation for uarts X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add 2 clock outputs for each uart (uart0 & 1): + the reference clock + the bus interface clock The clock frequencies are computed using the internal pll & uart configurat= ion registers. All clocks depend on the main input clock (ps_clk), which is hard-coded to 33.33MHz (zcu102 evaluation board frequency and frequency specified in Xilinx's device tree file) Signed-off-by: Damien Hedde --- hw/misc/zynq_slcr.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c index baa13d1316..0b599ebd97 100644 --- a/hw/misc/zynq_slcr.c +++ b/hw/misc/zynq_slcr.c @@ -33,6 +33,8 @@ } \ } while (0) =20 +#define INPUT_PS_REF_CLK_FREQUENCY (33333333) + #define XILINX_LOCK_KEY 0x767b #define XILINX_UNLOCK_KEY 0xdf0d =20 @@ -44,15 +46,27 @@ REG32(LOCKSTA, 0x00c) REG32(ARM_PLL_CTRL, 0x100) REG32(DDR_PLL_CTRL, 0x104) REG32(IO_PLL_CTRL, 0x108) +/* fields for [ARM|DDR|IO_PLL]_CTRL registers */ + FIELD(xxx_PLL_CTRL, PLL_RESET, 0, 1) + FIELD(xxx_PLL_CTRL, PLL_PWRDWN, 1, 1) + FIELD(xxx_PLL_CTRL, PLL_BYPASS_QUAL, 3, 1) + FIELD(xxx_PLL_CTRL, PLL_BYPASS_FORCE, 4, 1) + FIELD(xxx_PLL_CTRL, PLL_FPDIV, 12, 7) REG32(PLL_STATUS, 0x10c) REG32(ARM_PLL_CFG, 0x110) REG32(DDR_PLL_CFG, 0x114) REG32(IO_PLL_CFG, 0x118) =20 REG32(ARM_CLK_CTRL, 0x120) + FIELD(ARM_CLK_CTRL, SRCSEL, 4, 2) + FIELD(ARM_CLK_CTRL, DIVISOR, 8, 6) + FIELD(ARM_CLK_CTRL, CPU_1XCLKACT, 27, 1) + FIELD(ARM_CLK_CTRL, CPU_PERI_CLKACT, 28, 1) REG32(DDR_CLK_CTRL, 0x124) REG32(DCI_CLK_CTRL, 0x128) REG32(APER_CLK_CTRL, 0x12c) + FIELD(APER_CLK_CTRL, UART0_CPU1XCLKACT, 20, 1) + FIELD(APER_CLK_CTRL, UART1_CPU1XCLKACT, 21, 1) REG32(USB0_CLK_CTRL, 0x130) REG32(USB1_CLK_CTRL, 0x134) REG32(GEM0_RCLK_CTRL, 0x138) @@ -63,12 +77,19 @@ REG32(SMC_CLK_CTRL, 0x148) REG32(LQSPI_CLK_CTRL, 0x14c) REG32(SDIO_CLK_CTRL, 0x150) REG32(UART_CLK_CTRL, 0x154) + FIELD(UART_CLK_CTRL, CLKACT0, 0, 1) + FIELD(UART_CLK_CTRL, CLKACT1, 1, 1) + FIELD(UART_CLK_CTRL, SRCSEL, 4, 2) + FIELD(UART_CLK_CTRL, DIVISOR, 8, 6) REG32(SPI_CLK_CTRL, 0x158) REG32(CAN_CLK_CTRL, 0x15c) REG32(CAN_MIOCLK_CTRL, 0x160) REG32(DBG_CLK_CTRL, 0x164) REG32(PCAP_CLK_CTRL, 0x168) REG32(TOPSW_CLK_CTRL, 0x16c) +/* common fields to lots of *_CLK_CTRL registers */ + FIELD(xxx_CLK_CTRL, SRCSEL, 4, 2) + FIELD(xxx_CLK_CTRL, DIVISOR, 8, 6) =20 #define FPGA_CTRL_REGS(n, start) \ REG32(FPGA ## n ## _CLK_CTRL, (start)) \ @@ -178,8 +199,92 @@ typedef struct ZynqSLCRState { MemoryRegion iomem; =20 uint32_t regs[ZYNQ_SLCR_NUM_REGS]; + + ClockOut *uart0_amba_clk; + ClockOut *uart1_amba_clk; + ClockOut *uart0_ref_clk; + ClockOut *uart1_ref_clk; } ZynqSLCRState; =20 +/* + * return the output frequency of ARM/DDR/IO pll + * using input frequency and PLL_CTRL register + */ +static uint64_t zynq_slcr_compute_pll(uint64_t input, uint32_t ctrl_reg) +{ + uint32_t mult =3D ((ctrl_reg & R_xxx_PLL_CTRL_PLL_FPDIV_MASK) >> + R_xxx_PLL_CTRL_PLL_FPDIV_SHIFT); + + /* first, check if pll is bypassed */ + if (ctrl_reg & R_xxx_PLL_CTRL_PLL_BYPASS_FORCE_MASK) { + return input; + } + + /* is pll disabled ? */ + if (ctrl_reg & (R_xxx_PLL_CTRL_PLL_RESET_MASK | + R_xxx_PLL_CTRL_PLL_PWRDWN_MASK)) { + return 0; + } + + return input * mult; +} + +/* + * return the output frequency of a clock given: + * + the pll's frequencies in an array corresponding to mux's indexes + * + the register xxx_CLK_CTRL value + * + enable bit index in ctrl register + * + * This function make the assumption that ctrl_reg value is organized as f= ollow: + * + bits[13:8] clock divisor + * + bits[5:4] clock mux selector (index in array) + * + bits[index] clock enable + */ +static uint64_t zynq_slcr_compute_clock(const uint64_t plls[], + uint32_t ctrl_reg, + unsigned index) +{ + uint32_t divisor =3D FIELD_EX32(ctrl_reg, xxx_CLK_CTRL, DIVISOR); + uint32_t srcsel =3D FIELD_EX32(ctrl_reg, xxx_CLK_CTRL, SRCSEL); + + if ((ctrl_reg & (1u << index)) =3D=3D 0) { + return 0; + } + + return plls[srcsel] / (divisor ? divisor : 1u); +} + +#define ZYNQ_CLOCK(_state, _plls, _reg, _enable_field) \ + zynq_slcr_compute_clock((_plls), (_state)->regs[R_ ## _reg], \ + R_ ## _reg ## _ ## _enable_field ## _SHIFT) +#define ZYNQ_GATE(_state, _clk, _reg, _field) \ + (ARRAY_FIELD_EX32((_state)->regs, _reg, _field) ? (_clk) : 0) + +static void zynq_slcr_compute_clocks(ZynqSLCRState *s) +{ + uint64_t ps_clk =3D INPUT_PS_REF_CLK_FREQUENCY; + uint64_t io_pll =3D zynq_slcr_compute_pll(ps_clk, s->regs[R_IO_PLL_CTR= L]); + uint64_t arm_pll =3D zynq_slcr_compute_pll(ps_clk, s->regs[R_ARM_PLL_C= TRL]); + uint64_t ddr_pll =3D zynq_slcr_compute_pll(ps_clk, s->regs[R_DDR_PLL_C= TRL]); + uint64_t cpu_mux[4] =3D {arm_pll, arm_pll, ddr_pll, io_pll}; + uint64_t uart_mux[4] =3D {io_pll, io_pll, arm_pll, ddr_pll}; + uint64_t cpu1x_clk; + + /* compute uartX amba clocks */ + cpu1x_clk =3D ZYNQ_CLOCK(s, cpu_mux, ARM_CLK_CTRL, CPU_PERI_CLKACT); + cpu1x_clk =3D ZYNQ_GATE(s, cpu1x_clk, ARM_CLK_CTRL, CPU_1XCLKACT); + clock_set_frequency(s->uart0_amba_clk, + ZYNQ_GATE(s, cpu1x_clk, APER_CLK_CTRL, UART0_CPU1XCLKACT)); + clock_set_frequency(s->uart1_amba_clk, + ZYNQ_GATE(s, cpu1x_clk, APER_CLK_CTRL, UART1_CPU1XCLKACT)); + + /* compute uartX ref clocks */ + clock_set_frequency(s->uart0_ref_clk, + ZYNQ_CLOCK(s, uart_mux, UART_CLK_CTRL, CLKACT0)); + clock_set_frequency(s->uart1_ref_clk, + ZYNQ_CLOCK(s, uart_mux, UART_CLK_CTRL, CLKACT1)); +} + static void zynq_slcr_reset(DeviceState *d) { ZynqSLCRState *s =3D ZYNQ_SLCR(d); @@ -274,6 +379,8 @@ static void zynq_slcr_reset(DeviceState *d) s->regs[R_DDRIOB + 4] =3D s->regs[R_DDRIOB + 5] =3D s->regs[R_DDRIOB += 6] =3D 0x00000e00; s->regs[R_DDRIOB + 12] =3D 0x00000021; + + zynq_slcr_compute_clocks(s); } =20 =20 @@ -408,6 +515,14 @@ static void zynq_slcr_write(void *opaque, hwaddr offse= t, qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); } break; + case R_IO_PLL_CTRL: + case R_ARM_PLL_CTRL: + case R_DDR_PLL_CTRL: + case R_ARM_CLK_CTRL: + case R_APER_CLK_CTRL: + case R_UART_CLK_CTRL: + zynq_slcr_compute_clocks(s); + break; } } =20 @@ -417,6 +532,14 @@ static const MemoryRegionOps slcr_ops =3D { .endianness =3D DEVICE_NATIVE_ENDIAN, }; =20 +static const ClockPortInitArray zynq_slcr_clocks =3D { + QDEV_CLOCK_OUT(ZynqSLCRState, uart0_amba_clk), + QDEV_CLOCK_OUT(ZynqSLCRState, uart1_amba_clk), + QDEV_CLOCK_OUT(ZynqSLCRState, uart0_ref_clk), + QDEV_CLOCK_OUT(ZynqSLCRState, uart1_ref_clk), + QDEV_CLOCK_END, +}; + static void zynq_slcr_init(Object *obj) { ZynqSLCRState *s =3D ZYNQ_SLCR(obj); @@ -424,6 +547,8 @@ static void zynq_slcr_init(Object *obj) memory_region_init_io(&s->iomem, obj, &slcr_ops, s, "slcr", ZYNQ_SLCR_MMIO_SIZE); sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem); + + qdev_init_clocks(DEVICE(obj), zynq_slcr_clocks); } =20 static const VMStateDescription vmstate_zynq_slcr =3D { --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491312214927.0125333589816; Tue, 2 Oct 2018 07:41:52 -0700 (PDT) Received: from localhost ([::1]:44039 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lry-0001U9-U2 for importer@patchew.org; Tue, 02 Oct 2018 10:41:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46745) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmp-0005Ih-Hx for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdC-0004Qd-R6 for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:36 -0400 Received: from greensocs.com ([193.104.36.180]:53927) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7LdA-0004OJ-FH; Tue, 02 Oct 2018 10:26:32 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 150FD442AFC; Tue, 2 Oct 2018 16:26:10 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J83g-675ch5X; Tue, 2 Oct 2018 16:26:09 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id 7EB51442AED; Tue, 2 Oct 2018 16:26:07 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id EA803442AF5; Tue, 2 Oct 2018 16:26:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490370; bh=VsGaVmdCLu/Cm9SwiFoAqk3/5TqG8PUFL+m4hD9JGpQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=0FXRAjK+Z1P2zSJB+cT1yHJO54CdUnhcv82qEGHYdEdUX5aPaoZENL3OhQjskn5dA wd96myaeIxXwyvSf8KnRe2wN7sQLE977X+9iS0YNT8L9EeUMSOc9iUZcKYtzuYnCya gaEZrnU0epsFmIUfcdBBKWsefuB6GM78F+UXQImQ= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=giWZYfdb; dkim=pass (1024-bit key) header.d=greensocs.com header.b=giWZYfdb DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490367; bh=VsGaVmdCLu/Cm9SwiFoAqk3/5TqG8PUFL+m4hD9JGpQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=giWZYfdbjbJz72xI0ADvkOI7mR0QGXX1xjvckmiZ7t8DCoXpsJh79jishM68coMXT /KtaadVeHMu2NlJtrWzlBXTH3enGGQvqrPQGwyGiWJNGmZA+Qsek6jTk2UZW5r2k7v kPGZ81Ir5UXhZTkXUilW0k9xi7XH6vS9UVHCAr6c= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490367; bh=VsGaVmdCLu/Cm9SwiFoAqk3/5TqG8PUFL+m4hD9JGpQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=giWZYfdbjbJz72xI0ADvkOI7mR0QGXX1xjvckmiZ7t8DCoXpsJh79jishM68coMXT /KtaadVeHMu2NlJtrWzlBXTH3enGGQvqrPQGwyGiWJNGmZA+Qsek6jTk2UZW5r2k7v kPGZ81Ir5UXhZTkXUilW0k9xi7XH6vS9UVHCAr6c= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:42 +0200 Message-Id: <20181002142443.30976-9-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 8/9] hw/char/cadence_uart: add clock support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add bus interface and uart reference clock inputs. Note: it is hard to find out from the doc what is the behavior when only one of the clock is disabled. The implemented behaviour is that register access needs both clock being ac= tive. The bus interface control the mmios visibility The reference clock controls the baudrate generation. If it disabled, any input characters and events are ignored. Also register accesses are conditioned to the clock being enabled (but is it really the case in reality ?) and a guest error is triggerred if that is not the case. If theses clocks remains unconnected, the uart behaves as before (default to 50MHz ref clock). Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- include/hw/char/cadence_uart.h | 3 ++ hw/char/cadence_uart.c | 92 ++++++++++++++++++++++++++++++++-- hw/char/trace-events | 3 ++ 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h index 118e3f10de..fd1d4725f4 100644 --- a/include/hw/char/cadence_uart.h +++ b/include/hw/char/cadence_uart.h @@ -21,6 +21,7 @@ #include "hw/sysbus.h" #include "chardev/char-fe.h" #include "qemu/timer.h" +#include "hw/clock-port.h" =20 #define CADENCE_UART_RX_FIFO_SIZE 16 #define CADENCE_UART_TX_FIFO_SIZE 16 @@ -47,6 +48,8 @@ typedef struct { CharBackend chr; qemu_irq irq; QEMUTimer *fifo_trigger_handle; + ClockIn *refclk; + ClockIn *busclk; } CadenceUARTState; =20 static inline DeviceState *cadence_uart_create(hwaddr addr, diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index fbdbd463bb..feb5cee4d7 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -28,6 +28,7 @@ #include "qemu/timer.h" #include "qemu/log.h" #include "hw/char/cadence_uart.h" +#include "trace.h" =20 #ifdef CADENCE_UART_ERR_DEBUG #define DB_PRINT(...) do { \ @@ -94,7 +95,7 @@ #define LOCAL_LOOPBACK (0x2 << UART_MR_CHMODE_SH) #define REMOTE_LOOPBACK (0x3 << UART_MR_CHMODE_SH) =20 -#define UART_INPUT_CLK 50000000 +#define UART_DEFAULT_REF_CLK (50 * 1000 * 1000) =20 #define R_CR (0x00/4) #define R_MR (0x04/4) @@ -165,15 +166,30 @@ static void uart_send_breaks(CadenceUARTState *s) &break_enabled); } =20 +static unsigned int uart_input_clk(CadenceUARTState *s) +{ + return clock_get_frequency(s->refclk); +} + static void uart_parameters_setup(CadenceUARTState *s) { QEMUSerialSetParams ssp; unsigned int baud_rate, packet_size; =20 baud_rate =3D (s->r[R_MR] & UART_MR_CLKS) ? - UART_INPUT_CLK / 8 : UART_INPUT_CLK; + uart_input_clk(s) / 8 : uart_input_clk(s); + baud_rate /=3D (s->r[R_BRGR] * (s->r[R_BDIV] + 1)); + trace_cadence_uart_baudrate(baud_rate); + + ssp.speed =3D baud_rate; + if (ssp.speed =3D=3D 0) { + /* + * Avoid division-by-zero below. + * TODO: find something better + */ + ssp.speed =3D 1; + } =20 - ssp.speed =3D baud_rate / (s->r[R_BRGR] * (s->r[R_BDIV] + 1)); packet_size =3D 1; =20 switch (s->r[R_MR] & UART_MR_PAR) { @@ -337,6 +353,11 @@ static void uart_receive(void *opaque, const uint8_t *= buf, int size) CadenceUARTState *s =3D opaque; uint32_t ch_mode =3D s->r[R_MR] & UART_MR_CHMODE; =20 + /* ignore characters when unclocked */ + if (!clock_is_enabled(s->refclk)) { + return; + } + if (ch_mode =3D=3D NORMAL_MODE || ch_mode =3D=3D ECHO_MODE) { uart_write_rx_fifo(opaque, buf, size); } @@ -350,6 +371,11 @@ static void uart_event(void *opaque, int event) CadenceUARTState *s =3D opaque; uint8_t buf =3D '\0'; =20 + /* ignore events when unclocked */ + if (!clock_is_enabled(s->refclk)) { + return; + } + if (event =3D=3D CHR_EVENT_BREAK) { uart_write_rx_fifo(opaque, &buf, 1); } @@ -382,6 +408,14 @@ static void uart_write(void *opaque, hwaddr offset, { CadenceUARTState *s =3D opaque; =20 + /* ignore accesses when bus or ref clock is disabled */ + if (!(clock_is_enabled(s->busclk) && clock_is_enabled(s->refclk))) { + qemu_log_mask(LOG_GUEST_ERROR, + "cadence_uart: Trying to write register 0x%x" + " while clock is disabled\n", (unsigned) offset); + return; + } + DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value); offset >>=3D 2; if (offset >=3D CADENCE_UART_R_MAX) { @@ -440,6 +474,14 @@ static uint64_t uart_read(void *opaque, hwaddr offset, CadenceUARTState *s =3D opaque; uint32_t c =3D 0; =20 + /* ignore accesses when bus or ref clock is disabled */ + if (!(clock_is_enabled(s->busclk) && clock_is_enabled(s->refclk))) { + qemu_log_mask(LOG_GUEST_ERROR, + "cadence_uart: Trying to read register 0x%x" + " while clock is disabled\n", (unsigned) offset); + return 0; + } + offset >>=3D 2; if (offset >=3D CADENCE_UART_R_MAX) { c =3D 0; @@ -488,6 +530,14 @@ static void cadence_uart_realize(DeviceState *dev, Err= or **errp) uart_event, NULL, s, NULL, true); } =20 +static void cadence_uart_refclk_update(void *opaque) +{ + CadenceUARTState *s =3D opaque; + + /* recompute uart's speed on clock change */ + uart_parameters_setup(s); +} + static void cadence_uart_init(Object *obj) { SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); @@ -497,9 +547,26 @@ static void cadence_uart_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); sysbus_init_irq(sbd, &s->irq); =20 + s->refclk =3D qdev_init_clock_in(DEVICE(obj), "refclk", + cadence_uart_refclk_update, s); + /* initialize the frequency in case the clock remains unconnected */ + clock_init_frequency(s->refclk, UART_DEFAULT_REF_CLK); + s->busclk =3D qdev_init_clock_in(DEVICE(obj), "busclk", NULL, NULL); + /* initialize the frequency to non-zero in case it remains unconnected= */ + clock_init_frequency(s->busclk, 100 * 1000 * 1000); + s->char_tx_time =3D (NANOSECONDS_PER_SECOND / 9600) * 10; } =20 +static int cadence_uart_pre_load(void *opaque) +{ + CadenceUARTState *s =3D opaque; + + clock_init_frequency(s->refclk, UART_DEFAULT_REF_CLK); + clock_init_frequency(s->busclk, 100 * 1000 * 1000); + return 0; +} + static int cadence_uart_post_load(void *opaque, int version_id) { CadenceUARTState *s =3D opaque; @@ -516,10 +583,22 @@ static int cadence_uart_post_load(void *opaque, int v= ersion_id) return 0; } =20 +static const VMStateDescription vmstate_cadence_uart_clocks =3D { + .name =3D "cadence_uart_clocks", + .version_id =3D 0, + .minimum_version_id =3D 0, + .fields =3D (VMStateField[]) { + VMSTATE_CLOCKIN(refclk, CadenceUARTState), + VMSTATE_CLOCKIN(busclk, CadenceUARTState), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_cadence_uart =3D { .name =3D "cadence_uart", .version_id =3D 2, .minimum_version_id =3D 2, + .pre_load =3D cadence_uart_pre_load, .post_load =3D cadence_uart_post_load, .fields =3D (VMStateField[]) { VMSTATE_UINT32_ARRAY(r, CadenceUARTState, CADENCE_UART_R_MAX), @@ -532,7 +611,10 @@ static const VMStateDescription vmstate_cadence_uart = =3D { VMSTATE_UINT32(rx_wpos, CadenceUARTState), VMSTATE_TIMER_PTR(fifo_trigger_handle, CadenceUARTState), VMSTATE_END_OF_LIST() - } + }, + .subsections =3D (const VMStateDescription * []) { + &vmstate_cadence_uart_clocks, + }, }; =20 static Property cadence_uart_properties[] =3D { @@ -548,7 +630,7 @@ static void cadence_uart_class_init(ObjectClass *klass,= void *data) dc->vmsd =3D &vmstate_cadence_uart; dc->reset =3D cadence_uart_reset; dc->props =3D cadence_uart_properties; - } +} =20 static const TypeInfo cadence_uart_info =3D { .name =3D TYPE_CADENCE_UART, diff --git a/hw/char/trace-events b/hw/char/trace-events index b64213d4dd..2ea25d1ea1 100644 --- a/hw/char/trace-events +++ b/hw/char/trace-events @@ -73,3 +73,6 @@ cmsdk_apb_uart_receive(uint8_t c) "CMSDK APB UART: got ch= aracter 0x%x from backe cmsdk_apb_uart_tx_pending(void) "CMSDK APB UART: character send to backend= pending" cmsdk_apb_uart_tx(uint8_t c) "CMSDK APB UART: character 0x%x sent to backe= nd" cmsdk_apb_uart_set_params(int speed) "CMSDK APB UART: params set to %d 8N1" + +# hw/char/cadence_uart.c +cadence_uart_baudrate(unsigned baudrate) "baudrate %u" --=20 2.19.0 From nobody Wed May 1 06:06:30 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1538491310450794.1001134083152; Tue, 2 Oct 2018 07:41:50 -0700 (PDT) Received: from localhost ([::1]:44038 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lrx-0001Sp-3x for importer@patchew.org; Tue, 02 Oct 2018 10:41:49 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46709) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7Lmp-0005IS-Ia for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:36:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g7LdD-0004RB-JA for qemu-devel@nongnu.org; Tue, 02 Oct 2018 10:26:36 -0400 Received: from greensocs.com ([193.104.36.180]:53928) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g7LdA-0004OM-Hf; Tue, 02 Oct 2018 10:26:32 -0400 Received: from localhost (localhost [127.0.0.1]) by greensocs.com (Postfix) with ESMTP id 4F664442AFB; Tue, 2 Oct 2018 16:26:11 +0200 (CEST) Received: from greensocs.com ([127.0.0.1]) by localhost (gs-01.greensocs.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 6g9tA1GfWSVf; Tue, 2 Oct 2018 16:26:09 +0200 (CEST) Received: by greensocs.com (Postfix, from userid 998) id D21A5442AF5; Tue, 2 Oct 2018 16:26:07 +0200 (CEST) Received: from kouign-amann.hive.antfield.fr (antfield.tima.u-ga.fr [147.171.129.253]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: damien.hedde@greensocs.com) by greensocs.com (Postfix) with ESMTPSA id 6AB47442AFD; Tue, 2 Oct 2018 16:26:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490371; bh=jFdDOTrCjBSX31V7YSODO0nvlL+B8KjEWaH7DIakyp0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=fCcDoJWC3xZgdAPLCyboaeApG2IrTDP5qqaJ6CebqxjjU7NsAoE1hSCXwWxpqlqeb nE2suU7CTP/pzpmNysp3kO/JncmoodrRw2fTW0r1hAcJ7oHVJgxk9qA2h2PXMUMjA3 e2L4VbfRDQOHm7SJNZoRHZhun+Mijohz1czdwSyw= X-Virus-Scanned: amavisd-new at greensocs.com Authentication-Results: gs-01.greensocs.com (amavisd-new); dkim=pass (1024-bit key) header.d=greensocs.com header.b=QomYVnlv; dkim=pass (1024-bit key) header.d=greensocs.com header.b=QomYVnlv DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490367; bh=jFdDOTrCjBSX31V7YSODO0nvlL+B8KjEWaH7DIakyp0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=QomYVnlvv1AAJMtDNzt2gfFG00gfnM8/kNaCCEvuIUuL593kN9i6OJz1AWWiJJwN5 kHuFRIZ9qb4K5sgvEQLRja08HFk8l+eTXMwBqiptI4XwrIHBY3xdnHfY/93HFBwE1i dkjbK3cpW1OOxXDAt7MyKMEjkNociHON3AR4zrzk= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=greensocs.com; s=mail; t=1538490367; bh=jFdDOTrCjBSX31V7YSODO0nvlL+B8KjEWaH7DIakyp0=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=QomYVnlvv1AAJMtDNzt2gfFG00gfnM8/kNaCCEvuIUuL593kN9i6OJz1AWWiJJwN5 kHuFRIZ9qb4K5sgvEQLRja08HFk8l+eTXMwBqiptI4XwrIHBY3xdnHfY/93HFBwE1i dkjbK3cpW1OOxXDAt7MyKMEjkNociHON3AR4zrzk= From: Damien Hedde To: qemu-devel@nongnu.org Date: Tue, 2 Oct 2018 16:24:43 +0200 Message-Id: <20181002142443.30976-10-damien.hedde@greensocs.com> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002142443.30976-1-damien.hedde@greensocs.com> References: <20181002142443.30976-1-damien.hedde@greensocs.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 193.104.36.180 Subject: [Qemu-devel] [PATCH v5 9/9] hw/arm/xilinx_zynq: connect uart clocks to slcr X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org, alistair@alistair23.me, mark.burton@greensocs.com, saipava@xilinx.com, qemu-arm@nongnu.org, Damien Hedde , pbonzini@redhat.com, konrad@adacore.com, luc.michel@greensocs.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add the connection between the slcr's output clocks and the uarts inputs. Signed-off-by: Damien Hedde Reviewed-by: Philippe Mathieu-Daud=C3=A9 Tested-by: Philippe Mathieu-Daud=C3=A9 --- hw/arm/xilinx_zynq.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index f1496d2927..88f61c6a18 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -166,7 +166,7 @@ static void zynq_init(MachineState *machine) MemoryRegion *address_space_mem =3D get_system_memory(); MemoryRegion *ext_ram =3D g_new(MemoryRegion, 1); MemoryRegion *ocm_ram =3D g_new(MemoryRegion, 1); - DeviceState *dev; + DeviceState *dev, *slcr; SysBusDevice *busdev; qemu_irq pic[64]; int n; @@ -212,9 +212,10 @@ static void zynq_init(MachineState *machine) 1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa, 0); =20 - dev =3D qdev_create(NULL, "xilinx,zynq_slcr"); - qdev_init_nofail(dev); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xF8000000); + /* Create slcr, keep a pointer to connect clocks */ + slcr =3D qdev_create(NULL, "xilinx,zynq_slcr"); + qdev_init_nofail(slcr); + sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000); =20 dev =3D qdev_create(NULL, TYPE_A9MPCORE_PRIV); qdev_prop_set_uint32(dev, "num-cpu", 1); @@ -235,8 +236,12 @@ static void zynq_init(MachineState *machine) sysbus_create_simple("xlnx,ps7-usb", 0xE0002000, pic[53-IRQ_OFFSET]); sysbus_create_simple("xlnx,ps7-usb", 0xE0003000, pic[76-IRQ_OFFSET]); =20 - cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0)); - cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1)); + dev =3D cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_h= d(0)); + qdev_connect_clock(dev, "busclk", slcr, "uart0_amba_clk", &error_abort= ); + qdev_connect_clock(dev, "refclk", slcr, "uart0_ref_clk", &error_abort); + dev =3D cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_h= d(1)); + qdev_connect_clock(dev, "busclk", slcr, "uart1_amba_clk", &error_abort= ); + qdev_connect_clock(dev, "refclk", slcr, "uart1_ref_clk", &error_abort); =20 sysbus_create_varargs("cadence_ttc", 0xF8001000, pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NU= LL); --=20 2.19.0