Commit 7990da71 authored by Tomeu Vizoso's avatar Tomeu Vizoso Committed by Rafael J. Wysocki

PM / QoS: Add PM_QOS_MEMORY_BANDWIDTH class

Also adds a class type PM_QOS_SUM that aggregates the values by summing them.

It can be used by memory controllers to calculate the optimum clock frequency
based on the bandwidth needs of the different memory clients.
Signed-off-by: default avatarTomeu Vizoso <tomeu.vizoso@collabora.com>
Acked-by: default avatarPavel Machek <pavel@ucw.cz>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 0f33be00
...@@ -5,7 +5,8 @@ performance expectations by drivers, subsystems and user space applications on ...@@ -5,7 +5,8 @@ performance expectations by drivers, subsystems and user space applications on
one of the parameters. one of the parameters.
Two different PM QoS frameworks are available: Two different PM QoS frameworks are available:
1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput. 1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput,
memory_bandwidth.
2. the per-device PM QoS framework provides the API to manage the per-device latency 2. the per-device PM QoS framework provides the API to manage the per-device latency
constraints and PM QoS flags. constraints and PM QoS flags.
...@@ -13,6 +14,7 @@ Each parameters have defined units: ...@@ -13,6 +14,7 @@ Each parameters have defined units:
* latency: usec * latency: usec
* timeout: usec * timeout: usec
* throughput: kbs (kilo bit / sec) * throughput: kbs (kilo bit / sec)
* memory bandwidth: mbs (mega bit / sec)
1. PM QoS framework 1. PM QoS framework
......
...@@ -15,6 +15,7 @@ enum { ...@@ -15,6 +15,7 @@ enum {
PM_QOS_CPU_DMA_LATENCY, PM_QOS_CPU_DMA_LATENCY,
PM_QOS_NETWORK_LATENCY, PM_QOS_NETWORK_LATENCY,
PM_QOS_NETWORK_THROUGHPUT, PM_QOS_NETWORK_THROUGHPUT,
PM_QOS_MEMORY_BANDWIDTH,
/* insert new class ID */ /* insert new class ID */
PM_QOS_NUM_CLASSES, PM_QOS_NUM_CLASSES,
...@@ -32,6 +33,7 @@ enum pm_qos_flags_status { ...@@ -32,6 +33,7 @@ enum pm_qos_flags_status {
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC) #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0 #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
#define PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE 0
#define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE 0 #define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE 0
#define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0 #define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0
#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
...@@ -69,7 +71,8 @@ struct dev_pm_qos_request { ...@@ -69,7 +71,8 @@ struct dev_pm_qos_request {
enum pm_qos_type { enum pm_qos_type {
PM_QOS_UNITIALIZED, PM_QOS_UNITIALIZED,
PM_QOS_MAX, /* return the largest value */ PM_QOS_MAX, /* return the largest value */
PM_QOS_MIN /* return the smallest value */ PM_QOS_MIN, /* return the smallest value */
PM_QOS_SUM /* return the sum */
}; };
/* /*
......
...@@ -105,11 +105,27 @@ static struct pm_qos_object network_throughput_pm_qos = { ...@@ -105,11 +105,27 @@ static struct pm_qos_object network_throughput_pm_qos = {
}; };
static BLOCKING_NOTIFIER_HEAD(memory_bandwidth_notifier);
static struct pm_qos_constraints memory_bw_constraints = {
.list = PLIST_HEAD_INIT(memory_bw_constraints.list),
.target_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE,
.default_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE,
.no_constraint_value = PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE,
.type = PM_QOS_SUM,
.notifiers = &memory_bandwidth_notifier,
};
static struct pm_qos_object memory_bandwidth_pm_qos = {
.constraints = &memory_bw_constraints,
.name = "memory_bandwidth",
};
static struct pm_qos_object *pm_qos_array[] = { static struct pm_qos_object *pm_qos_array[] = {
&null_pm_qos, &null_pm_qos,
&cpu_dma_pm_qos, &cpu_dma_pm_qos,
&network_lat_pm_qos, &network_lat_pm_qos,
&network_throughput_pm_qos &network_throughput_pm_qos,
&memory_bandwidth_pm_qos,
}; };
static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf, static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
...@@ -130,6 +146,9 @@ static const struct file_operations pm_qos_power_fops = { ...@@ -130,6 +146,9 @@ static const struct file_operations pm_qos_power_fops = {
/* unlocked internal variant */ /* unlocked internal variant */
static inline int pm_qos_get_value(struct pm_qos_constraints *c) static inline int pm_qos_get_value(struct pm_qos_constraints *c)
{ {
struct plist_node *node;
int total_value = 0;
if (plist_head_empty(&c->list)) if (plist_head_empty(&c->list))
return c->no_constraint_value; return c->no_constraint_value;
...@@ -140,6 +159,12 @@ static inline int pm_qos_get_value(struct pm_qos_constraints *c) ...@@ -140,6 +159,12 @@ static inline int pm_qos_get_value(struct pm_qos_constraints *c)
case PM_QOS_MAX: case PM_QOS_MAX:
return plist_last(&c->list)->prio; return plist_last(&c->list)->prio;
case PM_QOS_SUM:
plist_for_each(node, &c->list)
total_value += node->prio;
return total_value;
default: default:
/* runtime check for not using enum */ /* runtime check for not using enum */
BUG(); BUG();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment