Commit | Line | Data |
---|---|---|
2b0b16d3 AS |
1 | /* |
2 | * Intel(R) Trace Hub pci driver | |
3 | * | |
4 | * Copyright (C) 2014-2015 Intel Corporation. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms and conditions of the GNU General Public License, | |
8 | * version 2, as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope it will be useful, but WITHOUT | |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | * more details. | |
14 | */ | |
15 | ||
16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
17 | ||
18 | #include <linux/types.h> | |
19 | #include <linux/module.h> | |
20 | #include <linux/device.h> | |
21 | #include <linux/sysfs.h> | |
22 | #include <linux/pci.h> | |
23 | ||
24 | #include "intel_th.h" | |
25 | ||
26 | #define DRIVER_NAME "intel_th_pci" | |
27 | ||
28 | #define BAR_MASK (BIT(TH_MMIO_CONFIG) | BIT(TH_MMIO_SW)) | |
29 | ||
a0e7df33 AS |
30 | #define PCI_REG_NPKDSC 0x80 |
31 | #define NPKDSC_TSACT BIT(5) | |
32 | ||
33 | static int intel_th_pci_activate(struct intel_th *th) | |
34 | { | |
35 | struct pci_dev *pdev = to_pci_dev(th->dev); | |
36 | u32 npkdsc; | |
37 | int err; | |
38 | ||
39 | if (!INTEL_TH_CAP(th, tscu_enable)) | |
40 | return 0; | |
41 | ||
42 | err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc); | |
43 | if (!err) { | |
44 | npkdsc |= NPKDSC_TSACT; | |
45 | err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc); | |
46 | } | |
47 | ||
48 | if (err) | |
49 | dev_err(&pdev->dev, "failed to read NPKDSC register\n"); | |
50 | ||
51 | return err; | |
52 | } | |
53 | ||
54 | static void intel_th_pci_deactivate(struct intel_th *th) | |
55 | { | |
56 | struct pci_dev *pdev = to_pci_dev(th->dev); | |
57 | u32 npkdsc; | |
58 | int err; | |
59 | ||
60 | if (!INTEL_TH_CAP(th, tscu_enable)) | |
61 | return; | |
62 | ||
63 | err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc); | |
64 | if (!err) { | |
65 | npkdsc |= NPKDSC_TSACT; | |
66 | err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc); | |
67 | } | |
68 | ||
69 | if (err) | |
70 | dev_err(&pdev->dev, "failed to read NPKDSC register\n"); | |
71 | } | |
72 | ||
2b0b16d3 AS |
73 | static int intel_th_pci_probe(struct pci_dev *pdev, |
74 | const struct pci_device_id *id) | |
75 | { | |
3321371b | 76 | struct intel_th_drvdata *drvdata = (void *)id->driver_data; |
2b0b16d3 AS |
77 | struct intel_th *th; |
78 | int err; | |
79 | ||
80 | err = pcim_enable_device(pdev); | |
81 | if (err) | |
82 | return err; | |
83 | ||
84 | err = pcim_iomap_regions_request_all(pdev, BAR_MASK, DRIVER_NAME); | |
85 | if (err) | |
86 | return err; | |
87 | ||
3321371b | 88 | th = intel_th_alloc(&pdev->dev, drvdata, pdev->resource, |
2b0b16d3 AS |
89 | DEVICE_COUNT_RESOURCE, pdev->irq); |
90 | if (IS_ERR(th)) | |
91 | return PTR_ERR(th); | |
2b0b16d3 | 92 | |
a0e7df33 AS |
93 | th->activate = intel_th_pci_activate; |
94 | th->deactivate = intel_th_pci_deactivate; | |
95 | ||
e9b2b3e7 AS |
96 | pci_set_master(pdev); |
97 | ||
2b0b16d3 AS |
98 | return 0; |
99 | } | |
100 | ||
101 | static void intel_th_pci_remove(struct pci_dev *pdev) | |
102 | { | |
103 | struct intel_th *th = pci_get_drvdata(pdev); | |
104 | ||
105 | intel_th_free(th); | |
106 | } | |
107 | ||
a0e7df33 AS |
108 | static const struct intel_th_drvdata intel_th_2x = { |
109 | .tscu_enable = 1, | |
110 | }; | |
111 | ||
2b0b16d3 AS |
112 | static const struct pci_device_id intel_th_pci_id_table[] = { |
113 | { | |
114 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26), | |
115 | .driver_data = (kernel_ulong_t)0, | |
116 | }, | |
117 | { | |
118 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126), | |
119 | .driver_data = (kernel_ulong_t)0, | |
120 | }, | |
6396b912 AS |
121 | { |
122 | /* Apollo Lake */ | |
123 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e), | |
124 | .driver_data = (kernel_ulong_t)0, | |
125 | }, | |
3f040887 AS |
126 | { |
127 | /* Broxton */ | |
128 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80), | |
129 | .driver_data = (kernel_ulong_t)0, | |
130 | }, | |
aaa3ca82 AS |
131 | { |
132 | /* Broxton B-step */ | |
133 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e), | |
134 | .driver_data = (kernel_ulong_t)0, | |
135 | }, | |
7a1a47ce AS |
136 | { |
137 | /* Kaby Lake PCH-H */ | |
138 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), | |
139 | .driver_data = (kernel_ulong_t)0, | |
140 | }, | |
5118ccd3 AS |
141 | { |
142 | /* Denverton */ | |
143 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), | |
144 | .driver_data = (kernel_ulong_t)0, | |
145 | }, | |
24600840 AS |
146 | { |
147 | /* Lewisburg PCH */ | |
148 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6), | |
149 | .driver_data = (kernel_ulong_t)0, | |
150 | }, | |
340837f9 AS |
151 | { |
152 | /* Gemini Lake */ | |
153 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), | |
a0e7df33 | 154 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
340837f9 | 155 | }, |
84331e13 AS |
156 | { |
157 | /* Cannon Lake H */ | |
158 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), | |
a0e7df33 | 159 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
84331e13 | 160 | }, |
efb3669e AS |
161 | { |
162 | /* Cannon Lake LP */ | |
163 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), | |
a0e7df33 | 164 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
efb3669e | 165 | }, |
920ce7c3 AS |
166 | { |
167 | /* Cedar Fork PCH */ | |
168 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1), | |
169 | .driver_data = (kernel_ulong_t)&intel_th_2x, | |
170 | }, | |
2b0b16d3 AS |
171 | { 0 }, |
172 | }; | |
173 | ||
174 | MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table); | |
175 | ||
176 | static struct pci_driver intel_th_pci_driver = { | |
177 | .name = DRIVER_NAME, | |
178 | .id_table = intel_th_pci_id_table, | |
179 | .probe = intel_th_pci_probe, | |
180 | .remove = intel_th_pci_remove, | |
181 | }; | |
182 | ||
183 | module_pci_driver(intel_th_pci_driver); | |
184 | ||
185 | MODULE_LICENSE("GPL v2"); | |
186 | MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver"); | |
187 | MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>"); |