5d8a1bc838
The possibility of a timeout being used with a PM QoS request incurs overhead for *all* PM QoS requests due to the necessary calls to cancel_delayed_work_sync(). Furthermore, using a timeout for a PM QoS request can lead to disastrous results on power consumption. It's always possible to find a fixed scope in which a PM QoS request should be applied, so timeouts aren't ever strictly needed; they're usually just a lazy way of using PM QoS. Remove the timeout API to eliminate the added overhead for non-timeout PM QoS requests, and so that timeouts cannot be misused. Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com> Signed-off-by: Nahuel Gómez <nahuelgomez329@gmail.com>
226 lines
8 KiB
C
Executable file
226 lines
8 KiB
C
Executable file
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_EXYNOS_PM_QOS_H
|
|
#define _LINUX_EXYNOS_PM_QOS_H
|
|
/* interface for the exynos_pm_qos_power infrastructure of the linux kernel.
|
|
*
|
|
* Mark Gross <mgross@linux.intel.com>
|
|
*/
|
|
#include <linux/plist.h>
|
|
#include <linux/notifier.h>
|
|
#include <linux/device.h>
|
|
#include <linux/mutex.h>
|
|
|
|
enum {
|
|
PM_QOS_NETWORK_LATENCY = 1,
|
|
PM_QOS_CLUSTER0_FREQ_MIN,
|
|
PM_QOS_CLUSTER0_FREQ_MAX,
|
|
PM_QOS_CLUSTER1_FREQ_MIN,
|
|
PM_QOS_CLUSTER1_FREQ_MAX,
|
|
PM_QOS_CLUSTER2_FREQ_MIN,
|
|
PM_QOS_CLUSTER2_FREQ_MAX,
|
|
PM_QOS_CPU_ONLINE_MIN,
|
|
PM_QOS_CPU_ONLINE_MAX,
|
|
PM_QOS_DEVICE_THROUGHPUT,
|
|
PM_QOS_INTCAM_THROUGHPUT,
|
|
PM_QOS_DEVICE_THROUGHPUT_MAX,
|
|
PM_QOS_INTCAM_THROUGHPUT_MAX,
|
|
PM_QOS_BUS_THROUGHPUT,
|
|
PM_QOS_BUS_THROUGHPUT_MAX,
|
|
PM_QOS_DISPLAY_THROUGHPUT,
|
|
PM_QOS_DISPLAY_THROUGHPUT_MAX,
|
|
PM_QOS_CAM_THROUGHPUT,
|
|
PM_QOS_AUD_THROUGHPUT,
|
|
PM_QOS_CAM_THROUGHPUT_MAX,
|
|
PM_QOS_AUD_THROUGHPUT_MAX,
|
|
PM_QOS_MFC_THROUGHPUT,
|
|
PM_QOS_NPU_THROUGHPUT,
|
|
PM_QOS_MFC_THROUGHPUT_MAX,
|
|
PM_QOS_NPU_THROUGHPUT_MAX,
|
|
PM_QOS_GPU_THROUGHPUT_MIN,
|
|
PM_QOS_GPU_THROUGHPUT_MAX,
|
|
PM_QOS_VPC_THROUGHPUT,
|
|
PM_QOS_VPC_THROUGHPUT_MAX,
|
|
PM_QOS_CSIS_THROUGHPUT,
|
|
PM_QOS_CSIS_THROUGHPUT_MAX,
|
|
PM_QOS_ISP_THROUGHPUT,
|
|
PM_QOS_ISP_THROUGHPUT_MAX,
|
|
PM_QOS_MFC1_THROUGHPUT,
|
|
PM_QOS_MFC1_THROUGHPUT_MAX,
|
|
PM_QOS_DNC_THROUGHPUT,
|
|
PM_QOS_DNC_THROUGHPUT_MAX,
|
|
PM_QOS_DSP_THROUGHPUT,
|
|
PM_QOS_DSP_THROUGHPUT_MAX,
|
|
PM_QOS_ALIVE_THROUGHPUT,
|
|
PM_QOS_ALIVE_THROUGHPUT_MAX,
|
|
PM_QOS_CHUB_THROUGHPUT,
|
|
PM_QOS_CHUB_THROUGHPUT_MAX,
|
|
PM_QOS_VTS_THROUGHPUT,
|
|
PM_QOS_VTS_THROUGHPUT_MAX,
|
|
PM_QOS_HSI0_THROUGHPUT,
|
|
PM_QOS_HSI0_THROUGHPUT_MAX,
|
|
PM_QOS_UFD_THROUGHPUT,
|
|
PM_QOS_UFD_THROUGHPUT_MAX,
|
|
/* insert new class ID */
|
|
EXYNOS_PM_QOS_NUM_CLASSES,
|
|
};
|
|
|
|
enum exynos_pm_qos_flags_status {
|
|
EXYNOS_PM_QOS_FLAGS_UNDEFINED = -1,
|
|
EXYNOS_PM_QOS_FLAGS_NONE,
|
|
EXYNOS_PM_QOS_FLAGS_SOME,
|
|
EXYNOS_PM_QOS_FLAGS_ALL,
|
|
};
|
|
|
|
#define EXYNOS_PM_QOS_DEFAULT_VALUE (-1)
|
|
#define EXYNOS_PM_QOS_LATENCY_ANY S32_MAX
|
|
#define EXYNOS_PM_QOS_LATENCY_ANY_NS ((s64)EXYNOS_PM_QOS_LATENCY_ANY * NSEC_PER_USEC)
|
|
|
|
#define EXYNOS_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_DEVICE_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_INTCAM_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_DEVICE_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_INTCAM_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_BUS_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_BUS_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_DISPLAY_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_DISPLAY_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_CAM_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_AUD_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_DSP_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_DNC_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_FSYS0_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_CAM_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_AUD_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_DSP_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_DNC_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_FSYS0_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_MFC_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_NPU_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_MFC_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_NPU_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE 0
|
|
#define PM_QOS_LATENCY_TOLERANCE_DEFAULT_VALUE 0
|
|
#define PM_QOS_MIN_FREQUENCY_DEFAULT_VALUE 0
|
|
#define PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE FREQ_QOS_MAX_DEFAULT_VALUE
|
|
#define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1)
|
|
#define PM_QOS_CLUSTER0_FREQ_MIN_DEFAULT_VALUE 0
|
|
#define PM_QOS_CLUSTER0_FREQ_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_CLUSTER1_FREQ_MIN_DEFAULT_VALUE 0
|
|
#define PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_CLUSTER2_FREQ_MIN_DEFAULT_VALUE 0
|
|
#define PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_CPU_ONLINE_MIN_DEFAULT_VALUE 1
|
|
#define PM_QOS_CPU_ONLINE_MAX_DEFAULT_VALUE NR_CPUS
|
|
#define PM_QOS_TNR_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_TNR_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_GPU_FREQ_MIN_DEFAULT_VALUE 0
|
|
#define PM_QOS_GPU_FREQ_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_VPC_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_VPC_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_CSIS_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_CSIS_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_ISP_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_ISP_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_MFC1_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_MFC1_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_DSP_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_DSP_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_CHUB_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_CHUB_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_VTS_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_VTS_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_HSI0_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_HSI0_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_ALIVE_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_ALIVE_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define PM_QOS_UFD_THROUGHPUT_DEFAULT_VALUE 0
|
|
#define PM_QOS_UFD_THROUGHPUT_MAX_DEFAULT_VALUE INT_MAX
|
|
#define EXYNOS_PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
|
|
|
|
#define exynos_pm_qos_add_request(arg...) do { \
|
|
exynos_pm_qos_add_request_trace((char *)__func__, __LINE__, ##arg); \
|
|
} while(0)
|
|
|
|
struct exynos_pm_qos_request {
|
|
struct plist_node node;
|
|
int exynos_pm_qos_class;
|
|
char *func;
|
|
unsigned int line;
|
|
ktime_t time;
|
|
};
|
|
|
|
struct exynos_pm_qos_flags_request {
|
|
struct list_head node;
|
|
s32 flags; /* Do not change to 64 bit */
|
|
};
|
|
|
|
enum exynos_pm_qos_type {
|
|
EXYNOS_PM_QOS_UNITIALIZED,
|
|
EXYNOS_PM_QOS_MAX, /* return the largest value */
|
|
EXYNOS_PM_QOS_MIN, /* return the smallest value */
|
|
EXYNOS_PM_QOS_SUM /* return the sum */
|
|
};
|
|
|
|
struct exynos_pm_qos_log {
|
|
ktime_t time;
|
|
char *func;
|
|
unsigned int line;
|
|
unsigned int prio;
|
|
unsigned int target;
|
|
unsigned int action;
|
|
};
|
|
#define EXYNOS_PM_QOS_LOG_LENGTH 128
|
|
/*
|
|
* Note: The lockless read path depends on the CPU accessing target_value
|
|
* or effective_flags atomically. Atomic access is only guaranteed on all CPU
|
|
* types linux supports for 32 bit quantites
|
|
*/
|
|
struct exynos_pm_qos_constraints {
|
|
struct plist_head list;
|
|
s32 target_value; /* Do not change to 64 bit */
|
|
s32 default_value;
|
|
s32 no_constraint_value;
|
|
enum exynos_pm_qos_type type;
|
|
struct blocking_notifier_head *notifiers;
|
|
spinlock_t lock;
|
|
struct mutex mlock;
|
|
|
|
struct exynos_pm_qos_log log[EXYNOS_PM_QOS_LOG_LENGTH];
|
|
unsigned int log_index;
|
|
};
|
|
|
|
struct exynos_pm_qos_flags {
|
|
struct list_head list;
|
|
s32 effective_flags; /* Do not change to 64 bit */
|
|
};
|
|
|
|
|
|
/* Action requested to exynos_pm_qos_update_target */
|
|
enum exynos_pm_qos_req_action {
|
|
EXYNOS_PM_QOS_ADD_REQ, /* Add a new request */
|
|
EXYNOS_PM_QOS_UPDATE_REQ, /* Update an existing request */
|
|
EXYNOS_PM_QOS_REMOVE_REQ /* Remove an existing request */
|
|
};
|
|
|
|
extern int exynos_pm_qos_update_target(struct exynos_pm_qos_constraints *c, struct plist_node *node,
|
|
enum exynos_pm_qos_req_action action, int value, bool nosync);
|
|
extern void exynos_pm_qos_add_request_trace(char *func, unsigned int line,
|
|
struct exynos_pm_qos_request *req, int exynos_pm_qos_class,
|
|
s32 value);
|
|
extern void exynos_pm_qos_update_request(struct exynos_pm_qos_request *req,
|
|
s32 new_value);
|
|
extern void exynos_pm_qos_update_request_nosync(struct exynos_pm_qos_request *req,
|
|
s32 new_value);
|
|
extern void exynos_pm_qos_remove_request(struct exynos_pm_qos_request *req);
|
|
|
|
extern int exynos_pm_qos_request(int exynos_pm_qos_class);
|
|
extern int exynos_pm_qos_add_notifier(int exynos_pm_qos_class, struct notifier_block *notifier);
|
|
extern int exynos_pm_qos_remove_notifier(int exynos_pm_qos_class, struct notifier_block *notifier);
|
|
extern int exynos_pm_qos_request_active(struct exynos_pm_qos_request *req);
|
|
extern s32 exynos_pm_qos_read_value(struct exynos_pm_qos_constraints *c);
|
|
extern int exynos_pm_qos_read_req_value(int pm_qos_class, struct exynos_pm_qos_request *req);
|
|
extern void show_exynos_pm_qos_data(int index);
|
|
|
|
#endif
|