From: Stephen Boyd <sboyd@codeaurora.org>
To: Sudeep Holla <sudeep.holla@arm.com>
Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
Liviu Dudau <Liviu.Dudau@arm.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
"Jon Medhurst (Tixy)" <tixy@linaro.org>,
Arnd Bergmann <arnd@arndb.de>, Kevin Hilman <khilman@kernel.org>,
Olof Johansson <olof@lixom.net>,
Mike Turquette <mturquette@linaro.org>
Subject: Re: [PATCH v4 3/8] clk: add support for clocks provided by SCP(System Control Processor)
Date: Thu, 2 Jul 2015 10:23:10 -0700 [thread overview]
Message-ID: <20150702172310.GF4301@codeaurora.org> (raw)
In-Reply-To: <1433760002-24120-4-git-send-email-sudeep.holla@arm.com>
On 06/08, Sudeep Holla wrote:
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 9897f353bf1a..0fe8daefc105 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -59,6 +59,16 @@ config COMMON_CLK_RK808
> clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
> by control register.
>
> +config COMMON_CLK_SCPI
> + tristate "Clock driver controlled via SCPI interface"
> + depends on ARM_SCPI_PROTOCOL || COMPILE_TEST
> + ---help---
> + This driver provides support for clocks that are controlled
> + by firmware that implements the SCPI interface.
> +
> + This driver uses SCPI Message Protocol to interact with the
> + firmware providing all the clock controls.
The tabbing is weird here. Both paragraphs should have the same
alignment.
> diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
> new file mode 100644
> index 000000000000..707b3430c55f
> --- /dev/null
> +++ b/drivers/clk/clk-scpi.c
> +
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/scpi_protocol.h>
Please include <linux/platform_device.h> as well.
> +
> +struct scpi_clk {
> + u32 id;
> + const char *name;
Do you need this? Or can you just use __clk_get_name() in places
where the name is used?
> + struct clk_hw hw;
> + struct scpi_dvfs_info *info;
> + struct scpi_ops *scpi_ops;
> +};
> +
> +#define to_scpi_clk(clk) container_of(clk, struct scpi_clk, hw)
> +
> +static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> +
> + return clk->scpi_ops->clk_get_val(clk->id);
> +}
> +
> +static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
Maybe a comment here like:
/*
* We can't figure out what rate it will be, so just return the rate
* back to the caller. scpi_clk_recalc_rate() will be called
* after the rate is set and we'll know what rate the clock is
* running at then.
*/
> + return rate;
> +}
> +
> +static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> +
> + return clk->scpi_ops->clk_set_val(clk->id, rate);
> +}
> +
> +static void scpi_clk_disable(struct clk_hw *hw)
> +{
> + scpi_clk_set_rate(hw, 0, 0);
Does this mean you have to set a rate to enable the clock? Are
you relying on drivers to call clk_set_rate() to implicitly
enable the clock? If so, it would be better to cache the rate of
the clock in set_rate if the clock isn't enabled in software and
then send the cached rate during enable.
> +}
> +
[..]
> +/* find closest match to given frequency in OPP table */
> +static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
> +{
> + int idx;
> + u32 fmin = 0, fmax = ~0, ftmp;
> + struct scpi_opp *opp = clk->info->opps;
> +
const?
> + for (idx = 0; idx < clk->info->count; idx++, opp++) {
> + ftmp = opp->freq;
> + if (ftmp >= (u32)rate) {
> + if (ftmp <= fmax)
> + fmax = ftmp;
> + break;
> + } else if (ftmp >= fmin) {
> + fmin = ftmp;
> + }
> + }
> + return fmax != ~0 ? fmax : fmin;
> +}
> +
> +static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> + int idx = clk->scpi_ops->dvfs_get_idx(clk->id);
> + struct scpi_opp *opp;
const?
> +
> + if (idx < 0)
> + return 0;
> +
> + opp = clk->info->opps + idx;
> + return opp->freq;
> +}
> +
> +static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> +
> + return __scpi_dvfs_round_rate(clk, rate);
> +}
> +
> +static int __scpi_find_dvfs_index(struct scpi_clk *clk, unsigned long rate)
> +{
> + int idx, max_opp = clk->info->count;
> + struct scpi_opp *opp = clk->info->opps;
const?
> +
> + for (idx = 0; idx < max_opp; idx++, opp++)
> + if (opp->freq == rate)
> + return idx;
> + return -EINVAL;
> +}
> +
[..]
> +static struct clk *
> +scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
> + struct scpi_clk *sclk)
> +{
> + struct clk_init_data init;
> + struct clk *clk;
> + unsigned long min = 0, max = 0;
> +
> + init.name = sclk->name;
> + init.flags = CLK_IS_ROOT;
> + init.num_parents = 0;
> + init.ops = match->data;
> + sclk->hw.init = &init;
> + sclk->scpi_ops = get_scpi_ops();
> +
> + if (init.ops == &scpi_dvfs_ops) {
> + sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id);
> + if (IS_ERR(sclk->info))
> + return NULL;
> + } else if (init.ops == &scpi_clk_ops) {
> + if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max)
> + return NULL;
> + } else {
> + return NULL;
> + }
> +
> + clk = devm_clk_register(dev, &sclk->hw);
> + if (!IS_ERR(clk) && max)
> + clk_set_rate_range(clk, min, max);
Hm.. we're planning to make clk_register() return a struct
clk_hw, so this will block that. We need some sort of clk_hw API
that allows us to setup min/max limits on the clock from the
provider side. Care to add that?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
WARNING: multiple messages have this Message-ID (diff)
From: sboyd@codeaurora.org (Stephen Boyd)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 3/8] clk: add support for clocks provided by SCP(System Control Processor)
Date: Thu, 2 Jul 2015 10:23:10 -0700 [thread overview]
Message-ID: <20150702172310.GF4301@codeaurora.org> (raw)
In-Reply-To: <1433760002-24120-4-git-send-email-sudeep.holla@arm.com>
On 06/08, Sudeep Holla wrote:
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index 9897f353bf1a..0fe8daefc105 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -59,6 +59,16 @@ config COMMON_CLK_RK808
> clocked at 32KHz each. Clkout1 is always on, Clkout2 can off
> by control register.
>
> +config COMMON_CLK_SCPI
> + tristate "Clock driver controlled via SCPI interface"
> + depends on ARM_SCPI_PROTOCOL || COMPILE_TEST
> + ---help---
> + This driver provides support for clocks that are controlled
> + by firmware that implements the SCPI interface.
> +
> + This driver uses SCPI Message Protocol to interact with the
> + firmware providing all the clock controls.
The tabbing is weird here. Both paragraphs should have the same
alignment.
> diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
> new file mode 100644
> index 000000000000..707b3430c55f
> --- /dev/null
> +++ b/drivers/clk/clk-scpi.c
> +
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/scpi_protocol.h>
Please include <linux/platform_device.h> as well.
> +
> +struct scpi_clk {
> + u32 id;
> + const char *name;
Do you need this? Or can you just use __clk_get_name() in places
where the name is used?
> + struct clk_hw hw;
> + struct scpi_dvfs_info *info;
> + struct scpi_ops *scpi_ops;
> +};
> +
> +#define to_scpi_clk(clk) container_of(clk, struct scpi_clk, hw)
> +
> +static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> +
> + return clk->scpi_ops->clk_get_val(clk->id);
> +}
> +
> +static long scpi_clk_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
Maybe a comment here like:
/*
* We can't figure out what rate it will be, so just return the rate
* back to the caller. scpi_clk_recalc_rate() will be called
* after the rate is set and we'll know what rate the clock is
* running at then.
*/
> + return rate;
> +}
> +
> +static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> +
> + return clk->scpi_ops->clk_set_val(clk->id, rate);
> +}
> +
> +static void scpi_clk_disable(struct clk_hw *hw)
> +{
> + scpi_clk_set_rate(hw, 0, 0);
Does this mean you have to set a rate to enable the clock? Are
you relying on drivers to call clk_set_rate() to implicitly
enable the clock? If so, it would be better to cache the rate of
the clock in set_rate if the clock isn't enabled in software and
then send the cached rate during enable.
> +}
> +
[..]
> +/* find closest match to given frequency in OPP table */
> +static int __scpi_dvfs_round_rate(struct scpi_clk *clk, unsigned long rate)
> +{
> + int idx;
> + u32 fmin = 0, fmax = ~0, ftmp;
> + struct scpi_opp *opp = clk->info->opps;
> +
const?
> + for (idx = 0; idx < clk->info->count; idx++, opp++) {
> + ftmp = opp->freq;
> + if (ftmp >= (u32)rate) {
> + if (ftmp <= fmax)
> + fmax = ftmp;
> + break;
> + } else if (ftmp >= fmin) {
> + fmin = ftmp;
> + }
> + }
> + return fmax != ~0 ? fmax : fmin;
> +}
> +
> +static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> + int idx = clk->scpi_ops->dvfs_get_idx(clk->id);
> + struct scpi_opp *opp;
const?
> +
> + if (idx < 0)
> + return 0;
> +
> + opp = clk->info->opps + idx;
> + return opp->freq;
> +}
> +
> +static long scpi_dvfs_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
> + struct scpi_clk *clk = to_scpi_clk(hw);
> +
> + return __scpi_dvfs_round_rate(clk, rate);
> +}
> +
> +static int __scpi_find_dvfs_index(struct scpi_clk *clk, unsigned long rate)
> +{
> + int idx, max_opp = clk->info->count;
> + struct scpi_opp *opp = clk->info->opps;
const?
> +
> + for (idx = 0; idx < max_opp; idx++, opp++)
> + if (opp->freq == rate)
> + return idx;
> + return -EINVAL;
> +}
> +
[..]
> +static struct clk *
> +scpi_clk_ops_init(struct device *dev, const struct of_device_id *match,
> + struct scpi_clk *sclk)
> +{
> + struct clk_init_data init;
> + struct clk *clk;
> + unsigned long min = 0, max = 0;
> +
> + init.name = sclk->name;
> + init.flags = CLK_IS_ROOT;
> + init.num_parents = 0;
> + init.ops = match->data;
> + sclk->hw.init = &init;
> + sclk->scpi_ops = get_scpi_ops();
> +
> + if (init.ops == &scpi_dvfs_ops) {
> + sclk->info = sclk->scpi_ops->dvfs_get_info(sclk->id);
> + if (IS_ERR(sclk->info))
> + return NULL;
> + } else if (init.ops == &scpi_clk_ops) {
> + if (sclk->scpi_ops->clk_get_range(sclk->id, &min, &max) || !max)
> + return NULL;
> + } else {
> + return NULL;
> + }
> +
> + clk = devm_clk_register(dev, &sclk->hw);
> + if (!IS_ERR(clk) && max)
> + clk_set_rate_range(clk, min, max);
Hm.. we're planning to make clk_register() return a struct
clk_hw, so this will block that. We need some sort of clk_hw API
that allows us to setup min/max limits on the clock from the
provider side. Care to add that?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
next prev parent reply other threads:[~2015-07-02 17:23 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-08 10:39 [PATCH v4 0/8] ARM64: juno: add SCPI mailbox protocol, clock and CPUFreq support Sudeep Holla
2015-06-08 10:39 ` Sudeep Holla
2015-06-08 10:39 ` [PATCH v4 1/8] Documentation: add DT binding for ARM System Control and Power Interface(SCPI) protocol Sudeep Holla
2015-06-08 10:39 ` Sudeep Holla
2015-06-08 10:39 ` Sudeep Holla
2015-07-08 13:59 ` Sudeep Holla
2015-07-08 13:59 ` Sudeep Holla
2015-07-22 8:43 ` Liviu Dudau
2015-07-22 8:43 ` Liviu Dudau
2015-07-22 8:43 ` Liviu Dudau
2015-07-22 9:25 ` Sudeep Holla
2015-07-22 9:25 ` Sudeep Holla
2015-07-22 9:55 ` Mark Rutland
2015-07-22 9:55 ` Mark Rutland
2015-07-22 15:56 ` Sudeep Holla
2015-07-22 15:56 ` Sudeep Holla
2015-07-22 15:56 ` Sudeep Holla
2015-07-22 16:23 ` Mark Rutland
2015-07-22 16:23 ` Mark Rutland
2015-06-08 10:39 ` [PATCH v4 2/8] firmware: add support " Sudeep Holla
2015-06-08 10:39 ` Sudeep Holla
2015-06-11 11:54 ` Jassi Brar
2015-06-11 11:54 ` Jassi Brar
2015-06-11 13:23 ` Sudeep Holla
2015-06-11 13:23 ` Sudeep Holla
2015-06-08 10:39 ` [PATCH v4 3/8] clk: add support for clocks provided by SCP(System Control Processor) Sudeep Holla
2015-06-08 10:39 ` Sudeep Holla
2015-07-02 17:23 ` Stephen Boyd [this message]
2015-07-02 17:23 ` Stephen Boyd
2015-07-03 14:52 ` Sudeep Holla
2015-07-03 14:52 ` Sudeep Holla
2015-07-03 16:12 ` Sudeep Holla
2015-07-03 16:12 ` Sudeep Holla
2015-07-06 19:52 ` Stephen Boyd
2015-07-06 19:52 ` Stephen Boyd
2015-07-07 16:03 ` Sudeep Holla
2015-07-07 16:03 ` Sudeep Holla
2015-07-08 1:46 ` Stephen Boyd
2015-07-08 1:46 ` Stephen Boyd
2015-07-16 16:11 ` Sudeep Holla
2015-07-16 16:11 ` Sudeep Holla
2015-07-16 19:31 ` Stephen Boyd
2015-07-16 19:31 ` Stephen Boyd
2015-07-17 11:17 ` Sudeep Holla
2015-07-17 11:17 ` Sudeep Holla
2015-07-17 18:13 ` Stephen Boyd
2015-07-17 18:13 ` Stephen Boyd
2015-07-20 8:54 ` Sudeep Holla
2015-07-20 8:54 ` Sudeep Holla
2015-07-21 18:05 ` Stephen Boyd
2015-07-21 18:05 ` Stephen Boyd
2015-07-22 14:19 ` Sudeep Holla
2015-07-22 14:19 ` Sudeep Holla
2015-06-08 10:39 ` [PATCH v4 4/8] clk: scpi: add support for cpufreq virtual device Sudeep Holla
2015-06-08 10:39 ` Sudeep Holla
2015-06-08 10:39 ` [PATCH v4 5/8] cpufreq: arm_big_little: add SCPI interface driver Sudeep Holla
2015-06-08 10:39 ` Sudeep Holla
2015-06-08 10:40 ` [PATCH v4 6/8] arm64: dts: add SRAM, MHU mailbox and SCPI support on Juno Sudeep Holla
2015-06-08 10:40 ` Sudeep Holla
2015-06-08 13:51 ` Jon Medhurst (Tixy)
2015-06-08 13:51 ` Jon Medhurst (Tixy)
2015-06-08 14:32 ` Sudeep Holla
2015-06-08 14:32 ` Sudeep Holla
2015-06-08 14:35 ` Liviu Dudau
2015-06-08 14:35 ` Liviu Dudau
2015-07-22 13:28 ` Liviu Dudau
2015-07-22 13:28 ` Liviu Dudau
2015-07-22 15:40 ` Sudeep Holla
2015-07-22 15:40 ` Sudeep Holla
2015-07-22 16:06 ` Liviu Dudau
2015-07-22 16:06 ` Liviu Dudau
2015-07-22 16:16 ` Sudeep Holla
2015-07-22 16:16 ` Sudeep Holla
2015-06-08 10:40 ` [PATCH v4 7/8] arm64: dts: add CPU topology " Sudeep Holla
2015-06-08 10:40 ` Sudeep Holla
2015-07-22 13:31 ` Liviu Dudau
2015-07-22 13:31 ` Liviu Dudau
2015-06-08 10:40 ` [PATCH v4 8/8] arm64: dts: add clock support for all the cpus Sudeep Holla
2015-06-08 10:40 ` Sudeep Holla
2015-07-22 13:32 ` Liviu Dudau
2015-07-22 13:32 ` Liviu Dudau
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=20150702172310.GF4301@codeaurora.org \
--to=sboyd@codeaurora.org \
--cc=Liviu.Dudau@arm.com \
--cc=arnd@arndb.de \
--cc=khilman@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=mturquette@linaro.org \
--cc=olof@lixom.net \
--cc=sudeep.holla@arm.com \
--cc=tixy@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.