mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	On some systems the nominal_perf value retrieved via CPPC is just a constant and fetching it doesn't require accessing any registers, so if it is the only CPPC capability that's needed, it is wasteful to run cppc_get_perf_caps() in order to get just that value alone, especially when this is done for CPUs other than the one running the code. For this reason, introduce cppc_get_nominal_perf() allowing nominal_perf to be obtained individually, by generalizing the existing cppc_get_desired_perf() (and renaming it) so it can be used to retrieve any specific CPPC capability value. While at it, clean up the cppc_get_desired_perf() kerneldoc comment a bit. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
		
			
				
	
	
		
			191 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* 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>
 | 
						|
 | 
						|
/* 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_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_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_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_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*/
 |