All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan.Cameron@huawei.com (Jonathan Cameron)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v6 06/20] firmware: arm_scmi: add initial support for performance protocol
Date: Mon, 5 Mar 2018 14:29:03 +0000	[thread overview]
Message-ID: <20180305152903.0000417e@huawei.com> (raw)
In-Reply-To: <1519403030-21189-7-git-send-email-sudeep.holla@arm.com>

On Fri, 23 Feb 2018 16:23:36 +0000
Sudeep Holla <sudeep.holla@arm.com> wrote:

> The performance protocol is intended for the performance management of
> group(s) of device(s) that run in the same performance domain. It
> includes even the CPUs. A performance domain is defined by a set of
> devices that always have to run at the same performance level.
> For example, a set of CPUs that share a voltage domain, and have a
> common frequency control, is said to be in the same performance domain.
> 
> The commands in this protocol provide functionality to describe the
> protocol version, describe various attribute flags, set and get the
> performance level of a domain. It also supports discovery of the list
> of performance levels supported by a performance domain, and the
> properties of each performance level.
> 
<snip>
> +
> +static int scmi_perf_attributes_get(const struct scmi_handle *handle,
> +				    struct scmi_perf_info *pi)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	struct scmi_msg_resp_perf_attributes *attr;
> +
> +	ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES,
> +				 SCMI_PROTOCOL_PERF, 0, sizeof(*attr), &t);
> +	if (ret)
> +		return ret;
> +
> +	attr = t->rx.buf;
> +
> +	ret = scmi_do_xfer(handle, t);
> +	if (!ret) {
Use a goto for the error path rather than indenting all this good path stuff.
The same would help readability in various other places.

> +		u16 flags = le16_to_cpu(attr->flags);
> +
> +		pi->num_domains = le16_to_cpu(attr->num_domains);
> +		pi->power_scale_mw = POWER_SCALE_IN_MILLIWATT(flags);
> +		pi->stats_addr = le32_to_cpu(attr->stats_addr_low) |
> +				(u64)le32_to_cpu(attr->stats_addr_high) << 32;
> +		pi->stats_size = le32_to_cpu(attr->stats_size);
> +	}
> +
> +	scmi_one_xfer_put(handle, t);
> +	return ret;
> +}
> +
...
> +
> +static struct scmi_perf_ops perf_ops = {
> +	.limits_set = scmi_perf_limits_set,
> +	.limits_get = scmi_perf_limits_get,
> +	.level_set = scmi_perf_level_set,
> +	.level_get = scmi_perf_level_get,
> +	.device_domain_id = scmi_dev_domain_id,
> +	.get_transition_latency = scmi_dvfs_get_transition_latency,
> +	.add_opps_to_device = scmi_dvfs_add_opps_to_device,
> +	.freq_set = scmi_dvfs_freq_set,
> +	.freq_get = scmi_dvfs_freq_get,
> +};
> +
> +static int scmi_perf_protocol_init(struct scmi_handle *handle)
> +{
> +	int domain;
> +	u32 version;
> +	struct scmi_perf_info *pinfo;
> +
> +	scmi_version_get(handle, SCMI_PROTOCOL_PERF, &version);
> +
> +	dev_dbg(handle->dev, "Performance Version %d.%d\n",
> +		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
> +
> +	pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
> +	if (!pinfo)
> +		return -ENOMEM;
> +
> +	scmi_perf_attributes_get(handle, pinfo);
> +
> +	pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains,
> +				       sizeof(*pinfo->dom_info), GFP_KERNEL);
> +	if (!pinfo->dom_info)
> +		return -ENOMEM;
> +
> +	for (domain = 0; domain < pinfo->num_domains; domain++) {
> +		struct perf_dom_info *dom = pinfo->dom_info + domain;
> +
> +		scmi_perf_domain_attributes_get(handle, domain, dom);
> +		scmi_perf_describe_levels_get(handle, domain, dom);
> +	}
> +
> +	handle->perf_ops = &perf_ops;
> +	handle->perf_priv = pinfo;
> +
> +	return 0;
> +}
> +
> +static int __init scmi_perf_init(void)
> +{
> +	return scmi_protocol_register(SCMI_PROTOCOL_PERF,
> +				      &scmi_perf_protocol_init);
> +}
> +subsys_initcall(scmi_perf_init);
> diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
> index db995126134d..d80f4c9a0fad 100644
> --- a/include/linux/scmi_protocol.h
> +++ b/include/linux/scmi_protocol.h
> @@ -44,15 +44,57 @@ struct scmi_revision_info {
>  	char sub_vendor_id[SCMI_MAX_STR_SIZE];
>  };
>  
> +struct scmi_handle;
> +
> +/**
> + * struct scmi_perf_ops - represents the various operations provided
> + *	by SCMI Performance Protocol
> + *
> + * @limits_set: sets limits on the performance level of a domain
> + * @limits_get: gets limits on the performance level of a domain
> + * @level_set: sets the performance level of a domain
> + * @level_get: gets the performance level of a domain
> + * @device_domain_id: gets the scmi domain id for a given device
> + * @get_transition_latency: gets the DVFS transition latency for a given device
> + * @add_opps_to_device: adds all the OPPs for a given device
> + * @freq_set: sets the frequency for a given device using sustained frequency
> + *	to sustained performance level mapping
> + * @freq_get: gets the frequency for a given device using sustained frequency
> + *	to sustained performance level mapping
> + */
> +struct scmi_perf_ops {
> +	int (*limits_set)(const struct scmi_handle *handle, u32 domain,
> +			  u32 max_perf, u32 min_perf);
> +	int (*limits_get)(const struct scmi_handle *handle, u32 domain,
> +			  u32 *max_perf, u32 *min_perf);
> +	int (*level_set)(const struct scmi_handle *handle, u32 domain,
> +			 u32 level);
> +	int (*level_get)(const struct scmi_handle *handle, u32 domain,
> +			 u32 *level);
> +	int (*device_domain_id)(struct device *dev);
> +	int (*get_transition_latency)(const struct scmi_handle *handle,
> +				      struct device *dev);
Naming consistency would improve this.
transition_latency_get for example.

> +	int (*add_opps_to_device)(const struct scmi_handle *handle,
> +				  struct device *dev);
> +	int (*freq_set)(const struct scmi_handle *handle, u32 domain,
> +			unsigned long rate);
> +	int (*freq_get)(const struct scmi_handle *handle, u32 domain,
> +			unsigned long *rate);
> +};
> +
>  /**
>   * struct scmi_handle - Handle returned to ARM SCMI clients for usage.
>   *
>   * @dev: pointer to the SCMI device
>   * @version: pointer to the structure containing SCMI version information
> + * @perf_ops: pointer to set of performance protocol operations
>   */
>  struct scmi_handle {
>  	struct device *dev;
>  	struct scmi_revision_info *version;
> +	struct scmi_perf_ops *perf_ops;
> +	/* for protocol internal use */
> +	void *perf_priv;
>  };
>  
>  enum scmi_std_protocol {

WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: Sudeep Holla <sudeep.holla@arm.com>
Cc: ALKML <linux-arm-kernel@lists.infradead.org>,
	LKML <linux-kernel@vger.kernel.org>,
	DTML <devicetree@vger.kernel.org>,
	Alexey Klimov <klimov.linux@gmail.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Arnd Bergmann <arnd@arndb.de>
Subject: Re: [PATCH v6 06/20] firmware: arm_scmi: add initial support for performance protocol
Date: Mon, 5 Mar 2018 14:29:03 +0000	[thread overview]
Message-ID: <20180305152903.0000417e@huawei.com> (raw)
In-Reply-To: <1519403030-21189-7-git-send-email-sudeep.holla@arm.com>

On Fri, 23 Feb 2018 16:23:36 +0000
Sudeep Holla <sudeep.holla@arm.com> wrote:

> The performance protocol is intended for the performance management of
> group(s) of device(s) that run in the same performance domain. It
> includes even the CPUs. A performance domain is defined by a set of
> devices that always have to run at the same performance level.
> For example, a set of CPUs that share a voltage domain, and have a
> common frequency control, is said to be in the same performance domain.
> 
> The commands in this protocol provide functionality to describe the
> protocol version, describe various attribute flags, set and get the
> performance level of a domain. It also supports discovery of the list
> of performance levels supported by a performance domain, and the
> properties of each performance level.
> 
<snip>
> +
> +static int scmi_perf_attributes_get(const struct scmi_handle *handle,
> +				    struct scmi_perf_info *pi)
> +{
> +	int ret;
> +	struct scmi_xfer *t;
> +	struct scmi_msg_resp_perf_attributes *attr;
> +
> +	ret = scmi_one_xfer_init(handle, PROTOCOL_ATTRIBUTES,
> +				 SCMI_PROTOCOL_PERF, 0, sizeof(*attr), &t);
> +	if (ret)
> +		return ret;
> +
> +	attr = t->rx.buf;
> +
> +	ret = scmi_do_xfer(handle, t);
> +	if (!ret) {
Use a goto for the error path rather than indenting all this good path stuff.
The same would help readability in various other places.

> +		u16 flags = le16_to_cpu(attr->flags);
> +
> +		pi->num_domains = le16_to_cpu(attr->num_domains);
> +		pi->power_scale_mw = POWER_SCALE_IN_MILLIWATT(flags);
> +		pi->stats_addr = le32_to_cpu(attr->stats_addr_low) |
> +				(u64)le32_to_cpu(attr->stats_addr_high) << 32;
> +		pi->stats_size = le32_to_cpu(attr->stats_size);
> +	}
> +
> +	scmi_one_xfer_put(handle, t);
> +	return ret;
> +}
> +
...
> +
> +static struct scmi_perf_ops perf_ops = {
> +	.limits_set = scmi_perf_limits_set,
> +	.limits_get = scmi_perf_limits_get,
> +	.level_set = scmi_perf_level_set,
> +	.level_get = scmi_perf_level_get,
> +	.device_domain_id = scmi_dev_domain_id,
> +	.get_transition_latency = scmi_dvfs_get_transition_latency,
> +	.add_opps_to_device = scmi_dvfs_add_opps_to_device,
> +	.freq_set = scmi_dvfs_freq_set,
> +	.freq_get = scmi_dvfs_freq_get,
> +};
> +
> +static int scmi_perf_protocol_init(struct scmi_handle *handle)
> +{
> +	int domain;
> +	u32 version;
> +	struct scmi_perf_info *pinfo;
> +
> +	scmi_version_get(handle, SCMI_PROTOCOL_PERF, &version);
> +
> +	dev_dbg(handle->dev, "Performance Version %d.%d\n",
> +		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
> +
> +	pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
> +	if (!pinfo)
> +		return -ENOMEM;
> +
> +	scmi_perf_attributes_get(handle, pinfo);
> +
> +	pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains,
> +				       sizeof(*pinfo->dom_info), GFP_KERNEL);
> +	if (!pinfo->dom_info)
> +		return -ENOMEM;
> +
> +	for (domain = 0; domain < pinfo->num_domains; domain++) {
> +		struct perf_dom_info *dom = pinfo->dom_info + domain;
> +
> +		scmi_perf_domain_attributes_get(handle, domain, dom);
> +		scmi_perf_describe_levels_get(handle, domain, dom);
> +	}
> +
> +	handle->perf_ops = &perf_ops;
> +	handle->perf_priv = pinfo;
> +
> +	return 0;
> +}
> +
> +static int __init scmi_perf_init(void)
> +{
> +	return scmi_protocol_register(SCMI_PROTOCOL_PERF,
> +				      &scmi_perf_protocol_init);
> +}
> +subsys_initcall(scmi_perf_init);
> diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
> index db995126134d..d80f4c9a0fad 100644
> --- a/include/linux/scmi_protocol.h
> +++ b/include/linux/scmi_protocol.h
> @@ -44,15 +44,57 @@ struct scmi_revision_info {
>  	char sub_vendor_id[SCMI_MAX_STR_SIZE];
>  };
>  
> +struct scmi_handle;
> +
> +/**
> + * struct scmi_perf_ops - represents the various operations provided
> + *	by SCMI Performance Protocol
> + *
> + * @limits_set: sets limits on the performance level of a domain
> + * @limits_get: gets limits on the performance level of a domain
> + * @level_set: sets the performance level of a domain
> + * @level_get: gets the performance level of a domain
> + * @device_domain_id: gets the scmi domain id for a given device
> + * @get_transition_latency: gets the DVFS transition latency for a given device
> + * @add_opps_to_device: adds all the OPPs for a given device
> + * @freq_set: sets the frequency for a given device using sustained frequency
> + *	to sustained performance level mapping
> + * @freq_get: gets the frequency for a given device using sustained frequency
> + *	to sustained performance level mapping
> + */
> +struct scmi_perf_ops {
> +	int (*limits_set)(const struct scmi_handle *handle, u32 domain,
> +			  u32 max_perf, u32 min_perf);
> +	int (*limits_get)(const struct scmi_handle *handle, u32 domain,
> +			  u32 *max_perf, u32 *min_perf);
> +	int (*level_set)(const struct scmi_handle *handle, u32 domain,
> +			 u32 level);
> +	int (*level_get)(const struct scmi_handle *handle, u32 domain,
> +			 u32 *level);
> +	int (*device_domain_id)(struct device *dev);
> +	int (*get_transition_latency)(const struct scmi_handle *handle,
> +				      struct device *dev);
Naming consistency would improve this.
transition_latency_get for example.

> +	int (*add_opps_to_device)(const struct scmi_handle *handle,
> +				  struct device *dev);
> +	int (*freq_set)(const struct scmi_handle *handle, u32 domain,
> +			unsigned long rate);
> +	int (*freq_get)(const struct scmi_handle *handle, u32 domain,
> +			unsigned long *rate);
> +};
> +
>  /**
>   * struct scmi_handle - Handle returned to ARM SCMI clients for usage.
>   *
>   * @dev: pointer to the SCMI device
>   * @version: pointer to the structure containing SCMI version information
> + * @perf_ops: pointer to set of performance protocol operations
>   */
>  struct scmi_handle {
>  	struct device *dev;
>  	struct scmi_revision_info *version;
> +	struct scmi_perf_ops *perf_ops;
> +	/* for protocol internal use */
> +	void *perf_priv;
>  };
>  
>  enum scmi_std_protocol {

  reply	other threads:[~2018-03-05 14:29 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-23 16:23 [PATCH v6 00/20] firmware: ARM System Control and Management Interface(SCMI) support Sudeep Holla
2018-02-23 16:23 ` Sudeep Holla
2018-02-23 16:23 ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 01/20] dt-bindings: mailbox: add support for mailbox client shared memory Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 02/20] dt-bindings: arm: add support for ARM System Control and Management Interface(SCMI) protocol Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 03/20] firmware: arm_scmi: add basic driver infrastructure for SCMI Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-26 15:57   ` Philippe Ombredanne
2018-02-26 15:57     ` Philippe Ombredanne
2018-02-26 17:10     ` Sudeep Holla
2018-02-26 17:10       ` Sudeep Holla
2018-03-05 13:52   ` Jonathan Cameron
2018-03-05 13:52     ` Jonathan Cameron
2018-03-05 14:30     ` Sudeep Holla
2018-03-05 14:30       ` Sudeep Holla
2018-03-05 14:47       ` Jonathan Cameron
2018-03-05 14:47         ` Jonathan Cameron
2018-02-23 16:23 ` [PATCH v6 04/20] firmware: arm_scmi: add common infrastructure and support for base protocol Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-03-05 14:11   ` Jonathan Cameron
2018-03-05 14:11     ` Jonathan Cameron
2018-02-23 16:23 ` [PATCH v6 05/20] firmware: arm_scmi: add scmi protocol bus to enumerate protocol devices Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-03-05 14:23   ` Jonathan Cameron
2018-03-05 14:23     ` Jonathan Cameron
2018-02-23 16:23 ` [PATCH v6 06/20] firmware: arm_scmi: add initial support for performance protocol Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-03-05 14:29   ` Jonathan Cameron [this message]
2018-03-05 14:29     ` Jonathan Cameron
2018-02-23 16:23 ` [PATCH v6 07/20] firmware: arm_scmi: add initial support for clock protocol Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 08/20] firmware: arm_scmi: add initial support for power protocol Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 09/20] firmware: arm_scmi: add initial support for sensor protocol Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 10/20] firmware: arm_scmi: probe and initialise all the supported protocols Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 11/20] firmware: arm_scmi: add support for polling based SCMI transfers Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 12/20] firmware: arm_scmi: add option for polling based performance domain operations Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 13/20] firmware: arm_scmi: refactor in preparation to support per-protocol channels Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-03-05 14:35   ` Jonathan Cameron
2018-03-05 14:35     ` Jonathan Cameron
2018-03-05 14:43     ` Sudeep Holla
2018-03-05 14:43       ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 14/20] firmware: arm_scmi: add per-protocol channels support using idr objects Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 15/20] firmware: arm_scmi: add device power domain support using genpd Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 16/20] clk: add support for clocks provided by SCMI Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-03-16 23:02   ` Stephen Boyd
2018-03-16 23:02     ` Stephen Boyd
2018-03-16 23:02     ` Stephen Boyd
2018-03-16 23:02     ` Stephen Boyd
2018-03-20 12:08     ` Sudeep Holla
2018-03-20 12:08       ` Sudeep Holla
2018-03-20 16:22       ` Stephen Boyd
2018-03-20 16:22         ` Stephen Boyd
2018-03-20 16:22         ` Stephen Boyd
2018-03-20 16:22         ` Stephen Boyd
2018-03-20 12:11   ` [PATCH] clk: scmi: use devm_of_clk_add_hw_provider() API and drop scmi_clocks_remove Sudeep Holla
2018-03-20 14:42     ` Sudeep Holla
2018-03-20 16:22     ` Stephen Boyd
2018-03-20 16:22       ` Stephen Boyd
2018-02-23 16:23 ` [PATCH v6 17/20] hwmon: (core) Add hwmon_max to hwmon_sensor_types enumeration Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 18/20] hwmon: add support for sensors exported via ARM SCMI Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 19/20] cpufreq: add support for CPU DVFS based on SCMI message protocol Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23 ` [PATCH v6 20/20] cpufreq: scmi: add support for fast frequency switching Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla
2018-02-23 16:23   ` Sudeep Holla

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=20180305152903.0000417e@huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=linux-arm-kernel@lists.infradead.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.