diff options
Diffstat (limited to 'include/acpi/cppc_acpi.h')
-rw-r--r-- | include/acpi/cppc_acpi.h | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h new file mode 100644 index 0000000000..6126c977ec --- /dev/null +++ b/include/acpi/cppc_acpi.h @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * CPPC (Collaborative Processor Performance Control) methods used + * by CPUfreq drivers. + * + * (C) Copyright 2014, 2015 Linaro Ltd. + * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org> + */ + +#ifndef _CPPC_ACPI_H +#define _CPPC_ACPI_H + +#include <linux/acpi.h> +#include <linux/cpufreq.h> +#include <linux/types.h> + +#include <acpi/pcc.h> +#include <acpi/processor.h> + +/* CPPCv2 and CPPCv3 support */ +#define CPPC_V2_REV 2 +#define CPPC_V3_REV 3 +#define CPPC_V2_NUM_ENT 21 +#define CPPC_V3_NUM_ENT 23 + +#define PCC_CMD_COMPLETE_MASK (1 << 0) +#define PCC_ERROR_MASK (1 << 2) + +#define MAX_CPC_REG_ENT 21 + +/* CPPC specific PCC commands. */ +#define CMD_READ 0 +#define CMD_WRITE 1 + +/* Each register has the folowing format. */ +struct cpc_reg { + u8 descriptor; + u16 length; + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 access_width; + u64 address; +} __packed; + +/* + * Each entry in the CPC table is either + * of type ACPI_TYPE_BUFFER or + * ACPI_TYPE_INTEGER. + */ +struct cpc_register_resource { + acpi_object_type type; + u64 __iomem *sys_mem_vaddr; + union { + struct cpc_reg reg; + u64 int_value; + } cpc_entry; +}; + +/* Container to hold the CPC details for each CPU */ +struct cpc_desc { + int num_entries; + int version; + int cpu_id; + int write_cmd_status; + int write_cmd_id; + struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT]; + struct acpi_psd_package domain_info; + struct kobject kobj; +}; + +/* These are indexes into the per-cpu cpc_regs[]. Order is important. */ +enum cppc_regs { + HIGHEST_PERF, + NOMINAL_PERF, + LOW_NON_LINEAR_PERF, + LOWEST_PERF, + GUARANTEED_PERF, + DESIRED_PERF, + MIN_PERF, + MAX_PERF, + PERF_REDUC_TOLERANCE, + TIME_WINDOW, + CTR_WRAP_TIME, + REFERENCE_CTR, + DELIVERED_CTR, + PERF_LIMITED, + ENABLE, + AUTO_SEL_ENABLE, + AUTO_ACT_WINDOW, + ENERGY_PERF, + REFERENCE_PERF, + LOWEST_FREQ, + NOMINAL_FREQ, +}; + +/* + * Categorization of registers as described + * in the ACPI v.5.1 spec. + * XXX: Only filling up ones which are used by governors + * today. + */ +struct cppc_perf_caps { + u32 guaranteed_perf; + u32 highest_perf; + u32 nominal_perf; + u32 lowest_perf; + u32 lowest_nonlinear_perf; + u32 lowest_freq; + u32 nominal_freq; + u32 energy_perf; + bool auto_sel; +}; + +struct cppc_perf_ctrls { + u32 max_perf; + u32 min_perf; + u32 desired_perf; + u32 energy_perf; +}; + +struct cppc_perf_fb_ctrs { + u64 reference; + u64 delivered; + u64 reference_perf; + u64 wraparound_time; +}; + +/* Per CPU container for runtime CPPC management. */ +struct cppc_cpudata { + struct list_head node; + struct cppc_perf_caps perf_caps; + struct cppc_perf_ctrls perf_ctrls; + struct cppc_perf_fb_ctrs perf_fb_ctrs; + unsigned int shared_type; + cpumask_var_t shared_cpu_map; +}; + +#ifdef CONFIG_ACPI_CPPC_LIB +extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf); +extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf); +extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); +extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); +extern int cppc_set_enable(int cpu, bool enable); +extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps); +extern bool cppc_perf_ctrs_in_pcc(void); +extern bool acpi_cpc_valid(void); +extern bool cppc_allow_fast_switch(void); +extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data); +extern unsigned int cppc_get_transition_latency(int cpu); +extern bool cpc_ffh_supported(void); +extern bool cpc_supported_by_cpu(void); +extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val); +extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val); +extern int cppc_get_epp_perf(int cpunum, u64 *epp_perf); +extern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable); +extern int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps); +extern int cppc_set_auto_sel(int cpu, bool enable); +#else /* !CONFIG_ACPI_CPPC_LIB */ +static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf) +{ + return -ENOTSUPP; +} +static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf) +{ + return -ENOTSUPP; +} +static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs) +{ + return -ENOTSUPP; +} +static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls) +{ + return -ENOTSUPP; +} +static inline int cppc_set_enable(int cpu, bool enable) +{ + return -ENOTSUPP; +} +static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps) +{ + return -ENOTSUPP; +} +static inline bool cppc_perf_ctrs_in_pcc(void) +{ + return false; +} +static inline bool acpi_cpc_valid(void) +{ + return false; +} +static inline bool cppc_allow_fast_switch(void) +{ + return false; +} +static inline unsigned int cppc_get_transition_latency(int cpu) +{ + return CPUFREQ_ETERNAL; +} +static inline bool cpc_ffh_supported(void) +{ + return false; +} +static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val) +{ + return -ENOTSUPP; +} +static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val) +{ + return -ENOTSUPP; +} +static inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable) +{ + return -ENOTSUPP; +} +static inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf) +{ + return -ENOTSUPP; +} +static inline int cppc_set_auto_sel(int cpu, bool enable) +{ + return -ENOTSUPP; +} +static inline int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps) +{ + return -ENOTSUPP; +} +#endif /* !CONFIG_ACPI_CPPC_LIB */ + +#endif /* _CPPC_ACPI_H*/ |