blob: c56773c257579fa177866a88c3159964373f3f69 [file] [log] [blame]
Thomas Gleixnerd2912cb2019-06-04 10:11:33 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Viresh Kumar4471a342012-10-26 00:47:42 +02002/*
3 * drivers/cpufreq/cpufreq_governor.h
4 *
5 * Header file for CPUFreq governors common code
6 *
7 * Copyright (C) 2001 Russell King
8 * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
9 * (C) 2003 Jun Nakajima <jun.nakajima@intel.com>
10 * (C) 2009 Alexander Clouter <alex@digriz.org.uk>
11 * (c) 2012 Viresh Kumar <viresh.kumar@linaro.org>
Viresh Kumar4471a342012-10-26 00:47:42 +020012 */
13
Borislav Petkovbeb0ff32013-04-02 12:26:15 +000014#ifndef _CPUFREQ_GOVERNOR_H
15#define _CPUFREQ_GOVERNOR_H
Viresh Kumar4471a342012-10-26 00:47:42 +020016
Rafael J. Wysocki2dd3e722015-12-08 21:44:05 +010017#include <linux/atomic.h>
Rafael J. Wysocki9be4fd22016-02-10 16:53:50 +010018#include <linux/irq_work.h>
Viresh Kumar4471a342012-10-26 00:47:42 +020019#include <linux/cpufreq.h>
Ingo Molnar55687da2017-02-08 18:51:31 +010020#include <linux/sched/cpufreq.h>
Viresh Kumar5ff0a262013-08-06 22:53:03 +053021#include <linux/kernel_stat.h>
22#include <linux/module.h>
Viresh Kumar4471a342012-10-26 00:47:42 +020023#include <linux/mutex.h>
Viresh Kumar4471a342012-10-26 00:47:42 +020024
Viresh Kumar4471a342012-10-26 00:47:42 +020025/* Ondemand Sampling types */
26enum {OD_NORMAL_SAMPLE, OD_SUB_SAMPLE};
27
Viresh Kumar4471a342012-10-26 00:47:42 +020028/*
29 * Abbreviations:
30 * dbs: used as a shortform for demand based switching It helps to keep variable
31 * names smaller, simpler
32 * cdbs: common dbs
Namhyung Kime5dde922013-02-28 05:38:00 +000033 * od_*: On-demand governor
Viresh Kumar4471a342012-10-26 00:47:42 +020034 * cs_*: Conservative governor
35 */
36
Rafael J. Wysockibc505472016-02-07 16:24:26 +010037/* Governor demand based switching data (per-policy or global). */
38struct dbs_data {
Rafael J. Wysocki0dd3c1d2016-03-22 02:47:51 +010039 struct gov_attr_set attr_set;
Rafael J. Wysockibc505472016-02-07 16:24:26 +010040 void *tuners;
Viresh Kumarff4b1782016-02-09 09:01:32 +053041 unsigned int ignore_nice_load;
42 unsigned int sampling_rate;
43 unsigned int sampling_down_factor;
44 unsigned int up_threshold;
Rafael J. Wysocki8847e032016-02-18 02:20:13 +010045 unsigned int io_is_busy;
Rafael J. Wysockibc505472016-02-07 16:24:26 +010046};
47
Rafael J. Wysocki0dd3c1d2016-03-22 02:47:51 +010048static inline struct dbs_data *to_dbs_data(struct gov_attr_set *attr_set)
49{
50 return container_of(attr_set, struct dbs_data, attr_set);
51}
52
Viresh Kumarc4435632016-02-09 09:01:33 +053053#define gov_show_one(_gov, file_name) \
54static ssize_t show_##file_name \
Rafael J. Wysocki0dd3c1d2016-03-22 02:47:51 +010055(struct gov_attr_set *attr_set, char *buf) \
Viresh Kumarc4435632016-02-09 09:01:33 +053056{ \
Rafael J. Wysocki0dd3c1d2016-03-22 02:47:51 +010057 struct dbs_data *dbs_data = to_dbs_data(attr_set); \
Viresh Kumarc4435632016-02-09 09:01:33 +053058 struct _gov##_dbs_tuners *tuners = dbs_data->tuners; \
59 return sprintf(buf, "%u\n", tuners->file_name); \
60}
61
62#define gov_show_one_common(file_name) \
63static ssize_t show_##file_name \
Rafael J. Wysocki0dd3c1d2016-03-22 02:47:51 +010064(struct gov_attr_set *attr_set, char *buf) \
Viresh Kumarc4435632016-02-09 09:01:33 +053065{ \
Rafael J. Wysocki0dd3c1d2016-03-22 02:47:51 +010066 struct dbs_data *dbs_data = to_dbs_data(attr_set); \
Viresh Kumarc4435632016-02-09 09:01:33 +053067 return sprintf(buf, "%u\n", dbs_data->file_name); \
68}
69
70#define gov_attr_ro(_name) \
71static struct governor_attr _name = \
72__ATTR(_name, 0444, show_##_name, NULL)
73
74#define gov_attr_rw(_name) \
75static struct governor_attr _name = \
76__ATTR(_name, 0644, show_##_name, store_##_name)
77
Viresh Kumar44152cb2015-07-18 11:30:59 +053078/* Common to all CPUs of a policy */
Rafael J. Wysockie40e7b22016-02-10 17:07:44 +010079struct policy_dbs_info {
Viresh Kumar44152cb2015-07-18 11:30:59 +053080 struct cpufreq_policy *policy;
81 /*
Viresh Kumar70f43e52015-12-09 07:34:42 +053082 * Per policy mutex that serializes load evaluation from limit-change
83 * and work-handler.
Viresh Kumar44152cb2015-07-18 11:30:59 +053084 */
Viresh Kumar26f0dbc2016-11-08 11:06:33 +053085 struct mutex update_mutex;
Viresh Kumar70f43e52015-12-09 07:34:42 +053086
Rafael J. Wysocki9be4fd22016-02-10 16:53:50 +010087 u64 last_sample_time;
88 s64 sample_delay_ns;
Rafael J. Wysocki686cc632016-02-08 23:41:10 +010089 atomic_t work_count;
Rafael J. Wysocki9be4fd22016-02-10 16:53:50 +010090 struct irq_work irq_work;
Viresh Kumar70f43e52015-12-09 07:34:42 +053091 struct work_struct work;
Rafael J. Wysockibc505472016-02-07 16:24:26 +010092 /* dbs_data may be shared between multiple policy objects */
93 struct dbs_data *dbs_data;
Viresh Kumarc54df072016-02-10 11:00:25 +053094 struct list_head list;
Rafael J. Wysocki57dc3bc2016-02-15 02:20:51 +010095 /* Multiplier for increasing sample delay temporarily. */
96 unsigned int rate_mult;
Stratos Karafotis00bfe052016-11-16 19:26:29 +020097 unsigned int idle_periods; /* For conservative */
Rafael J. Wysockie4db2812016-02-15 02:13:42 +010098 /* Status indicators */
99 bool is_shared; /* This object is used by multiple CPUs */
100 bool work_in_progress; /* Work is being queued up or in progress */
Viresh Kumar44152cb2015-07-18 11:30:59 +0530101};
102
Rafael J. Wysockie40e7b22016-02-10 17:07:44 +0100103static inline void gov_update_sample_delay(struct policy_dbs_info *policy_dbs,
Rafael J. Wysocki9be4fd22016-02-10 16:53:50 +0100104 unsigned int delay_us)
105{
Rafael J. Wysockie40e7b22016-02-10 17:07:44 +0100106 policy_dbs->sample_delay_ns = delay_us * NSEC_PER_USEC;
Rafael J. Wysocki9be4fd22016-02-10 16:53:50 +0100107}
108
Viresh Kumar4471a342012-10-26 00:47:42 +0200109/* Per cpu structures */
Viresh Kumar875b8502015-06-19 17:18:03 +0530110struct cpu_dbs_info {
Viresh Kumar1e7586a2012-10-26 00:51:21 +0200111 u64 prev_cpu_idle;
Rafael J. Wysockib4f4b4b2016-04-28 01:19:03 +0200112 u64 prev_update_time;
Viresh Kumar1e7586a2012-10-26 00:51:21 +0200113 u64 prev_cpu_nice;
Srivatsa S. Bhat18b46ab2014-06-08 02:11:43 +0530114 /*
Viresh Kumarc8ae4812014-06-09 14:21:24 +0530115 * Used to keep track of load in the previous interval. However, when
116 * explicitly set to zero, it is used as a flag to ensure that we copy
117 * the previous load to the current interval only once, upon the first
118 * wake-up from idle.
Srivatsa S. Bhat18b46ab2014-06-08 02:11:43 +0530119 */
Viresh Kumarc8ae4812014-06-09 14:21:24 +0530120 unsigned int prev_load;
Rafael J. Wysocki9be4fd22016-02-10 16:53:50 +0100121 struct update_util_data update_util;
Rafael J. Wysockie40e7b22016-02-10 17:07:44 +0100122 struct policy_dbs_info *policy_dbs;
Viresh Kumar4471a342012-10-26 00:47:42 +0200123};
124
Stratos Karafotisc4afc412013-08-26 21:42:21 +0300125/* Common Governor data across policies */
Rafael J. Wysocki7bdad342016-02-07 16:05:07 +0100126struct dbs_governor {
Rafael J. Wysockiaf926182016-02-05 03:16:08 +0100127 struct cpufreq_governor gov;
Viresh Kumarc4435632016-02-09 09:01:33 +0530128 struct kobj_type kobj_type;
Viresh Kumar4471a342012-10-26 00:47:42 +0200129
Viresh Kumar0b981e72013-10-02 14:13:18 +0530130 /*
131 * Common data for platforms that don't set
132 * CPUFREQ_HAVE_GOVERNOR_PER_POLICY
133 */
Viresh Kumar4d5dcc42013-03-27 15:58:58 +0000134 struct dbs_data *gdbs_data;
Viresh Kumar4471a342012-10-26 00:47:42 +0200135
Viresh Kumar26f0dbc2016-11-08 11:06:33 +0530136 unsigned int (*gov_dbs_update)(struct cpufreq_policy *policy);
Rafael J. Wysocki7d5a9952016-02-18 18:40:14 +0100137 struct policy_dbs_info *(*alloc)(void);
138 void (*free)(struct policy_dbs_info *policy_dbs);
Rafael J. Wysocki9a15fb22016-05-18 22:59:49 +0200139 int (*init)(struct dbs_data *dbs_data);
140 void (*exit)(struct dbs_data *dbs_data);
Rafael J. Wysocki702c9e52016-02-18 02:21:21 +0100141 void (*start)(struct cpufreq_policy *policy);
Viresh Kumar4471a342012-10-26 00:47:42 +0200142};
143
Rafael J. Wysockiea59ee0d2016-02-07 16:09:51 +0100144static inline struct dbs_governor *dbs_governor_of(struct cpufreq_policy *policy)
145{
146 return container_of(policy->governor, struct dbs_governor, gov);
147}
148
Rafael J. Wysockie7888922016-06-02 23:24:15 +0200149/* Governor callback routines */
150int cpufreq_dbs_governor_init(struct cpufreq_policy *policy);
151void cpufreq_dbs_governor_exit(struct cpufreq_policy *policy);
152int cpufreq_dbs_governor_start(struct cpufreq_policy *policy);
153void cpufreq_dbs_governor_stop(struct cpufreq_policy *policy);
154void cpufreq_dbs_governor_limits(struct cpufreq_policy *policy);
155
156#define CPUFREQ_DBS_GOVERNOR_INITIALIZER(_name_) \
157 { \
158 .name = _name_, \
Viresh Kumared4676e2017-07-19 15:42:46 +0530159 .dynamic_switching = true, \
Rafael J. Wysockie7888922016-06-02 23:24:15 +0200160 .owner = THIS_MODULE, \
161 .init = cpufreq_dbs_governor_init, \
162 .exit = cpufreq_dbs_governor_exit, \
163 .start = cpufreq_dbs_governor_start, \
164 .stop = cpufreq_dbs_governor_stop, \
165 .limits = cpufreq_dbs_governor_limits, \
166 }
167
Rafael J. Wysocki8434dad2016-02-18 02:22:42 +0100168/* Governor specific operations */
Viresh Kumar4471a342012-10-26 00:47:42 +0200169struct od_ops {
Viresh Kumar4471a342012-10-26 00:47:42 +0200170 unsigned int (*powersave_bias_target)(struct cpufreq_policy *policy,
171 unsigned int freq_next, unsigned int relation);
Viresh Kumar4471a342012-10-26 00:47:42 +0200172};
173
Rafael J. Wysocki4cccf752016-02-15 02:19:31 +0100174unsigned int dbs_update(struct cpufreq_policy *policy);
Jacob Shinfb308092013-04-02 09:56:56 -0500175void od_register_powersave_bias_handler(unsigned int (*f)
176 (struct cpufreq_policy *, unsigned int, unsigned int),
177 unsigned int powersave_bias);
178void od_unregister_powersave_bias_handler(void);
Rafael J. Wysocki0dd3c1d2016-03-22 02:47:51 +0100179ssize_t store_sampling_rate(struct gov_attr_set *attr_set, const char *buf,
Viresh Kumaraded3872016-02-11 17:31:15 +0530180 size_t count);
Rafael J. Wysocki8c8f77f2016-02-21 00:51:27 +0100181void gov_update_cpu_data(struct dbs_data *dbs_data);
Borislav Petkovbeb0ff32013-04-02 12:26:15 +0000182#endif /* _CPUFREQ_GOVERNOR_H */