1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Hardware Feedback Interface Driver
4  *
5  * Copyright (c) 2021, Intel Corporation.
6  *
7  * Authors: Aubrey Li <aubrey.li@linux.intel.com>
8  *          Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
9  *
10  *
11  * The Hardware Feedback Interface provides a performance and energy efficiency
12  * capability information for each CPU in the system. Depending on the processor
13  * model, hardware may periodically update these capabilities as a result of
14  * changes in the operating conditions (e.g., power limits or thermal
15  * constraints). On other processor models, there is a single HFI update
16  * at boot.
17  *
18  * This file provides functionality to process HFI updates and relay these
19  * updates to userspace.
20  */
21 
22 #define pr_fmt(fmt)  "intel-hfi: " fmt
23 
24 #include <linux/bitops.h>
25 #include <linux/cpufeature.h>
26 #include <linux/math.h>
27 #include <linux/printk.h>
28 #include <linux/processor.h>
29 #include <linux/slab.h>
30 #include <linux/topology.h>
31 
32 #include "intel_hfi.h"
33 
34 /* CPUID detection and enumeration definitions for HFI */
35 
36 #define CPUID_HFI_LEAF 6
37 
38 union hfi_capabilities {
39 	struct {
40 		u8	performance:1;
41 		u8	energy_efficiency:1;
42 		u8	__reserved:6;
43 	} split;
44 	u8 bits;
45 };
46 
47 union cpuid6_edx {
48 	struct {
49 		union hfi_capabilities	capabilities;
50 		u32			table_pages:4;
51 		u32			__reserved:4;
52 		s32			index:16;
53 	} split;
54 	u32 full;
55 };
56 
57 /**
58  * struct hfi_cpu_data - HFI capabilities per CPU
59  * @perf_cap:		Performance capability
60  * @ee_cap:		Energy efficiency capability
61  *
62  * Capabilities of a logical processor in the HFI table. These capabilities are
63  * unitless.
64  */
65 struct hfi_cpu_data {
66 	u8	perf_cap;
67 	u8	ee_cap;
68 } __packed;
69 
70 /**
71  * struct hfi_hdr - Header of the HFI table
72  * @perf_updated:	Hardware updated performance capabilities
73  * @ee_updated:		Hardware updated energy efficiency capabilities
74  *
75  * Properties of the data in an HFI table.
76  */
77 struct hfi_hdr {
78 	u8	perf_updated;
79 	u8	ee_updated;
80 } __packed;
81 
82 /**
83  * struct hfi_instance - Representation of an HFI instance (i.e., a table)
84  * @local_table:	Base of the local copy of the HFI table
85  * @timestamp:		Timestamp of the last update of the local table.
86  *			Located at the base of the local table.
87  * @hdr:		Base address of the header of the local table
88  * @data:		Base address of the data of the local table
89  *
90  * A set of parameters to parse and navigate a specific HFI table.
91  */
92 struct hfi_instance {
93 	union {
94 		void			*local_table;
95 		u64			*timestamp;
96 	};
97 	void			*hdr;
98 	void			*data;
99 };
100 
101 /**
102  * struct hfi_features - Supported HFI features
103  * @nr_table_pages:	Size of the HFI table in 4KB pages
104  * @cpu_stride:		Stride size to locate the capability data of a logical
105  *			processor within the table (i.e., row stride)
106  * @hdr_size:		Size of the table header
107  *
108  * Parameters and supported features that are common to all HFI instances
109  */
110 struct hfi_features {
111 	unsigned int	nr_table_pages;
112 	unsigned int	cpu_stride;
113 	unsigned int	hdr_size;
114 };
115 
116 static int max_hfi_instances;
117 static struct hfi_instance *hfi_instances;
118 
119 static struct hfi_features hfi_features;
120 
121 static __init int hfi_parse_features(void)
122 {
123 	unsigned int nr_capabilities;
124 	union cpuid6_edx edx;
125 
126 	if (!boot_cpu_has(X86_FEATURE_HFI))
127 		return -ENODEV;
128 
129 	/*
130 	 * If we are here we know that CPUID_HFI_LEAF exists. Parse the
131 	 * supported capabilities and the size of the HFI table.
132 	 */
133 	edx.full = cpuid_edx(CPUID_HFI_LEAF);
134 
135 	if (!edx.split.capabilities.split.performance) {
136 		pr_debug("Performance reporting not supported! Not using HFI\n");
137 		return -ENODEV;
138 	}
139 
140 	/*
141 	 * The number of supported capabilities determines the number of
142 	 * columns in the HFI table. Exclude the reserved bits.
143 	 */
144 	edx.split.capabilities.split.__reserved = 0;
145 	nr_capabilities = hweight8(edx.split.capabilities.bits);
146 
147 	/* The number of 4KB pages required by the table */
148 	hfi_features.nr_table_pages = edx.split.table_pages + 1;
149 
150 	/*
151 	 * The header contains change indications for each supported feature.
152 	 * The size of the table header is rounded up to be a multiple of 8
153 	 * bytes.
154 	 */
155 	hfi_features.hdr_size = DIV_ROUND_UP(nr_capabilities, 8) * 8;
156 
157 	/*
158 	 * Data of each logical processor is also rounded up to be a multiple
159 	 * of 8 bytes.
160 	 */
161 	hfi_features.cpu_stride = DIV_ROUND_UP(nr_capabilities, 8) * 8;
162 
163 	return 0;
164 }
165 
166 void __init intel_hfi_init(void)
167 {
168 	if (hfi_parse_features())
169 		return;
170 
171 	/* There is one HFI instance per die/package. */
172 	max_hfi_instances = topology_max_packages() *
173 			    topology_max_die_per_package();
174 
175 	/*
176 	 * This allocation may fail. CPU hotplug callbacks must check
177 	 * for a null pointer.
178 	 */
179 	hfi_instances = kcalloc(max_hfi_instances, sizeof(*hfi_instances),
180 				GFP_KERNEL);
181 }
182