162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * CPPC (Collaborative Processor Performance Control) methods used
462306a36Sopenharmony_ci * by CPUfreq drivers.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * (C) Copyright 2014, 2015 Linaro Ltd.
762306a36Sopenharmony_ci * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef _CPPC_ACPI_H
1162306a36Sopenharmony_ci#define _CPPC_ACPI_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/acpi.h>
1462306a36Sopenharmony_ci#include <linux/cpufreq.h>
1562306a36Sopenharmony_ci#include <linux/types.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <acpi/pcc.h>
1862306a36Sopenharmony_ci#include <acpi/processor.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* CPPCv2 and CPPCv3 support */
2162306a36Sopenharmony_ci#define CPPC_V2_REV	2
2262306a36Sopenharmony_ci#define CPPC_V3_REV	3
2362306a36Sopenharmony_ci#define CPPC_V2_NUM_ENT	21
2462306a36Sopenharmony_ci#define CPPC_V3_NUM_ENT	23
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define PCC_CMD_COMPLETE_MASK	(1 << 0)
2762306a36Sopenharmony_ci#define PCC_ERROR_MASK		(1 << 2)
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#define MAX_CPC_REG_ENT 21
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/* CPPC specific PCC commands. */
3262306a36Sopenharmony_ci#define	CMD_READ 0
3362306a36Sopenharmony_ci#define	CMD_WRITE 1
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/* Each register has the folowing format. */
3662306a36Sopenharmony_cistruct cpc_reg {
3762306a36Sopenharmony_ci	u8 descriptor;
3862306a36Sopenharmony_ci	u16 length;
3962306a36Sopenharmony_ci	u8 space_id;
4062306a36Sopenharmony_ci	u8 bit_width;
4162306a36Sopenharmony_ci	u8 bit_offset;
4262306a36Sopenharmony_ci	u8 access_width;
4362306a36Sopenharmony_ci	u64 address;
4462306a36Sopenharmony_ci} __packed;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/*
4762306a36Sopenharmony_ci * Each entry in the CPC table is either
4862306a36Sopenharmony_ci * of type ACPI_TYPE_BUFFER or
4962306a36Sopenharmony_ci * ACPI_TYPE_INTEGER.
5062306a36Sopenharmony_ci */
5162306a36Sopenharmony_cistruct cpc_register_resource {
5262306a36Sopenharmony_ci	acpi_object_type type;
5362306a36Sopenharmony_ci	u64 __iomem *sys_mem_vaddr;
5462306a36Sopenharmony_ci	union {
5562306a36Sopenharmony_ci		struct cpc_reg reg;
5662306a36Sopenharmony_ci		u64 int_value;
5762306a36Sopenharmony_ci	} cpc_entry;
5862306a36Sopenharmony_ci};
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci/* Container to hold the CPC details for each CPU */
6162306a36Sopenharmony_cistruct cpc_desc {
6262306a36Sopenharmony_ci	int num_entries;
6362306a36Sopenharmony_ci	int version;
6462306a36Sopenharmony_ci	int cpu_id;
6562306a36Sopenharmony_ci	int write_cmd_status;
6662306a36Sopenharmony_ci	int write_cmd_id;
6762306a36Sopenharmony_ci	struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
6862306a36Sopenharmony_ci	struct acpi_psd_package domain_info;
6962306a36Sopenharmony_ci	struct kobject kobj;
7062306a36Sopenharmony_ci};
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* These are indexes into the per-cpu cpc_regs[]. Order is important. */
7362306a36Sopenharmony_cienum cppc_regs {
7462306a36Sopenharmony_ci	HIGHEST_PERF,
7562306a36Sopenharmony_ci	NOMINAL_PERF,
7662306a36Sopenharmony_ci	LOW_NON_LINEAR_PERF,
7762306a36Sopenharmony_ci	LOWEST_PERF,
7862306a36Sopenharmony_ci	GUARANTEED_PERF,
7962306a36Sopenharmony_ci	DESIRED_PERF,
8062306a36Sopenharmony_ci	MIN_PERF,
8162306a36Sopenharmony_ci	MAX_PERF,
8262306a36Sopenharmony_ci	PERF_REDUC_TOLERANCE,
8362306a36Sopenharmony_ci	TIME_WINDOW,
8462306a36Sopenharmony_ci	CTR_WRAP_TIME,
8562306a36Sopenharmony_ci	REFERENCE_CTR,
8662306a36Sopenharmony_ci	DELIVERED_CTR,
8762306a36Sopenharmony_ci	PERF_LIMITED,
8862306a36Sopenharmony_ci	ENABLE,
8962306a36Sopenharmony_ci	AUTO_SEL_ENABLE,
9062306a36Sopenharmony_ci	AUTO_ACT_WINDOW,
9162306a36Sopenharmony_ci	ENERGY_PERF,
9262306a36Sopenharmony_ci	REFERENCE_PERF,
9362306a36Sopenharmony_ci	LOWEST_FREQ,
9462306a36Sopenharmony_ci	NOMINAL_FREQ,
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/*
9862306a36Sopenharmony_ci * Categorization of registers as described
9962306a36Sopenharmony_ci * in the ACPI v.5.1 spec.
10062306a36Sopenharmony_ci * XXX: Only filling up ones which are used by governors
10162306a36Sopenharmony_ci * today.
10262306a36Sopenharmony_ci */
10362306a36Sopenharmony_cistruct cppc_perf_caps {
10462306a36Sopenharmony_ci	u32 guaranteed_perf;
10562306a36Sopenharmony_ci	u32 highest_perf;
10662306a36Sopenharmony_ci	u32 nominal_perf;
10762306a36Sopenharmony_ci	u32 lowest_perf;
10862306a36Sopenharmony_ci	u32 lowest_nonlinear_perf;
10962306a36Sopenharmony_ci	u32 lowest_freq;
11062306a36Sopenharmony_ci	u32 nominal_freq;
11162306a36Sopenharmony_ci	u32 energy_perf;
11262306a36Sopenharmony_ci	bool auto_sel;
11362306a36Sopenharmony_ci};
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_cistruct cppc_perf_ctrls {
11662306a36Sopenharmony_ci	u32 max_perf;
11762306a36Sopenharmony_ci	u32 min_perf;
11862306a36Sopenharmony_ci	u32 desired_perf;
11962306a36Sopenharmony_ci	u32 energy_perf;
12062306a36Sopenharmony_ci};
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_cistruct cppc_perf_fb_ctrs {
12362306a36Sopenharmony_ci	u64 reference;
12462306a36Sopenharmony_ci	u64 delivered;
12562306a36Sopenharmony_ci	u64 reference_perf;
12662306a36Sopenharmony_ci	u64 wraparound_time;
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/* Per CPU container for runtime CPPC management. */
13062306a36Sopenharmony_cistruct cppc_cpudata {
13162306a36Sopenharmony_ci	struct list_head node;
13262306a36Sopenharmony_ci	struct cppc_perf_caps perf_caps;
13362306a36Sopenharmony_ci	struct cppc_perf_ctrls perf_ctrls;
13462306a36Sopenharmony_ci	struct cppc_perf_fb_ctrs perf_fb_ctrs;
13562306a36Sopenharmony_ci	unsigned int shared_type;
13662306a36Sopenharmony_ci	cpumask_var_t shared_cpu_map;
13762306a36Sopenharmony_ci};
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#ifdef CONFIG_ACPI_CPPC_LIB
14062306a36Sopenharmony_ciextern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
14162306a36Sopenharmony_ciextern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf);
14262306a36Sopenharmony_ciextern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
14362306a36Sopenharmony_ciextern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
14462306a36Sopenharmony_ciextern int cppc_set_enable(int cpu, bool enable);
14562306a36Sopenharmony_ciextern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
14662306a36Sopenharmony_ciextern bool cppc_perf_ctrs_in_pcc(void);
14762306a36Sopenharmony_ciextern bool acpi_cpc_valid(void);
14862306a36Sopenharmony_ciextern bool cppc_allow_fast_switch(void);
14962306a36Sopenharmony_ciextern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
15062306a36Sopenharmony_ciextern unsigned int cppc_get_transition_latency(int cpu);
15162306a36Sopenharmony_ciextern bool cpc_ffh_supported(void);
15262306a36Sopenharmony_ciextern bool cpc_supported_by_cpu(void);
15362306a36Sopenharmony_ciextern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
15462306a36Sopenharmony_ciextern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
15562306a36Sopenharmony_ciextern int cppc_get_epp_perf(int cpunum, u64 *epp_perf);
15662306a36Sopenharmony_ciextern int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable);
15762306a36Sopenharmony_ciextern int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps);
15862306a36Sopenharmony_ciextern int cppc_set_auto_sel(int cpu, bool enable);
15962306a36Sopenharmony_ci#else /* !CONFIG_ACPI_CPPC_LIB */
16062306a36Sopenharmony_cistatic inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
16162306a36Sopenharmony_ci{
16262306a36Sopenharmony_ci	return -ENOTSUPP;
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_cistatic inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	return -ENOTSUPP;
16762306a36Sopenharmony_ci}
16862306a36Sopenharmony_cistatic inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	return -ENOTSUPP;
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_cistatic inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	return -ENOTSUPP;
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_cistatic inline int cppc_set_enable(int cpu, bool enable)
17762306a36Sopenharmony_ci{
17862306a36Sopenharmony_ci	return -ENOTSUPP;
17962306a36Sopenharmony_ci}
18062306a36Sopenharmony_cistatic inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
18162306a36Sopenharmony_ci{
18262306a36Sopenharmony_ci	return -ENOTSUPP;
18362306a36Sopenharmony_ci}
18462306a36Sopenharmony_cistatic inline bool cppc_perf_ctrs_in_pcc(void)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	return false;
18762306a36Sopenharmony_ci}
18862306a36Sopenharmony_cistatic inline bool acpi_cpc_valid(void)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci	return false;
19162306a36Sopenharmony_ci}
19262306a36Sopenharmony_cistatic inline bool cppc_allow_fast_switch(void)
19362306a36Sopenharmony_ci{
19462306a36Sopenharmony_ci	return false;
19562306a36Sopenharmony_ci}
19662306a36Sopenharmony_cistatic inline unsigned int cppc_get_transition_latency(int cpu)
19762306a36Sopenharmony_ci{
19862306a36Sopenharmony_ci	return CPUFREQ_ETERNAL;
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_cistatic inline bool cpc_ffh_supported(void)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	return false;
20362306a36Sopenharmony_ci}
20462306a36Sopenharmony_cistatic inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
20562306a36Sopenharmony_ci{
20662306a36Sopenharmony_ci	return -ENOTSUPP;
20762306a36Sopenharmony_ci}
20862306a36Sopenharmony_cistatic inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
20962306a36Sopenharmony_ci{
21062306a36Sopenharmony_ci	return -ENOTSUPP;
21162306a36Sopenharmony_ci}
21262306a36Sopenharmony_cistatic inline int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
21362306a36Sopenharmony_ci{
21462306a36Sopenharmony_ci	return -ENOTSUPP;
21562306a36Sopenharmony_ci}
21662306a36Sopenharmony_cistatic inline int cppc_get_epp_perf(int cpunum, u64 *epp_perf)
21762306a36Sopenharmony_ci{
21862306a36Sopenharmony_ci	return -ENOTSUPP;
21962306a36Sopenharmony_ci}
22062306a36Sopenharmony_cistatic inline int cppc_set_auto_sel(int cpu, bool enable)
22162306a36Sopenharmony_ci{
22262306a36Sopenharmony_ci	return -ENOTSUPP;
22362306a36Sopenharmony_ci}
22462306a36Sopenharmony_cistatic inline int cppc_get_auto_sel_caps(int cpunum, struct cppc_perf_caps *perf_caps)
22562306a36Sopenharmony_ci{
22662306a36Sopenharmony_ci	return -ENOTSUPP;
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci#endif /* !CONFIG_ACPI_CPPC_LIB */
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci#endif /* _CPPC_ACPI_H*/
231