2019-06-04 16:11:33 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
PM: Introduce devfreq: generic DVFS framework with device-specific OPPs
With OPPs, a device may have multiple operable frequency and voltage
sets. However, there can be multiple possible operable sets and a system
will need to choose one from them. In order to reduce the power
consumption (by reducing frequency and voltage) without affecting the
performance too much, a Dynamic Voltage and Frequency Scaling (DVFS)
scheme may be used.
This patch introduces the DVFS capability to non-CPU devices with OPPs.
DVFS is a techique whereby the frequency and supplied voltage of a
device is adjusted on-the-fly. DVFS usually sets the frequency as low
as possible with given conditions (such as QoS assurance) and adjusts
voltage according to the chosen frequency in order to reduce power
consumption and heat dissipation.
The generic DVFS for devices, devfreq, may appear quite similar with
/drivers/cpufreq. However, cpufreq does not allow to have multiple
devices registered and is not suitable to have multiple heterogenous
devices with different (but simple) governors.
Normally, DVFS mechanism controls frequency based on the demand for
the device, and then, chooses voltage based on the chosen frequency.
devfreq also controls the frequency based on the governor's frequency
recommendation and let OPP pick up the pair of frequency and voltage
based on the recommended frequency. Then, the chosen OPP is passed to
device driver's "target" callback.
When PM QoS is going to be used with the devfreq device, the device
driver should enable OPPs that are appropriate with the current PM QoS
requests. In order to do so, the device driver may call opp_enable and
opp_disable at the notifier callback of PM QoS so that PM QoS's
update_target() call enables the appropriate OPPs. Note that at least
one of OPPs should be enabled at any time; be careful when there is a
transition.
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Mike Turquette <mturquette@ti.com>
Acked-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-10-02 06:19:15 +08:00
|
|
|
/*
|
|
|
|
* governor.h - internal header for devfreq governors.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Samsung Electronics
|
|
|
|
* MyungJoo Ham <myungjoo.ham@samsung.com>
|
|
|
|
*
|
|
|
|
* This header is for devfreq governors in drivers/devfreq/
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _GOVERNOR_H
|
|
|
|
#define _GOVERNOR_H
|
|
|
|
|
|
|
|
#include <linux/devfreq.h>
|
|
|
|
|
|
|
|
#define to_devfreq(DEV) container_of((DEV), struct devfreq, dev)
|
|
|
|
|
2012-10-26 07:50:09 +08:00
|
|
|
/* Devfreq events */
|
|
|
|
#define DEVFREQ_GOV_START 0x1
|
|
|
|
#define DEVFREQ_GOV_STOP 0x2
|
2020-01-29 12:24:18 +08:00
|
|
|
#define DEVFREQ_GOV_UPDATE_INTERVAL 0x3
|
2012-10-26 07:50:18 +08:00
|
|
|
#define DEVFREQ_GOV_SUSPEND 0x4
|
|
|
|
#define DEVFREQ_GOV_RESUME 0x5
|
2012-10-26 07:50:09 +08:00
|
|
|
|
2018-08-04 04:05:10 +08:00
|
|
|
#define DEVFREQ_MIN_FREQ 0
|
|
|
|
#define DEVFREQ_MAX_FREQ ULONG_MAX
|
|
|
|
|
2017-04-06 12:19:35 +08:00
|
|
|
/**
|
|
|
|
* struct devfreq_governor - Devfreq policy governor
|
|
|
|
* @node: list node - contains registered devfreq governors
|
|
|
|
* @name: Governor's name
|
|
|
|
* @immutable: Immutable flag for governor. If the value is 1,
|
2020-02-14 14:05:06 +08:00
|
|
|
* this governor is never changeable to other governor.
|
2019-11-05 05:56:14 +08:00
|
|
|
* @interrupt_driven: Devfreq core won't schedule polling work for this
|
|
|
|
* governor if value is set to 1.
|
2017-04-06 12:19:35 +08:00
|
|
|
* @get_target_freq: Returns desired operating frequency for the device.
|
|
|
|
* Basically, get_target_freq will run
|
|
|
|
* devfreq_dev_profile.get_dev_status() to get the
|
|
|
|
* status of the device (load = busy_time / total_time).
|
|
|
|
* If no_central_polling is set, this callback is called
|
|
|
|
* only with update_devfreq() notified by OPP.
|
|
|
|
* @event_handler: Callback for devfreq core framework to notify events
|
|
|
|
* to governors. Events include per device governor
|
|
|
|
* init and exit, opp changes out of devfreq, suspend
|
|
|
|
* and resume of per device devfreq during device idle.
|
|
|
|
*
|
|
|
|
* Note that the callbacks are called with devfreq->lock locked by devfreq.
|
|
|
|
*/
|
|
|
|
struct devfreq_governor {
|
|
|
|
struct list_head node;
|
|
|
|
|
|
|
|
const char name[DEVFREQ_NAME_LEN];
|
|
|
|
const unsigned int immutable;
|
2019-11-05 05:56:14 +08:00
|
|
|
const unsigned int interrupt_driven;
|
2017-04-06 12:19:35 +08:00
|
|
|
int (*get_target_freq)(struct devfreq *this, unsigned long *freq);
|
|
|
|
int (*event_handler)(struct devfreq *devfreq,
|
|
|
|
unsigned int event, void *data);
|
|
|
|
};
|
|
|
|
|
2020-01-08 18:35:49 +08:00
|
|
|
void devfreq_monitor_start(struct devfreq *devfreq);
|
|
|
|
void devfreq_monitor_stop(struct devfreq *devfreq);
|
|
|
|
void devfreq_monitor_suspend(struct devfreq *devfreq);
|
|
|
|
void devfreq_monitor_resume(struct devfreq *devfreq);
|
2020-01-29 12:24:18 +08:00
|
|
|
void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay);
|
2012-10-30 04:01:43 +08:00
|
|
|
|
2020-01-08 18:35:49 +08:00
|
|
|
int devfreq_add_governor(struct devfreq_governor *governor);
|
|
|
|
int devfreq_remove_governor(struct devfreq_governor *governor);
|
2012-10-30 04:01:43 +08:00
|
|
|
|
2020-01-08 18:35:49 +08:00
|
|
|
int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
|
2017-01-31 14:38:17 +08:00
|
|
|
|
2017-08-24 09:42:50 +08:00
|
|
|
static inline int devfreq_update_stats(struct devfreq *df)
|
|
|
|
{
|
|
|
|
return df->profile->get_dev_status(df->dev.parent, &df->last_status);
|
|
|
|
}
|
PM: Introduce devfreq: generic DVFS framework with device-specific OPPs
With OPPs, a device may have multiple operable frequency and voltage
sets. However, there can be multiple possible operable sets and a system
will need to choose one from them. In order to reduce the power
consumption (by reducing frequency and voltage) without affecting the
performance too much, a Dynamic Voltage and Frequency Scaling (DVFS)
scheme may be used.
This patch introduces the DVFS capability to non-CPU devices with OPPs.
DVFS is a techique whereby the frequency and supplied voltage of a
device is adjusted on-the-fly. DVFS usually sets the frequency as low
as possible with given conditions (such as QoS assurance) and adjusts
voltage according to the chosen frequency in order to reduce power
consumption and heat dissipation.
The generic DVFS for devices, devfreq, may appear quite similar with
/drivers/cpufreq. However, cpufreq does not allow to have multiple
devices registered and is not suitable to have multiple heterogenous
devices with different (but simple) governors.
Normally, DVFS mechanism controls frequency based on the demand for
the device, and then, chooses voltage based on the chosen frequency.
devfreq also controls the frequency based on the governor's frequency
recommendation and let OPP pick up the pair of frequency and voltage
based on the recommended frequency. Then, the chosen OPP is passed to
device driver's "target" callback.
When PM QoS is going to be used with the devfreq device, the device
driver should enable OPPs that are appropriate with the current PM QoS
requests. In order to do so, the device driver may call opp_enable and
opp_disable at the notifier callback of PM QoS so that PM QoS's
update_target() call enables the appropriate OPPs. Note that at least
one of OPPs should be enabled at any time; be careful when there is a
transition.
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Mike Turquette <mturquette@ti.com>
Acked-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
2011-10-02 06:19:15 +08:00
|
|
|
#endif /* _GOVERNOR_H */
|