xref: /linux/drivers/hwtracing/intel_th/pci.c (revision e9f0878c4b2004ac19581274c1ae4c61ae3ca70e)
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 
20 #define BAR_MASK (BIT(TH_MMIO_CONFIG) | BIT(TH_MMIO_SW))
21 
22 #define PCI_REG_NPKDSC	0x80
23 #define NPKDSC_TSACT	BIT(5)
24 
25 static int intel_th_pci_activate(struct intel_th *th)
26 {
27 	struct pci_dev *pdev = to_pci_dev(th->dev);
28 	u32 npkdsc;
29 	int err;
30 
31 	if (!INTEL_TH_CAP(th, tscu_enable))
32 		return 0;
33 
34 	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
35 	if (!err) {
36 		npkdsc |= NPKDSC_TSACT;
37 		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
38 	}
39 
40 	if (err)
41 		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
42 
43 	return err;
44 }
45 
46 static void intel_th_pci_deactivate(struct intel_th *th)
47 {
48 	struct pci_dev *pdev = to_pci_dev(th->dev);
49 	u32 npkdsc;
50 	int err;
51 
52 	if (!INTEL_TH_CAP(th, tscu_enable))
53 		return;
54 
55 	err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
56 	if (!err) {
57 		npkdsc |= NPKDSC_TSACT;
58 		err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
59 	}
60 
61 	if (err)
62 		dev_err(&pdev->dev, "failed to read NPKDSC register\n");
63 }
64 
65 static int intel_th_pci_probe(struct pci_dev *pdev,
66 			      const struct pci_device_id *id)
67 {
68 	struct intel_th_drvdata *drvdata = (void *)id->driver_data;
69 	struct intel_th *th;
70 	int err;
71 
72 	err = pcim_enable_device(pdev);
73 	if (err)
74 		return err;
75 
76 	err = pcim_iomap_regions_request_all(pdev, BAR_MASK, DRIVER_NAME);
77 	if (err)
78 		return err;
79 
80 	th = intel_th_alloc(&pdev->dev, drvdata, pdev->resource,
81 			    DEVICE_COUNT_RESOURCE, pdev->irq);
82 	if (IS_ERR(th))
83 		return PTR_ERR(th);
84 
85 	th->activate   = intel_th_pci_activate;
86 	th->deactivate = intel_th_pci_deactivate;
87 
88 	pci_set_master(pdev);
89 
90 	return 0;
91 }
92 
93 static void intel_th_pci_remove(struct pci_dev *pdev)
94 {
95 	struct intel_th *th = pci_get_drvdata(pdev);
96 
97 	intel_th_free(th);
98 }
99 
100 static const struct intel_th_drvdata intel_th_2x = {
101 	.tscu_enable	= 1,
102 };
103 
104 static const struct pci_device_id intel_th_pci_id_table[] = {
105 	{
106 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26),
107 		.driver_data = (kernel_ulong_t)0,
108 	},
109 	{
110 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126),
111 		.driver_data = (kernel_ulong_t)0,
112 	},
113 	{
114 		/* Apollo Lake */
115 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e),
116 		.driver_data = (kernel_ulong_t)0,
117 	},
118 	{
119 		/* Broxton */
120 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),
121 		.driver_data = (kernel_ulong_t)0,
122 	},
123 	{
124 		/* Broxton B-step */
125 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e),
126 		.driver_data = (kernel_ulong_t)0,
127 	},
128 	{
129 		/* Kaby Lake PCH-H */
130 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
131 		.driver_data = (kernel_ulong_t)0,
132 	},
133 	{
134 		/* Denverton */
135 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),
136 		.driver_data = (kernel_ulong_t)0,
137 	},
138 	{
139 		/* Lewisburg PCH */
140 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6),
141 		.driver_data = (kernel_ulong_t)0,
142 	},
143 	{
144 		/* Gemini Lake */
145 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
146 		.driver_data = (kernel_ulong_t)&intel_th_2x,
147 	},
148 	{
149 		/* Cannon Lake H */
150 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
151 		.driver_data = (kernel_ulong_t)&intel_th_2x,
152 	},
153 	{
154 		/* Cannon Lake LP */
155 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
156 		.driver_data = (kernel_ulong_t)&intel_th_2x,
157 	},
158 	{
159 		/* Cedar Fork PCH */
160 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
161 		.driver_data = (kernel_ulong_t)&intel_th_2x,
162 	},
163 	{ 0 },
164 };
165 
166 MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table);
167 
168 static struct pci_driver intel_th_pci_driver = {
169 	.name		= DRIVER_NAME,
170 	.id_table	= intel_th_pci_id_table,
171 	.probe		= intel_th_pci_probe,
172 	.remove		= intel_th_pci_remove,
173 };
174 
175 module_pci_driver(intel_th_pci_driver);
176 
177 MODULE_LICENSE("GPL v2");
178 MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver");
179 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");
180