]>
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 | ||
a0e7df33 AS |
123 | static const struct intel_th_drvdata intel_th_2x = { |
124 | .tscu_enable = 1, | |
4c5bb6eb | 125 | .has_mintctl = 1, |
a0e7df33 AS |
126 | }; |
127 | ||
2b0b16d3 AS |
128 | static const struct pci_device_id intel_th_pci_id_table[] = { |
129 | { | |
130 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26), | |
131 | .driver_data = (kernel_ulong_t)0, | |
132 | }, | |
133 | { | |
134 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126), | |
135 | .driver_data = (kernel_ulong_t)0, | |
136 | }, | |
6396b912 AS |
137 | { |
138 | /* Apollo Lake */ | |
139 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e), | |
140 | .driver_data = (kernel_ulong_t)0, | |
141 | }, | |
3f040887 AS |
142 | { |
143 | /* Broxton */ | |
144 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80), | |
145 | .driver_data = (kernel_ulong_t)0, | |
146 | }, | |
aaa3ca82 AS |
147 | { |
148 | /* Broxton B-step */ | |
149 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e), | |
150 | .driver_data = (kernel_ulong_t)0, | |
151 | }, | |
7a1a47ce AS |
152 | { |
153 | /* Kaby Lake PCH-H */ | |
154 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), | |
155 | .driver_data = (kernel_ulong_t)0, | |
156 | }, | |
5118ccd3 AS |
157 | { |
158 | /* Denverton */ | |
159 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), | |
160 | .driver_data = (kernel_ulong_t)0, | |
161 | }, | |
24600840 AS |
162 | { |
163 | /* Lewisburg PCH */ | |
164 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6), | |
165 | .driver_data = (kernel_ulong_t)0, | |
166 | }, | |
164eb56e AS |
167 | { |
168 | /* Lewisburg PCH */ | |
169 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226), | |
170 | .driver_data = (kernel_ulong_t)0, | |
171 | }, | |
340837f9 AS |
172 | { |
173 | /* Gemini Lake */ | |
174 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), | |
a0e7df33 | 175 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
340837f9 | 176 | }, |
84331e13 AS |
177 | { |
178 | /* Cannon Lake H */ | |
179 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), | |
a0e7df33 | 180 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
84331e13 | 181 | }, |
efb3669e AS |
182 | { |
183 | /* Cannon Lake LP */ | |
184 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), | |
a0e7df33 | 185 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
efb3669e | 186 | }, |
920ce7c3 AS |
187 | { |
188 | /* Cedar Fork PCH */ | |
189 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1), | |
190 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
191 | }, | |
59d08d00 AS |
192 | { |
193 | /* Ice Lake PCH */ | |
194 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6), | |
195 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
196 | }, | |
e60e9a4b AS |
197 | { |
198 | /* Comet Lake */ | |
199 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6), | |
200 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
201 | }, | |
3adbb571 AS |
202 | { |
203 | /* Comet Lake PCH */ | |
204 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6), | |
205 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
206 | }, | |
e4de2a5d AS |
207 | { |
208 | /* Comet Lake PCH-V */ | |
209 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6), | |
210 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
211 | }, | |
4aa5aed2 AS |
212 | { |
213 | /* Ice Lake NNPI */ | |
214 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5), | |
215 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
216 | }, | |
6a174342 AS |
217 | { |
218 | /* Ice Lake CPU */ | |
219 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29), | |
220 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
221 | }, | |
6e6c18bc AS |
222 | { |
223 | /* Tiger Lake CPU */ | |
224 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33), | |
225 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
226 | }, | |
9c78255f AS |
227 | { |
228 | /* Tiger Lake PCH */ | |
229 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), | |
230 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
231 | }, | |
9d55499d AS |
232 | { |
233 | /* Jasper Lake PCH */ | |
234 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), | |
235 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
236 | }, | |
88385866 AS |
237 | { |
238 | /* Elkhart Lake */ | |
239 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), | |
240 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
241 | }, | |
2b0b16d3 AS |
242 | { 0 }, |
243 | }; | |
244 | ||
245 | MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table); | |
246 | ||
247 | static struct pci_driver intel_th_pci_driver = { | |
248 | .name = DRIVER_NAME, | |
249 | .id_table = intel_th_pci_id_table, | |
250 | .probe = intel_th_pci_probe, | |
251 | .remove = intel_th_pci_remove, | |
252 | }; | |
253 | ||
254 | module_pci_driver(intel_th_pci_driver); | |
255 | ||
256 | MODULE_LICENSE("GPL v2"); | |
257 | MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver"); | |
258 | MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>"); |