xref: /aosp_15_r20/external/coreboot/util/inteltool/gpio_groups.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* inteltool - dump all registers on an Intel CPU + chipset based system */
2 /* SPDX-License-Identifier: GPL-2.0-only */
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <assert.h>
9 #include <inttypes.h>
10 #include "inteltool.h"
11 #include "pcr.h"
12 
13 #include "gpio_names/apollolake.h"
14 #include "gpio_names/cannonlake.h"
15 #include "gpio_names/cannonlake_lp.h"
16 #include "gpio_names/denverton.h"
17 #include "gpio_names/geminilake.h"
18 #include "gpio_names/icelake.h"
19 #include "gpio_names/lewisburg.h"
20 #include "gpio_names/emmitsburg.h"
21 #include "gpio_names/sunrise.h"
22 #include "gpio_names/tigerlake.h"
23 #include "gpio_names/alderlake_n.h"
24 #include "gpio_names/alderlake_h.h"
25 #include "gpio_names/alderlake_p.h"
26 #include "gpio_names/elkhartlake.h"
27 #include "gpio_names/jasperlake.h"
28 #include "gpio_names/meteorlake.h"
29 
30 #define SBBAR_SIZE	(16 * MiB)
31 #define PCR_PORT_SIZE	(64 * KiB)
32 
decode_pad_mode(const struct gpio_group * const group,const size_t pad,const uint32_t dw0)33 static const char *decode_pad_mode(const struct gpio_group *const group,
34 				   const size_t pad, const uint32_t dw0)
35 {
36 	const size_t pad_mode = dw0 >> 10 & 7;
37 	const char *const pad_name =
38 		group->pad_names[pad * group->func_count + pad_mode];
39 
40 	if (!pad_mode)
41 		return pad_name[0] == '*' ? "*GPIO" : "GPIO";
42 	else if (pad_mode < group->func_count)
43 		return group->pad_names[pad * group->func_count + pad_mode];
44 	else
45 		return "RESERVED";
46 }
47 
print_gpio_group(const uint8_t pid,size_t pad_cfg,const struct gpio_group * const group,size_t pad_stepping)48 static void print_gpio_group(const uint8_t pid, size_t pad_cfg,
49 			     const struct gpio_group *const group,
50 			     size_t pad_stepping)
51 {
52 	size_t p;
53 
54 	printf("%s\n", group->display);
55 
56 	for (p = 0; p < group->pad_count; ++p, pad_cfg += pad_stepping) {
57 		const uint32_t dw0 = read_pcr32(pid, pad_cfg);
58 		const uint32_t dw1 = read_pcr32(pid, pad_cfg + 4);
59 		const char *const pad_name =
60 			group->pad_names[p * group->func_count];
61 
62 		printf("0x%04zx: 0x%016"PRIx64" %-12s %-20s\n", pad_cfg,
63 		       (uint64_t)dw1 << 32 | dw0,
64 		       pad_name[0] == '*' ? &pad_name[1] : pad_name,
65 		       decode_pad_mode(group, p, dw0));
66 	}
67 }
68 
print_gpio_community(const struct gpio_community * const community,size_t pad_stepping)69 static void print_gpio_community(const struct gpio_community *const community,
70 				 size_t pad_stepping)
71 {
72 	size_t group, pad_count;
73 	size_t pad_cfg; /* offset in bytes under this communities PCR port */
74 
75 	printf("%s\n\nPCR Port ID: 0x%06zx\n\n",
76 	       community->name, (size_t)community->pcr_port_id << 16);
77 
78 	for (group = 0, pad_count = 0; group < community->group_count; ++group)
79 		pad_count += community->groups[group]->pad_count;
80 	assert(pad_count * 8 <= PCR_PORT_SIZE - 0x10);
81 
82 	pad_cfg = read_pcr32(community->pcr_port_id, 0x0c);
83 	if (pad_cfg + pad_count * 8 > PCR_PORT_SIZE) {
84 		fprintf(stderr, "Bad Pad Base Address: 0x%08zx\n", pad_cfg);
85 		return;
86 	}
87 
88 	for (group = 0; group < community->group_count; ++group) {
89 		if (community->groups[group]->pad_offset)
90 			pad_cfg = community->groups[group]->pad_offset;
91 		print_gpio_group(community->pcr_port_id,
92 				 pad_cfg, community->groups[group],
93 				 pad_stepping);
94 		pad_cfg += community->groups[group]->pad_count * pad_stepping;
95 	}
96 }
97 
get_gpio_communities(struct pci_dev * const sb,size_t * community_count,size_t * pad_stepping)98 const struct gpio_community *const *get_gpio_communities(struct pci_dev *const sb,
99 						size_t* community_count,
100 						size_t* pad_stepping)
101 {
102 	*pad_stepping = 8;
103 
104 	switch (sb->device_id) {
105 	case PCI_DEVICE_ID_INTEL_H110:
106 	case PCI_DEVICE_ID_INTEL_H170:
107 	case PCI_DEVICE_ID_INTEL_Z170:
108 	case PCI_DEVICE_ID_INTEL_Q170:
109 	case PCI_DEVICE_ID_INTEL_Q150:
110 	case PCI_DEVICE_ID_INTEL_B150:
111 	case PCI_DEVICE_ID_INTEL_C236:
112 	case PCI_DEVICE_ID_INTEL_C232:
113 	case PCI_DEVICE_ID_INTEL_QM170:
114 	case PCI_DEVICE_ID_INTEL_HM170:
115 	case PCI_DEVICE_ID_INTEL_CM236:
116 	case PCI_DEVICE_ID_INTEL_H270:
117 	case PCI_DEVICE_ID_INTEL_Z270:
118 	case PCI_DEVICE_ID_INTEL_Q270:
119 	case PCI_DEVICE_ID_INTEL_Q250:
120 	case PCI_DEVICE_ID_INTEL_B250:
121 	case PCI_DEVICE_ID_INTEL_Z370:
122 	case PCI_DEVICE_ID_INTEL_H310C:
123 	case PCI_DEVICE_ID_INTEL_X299:
124 		*community_count = ARRAY_SIZE(sunrise_communities);
125 		return sunrise_communities;
126 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE:
127 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL:
128 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL:
129 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL:
130 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL:
131 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL:
132 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL:
133 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE:
134 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM:
135 	case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM:
136 		*community_count = ARRAY_SIZE(sunrise_lp_communities);
137 		return sunrise_lp_communities;
138 	case PCI_DEVICE_ID_INTEL_C621:
139 	case PCI_DEVICE_ID_INTEL_C622:
140 	case PCI_DEVICE_ID_INTEL_C624:
141 	case PCI_DEVICE_ID_INTEL_C625:
142 	case PCI_DEVICE_ID_INTEL_C626:
143 	case PCI_DEVICE_ID_INTEL_C627:
144 	case PCI_DEVICE_ID_INTEL_C628:
145 	case PCI_DEVICE_ID_INTEL_C629:
146 	case PCI_DEVICE_ID_INTEL_C621A:
147 	case PCI_DEVICE_ID_INTEL_C627A:
148 	case PCI_DEVICE_ID_INTEL_C629A:
149 	case PCI_DEVICE_ID_INTEL_C624_SUPER:
150 	case PCI_DEVICE_ID_INTEL_C627_SUPER_1:
151 	case PCI_DEVICE_ID_INTEL_C621_SUPER:
152 	case PCI_DEVICE_ID_INTEL_C627_SUPER_2:
153 	case PCI_DEVICE_ID_INTEL_C628_SUPER:
154 	case PCI_DEVICE_ID_INTEL_C621A_SUPER:
155 	case PCI_DEVICE_ID_INTEL_C627A_SUPER:
156 	case PCI_DEVICE_ID_INTEL_C629A_SUPER:
157 		*community_count = ARRAY_SIZE(lewisburg_communities);
158 		return lewisburg_communities;
159 	case PCI_DEVICE_ID_INTEL_EBG:
160 		*pad_stepping = 16;
161 		*community_count = ARRAY_SIZE(emmitsburg_communities);
162 		return emmitsburg_communities;
163 	case PCI_DEVICE_ID_INTEL_DNV_LPC:
164 		*community_count = ARRAY_SIZE(denverton_communities);
165 		return denverton_communities;
166 	case PCI_DEVICE_ID_INTEL_APL_LPC:
167 		*community_count = ARRAY_SIZE(apl_communities);
168 		return apl_communities;
169 	case PCI_DEVICE_ID_INTEL_GLK_LPC:
170 		*community_count = ARRAY_SIZE(glk_communities);
171 		*pad_stepping = 16;
172 		return glk_communities;
173 	case PCI_DEVICE_ID_INTEL_CANNONPOINT_LP_U_PREM:
174 	case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_PREM:
175 	case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_BASE:
176 		*community_count = ARRAY_SIZE(cannonlake_pch_lp_communities);
177 		*pad_stepping = 16;
178 		return cannonlake_pch_lp_communities;
179 	case PCI_DEVICE_ID_INTEL_H310:
180 	case PCI_DEVICE_ID_INTEL_H370:
181 	case PCI_DEVICE_ID_INTEL_Z390:
182 	case PCI_DEVICE_ID_INTEL_Q370:
183 	case PCI_DEVICE_ID_INTEL_B360:
184 	case PCI_DEVICE_ID_INTEL_C246:
185 	case PCI_DEVICE_ID_INTEL_C242:
186 	case PCI_DEVICE_ID_INTEL_QM370:
187 	case PCI_DEVICE_ID_INTEL_HM370:
188 	case PCI_DEVICE_ID_INTEL_CM246:
189 		*community_count = ARRAY_SIZE(cannonlake_pch_h_communities);
190 		*pad_stepping = 16;
191 		return cannonlake_pch_h_communities;
192 	case PCI_DEVICE_ID_INTEL_ICELAKE_LP_U:
193 		*community_count = ARRAY_SIZE(icelake_pch_h_communities);
194 		*pad_stepping = 16;
195 		return icelake_pch_h_communities;
196 	case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_SUPER:
197 	case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_PREM:
198 	case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_BASE:
199 	case PCI_DEVICE_ID_INTEL_TIGERPOINT_Y_SUPER:
200 	case PCI_DEVICE_ID_INTEL_TIGERPOINT_Y_PREM:
201 		*community_count = ARRAY_SIZE(tigerlake_pch_lp_communities);
202 		*pad_stepping = 16;
203 		return tigerlake_pch_lp_communities;
204 	case PCI_DEVICE_ID_INTEL_Q570:
205 	case PCI_DEVICE_ID_INTEL_Z590:
206 	case PCI_DEVICE_ID_INTEL_H570:
207 	case PCI_DEVICE_ID_INTEL_B560:
208 	case PCI_DEVICE_ID_INTEL_H510:
209 	case PCI_DEVICE_ID_INTEL_WM590:
210 	case PCI_DEVICE_ID_INTEL_QM580:
211 	case PCI_DEVICE_ID_INTEL_HM570:
212 	case PCI_DEVICE_ID_INTEL_C252:
213 	case PCI_DEVICE_ID_INTEL_C256:
214 	case PCI_DEVICE_ID_INTEL_W580:
215 		*community_count = ARRAY_SIZE(tigerlake_pch_h_communities);
216 		*pad_stepping = 16;
217 		return tigerlake_pch_h_communities;
218 	case PCI_DEVICE_ID_INTEL_H610E:
219 	case PCI_DEVICE_ID_INTEL_Q670E:
220 	case PCI_DEVICE_ID_INTEL_R680E:
221 	case PCI_DEVICE_ID_INTEL_H610:
222 	case PCI_DEVICE_ID_INTEL_B660:
223 	case PCI_DEVICE_ID_INTEL_H670:
224 	case PCI_DEVICE_ID_INTEL_Q670:
225 	case PCI_DEVICE_ID_INTEL_Z690:
226 	case PCI_DEVICE_ID_INTEL_W680:
227 	case PCI_DEVICE_ID_INTEL_WM690:
228 	case PCI_DEVICE_ID_INTEL_HM670:
229 	case PCI_DEVICE_ID_INTEL_W790:
230 	case PCI_DEVICE_ID_INTEL_Z790:
231 	case PCI_DEVICE_ID_INTEL_H770:
232 	case PCI_DEVICE_ID_INTEL_B760:
233 	case PCI_DEVICE_ID_INTEL_HM770:
234 	case PCI_DEVICE_ID_INTEL_WM790:
235 	case PCI_DEVICE_ID_INTEL_C262:
236 	case PCI_DEVICE_ID_INTEL_C266:
237 		*community_count = ARRAY_SIZE(alderlake_pch_h_communities);
238 		*pad_stepping = 16;
239 		return alderlake_pch_h_communities;
240 	case PCI_DEVICE_ID_INTEL_ADL_P:
241 	case PCI_DEVICE_ID_INTEL_ADL_M:
242 	case PCI_DEVICE_ID_INTEL_RPL_P:
243 		*community_count = ARRAY_SIZE(alderlake_pch_p_communities);
244 		*pad_stepping = 16;
245 		return alderlake_pch_p_communities;
246 	case PCI_DEVICE_ID_INTEL_ADL_N:
247 		*community_count = ARRAY_SIZE(alderlake_pch_n_communities);
248 		*pad_stepping = 16;
249 		return alderlake_pch_n_communities;
250 	case PCI_DEVICE_ID_INTEL_JSL:
251 		*community_count = ARRAY_SIZE(jasperlake_pch_communities);
252 		*pad_stepping = 16;
253  		return jasperlake_pch_communities;
254 	case PCI_DEVICE_ID_INTEL_EHL:
255 		*community_count = ARRAY_SIZE(elkhartlake_pch_communities);
256 		*pad_stepping = 16;
257 		return elkhartlake_pch_communities;
258 	case PCI_DEVICE_ID_INTEL_MTL_0:
259 	case PCI_DEVICE_ID_INTEL_MTL_1:
260 	case PCI_DEVICE_ID_INTEL_MTL_2:
261 	case PCI_DEVICE_ID_INTEL_MTL_3:
262 	case PCI_DEVICE_ID_INTEL_MTL_4:
263 	case PCI_DEVICE_ID_INTEL_MTL_5:
264 	case PCI_DEVICE_ID_INTEL_MTL_6:
265 	case PCI_DEVICE_ID_INTEL_MTL_7:
266 		*community_count = ARRAY_SIZE(meteorlake_pch_communities);
267 		*pad_stepping = 16;
268 		return meteorlake_pch_communities;
269 	default:
270 		return NULL;
271 	}
272 }
273 
print_gpio_groups(struct pci_dev * const sb)274 void print_gpio_groups(struct pci_dev *const sb)
275 {
276 	size_t community_count;
277 	const struct gpio_community *const *communities;
278 	size_t pad_stepping;
279 
280 	communities = get_gpio_communities(sb, &community_count, &pad_stepping);
281 
282 	if (!communities)
283 		return;
284 
285 	pcr_init(sb);
286 
287 	printf("\n============= GPIOS =============\n\n");
288 
289 	for (; community_count; --community_count)
290 		print_gpio_community(*communities++, pad_stepping);
291 }
292