On Mon, Jun 13, 2016 at 9:27 AM, <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 | 112 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 112 insertions(+) > create mode 100644 docs/clock.txt > > diff --git a/docs/clock.txt b/docs/clock.txt > new file mode 100644 > index 0000000..f4ad4c8 > --- /dev/null > +++ b/docs/clock.txt > @@ -0,0 +1,112 @@ > + > +What is a QEMU_CLOCK > +==================== > + > +A QEMU_CLOCK is a QOM Object developed for the purpose of modeling a clock > tree > +with QEMU. > + > +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. > + > +Bounding 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_bound(clk_a, clk_b) will bound clk_a and clk_b. > + > +Binding two qemu-clk together is a unidirectional link which means that > changing > +the rate of clk_a will propagate to clk_b and not the opposite. The bound > +process automatically refresh 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_bound(clk_a, clk_b); > +qemu_clk_bound(clk_a, clk_c); > + > +A clock rate change one clk_a will propagate to clk_b and clk_c. > + > +Implementing a callback on a rate change > +======================================== > + > +The function prototype is the following: > +typedef float (*qemu_clk_rate_change_cb)(void *opaque, float 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: > +float qemu_clk_rate_change_cb(void *opaque, float rate) > +{ > + return 4.0 * 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. > + > +NOTE: It's not recommended that the clock is driven by more than one clock > as it > +would mean that we don't know which clock trigger the callback.
Would this not be something worth knowing? Thanks, Alistair > +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: > + > + type System > + dev: xlnx.zynqmp_crf, id "" > + gpio-out "sysbus-irq" 1 > + gpio-out "RST_A9" 4 > + qemu-clk "dbg_trace" 0.0 > + qemu-clk "vpll_to_lpd" 625000000.0 > + qemu-clk "dp_stc_ref" 0.0 > + qemu-clk "dpll_to_lpd" 12500000.0 > + qemu-clk "acpu_clk" 0.0 > + qemu-clk "pcie_ref" 0.0 > + qemu-clk "topsw_main" 0.0 > + qemu-clk "topsw_lsbus" 0.0 > + qemu-clk "dp_audio_ref" 0.0 > + qemu-clk "sata_ref" 0.0 > + qemu-clk "dp_video_ref" 71428568.0 > + qemu-clk "vpll_clk" 2500000000.0 > + qemu-clk "apll_to_lpd" 12500000.0 > + qemu-clk "dpll_clk" 50000000.0 > + qemu-clk "gpu_ref" 0.0 > + qemu-clk "aux_refclk" 0.0 > + qemu-clk "video_clk" 27000000.0 > + qemu-clk "gdma_ref" 0.0 > + qemu-clk "gt_crx_ref_clk" 0.0 > + qemu-clk "dbg_fdp" 0.0 > + qemu-clk "apll_clk" 50000000.0 > + qemu-clk "pss_alt_ref_clk" 0.0 > + qemu-clk "ddr" 0.0 > + qemu-clk "pss_ref_clk" 50000000.0 > + qemu-clk "dpdma_ref" 0.0 > + qemu-clk "dbg_tstmp" 0.0 > + mmio 00000000fd1a0000/000000000000010c > + > +This way a DeviceState can have multiple clock input or output. > + > -- > 2.5.5 > >