]>
Commit | Line | Data |
---|---|---|
50352fa7 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2b0b16d3 AS |
2 | /* |
3 | * Intel(R) Trace Hub pci driver | |
4 | * | |
5 | * Copyright (C) 2014-2015 Intel Corporation. | |
2b0b16d3 AS |
6 | */ |
7 | ||
8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
9 | ||
10 | #include <linux/types.h> | |
11 | #include <linux/module.h> | |
12 | #include <linux/device.h> | |
13 | #include <linux/sysfs.h> | |
14 | #include <linux/pci.h> | |
15 | ||
16 | #include "intel_th.h" | |
17 | ||
18 | #define DRIVER_NAME "intel_th_pci" | |
19 | ||
db73a059 AS |
20 | enum { |
21 | TH_PCI_CONFIG_BAR = 0, | |
22 | TH_PCI_STH_SW_BAR = 2, | |
fc027f4c | 23 | TH_PCI_RTIT_BAR = 4, |
db73a059 AS |
24 | }; |
25 | ||
26 | #define BAR_MASK (BIT(TH_PCI_CONFIG_BAR) | BIT(TH_PCI_STH_SW_BAR)) | |
2b0b16d3 | 27 | |
a0e7df33 AS |
28 | #define PCI_REG_NPKDSC 0x80 |
29 | #define NPKDSC_TSACT BIT(5) | |
30 | ||
31 | static int intel_th_pci_activate(struct intel_th *th) | |
32 | { | |
33 | struct pci_dev *pdev = to_pci_dev(th->dev); | |
34 | u32 npkdsc; | |
35 | int err; | |
36 | ||
37 | if (!INTEL_TH_CAP(th, tscu_enable)) | |
38 | return 0; | |
39 | ||
40 | err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc); | |
41 | if (!err) { | |
42 | npkdsc |= NPKDSC_TSACT; | |
43 | err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc); | |
44 | } | |
45 | ||
46 | if (err) | |
47 | dev_err(&pdev->dev, "failed to read NPKDSC register\n"); | |
48 | ||
49 | return err; | |
50 | } | |
51 | ||
52 | static void intel_th_pci_deactivate(struct intel_th *th) | |
53 | { | |
54 | struct pci_dev *pdev = to_pci_dev(th->dev); | |
55 | u32 npkdsc; | |
56 | int err; | |
57 | ||
58 | if (!INTEL_TH_CAP(th, tscu_enable)) | |
59 | return; | |
60 | ||
61 | err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc); | |
62 | if (!err) { | |
63 | npkdsc |= NPKDSC_TSACT; | |
64 | err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc); | |
65 | } | |
66 | ||
67 | if (err) | |
68 | dev_err(&pdev->dev, "failed to read NPKDSC register\n"); | |
69 | } | |
70 | ||
2b0b16d3 AS |
71 | static int intel_th_pci_probe(struct pci_dev *pdev, |
72 | const struct pci_device_id *id) | |
73 | { | |
3321371b | 74 | struct intel_th_drvdata *drvdata = (void *)id->driver_data; |
7b7036d4 | 75 | struct resource resource[TH_MMIO_END + TH_NVEC_MAX] = { |
db73a059 AS |
76 | [TH_MMIO_CONFIG] = pdev->resource[TH_PCI_CONFIG_BAR], |
77 | [TH_MMIO_SW] = pdev->resource[TH_PCI_STH_SW_BAR], | |
78 | }; | |
7b7036d4 | 79 | int err, r = TH_MMIO_SW + 1, i; |
2b0b16d3 | 80 | struct intel_th *th; |
2b0b16d3 AS |
81 | |
82 | err = pcim_enable_device(pdev); | |
83 | if (err) | |
84 | return err; | |
85 | ||
86 | err = pcim_iomap_regions_request_all(pdev, BAR_MASK, DRIVER_NAME); | |
87 | if (err) | |
88 | return err; | |
89 | ||
fc027f4c AS |
90 | if (pdev->resource[TH_PCI_RTIT_BAR].start) { |
91 | resource[TH_MMIO_RTIT] = pdev->resource[TH_PCI_RTIT_BAR]; | |
92 | r++; | |
93 | } | |
94 | ||
7b7036d4 AS |
95 | err = pci_alloc_irq_vectors(pdev, 1, 8, PCI_IRQ_ALL_TYPES); |
96 | if (err > 0) | |
97 | for (i = 0; i < err; i++, r++) { | |
98 | resource[r].flags = IORESOURCE_IRQ; | |
99 | resource[r].start = pci_irq_vector(pdev, i); | |
100 | } | |
62a59302 AS |
101 | |
102 | th = intel_th_alloc(&pdev->dev, drvdata, resource, r); | |
2b0b16d3 AS |
103 | if (IS_ERR(th)) |
104 | return PTR_ERR(th); | |
2b0b16d3 | 105 | |
a0e7df33 AS |
106 | th->activate = intel_th_pci_activate; |
107 | th->deactivate = intel_th_pci_deactivate; | |
108 | ||
e9b2b3e7 AS |
109 | pci_set_master(pdev); |
110 | ||
2b0b16d3 AS |
111 | return 0; |
112 | } | |
113 | ||
114 | static void intel_th_pci_remove(struct pci_dev *pdev) | |
115 | { | |
116 | struct intel_th *th = pci_get_drvdata(pdev); | |
117 | ||
118 | intel_th_free(th); | |
7b7036d4 AS |
119 | |
120 | pci_free_irq_vectors(pdev); | |
2b0b16d3 AS |
121 | } |
122 | ||
397c7729 AS |
123 | static const struct intel_th_drvdata intel_th_1x_multi_is_broken = { |
124 | .multi_is_broken = 1, | |
125 | }; | |
126 | ||
a0e7df33 AS |
127 | static const struct intel_th_drvdata intel_th_2x = { |
128 | .tscu_enable = 1, | |
4c5bb6eb | 129 | .has_mintctl = 1, |
a0e7df33 AS |
130 | }; |
131 | ||
2b0b16d3 AS |
132 | static const struct pci_device_id intel_th_pci_id_table[] = { |
133 | { | |
134 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26), | |
135 | .driver_data = (kernel_ulong_t)0, | |
136 | }, | |
137 | { | |
138 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126), | |
139 | .driver_data = (kernel_ulong_t)0, | |
140 | }, | |
6396b912 AS |
141 | { |
142 | /* Apollo Lake */ | |
143 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e), | |
144 | .driver_data = (kernel_ulong_t)0, | |
145 | }, | |
3f040887 AS |
146 | { |
147 | /* Broxton */ | |
148 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80), | |
149 | .driver_data = (kernel_ulong_t)0, | |
150 | }, | |
aaa3ca82 AS |
151 | { |
152 | /* Broxton B-step */ | |
153 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e), | |
154 | .driver_data = (kernel_ulong_t)0, | |
155 | }, | |
7a1a47ce AS |
156 | { |
157 | /* Kaby Lake PCH-H */ | |
158 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), | |
397c7729 | 159 | .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, |
7a1a47ce | 160 | }, |
5118ccd3 AS |
161 | { |
162 | /* Denverton */ | |
163 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), | |
164 | .driver_data = (kernel_ulong_t)0, | |
165 | }, | |
24600840 AS |
166 | { |
167 | /* Lewisburg PCH */ | |
168 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6), | |
169 | .driver_data = (kernel_ulong_t)0, | |
170 | }, | |
164eb56e AS |
171 | { |
172 | /* Lewisburg PCH */ | |
173 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226), | |
174 | .driver_data = (kernel_ulong_t)0, | |
175 | }, | |
340837f9 AS |
176 | { |
177 | /* Gemini Lake */ | |
178 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), | |
a0e7df33 | 179 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
340837f9 | 180 | }, |
84331e13 AS |
181 | { |
182 | /* Cannon Lake H */ | |
183 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), | |
a0e7df33 | 184 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
84331e13 | 185 | }, |
efb3669e AS |
186 | { |
187 | /* Cannon Lake LP */ | |
188 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), | |
a0e7df33 | 189 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
efb3669e | 190 | }, |
920ce7c3 AS |
191 | { |
192 | /* Cedar Fork PCH */ | |
193 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1), | |
194 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
195 | }, | |
59d08d00 AS |
196 | { |
197 | /* Ice Lake PCH */ | |
198 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6), | |
199 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
200 | }, | |
e60e9a4b AS |
201 | { |
202 | /* Comet Lake */ | |
203 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6), | |
204 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
205 | }, | |
3adbb571 AS |
206 | { |
207 | /* Comet Lake PCH */ | |
208 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6), | |
209 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
210 | }, | |
e4de2a5d AS |
211 | { |
212 | /* Comet Lake PCH-V */ | |
213 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6), | |
397c7729 | 214 | .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, |
e4de2a5d | 215 | }, |
4aa5aed2 AS |
216 | { |
217 | /* Ice Lake NNPI */ | |
218 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5), | |
219 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
220 | }, | |
6a174342 AS |
221 | { |
222 | /* Ice Lake CPU */ | |
223 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29), | |
224 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
225 | }, | |
6e6c18bc AS |
226 | { |
227 | /* Tiger Lake CPU */ | |
228 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33), | |
229 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
230 | }, | |
9c78255f AS |
231 | { |
232 | /* Tiger Lake PCH */ | |
233 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), | |
234 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
235 | }, | |
6227585d AS |
236 | { |
237 | /* Tiger Lake PCH-H */ | |
238 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6), | |
239 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
240 | }, | |
9d55499d AS |
241 | { |
242 | /* Jasper Lake PCH */ | |
243 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), | |
244 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
245 | }, | |
203c1f61 AS |
246 | { |
247 | /* Jasper Lake CPU */ | |
248 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29), | |
249 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
250 | }, | |
add492d2 AS |
251 | { |
252 | /* Elkhart Lake CPU */ | |
253 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529), | |
254 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
255 | }, | |
88385866 AS |
256 | { |
257 | /* Elkhart Lake */ | |
258 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), | |
259 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
260 | }, | |
fd73d74a AS |
261 | { |
262 | /* Emmitsburg PCH */ | |
263 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc), | |
264 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
265 | }, | |
951e4d71 AS |
266 | { |
267 | /* Alder Lake */ | |
268 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7aa6), | |
269 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
270 | }, | |
9f126c56 AS |
271 | { |
272 | /* Alder Lake CPU */ | |
273 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), | |
274 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
275 | }, | |
2b0b16d3 AS |
276 | { 0 }, |
277 | }; | |
278 | ||
279 | MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table); | |
280 | ||
281 | static struct pci_driver intel_th_pci_driver = { | |
282 | .name = DRIVER_NAME, | |
283 | .id_table = intel_th_pci_id_table, | |
284 | .probe = intel_th_pci_probe, | |
285 | .remove = intel_th_pci_remove, | |
286 | }; | |
287 | ||
288 | module_pci_driver(intel_th_pci_driver); | |
289 | ||
290 | MODULE_LICENSE("GPL v2"); | |
291 | MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver"); | |
292 | MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>"); |