On 5 October 2016 at 23:11, <fred.kon...@greensocs.com> wrote:
> From: KONRAD Frederic <fred.kon...@greensocs.com>
> This adds the qemu-clock documentation.
> Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com>
> docs/clock.txt | 109
> 1 file changed, 109 insertions(+)
> create mode 100644 docs/clock.txt
> diff --git a/docs/clock.txt b/docs/clock.txt
> new file mode 100644
> index 0000000..b25c5ab
> --- /dev/null
> +++ b/docs/clock.txt
> @@ -0,0 +1,109 @@
> +What is a QEMU_CLOCK
> +A QEMU_CLOCK is a QOM Object developed for the purpose of modeling a clock
> +with QEMU.
This doesn't match the type name you use in the code.
> +It only simulates the clock by keeping a copy of the current frequency and
> +doesn't model the signal itself such as pin toggle or duty cycle.
> +It allows to model the impact of badly configured PLL, clock source selection
> +or disabled clock on the models.
So is a QEMU_CLOCK a clock source?
How does this scheme model "I'm a device, and I have a clock
input (ie a clock sink)" ?
> +Binding the clock together to create a tree
> +In order to create a clock tree with QEMU_CLOCK two or more clock must be
> +together. Let's say there are two clocks clk_a and clk_b:
> +Using qemu_clk_bind(clk_a, clk_b) will bind clk_a and clk_b.
> +Binding two qemu-clk together creates a unidirectional link which means that
> +changing the rate of clk_a will propagate to clk_b and not the opposite.
> +The binding process automatically refreshes clk_b rate.
> +Clock can be bound and unbound during execution for modeling eg: a clock
> +A clock can drive more than one other clock. eg with this code:
> +qemu_clk_bind(clk_a, clk_b);
> +qemu_clk_bind(clk_a, clk_c);
> +A clock rate change one clk_a will propagate to clk_b and clk_c.
What's the rate of a clock initially? Do you need to call
qemu_clk_update_rate() during board construction for a
fixed clock (or is it forbidden to call it during board
construction? during device reset?)
Presumably it's a programming error to bind a bunch of clocks
in a loop...
> +Implementing a callback on a rate change
> +The function prototype is the following:
> +typedef uint64_t (*qemu_clk_rate_change_cb)(void *opaque, uint64_t rate);
> +It's main goal is to modify the rate before it's passed to the next clocks in
> +the tree.
> +eg: for a 4x PLL the function will be:
> +uint64_t qemu_clk_rate_change_cb(void *opaque, uint64_t rate)
> + return 4 * rate;
> +To set the callback for the clock:
> +void qemu_clk_set_callback(qemu_clk clk, qemu_clk_on_rate_update_cb cb,
> + void *opaque);
> +can be called.
> +The rate update process
> +The rate update happen in this way:
> +When a model wants to update a clock frequency (eg: based on a register
> +or something similar) it will call qemu_clk_update_rate(..) on the clock:
> + * The callback associated to the clock is called with the new rate.
> + * qemu_clk_update_rate(..) is then called on all bound clock with the
> + value returned by the callback.
> +NOTE: When no callback is attached, the clock qemu_clk_update_rate(..) is
> +with the unmodified rate.
> +Attaching a QEMU_CLOCK to a DeviceState
> +Attaching a qemu-clk to a DeviceState is required to be able to get the clock
> +outside the model through qemu_clk_get_pin(..).
> +It is also required to be able to print the clock and its rate with info
> +For example:
This seems to be missing a description of how you actually write
a device that has some clocksources.