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 > tree > +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 > bound > +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 > +selector. > + > +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 > change > +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 > called > +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 > qtree. > +For example: This seems to be missing a description of how you actually write a device that has some clocksources. thanks -- PMM