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 enum { 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 30 static 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 51 static 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 70 static 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 120 err_free_irq: 121 pci_free_irq_vectors(pdev); 122 return err; 123 } 124 125 static 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 134 static const struct intel_th_drvdata intel_th_1x_multi_is_broken = { 135 .multi_is_broken = 1, 136 }; 137 138 static const struct intel_th_drvdata intel_th_2x = { 139 .tscu_enable = 1, 140 .has_mintctl = 1, 141 }; 142 143 static 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 /* Alder Lake CPU */ 339 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), 340 .driver_data = (kernel_ulong_t)&intel_th_2x, 341 }, 342 { 343 /* Rocket Lake CPU */ 344 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19), 345 .driver_data = (kernel_ulong_t)&intel_th_2x, 346 }, 347 { 0 }, 348 }; 349 350 MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table); 351 352 static struct pci_driver intel_th_pci_driver = { 353 .name = DRIVER_NAME, 354 .id_table = intel_th_pci_id_table, 355 .probe = intel_th_pci_probe, 356 .remove = intel_th_pci_remove, 357 }; 358 359 module_pci_driver(intel_th_pci_driver); 360 361 MODULE_LICENSE("GPL v2"); 362 MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver"); 363 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>"); 364