From: "Philippe Mathieu-Daudé" <philmd@redhat.com>
To: Damien Hedde <damien.hedde@greensocs.com>, qemu-devel@nongnu.org
Cc: edgar.iglesias@xilinx.com, peter.maydell@linaro.org,
alistair@alistair23.me, mark.burton@greensocs.com,
saipava@xilinx.com, qemu-arm@nongnu.org, pbonzini@redhat.com,
konrad@adacore.com, luc.michel@greensocs.com
Subject: Re: [Qemu-devel] [PATCH v5 5/9] docs/clocks: add device's clock documentation
Date: Wed, 3 Oct 2018 01:48:02 +0200 [thread overview]
Message-ID: <5bd8bb78-e894-7e63-93fc-241d57f8cbd3@redhat.com> (raw)
In-Reply-To: <20181002142443.30976-6-damien.hedde@greensocs.com>
On 10/2/18 4:24 PM, Damien Hedde wrote:
> 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 <damien.hedde@greensocs.com>
> ---
> 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
> +========================
> +
> +Clocks are ports representing input and output clocks of a device. They are 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.
A simple ASCII diagram would help to make this clearer.
> +
> +The clock value: ClockState
> +===========================
> +
> +The ClockState is the structure carried by the CLOCK_OUT and CLOCK_IN objects.
This is only true for ClockIn, right?
> +It contains one integer field representing the frequency of the clock in Hertz.
unsigned
> +
> +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.
OK.
> +
> +Adding clocks to a device
> +=========================
> +
> +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 saved
ClockIn/ClockOut
> +in the device's state structure.
> +
> +Theses objects will be automatically deleted by the qom reference mechanism.
QOM
> +
> +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
> +========================
> +
> +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 = 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
> +=================
> +
> +Sometimes, one needs to forward, or inherit, a clock from another device.
> +Typically, when doing device composition, a device might expose a sub-device'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 = 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
> +==============================
> +
> +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".
Maybe "clk_in" "clk_out" to avoid confusion with ClkIn and ClkOut.
> +
> +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
> +=======================
> +
> +A device can change its outputs using the clock_set function. It will trigger
> +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 phase:
> +dev->clkout = 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 */
1GHz
> +
> +Callback on input clock change
> +==============================
> +
> +Here is an example of an input callback:
> +void clock_callback(void *opaque) {
> + MyDeviceState *s = (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));
Yes.
> +}
> +
> +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
> +=========
> +
> +Only the CLOCK_IN object has a state. CLOCK_OUT frequency should not be set
ClkIn ClkOut
> +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 vmstate
> +description is:
> +VMStateDescription my_device_vmstate = {
> + .name = "my_device",
> + .fields = (VMStateField[]) {
> + VMSTATE_CLOCKIN(clk, MyDeviceState),
> + VMSTATE_END_OF_LIST()
> + }
> +};
> +
> +When adding a input clock support to an existing device, you must care about
> +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.
>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
next prev parent reply other threads:[~2018-10-02 23:48 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-02 14:24 [Qemu-devel] [PATCH v5 0/9] Clock framework API Damien Hedde
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 1/9] hw/core/clock-port: introduce clock port objects Damien Hedde
2018-10-02 23:53 ` Philippe Mathieu-Daudé
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 2/9] qdev: add clock input&output support to devices Damien Hedde
2018-10-02 23:36 ` Philippe Mathieu-Daudé
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 3/9] qdev-monitor: print the device's clock with info qtree Damien Hedde
2018-10-02 22:42 ` Philippe Mathieu-Daudé
2018-10-12 10:20 ` Damien Hedde
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 4/9] qdev-clock: introduce an init array to ease the device construction Damien Hedde
2018-10-03 8:23 ` Philippe Mathieu-Daudé
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 5/9] docs/clocks: add device's clock documentation Damien Hedde
2018-10-02 23:48 ` Philippe Mathieu-Daudé [this message]
2018-10-03 8:18 ` Philippe Mathieu-Daudé
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 6/9] hw/misc/zynq_slcr: use standard register definition Damien Hedde
2018-10-04 17:24 ` Alistair Francis
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 7/9] hw/misc/zynq_slcr: add clock generation for uarts Damien Hedde
2018-10-02 23:10 ` Philippe Mathieu-Daudé
2018-10-12 13:24 ` Damien Hedde
2018-10-12 13:27 ` Peter Maydell
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 8/9] hw/char/cadence_uart: add clock support Damien Hedde
2018-10-02 23:26 ` Philippe Mathieu-Daudé
2018-10-12 13:42 ` Damien Hedde
2018-10-02 14:24 ` [Qemu-devel] [PATCH v5 9/9] hw/arm/xilinx_zynq: connect uart clocks to slcr Damien Hedde
2018-10-02 23:28 ` Philippe Mathieu-Daudé
2018-10-04 16:13 ` [Qemu-devel] [PATCH v5 0/9] Clock framework API Philippe Mathieu-Daudé
2018-10-11 16:20 ` Damien Hedde
2018-10-11 16:23 ` Peter Maydell
2018-10-11 17:00 ` Philippe Mathieu-Daudé
2018-10-11 17:12 ` Peter Maydell
2018-10-11 17:16 ` Philippe Mathieu-Daudé
2018-10-12 15:26 ` Damien Hedde
2018-10-16 15:48 ` Peter Maydell
2018-12-18 15:24 ` Damien Hedde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5bd8bb78-e894-7e63-93fc-241d57f8cbd3@redhat.com \
--to=philmd@redhat.com \
--cc=alistair@alistair23.me \
--cc=damien.hedde@greensocs.com \
--cc=edgar.iglesias@xilinx.com \
--cc=konrad@adacore.com \
--cc=luc.michel@greensocs.com \
--cc=mark.burton@greensocs.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=saipava@xilinx.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).