Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Intel(R) Trace Hub pci driver
  4 *
  5 * Copyright (C) 2014-2015 Intel Corporation.
  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
 20enum {
 21	TH_PCI_CONFIG_BAR	= 0,
 22	TH_PCI_STH_SW_BAR	= 2,
 23	TH_PCI_RTIT_BAR		= 4,
 24};
 25
 26
 27#define PCI_REG_NPKDSC	0x80
 28#define NPKDSC_TSACT	BIT(5)
 29
 30static int intel_th_pci_activate(struct intel_th *th)
 31{
 32	struct pci_dev *pdev = to_pci_dev(th->dev);
 33	u32 npkdsc;
 34	int err;
 35
 36	if (!INTEL_TH_CAP(th, tscu_enable))
 37		return 0;
 38
 39	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
 40	if (!err) {
 41		npkdsc |= NPKDSC_TSACT;
 42		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
 43	}
 44
 45	if (err)
 46		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
 47
 48	return err;
 49}
 50
 51static void intel_th_pci_deactivate(struct intel_th *th)
 52{
 53	struct pci_dev *pdev = to_pci_dev(th->dev);
 54	u32 npkdsc;
 55	int err;
 56
 57	if (!INTEL_TH_CAP(th, tscu_enable))
 58		return;
 59
 60	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
 61	if (!err) {
 62		npkdsc |= NPKDSC_TSACT;
 63		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
 64	}
 65
 66	if (err)
 67		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
 68}
 69
 70static int intel_th_pci_probe(struct pci_dev *pdev,
 71			      const struct pci_device_id *id)
 72{
 73	const struct intel_th_drvdata *drvdata = (void *)id->driver_data;
 74	struct resource resource[TH_MMIO_END + TH_NVEC_MAX] = {
 75		[TH_MMIO_CONFIG]	= pdev->resource[TH_PCI_CONFIG_BAR],
 76		[TH_MMIO_SW]		= pdev->resource[TH_PCI_STH_SW_BAR],
 77	};
 78	int err, r = TH_MMIO_SW + 1, i;
 79	struct intel_th *th;
 80
 81	err = pcim_enable_device(pdev);
 82	if (err)
 83		return err;
 84
 85	err = pcim_request_all_regions(pdev, DRIVER_NAME);
 86	if (err)
 87		return err;
 88
 89	if (!pcim_iomap(pdev, TH_PCI_CONFIG_BAR, 0))
 90		return -ENOMEM;
 91
 92	if (!pcim_iomap(pdev, TH_PCI_STH_SW_BAR, 0))
 93		return -ENOMEM;
 94
 95	if (pdev->resource[TH_PCI_RTIT_BAR].start) {
 96		resource[TH_MMIO_RTIT] = pdev->resource[TH_PCI_RTIT_BAR];
 97		r++;
 98	}
 99
100	err = pci_alloc_irq_vectors(pdev, 1, 8, PCI_IRQ_ALL_TYPES);
101	if (err > 0)
102		for (i = 0; i < err; i++, r++) {
103			resource[r].flags = IORESOURCE_IRQ;
104			resource[r].start = pci_irq_vector(pdev, i);
105		}
106
107	th = intel_th_alloc(&pdev->dev, drvdata, resource, r);
108	if (IS_ERR(th)) {
109		err = PTR_ERR(th);
110		goto err_free_irq;
111	}
112
113	th->activate   = intel_th_pci_activate;
114	th->deactivate = intel_th_pci_deactivate;
115
116	pci_set_master(pdev);
117
118	return 0;
119
120err_free_irq:
121	pci_free_irq_vectors(pdev);
122	return err;
123}
124
125static void intel_th_pci_remove(struct pci_dev *pdev)
126{
127	struct intel_th *th = pci_get_drvdata(pdev);
128
129	intel_th_free(th);
130
131	pci_free_irq_vectors(pdev);
132}
133
134static const struct intel_th_drvdata intel_th_1x_multi_is_broken = {
135	.multi_is_broken	= 1,
136};
137
138static const struct intel_th_drvdata intel_th_2x = {
139	.tscu_enable	= 1,
140	.has_mintctl	= 1,
141};
142
143static const struct pci_device_id intel_th_pci_id_table[] = {
144	{
145		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26),
146		.driver_data = (kernel_ulong_t)0,
147	},
148	{
149		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126),
150		.driver_data = (kernel_ulong_t)0,
151	},
152	{
153		/* Apollo Lake */
154		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e),
155		.driver_data = (kernel_ulong_t)0,
156	},
157	{
158		/* Broxton */
159		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),
160		.driver_data = (kernel_ulong_t)0,
161	},
162	{
163		/* Broxton B-step */
164		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e),
165		.driver_data = (kernel_ulong_t)0,
166	},
167	{
168		/* Kaby Lake PCH-H */
169		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
170		.driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
171	},
172	{
173		/* Denverton */
174		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),
175		.driver_data = (kernel_ulong_t)0,
176	},
177	{
178		/* Lewisburg PCH */
179		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6),
180		.driver_data = (kernel_ulong_t)0,
181	},
182	{
183		/* Lewisburg PCH */
184		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226),
185		.driver_data = (kernel_ulong_t)0,
186	},
187	{
188		/* Gemini Lake */
189		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
190		.driver_data = (kernel_ulong_t)&intel_th_2x,
191	},
192	{
193		/* Cannon Lake H */
194		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
195		.driver_data = (kernel_ulong_t)&intel_th_2x,
196	},
197	{
198		/* Cannon Lake LP */
199		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
200		.driver_data = (kernel_ulong_t)&intel_th_2x,
201	},
202	{
203		/* Cedar Fork PCH */
204		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
205		.driver_data = (kernel_ulong_t)&intel_th_2x,
206	},
207	{
208		/* Ice Lake PCH */
209		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
210		.driver_data = (kernel_ulong_t)&intel_th_2x,
211	},
212	{
213		/* Comet Lake */
214		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6),
215		.driver_data = (kernel_ulong_t)&intel_th_2x,
216	},
217	{
218		/* Comet Lake PCH */
219		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6),
220		.driver_data = (kernel_ulong_t)&intel_th_2x,
221	},
222	{
223		/* Comet Lake PCH-V */
224		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6),
225		.driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
226	},
227	{
228		/* Ice Lake NNPI */
229		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),
230		.driver_data = (kernel_ulong_t)&intel_th_2x,
231	},
232	{
233		/* Ice Lake CPU */
234		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29),
235		.driver_data = (kernel_ulong_t)&intel_th_2x,
236	},
237	{
238		/* Tiger Lake CPU */
239		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33),
240		.driver_data = (kernel_ulong_t)&intel_th_2x,
241	},
242	{
243		/* Tiger Lake PCH */
244		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
245		.driver_data = (kernel_ulong_t)&intel_th_2x,
246	},
247	{
248		/* Tiger Lake PCH-H */
249		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6),
250		.driver_data = (kernel_ulong_t)&intel_th_2x,
251	},
252	{
253		/* Jasper Lake PCH */
254		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),
255		.driver_data = (kernel_ulong_t)&intel_th_2x,
256	},
257	{
258		/* Jasper Lake CPU */
259		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29),
260		.driver_data = (kernel_ulong_t)&intel_th_2x,
261	},
262	{
263		/* Elkhart Lake CPU */
264		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529),
265		.driver_data = (kernel_ulong_t)&intel_th_2x,
266	},
267	{
268		/* Elkhart Lake */
269		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26),
270		.driver_data = (kernel_ulong_t)&intel_th_2x,
271	},
272	{
273		/* Emmitsburg PCH */
274		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc),
275		.driver_data = (kernel_ulong_t)&intel_th_2x,
276	},
277	{
278		/* Alder Lake */
279		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7aa6),
280		.driver_data = (kernel_ulong_t)&intel_th_2x,
281	},
282	{
283		/* Alder Lake-P */
284		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6),
285		.driver_data = (kernel_ulong_t)&intel_th_2x,
286	},
287	{
288		/* Alder Lake-M */
289		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6),
290		.driver_data = (kernel_ulong_t)&intel_th_2x,
291	},
292	{
293		/* Meteor Lake-P */
294		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7e24),
295		.driver_data = (kernel_ulong_t)&intel_th_2x,
296	},
297	{
298		/* Meteor Lake-S */
299		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7f26),
300		.driver_data = (kernel_ulong_t)&intel_th_2x,
301	},
302	{
303		/* Meteor Lake-S CPU */
304		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24),
305		.driver_data = (kernel_ulong_t)&intel_th_2x,
306	},
307	{
308		/* Raptor Lake-S */
309		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26),
310		.driver_data = (kernel_ulong_t)&intel_th_2x,
311	},
312	{
313		/* Raptor Lake-S CPU */
314		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa76f),
315		.driver_data = (kernel_ulong_t)&intel_th_2x,
316	},
317	{
318		/* Granite Rapids */
319		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0963),
320		.driver_data = (kernel_ulong_t)&intel_th_2x,
321	},
322	{
323		/* Granite Rapids SOC */
324		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3256),
325		.driver_data = (kernel_ulong_t)&intel_th_2x,
326	},
327	{
328		/* Sapphire Rapids SOC */
329		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3456),
330		.driver_data = (kernel_ulong_t)&intel_th_2x,
331	},
332	{
333		/* Lunar Lake */
334		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824),
335		.driver_data = (kernel_ulong_t)&intel_th_2x,
336	},
337	{
338		/* Arrow Lake */
339		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7724),
340		.driver_data = (kernel_ulong_t)&intel_th_2x,
341	},
342	{
343		/* Panther Lake-H */
344		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe324),
345		.driver_data = (kernel_ulong_t)&intel_th_2x,
346	},
347	{
348		/* Panther Lake-P/U */
349		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe424),
350		.driver_data = (kernel_ulong_t)&intel_th_2x,
351	},
352	{
353		/* Alder Lake CPU */
354		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
355		.driver_data = (kernel_ulong_t)&intel_th_2x,
356	},
357	{
358		/* Rocket Lake CPU */
359		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19),
360		.driver_data = (kernel_ulong_t)&intel_th_2x,
361	},
362	{ 0 },
363};
364
365MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table);
366
367static struct pci_driver intel_th_pci_driver = {
368	.name		= DRIVER_NAME,
369	.id_table	= intel_th_pci_id_table,
370	.probe		= intel_th_pci_probe,
371	.remove		= intel_th_pci_remove,
372};
373
374module_pci_driver(intel_th_pci_driver);
375
376MODULE_LICENSE("GPL v2");
377MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver");
378MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");