Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * CPPC (Collaborative Processor Performance Control) methods used
0004  * by CPUfreq drivers.
0005  *
0006  * (C) Copyright 2014, 2015 Linaro Ltd.
0007  * Author: Ashwin Chaugule <ashwin.chaugule@linaro.org>
0008  */
0009 
0010 #ifndef _CPPC_ACPI_H
0011 #define _CPPC_ACPI_H
0012 
0013 #include <linux/acpi.h>
0014 #include <linux/cpufreq.h>
0015 #include <linux/types.h>
0016 
0017 #include <acpi/pcc.h>
0018 #include <acpi/processor.h>
0019 
0020 /* CPPCv2 and CPPCv3 support */
0021 #define CPPC_V2_REV 2
0022 #define CPPC_V3_REV 3
0023 #define CPPC_V2_NUM_ENT 21
0024 #define CPPC_V3_NUM_ENT 23
0025 
0026 #define PCC_CMD_COMPLETE_MASK   (1 << 0)
0027 #define PCC_ERROR_MASK      (1 << 2)
0028 
0029 #define MAX_CPC_REG_ENT 21
0030 
0031 /* CPPC specific PCC commands. */
0032 #define CMD_READ 0
0033 #define CMD_WRITE 1
0034 
0035 /* Each register has the folowing format. */
0036 struct cpc_reg {
0037     u8 descriptor;
0038     u16 length;
0039     u8 space_id;
0040     u8 bit_width;
0041     u8 bit_offset;
0042     u8 access_width;
0043     u64 address;
0044 } __packed;
0045 
0046 /*
0047  * Each entry in the CPC table is either
0048  * of type ACPI_TYPE_BUFFER or
0049  * ACPI_TYPE_INTEGER.
0050  */
0051 struct cpc_register_resource {
0052     acpi_object_type type;
0053     u64 __iomem *sys_mem_vaddr;
0054     union {
0055         struct cpc_reg reg;
0056         u64 int_value;
0057     } cpc_entry;
0058 };
0059 
0060 /* Container to hold the CPC details for each CPU */
0061 struct cpc_desc {
0062     int num_entries;
0063     int version;
0064     int cpu_id;
0065     int write_cmd_status;
0066     int write_cmd_id;
0067     struct cpc_register_resource cpc_regs[MAX_CPC_REG_ENT];
0068     struct acpi_psd_package domain_info;
0069     struct kobject kobj;
0070 };
0071 
0072 /* These are indexes into the per-cpu cpc_regs[]. Order is important. */
0073 enum cppc_regs {
0074     HIGHEST_PERF,
0075     NOMINAL_PERF,
0076     LOW_NON_LINEAR_PERF,
0077     LOWEST_PERF,
0078     GUARANTEED_PERF,
0079     DESIRED_PERF,
0080     MIN_PERF,
0081     MAX_PERF,
0082     PERF_REDUC_TOLERANCE,
0083     TIME_WINDOW,
0084     CTR_WRAP_TIME,
0085     REFERENCE_CTR,
0086     DELIVERED_CTR,
0087     PERF_LIMITED,
0088     ENABLE,
0089     AUTO_SEL_ENABLE,
0090     AUTO_ACT_WINDOW,
0091     ENERGY_PERF,
0092     REFERENCE_PERF,
0093     LOWEST_FREQ,
0094     NOMINAL_FREQ,
0095 };
0096 
0097 /*
0098  * Categorization of registers as described
0099  * in the ACPI v.5.1 spec.
0100  * XXX: Only filling up ones which are used by governors
0101  * today.
0102  */
0103 struct cppc_perf_caps {
0104     u32 guaranteed_perf;
0105     u32 highest_perf;
0106     u32 nominal_perf;
0107     u32 lowest_perf;
0108     u32 lowest_nonlinear_perf;
0109     u32 lowest_freq;
0110     u32 nominal_freq;
0111 };
0112 
0113 struct cppc_perf_ctrls {
0114     u32 max_perf;
0115     u32 min_perf;
0116     u32 desired_perf;
0117 };
0118 
0119 struct cppc_perf_fb_ctrs {
0120     u64 reference;
0121     u64 delivered;
0122     u64 reference_perf;
0123     u64 wraparound_time;
0124 };
0125 
0126 /* Per CPU container for runtime CPPC management. */
0127 struct cppc_cpudata {
0128     struct list_head node;
0129     struct cppc_perf_caps perf_caps;
0130     struct cppc_perf_ctrls perf_ctrls;
0131     struct cppc_perf_fb_ctrs perf_fb_ctrs;
0132     unsigned int shared_type;
0133     cpumask_var_t shared_cpu_map;
0134 };
0135 
0136 #ifdef CONFIG_ACPI_CPPC_LIB
0137 extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf);
0138 extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf);
0139 extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs);
0140 extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
0141 extern int cppc_set_enable(int cpu, bool enable);
0142 extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
0143 extern bool acpi_cpc_valid(void);
0144 extern bool cppc_allow_fast_switch(void);
0145 extern int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data);
0146 extern unsigned int cppc_get_transition_latency(int cpu);
0147 extern bool cpc_ffh_supported(void);
0148 extern bool cpc_supported_by_cpu(void);
0149 extern int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val);
0150 extern int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val);
0151 #else /* !CONFIG_ACPI_CPPC_LIB */
0152 static inline int cppc_get_desired_perf(int cpunum, u64 *desired_perf)
0153 {
0154     return -ENOTSUPP;
0155 }
0156 static inline int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf)
0157 {
0158     return -ENOTSUPP;
0159 }
0160 static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs)
0161 {
0162     return -ENOTSUPP;
0163 }
0164 static inline int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
0165 {
0166     return -ENOTSUPP;
0167 }
0168 static inline int cppc_set_enable(int cpu, bool enable)
0169 {
0170     return -ENOTSUPP;
0171 }
0172 static inline int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps)
0173 {
0174     return -ENOTSUPP;
0175 }
0176 static inline bool acpi_cpc_valid(void)
0177 {
0178     return false;
0179 }
0180 static inline bool cppc_allow_fast_switch(void)
0181 {
0182     return false;
0183 }
0184 static inline unsigned int cppc_get_transition_latency(int cpu)
0185 {
0186     return CPUFREQ_ETERNAL;
0187 }
0188 static inline bool cpc_ffh_supported(void)
0189 {
0190     return false;
0191 }
0192 static inline int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
0193 {
0194     return -ENOTSUPP;
0195 }
0196 static inline int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
0197 {
0198     return -ENOTSUPP;
0199 }
0200 #endif /* !CONFIG_ACPI_CPPC_LIB */
0201 
0202 #endif /* _CPPC_ACPI_H*/