forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
4.1 KiB
186 lines
4.1 KiB
/* 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 <[email protected]> |
|
*/ |
|
|
|
#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> |
|
|
|
/* Support CPPCv2 and CPPCv3 */ |
|
#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; |
|
}; |
|
|
|
struct cppc_perf_ctrls { |
|
u32 max_perf; |
|
u32 min_perf; |
|
u32 desired_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_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_get_perf_caps(int cpu, struct cppc_perf_caps *caps); |
|
extern bool acpi_cpc_valid(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 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); |
|
#else /* !CONFIG_ACPI_CPPC_LIB */ |
|
static inline int cppc_get_desired_perf(int cpunum, u64 *desired_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_get_perf_caps(int cpu, struct cppc_perf_caps *caps) |
|
{ |
|
return -ENOTSUPP; |
|
} |
|
static inline bool acpi_cpc_valid(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; |
|
} |
|
#endif /* !CONFIG_ACPI_CPPC_LIB */ |
|
|
|
#endif /* _CPPC_ACPI_H*/
|
|
|