diff mbox

[RFC,05/11] docs: add qemu-clock documentation

Message ID 1465835259-21449-6-git-send-email-fred.konrad@greensocs.com (mailing list archive)
State New, archived
Headers show

Commit Message

KONRAD Frédéric June 13, 2016, 4:27 p.m. UTC
From: KONRAD Frederic <fred.konrad@greensocs.com>

This adds the qemu-clock documentation.

Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
---
 docs/clock.txt | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)
 create mode 100644 docs/clock.txt

Comments

Alistair Francis June 29, 2016, 12:38 a.m. UTC | #1
On Mon, Jun 13, 2016 at 9:27 AM,  <fred.konrad@greensocs.com> wrote:
> From: KONRAD Frederic <fred.konrad@greensocs.com>
>
> This adds the qemu-clock documentation.
>
> Signed-off-by: KONRAD Frederic <fred.konrad@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
>
>
Peter Maydell July 29, 2016, 1:47 p.m. UTC | #2
On 13 June 2016 at 17:27,  <fred.konrad@greensocs.com> wrote:
> From: KONRAD Frederic <fred.konrad@greensocs.com>
>
> This adds the qemu-clock documentation.
>
> Signed-off-by: KONRAD Frederic <fred.konrad@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.

I think this would be a good place to give a brief bullet-point summary
of the operations that can be done on a clock (which then can be
expanded on in sections below).


> +
> +Bounding the clock together to create a tree

"Binding" ?

> +============================================
> +
> +In order to create a clock tree with QEMU_CLOCK two or more clock must be bound
> +together.

Is the simple case of "only one clock, not bound to any other clock,
with a callback" not a valid clock tree ?

> 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.

"bind" ? (and in the function name)

> +
> +Binding two qemu-clk together is a unidirectional link which means that changing

"creates a unidirectional link" ?

> +the rate of clk_a will propagate to clk_b and not the opposite. The bound
> +process automatically refresh clk_b rate.

"refreshes"

> +
> +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.

If you bind clock A to clock B, then is trying to change the rate
of clock B (a) a bug (assert, or fail the call) (b) OK but
ignored (c) OK but the changed rate doesn't get used until/unless
the clocks are unbound ?

Is it possible to bind two clocks together but with a frequency
difference between them (ie to model the common case where there's
some master clock and then a clock divider that creates various
other clocks based on the rate of that master) ?

> +
> +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

did you mean "callback" here ?

> +would mean that we don't know which clock trigger the callback.
> +
> +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

thanks
-- PMM
KONRAD Frédéric Aug. 2, 2016, 9:29 a.m. UTC | #3
Le 29/06/2016 à 02:38, Alistair Francis a écrit :
> On Mon, Jun 13, 2016 at 9:27 AM,  <fred.konrad@greensocs.com> wrote:
>> From: KONRAD Frederic <fred.konrad@greensocs.com>
>>
>> This adds the qemu-clock documentation.
>>
>> Signed-off-by: KONRAD Frederic <fred.konrad@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?

I think it shouldn't be the case as connecting two inputs on an output 
doesn't mean anything?
Maybe worth adding something to ensure it can't happen and modify 
qemu_clk_bind_clock to automatically unbind the old clock?

Fred
>
> 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
>>
>>
Alistair Francis Aug. 4, 2016, 12:28 a.m. UTC | #4
On Tue, Aug 2, 2016 at 2:29 AM, KONRAD Frederic
<fred.konrad@greensocs.com> wrote:
>
>
> Le 29/06/2016 à 02:38, Alistair Francis a écrit :
>>
>> On Mon, Jun 13, 2016 at 9:27 AM,  <fred.konrad@greensocs.com> wrote:
>>>
>>> From: KONRAD Frederic <fred.konrad@greensocs.com>
>>>
>>> This adds the qemu-clock documentation.
>>>
>>> Signed-off-by: KONRAD Frederic <fred.konrad@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?
>
>
> I think it shouldn't be the case as connecting two inputs on an output
> doesn't mean anything?

I think I meant worth knowing what you were connected to in general.

> Maybe worth adding something to ensure it can't happen and modify
> qemu_clk_bind_clock to automatically unbind the old clock?

I think that's a good idea.

Thanks,

Alistair

>
> Fred
>
>>
>> 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
>>>
>>>
>
>
diff mbox

Patch

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.
+
+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.
+