blob: 4faecf3206ace6b58527a5a5bdffb9a2b8408724 [file] [log] [blame]
Patrick Georgiea063cb2020-05-08 19:28:13 +02001/* inteltool - dump all registers on an Intel CPU + chipset based system */
Patrick Georgi7333a112020-05-08 20:48:04 +02002/* SPDX-License-Identifier: GPL-2.0-only */
Nico Huber18980232017-04-07 12:26:07 +02003
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
Johanna Schanderf80c5d92020-01-29 09:20:23 +010013#include "gpio_names/apollolake.h"
Johanna Schanderd5a65302020-01-29 09:16:06 +010014#include "gpio_names/cannonlake.h"
Matt DeVillier3c784452019-06-11 23:23:46 -050015#include "gpio_names/cannonlake_lp.h"
Johanna Schander7da602f2020-01-29 09:51:25 +010016#include "gpio_names/denverton.h"
Johanna Schanderdca20cd2020-01-29 09:14:18 +010017#include "gpio_names/icelake.h"
Johanna Schanderaff7d1f2020-01-29 09:29:39 +010018#include "gpio_names/lewisburg.h"
Johanna Schandere98af862020-01-29 09:25:45 +010019#include "gpio_names/sunrise.h"
Michał Żygowski8ac40f32021-07-09 16:00:16 +020020#include "gpio_names/tigerlake.h"
Johanna Schanderdca20cd2020-01-29 09:14:18 +010021
Nico Huber18980232017-04-07 12:26:07 +020022#define SBBAR_SIZE (16 * MiB)
23#define PCR_PORT_SIZE (64 * KiB)
24
Nico Huber18980232017-04-07 12:26:07 +020025static const char *decode_pad_mode(const struct gpio_group *const group,
26 const size_t pad, const uint32_t dw0)
27{
28 const size_t pad_mode = dw0 >> 10 & 7;
Nico Huber8a95c6c2018-11-27 12:27:22 +010029 const char *const pad_name =
30 group->pad_names[pad * group->func_count + pad_mode];
31
Nico Huber18980232017-04-07 12:26:07 +020032 if (!pad_mode)
Nico Huber8a95c6c2018-11-27 12:27:22 +010033 return pad_name[0] == '*' ? "*GPIO" : "GPIO";
Nico Huber18980232017-04-07 12:26:07 +020034 else if (pad_mode < group->func_count)
35 return group->pad_names[pad * group->func_count + pad_mode];
36 else
37 return "RESERVED";
38}
39
40static void print_gpio_group(const uint8_t pid, size_t pad_cfg,
Thomas Heijligen725369f2019-02-19 10:51:34 +000041 const struct gpio_group *const group,
42 size_t pad_stepping)
Nico Huber18980232017-04-07 12:26:07 +020043{
44 size_t p;
45
46 printf("%s\n", group->display);
47
Thomas Heijligen725369f2019-02-19 10:51:34 +000048 for (p = 0; p < group->pad_count; ++p, pad_cfg += pad_stepping) {
Nico Huber18980232017-04-07 12:26:07 +020049 const uint32_t dw0 = read_pcr32(pid, pad_cfg);
50 const uint32_t dw1 = read_pcr32(pid, pad_cfg + 4);
Nico Huber8a95c6c2018-11-27 12:27:22 +010051 const char *const pad_name =
52 group->pad_names[p * group->func_count];
Nico Huber18980232017-04-07 12:26:07 +020053
Nico Huber8a95c6c2018-11-27 12:27:22 +010054 printf("0x%04zx: 0x%016"PRIx64" %-12s %-20s\n", pad_cfg,
Nico Huber18980232017-04-07 12:26:07 +020055 (uint64_t)dw1 << 32 | dw0,
Nico Huber8a95c6c2018-11-27 12:27:22 +010056 pad_name[0] == '*' ? &pad_name[1] : pad_name,
Nico Huber18980232017-04-07 12:26:07 +020057 decode_pad_mode(group, p, dw0));
58 }
59}
60
Thomas Heijligen725369f2019-02-19 10:51:34 +000061static void print_gpio_community(const struct gpio_community *const community,
62 size_t pad_stepping)
Nico Huber18980232017-04-07 12:26:07 +020063{
64 size_t group, pad_count;
65 size_t pad_cfg; /* offset in bytes under this communities PCR port */
66
67 printf("%s\n\nPCR Port ID: 0x%06zx\n\n",
68 community->name, (size_t)community->pcr_port_id << 16);
69
70 for (group = 0, pad_count = 0; group < community->group_count; ++group)
71 pad_count += community->groups[group]->pad_count;
72 assert(pad_count * 8 <= PCR_PORT_SIZE - 0x10);
73
74 pad_cfg = read_pcr32(community->pcr_port_id, 0x0c);
75 if (pad_cfg + pad_count * 8 > PCR_PORT_SIZE) {
76 fprintf(stderr, "Bad Pad Base Address: 0x%08zx\n", pad_cfg);
77 return;
78 }
79
80 for (group = 0; group < community->group_count; ++group) {
81 print_gpio_group(community->pcr_port_id,
Thomas Heijligen725369f2019-02-19 10:51:34 +000082 pad_cfg, community->groups[group],
83 pad_stepping);
84 pad_cfg += community->groups[group]->pad_count * pad_stepping;
Nico Huber18980232017-04-07 12:26:07 +020085 }
86}
87
Johanna Schandere32ded82020-01-29 10:08:17 +010088const struct gpio_community *const *get_gpio_communities(struct pci_dev *const sb,
89 size_t* community_count,
90 size_t* pad_stepping)
Nico Huber18980232017-04-07 12:26:07 +020091{
Johanna Schandere32ded82020-01-29 10:08:17 +010092 *pad_stepping = 8;
Nico Huber18980232017-04-07 12:26:07 +020093
94 switch (sb->device_id) {
Pavel Sayekat9429b702019-07-28 23:09:08 +060095 case PCI_DEVICE_ID_INTEL_H110:
Felix Singerf98dc482019-07-29 21:53:14 +020096 case PCI_DEVICE_ID_INTEL_H170:
97 case PCI_DEVICE_ID_INTEL_Z170:
98 case PCI_DEVICE_ID_INTEL_Q170:
99 case PCI_DEVICE_ID_INTEL_Q150:
Nico Huber54fe32f2017-10-03 16:03:07 +0200100 case PCI_DEVICE_ID_INTEL_B150:
Christian Walter9a8c5e72019-05-06 17:50:57 +0200101 case PCI_DEVICE_ID_INTEL_C236:
Felix Singerf98dc482019-07-29 21:53:14 +0200102 case PCI_DEVICE_ID_INTEL_C232:
103 case PCI_DEVICE_ID_INTEL_QM170:
104 case PCI_DEVICE_ID_INTEL_HM170:
105 case PCI_DEVICE_ID_INTEL_CM236:
Timofey Komarov6c800822021-06-25 12:07:32 +0300106 case PCI_DEVICE_ID_INTEL_H270:
107 case PCI_DEVICE_ID_INTEL_Z270:
108 case PCI_DEVICE_ID_INTEL_Q270:
109 case PCI_DEVICE_ID_INTEL_Q250:
110 case PCI_DEVICE_ID_INTEL_B250:
111 case PCI_DEVICE_ID_INTEL_Z370:
112 case PCI_DEVICE_ID_INTEL_H310C:
113 case PCI_DEVICE_ID_INTEL_X299:
Johanna Schandere32ded82020-01-29 10:08:17 +0100114 *community_count = ARRAY_SIZE(sunrise_communities);
115 return sunrise_communities;
Felix Singer0a7543d2019-02-19 23:49:11 +0100116 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE:
117 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL:
118 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL:
119 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL:
120 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL:
121 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL:
122 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL:
Matthew Garrett2bf28e52018-07-23 21:09:47 -0700123 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE:
124 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM:
125 case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM:
Johanna Schandere32ded82020-01-29 10:08:17 +0100126 *community_count = ARRAY_SIZE(sunrise_lp_communities);
127 return sunrise_lp_communities;
Maxim Polyakovb89ce2e2019-08-17 14:54:02 +0300128 case PCI_DEVICE_ID_INTEL_C621:
129 case PCI_DEVICE_ID_INTEL_C622:
130 case PCI_DEVICE_ID_INTEL_C624:
131 case PCI_DEVICE_ID_INTEL_C625:
132 case PCI_DEVICE_ID_INTEL_C626:
133 case PCI_DEVICE_ID_INTEL_C627:
134 case PCI_DEVICE_ID_INTEL_C628:
135 case PCI_DEVICE_ID_INTEL_C629:
Maxim Polyakovde7092b2020-07-17 00:19:41 +0300136 case PCI_DEVICE_ID_INTEL_C621A:
137 case PCI_DEVICE_ID_INTEL_C627A:
138 case PCI_DEVICE_ID_INTEL_C629A:
Maxim Polyakovb89ce2e2019-08-17 14:54:02 +0300139 case PCI_DEVICE_ID_INTEL_C624_SUPER:
140 case PCI_DEVICE_ID_INTEL_C627_SUPER_1:
141 case PCI_DEVICE_ID_INTEL_C621_SUPER:
142 case PCI_DEVICE_ID_INTEL_C627_SUPER_2:
143 case PCI_DEVICE_ID_INTEL_C628_SUPER:
Maxim Polyakovde7092b2020-07-17 00:19:41 +0300144 case PCI_DEVICE_ID_INTEL_C621A_SUPER:
145 case PCI_DEVICE_ID_INTEL_C627A_SUPER:
146 case PCI_DEVICE_ID_INTEL_C629A_SUPER:
Johanna Schandere32ded82020-01-29 10:08:17 +0100147 *community_count = ARRAY_SIZE(lewisburg_communities);
148 return lewisburg_communities;
Thomas Heijligenda027192019-01-12 19:20:50 +0100149 case PCI_DEVICE_ID_INTEL_DNV_LPC:
Johanna Schandere32ded82020-01-29 10:08:17 +0100150 *community_count = ARRAY_SIZE(denverton_communities);
151 return denverton_communities;
Nico Huber8a95c6c2018-11-27 12:27:22 +0100152 case PCI_DEVICE_ID_INTEL_APL_LPC:
Johanna Schandere32ded82020-01-29 10:08:17 +0100153 *community_count = ARRAY_SIZE(apl_communities);
154 return apl_communities;
Matt DeVillier3c784452019-06-11 23:23:46 -0500155 case PCI_DEVICE_ID_INTEL_CANNONPOINT_LP_U_PREM:
Matt DeVillier62e883d2020-08-08 11:17:31 -0500156 case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_PREM:
157 case PCI_DEVICE_ID_INTEL_COMETPOINT_LP_U_BASE:
Matt DeVillier3c784452019-06-11 23:23:46 -0500158 *community_count = ARRAY_SIZE(cannonlake_pch_lp_communities);
159 *pad_stepping = 16;
160 return cannonlake_pch_lp_communities;
Thomas Heijligen725369f2019-02-19 10:51:34 +0000161 case PCI_DEVICE_ID_INTEL_H310:
162 case PCI_DEVICE_ID_INTEL_H370:
163 case PCI_DEVICE_ID_INTEL_Z390:
164 case PCI_DEVICE_ID_INTEL_Q370:
165 case PCI_DEVICE_ID_INTEL_B360:
166 case PCI_DEVICE_ID_INTEL_C246:
167 case PCI_DEVICE_ID_INTEL_C242:
168 case PCI_DEVICE_ID_INTEL_QM370:
169 case PCI_DEVICE_ID_INTEL_HM370:
170 case PCI_DEVICE_ID_INTEL_CM246:
Johanna Schandere32ded82020-01-29 10:08:17 +0100171 *community_count = ARRAY_SIZE(cannonlake_pch_h_communities);
172 *pad_stepping = 16;
173 return cannonlake_pch_h_communities;
Johanna Schander0174ea72020-01-04 15:14:59 +0100174 case PCI_DEVICE_ID_INTEL_ICELAKE_LP_U:
Johanna Schandere32ded82020-01-29 10:08:17 +0100175 *community_count = ARRAY_SIZE(icelake_pch_h_communities);
176 *pad_stepping = 16;
177 return icelake_pch_h_communities;
Michał Żygowski8ac40f32021-07-09 16:00:16 +0200178 case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_SUPER:
179 case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_PREM:
180 case PCI_DEVICE_ID_INTEL_TIGERPOINT_U_BASE:
181 case PCI_DEVICE_ID_INTEL_TIGERPOINT_Y_SUPER:
182 case PCI_DEVICE_ID_INTEL_TIGERPOINT_Y_PREM:
183 *community_count = ARRAY_SIZE(tigerlake_pch_lp_communities);
184 *pad_stepping = 16;
185 return tigerlake_pch_lp_communities;
186 case PCI_DEVICE_ID_INTEL_Q570:
187 case PCI_DEVICE_ID_INTEL_Z590:
188 case PCI_DEVICE_ID_INTEL_H570:
189 case PCI_DEVICE_ID_INTEL_B560:
190 case PCI_DEVICE_ID_INTEL_H510:
191 case PCI_DEVICE_ID_INTEL_WM590:
192 case PCI_DEVICE_ID_INTEL_QM580:
193 case PCI_DEVICE_ID_INTEL_HM570:
194 case PCI_DEVICE_ID_INTEL_C252:
195 case PCI_DEVICE_ID_INTEL_C256:
196 case PCI_DEVICE_ID_INTEL_W580:
197 *community_count = ARRAY_SIZE(tigerlake_pch_h_communities);
198 *pad_stepping = 16;
199 return tigerlake_pch_h_communities;
Nico Huber18980232017-04-07 12:26:07 +0200200 default:
Johanna Schandere32ded82020-01-29 10:08:17 +0100201 return NULL;
Nico Huber18980232017-04-07 12:26:07 +0200202 }
Johanna Schandere32ded82020-01-29 10:08:17 +0100203}
204
205void print_gpio_groups(struct pci_dev *const sb)
206{
207 size_t community_count;
208 const struct gpio_community *const *communities;
209 size_t pad_stepping;
210
211 communities = get_gpio_communities(sb, &community_count, &pad_stepping);
212
213 if (!communities)
214 return;
215
216 pcr_init(sb);
Nico Huber18980232017-04-07 12:26:07 +0200217
218 printf("\n============= GPIOS =============\n\n");
219
220 for (; community_count; --community_count)
Thomas Heijligen725369f2019-02-19 10:51:34 +0000221 print_gpio_community(*communities++, pad_stepping);
Nico Huber18980232017-04-07 12:26:07 +0200222}