All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mike Turquette <mturquette@linaro.org>
To: Hans de Goede <hdegoede@redhat.com>,
	Emilio Lopez <emilio@elopez.com.ar>,
	chris@printf.net, david.lanzendoerfer@o2s.ch,
	ulf.hansson@linaro.org
Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-mmc@vger.kernel.org,
	Maxime Ripard <maxime.ripard@free-electrons.com>
Subject: Re: [PATCH v2 03/12] clk: Add a function to retrieve phase
Date: Mon, 01 Sep 2014 12:00:54 -0700	[thread overview]
Message-ID: <20140901190054.5251.56409@quantum> (raw)
In-Reply-To: <1409428991-2442-4-git-send-email-maxime.ripard@free-electrons.com>

Quoting Maxime Ripard (2014-08-30 13:03:02)
> The current phase API doesn't look into the actual hardware to get the phase
> value, but will rather get it from a variable only set by the set_phase
> function.
> 
> This will cause issue when the client driver will never call the set_phase
> function, where we can end up having a reported phase that will not match what
> the hardware has been programmed to by the bootloader or what phase is
> programmed out of reset.
> 
> Add a new get_phase function for the drivers to implement so that we can get
> this value.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/clk.c            | 17 ++++++++++++++---
>  include/linux/clk-provider.h |  5 +++++
>  2 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index d87661af0c72..7dbceca694f1 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1797,8 +1797,8 @@ out:
>   * clk_get_phase - return the phase shift of a clock signal
>   * @clk: clock signal source
>   *
> - * Returns the phase shift of a clock node in degrees, otherwise returns
> - * -EERROR.
> + * Returns the phase shift of a clock node in degrees. Any negative
> + * values are errors.
>   */
>  int clk_get_phase(struct clk *clk)
>  {
> @@ -1808,7 +1808,18 @@ int clk_get_phase(struct clk *clk)
>                 goto out;
>  
>         clk_prepare_lock();
> -       ret = clk->phase;
> +
> +       if (clk->phase) {

So if a phase is zero, then we fall through and query the hardware?
Seems like this case might be hit a lot for clocks that implement
.get_phase but never have their phase shifted, and accesses to the
registers may be much slower than to memory.

Do you expect the phase to be changed behind our backs? E.g. firmware
changes it, or coming in and out of idle state, etc. If not then we can
store the phase at clock registration time and use a cached value.

See how the CLK_GET_RATE_NOCACHE and CLK_GET_ACCURACY_NOCACHE flags are
used for details on how we can handle the case where the phase might
change behind our back.

Regards,
Mike

> +               ret = clk->phase;
> +               goto out_unlock;
> +       }
> +
> +       if (!clk->ops->get_phase)
> +               goto out_unlock;
> +
> +       ret = clk->ops->get_phase(clk->hw);
> +
> +out_unlock:
>         clk_prepare_unlock();
>  
>  out:
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index 69b20d4c1e1a..abec961092a7 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -130,6 +130,10 @@ struct dentry;
>   *             set then clock accuracy will be initialized to parent accuracy
>   *             or 0 (perfect clock) if clock has no parent.
>   *
> + * @get_phase: Queries the hardware to get the current phase of a clock.
> + *             Returned values are 0-359 degrees on success, negative
> + *             error codes on failure.
> + *
>   * @set_phase: Shift the phase this clock signal in degrees specified
>   *             by the second argument. Valid values for degrees are
>   *             0-359. Return 0 on success, otherwise -EERROR.
> @@ -182,6 +186,7 @@ struct clk_ops {
>                                     unsigned long parent_rate, u8 index);
>         unsigned long   (*recalc_accuracy)(struct clk_hw *hw,
>                                            unsigned long parent_accuracy);
> +       int             (*get_phase)(struct clk_hw *hw);
>         int             (*set_phase)(struct clk_hw *hw, int degrees);
>         void            (*init)(struct clk_hw *hw);
>         int             (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
> -- 
> 2.0.2
> 

WARNING: multiple messages have this Message-ID (diff)
From: mturquette@linaro.org (Mike Turquette)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 03/12] clk: Add a function to retrieve phase
Date: Mon, 01 Sep 2014 12:00:54 -0700	[thread overview]
Message-ID: <20140901190054.5251.56409@quantum> (raw)
In-Reply-To: <1409428991-2442-4-git-send-email-maxime.ripard@free-electrons.com>

Quoting Maxime Ripard (2014-08-30 13:03:02)
> The current phase API doesn't look into the actual hardware to get the phase
> value, but will rather get it from a variable only set by the set_phase
> function.
> 
> This will cause issue when the client driver will never call the set_phase
> function, where we can end up having a reported phase that will not match what
> the hardware has been programmed to by the bootloader or what phase is
> programmed out of reset.
> 
> Add a new get_phase function for the drivers to implement so that we can get
> this value.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
>  drivers/clk/clk.c            | 17 ++++++++++++++---
>  include/linux/clk-provider.h |  5 +++++
>  2 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index d87661af0c72..7dbceca694f1 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -1797,8 +1797,8 @@ out:
>   * clk_get_phase - return the phase shift of a clock signal
>   * @clk: clock signal source
>   *
> - * Returns the phase shift of a clock node in degrees, otherwise returns
> - * -EERROR.
> + * Returns the phase shift of a clock node in degrees. Any negative
> + * values are errors.
>   */
>  int clk_get_phase(struct clk *clk)
>  {
> @@ -1808,7 +1808,18 @@ int clk_get_phase(struct clk *clk)
>                 goto out;
>  
>         clk_prepare_lock();
> -       ret = clk->phase;
> +
> +       if (clk->phase) {

So if a phase is zero, then we fall through and query the hardware?
Seems like this case might be hit a lot for clocks that implement
.get_phase but never have their phase shifted, and accesses to the
registers may be much slower than to memory.

Do you expect the phase to be changed behind our backs? E.g. firmware
changes it, or coming in and out of idle state, etc. If not then we can
store the phase at clock registration time and use a cached value.

See how the CLK_GET_RATE_NOCACHE and CLK_GET_ACCURACY_NOCACHE flags are
used for details on how we can handle the case where the phase might
change behind our back.

Regards,
Mike

> +               ret = clk->phase;
> +               goto out_unlock;
> +       }
> +
> +       if (!clk->ops->get_phase)
> +               goto out_unlock;
> +
> +       ret = clk->ops->get_phase(clk->hw);
> +
> +out_unlock:
>         clk_prepare_unlock();
>  
>  out:
> diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
> index 69b20d4c1e1a..abec961092a7 100644
> --- a/include/linux/clk-provider.h
> +++ b/include/linux/clk-provider.h
> @@ -130,6 +130,10 @@ struct dentry;
>   *             set then clock accuracy will be initialized to parent accuracy
>   *             or 0 (perfect clock) if clock has no parent.
>   *
> + * @get_phase: Queries the hardware to get the current phase of a clock.
> + *             Returned values are 0-359 degrees on success, negative
> + *             error codes on failure.
> + *
>   * @set_phase: Shift the phase this clock signal in degrees specified
>   *             by the second argument. Valid values for degrees are
>   *             0-359. Return 0 on success, otherwise -EERROR.
> @@ -182,6 +186,7 @@ struct clk_ops {
>                                     unsigned long parent_rate, u8 index);
>         unsigned long   (*recalc_accuracy)(struct clk_hw *hw,
>                                            unsigned long parent_accuracy);
> +       int             (*get_phase)(struct clk_hw *hw);
>         int             (*set_phase)(struct clk_hw *hw, int degrees);
>         void            (*init)(struct clk_hw *hw);
>         int             (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
> -- 
> 2.0.2
> 

  parent reply	other threads:[~2014-09-01 19:00 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-30 20:02 [PATCH v2 00/12] clk: sunxi: Improve MMC clocks support Maxime Ripard
2014-08-30 20:02 ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 01/12] clk: introduce clk_set_phase function & callback Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 02/12] clk: Include of.h in clock-provider.h Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 03/12] clk: Add a function to retrieve phase Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-31 10:15   ` Hans de Goede
2014-08-31 10:15     ` Hans de Goede
2014-09-01 10:20     ` Maxime Ripard
2014-09-01 10:20       ` Maxime Ripard
2014-09-01 11:27       ` Hans de Goede
2014-09-01 11:27         ` Hans de Goede
2014-09-02  9:50         ` Maxime Ripard
2014-09-02  9:50           ` Maxime Ripard
2014-09-02 11:03           ` David Lanzendörfer
2014-09-02 11:03             ` David Lanzendörfer
2014-09-01 19:00   ` Mike Turquette [this message]
2014-09-01 19:00     ` Mike Turquette
2014-09-02  9:34     ` Maxime Ripard
2014-09-02  9:34       ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 04/12] clk: sunxi: factors: Invert the probing logic Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 05/12] clk: sunxi: Introduce mbus compatible Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 06/12] ARM: sunxi: dt: Switch to the new " Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 07/12] clk: sunxi: Move mod0 clock to a file of its own Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 08/12] clk: sunxi: Move mbus to mod0 file Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 09/12] ARM: sunxi: dt: Add sample and output mmc clocks Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-09-04  7:31   ` Chen-Yu Tsai
2014-08-30 20:03 ` [PATCH v2 10/12] clk: sunxi: mod0: Introduce MMC proper phase handling Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-09-01 21:39   ` Mike Turquette
2014-09-01 21:39     ` Mike Turquette
2014-09-02  7:52     ` Maxime Ripard
2014-09-02  7:52       ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 11/12] mmc: sunxi: Convert MMC driver to the standard clock phase API Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard
2014-08-30 20:03 ` [PATCH v2 12/12] clk: sunxi: Remove custom phase function Maxime Ripard
2014-08-30 20:03   ` Maxime Ripard

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=20140901190054.5251.56409@quantum \
    --to=mturquette@linaro.org \
    --cc=chris@printf.net \
    --cc=david.lanzendoerfer@o2s.ch \
    --cc=devicetree@vger.kernel.org \
    --cc=emilio@elopez.com.ar \
    --cc=hdegoede@redhat.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-mmc@vger.kernel.org \
    --cc=maxime.ripard@free-electrons.com \
    --cc=ulf.hansson@linaro.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.