359 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Intel(R) Trace Hub pci driver4 *5 * Copyright (C) 2014-2015 Intel Corporation.6 */7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 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#define BAR_MASK (BIT(TH_PCI_CONFIG_BAR) | BIT(TH_PCI_STH_SW_BAR))27 28#define PCI_REG_NPKDSC 0x8029#define NPKDSC_TSACT BIT(5)30 31static 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 52static 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 71static int intel_th_pci_probe(struct pci_dev *pdev,72 const struct pci_device_id *id)73{74 const struct intel_th_drvdata *drvdata = (void *)id->driver_data;75 struct resource resource[TH_MMIO_END + TH_NVEC_MAX] = {76 [TH_MMIO_CONFIG] = pdev->resource[TH_PCI_CONFIG_BAR],77 [TH_MMIO_SW] = pdev->resource[TH_PCI_STH_SW_BAR],78 };79 int err, r = TH_MMIO_SW + 1, i;80 struct intel_th *th;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 90 if (pdev->resource[TH_PCI_RTIT_BAR].start) {91 resource[TH_MMIO_RTIT] = pdev->resource[TH_PCI_RTIT_BAR];92 r++;93 }94 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 }101 102 th = intel_th_alloc(&pdev->dev, drvdata, resource, r);103 if (IS_ERR(th)) {104 err = PTR_ERR(th);105 goto err_free_irq;106 }107 108 th->activate = intel_th_pci_activate;109 th->deactivate = intel_th_pci_deactivate;110 111 pci_set_master(pdev);112 113 return 0;114 115err_free_irq:116 pci_free_irq_vectors(pdev);117 return err;118}119 120static void intel_th_pci_remove(struct pci_dev *pdev)121{122 struct intel_th *th = pci_get_drvdata(pdev);123 124 intel_th_free(th);125 126 pci_free_irq_vectors(pdev);127}128 129static const struct intel_th_drvdata intel_th_1x_multi_is_broken = {130 .multi_is_broken = 1,131};132 133static const struct intel_th_drvdata intel_th_2x = {134 .tscu_enable = 1,135 .has_mintctl = 1,136};137 138static const struct pci_device_id intel_th_pci_id_table[] = {139 {140 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26),141 .driver_data = (kernel_ulong_t)0,142 },143 {144 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126),145 .driver_data = (kernel_ulong_t)0,146 },147 {148 /* Apollo Lake */149 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e),150 .driver_data = (kernel_ulong_t)0,151 },152 {153 /* Broxton */154 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),155 .driver_data = (kernel_ulong_t)0,156 },157 {158 /* Broxton B-step */159 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e),160 .driver_data = (kernel_ulong_t)0,161 },162 {163 /* Kaby Lake PCH-H */164 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),165 .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,166 },167 {168 /* Denverton */169 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),170 .driver_data = (kernel_ulong_t)0,171 },172 {173 /* Lewisburg PCH */174 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6),175 .driver_data = (kernel_ulong_t)0,176 },177 {178 /* Lewisburg PCH */179 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226),180 .driver_data = (kernel_ulong_t)0,181 },182 {183 /* Gemini Lake */184 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),185 .driver_data = (kernel_ulong_t)&intel_th_2x,186 },187 {188 /* Cannon Lake H */189 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),190 .driver_data = (kernel_ulong_t)&intel_th_2x,191 },192 {193 /* Cannon Lake LP */194 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),195 .driver_data = (kernel_ulong_t)&intel_th_2x,196 },197 {198 /* Cedar Fork PCH */199 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),200 .driver_data = (kernel_ulong_t)&intel_th_2x,201 },202 {203 /* Ice Lake PCH */204 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),205 .driver_data = (kernel_ulong_t)&intel_th_2x,206 },207 {208 /* Comet Lake */209 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6),210 .driver_data = (kernel_ulong_t)&intel_th_2x,211 },212 {213 /* Comet Lake PCH */214 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6),215 .driver_data = (kernel_ulong_t)&intel_th_2x,216 },217 {218 /* Comet Lake PCH-V */219 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6),220 .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,221 },222 {223 /* Ice Lake NNPI */224 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),225 .driver_data = (kernel_ulong_t)&intel_th_2x,226 },227 {228 /* Ice Lake CPU */229 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29),230 .driver_data = (kernel_ulong_t)&intel_th_2x,231 },232 {233 /* Tiger Lake CPU */234 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33),235 .driver_data = (kernel_ulong_t)&intel_th_2x,236 },237 {238 /* Tiger Lake PCH */239 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),240 .driver_data = (kernel_ulong_t)&intel_th_2x,241 },242 {243 /* Tiger Lake PCH-H */244 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6),245 .driver_data = (kernel_ulong_t)&intel_th_2x,246 },247 {248 /* Jasper Lake PCH */249 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),250 .driver_data = (kernel_ulong_t)&intel_th_2x,251 },252 {253 /* Jasper Lake CPU */254 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29),255 .driver_data = (kernel_ulong_t)&intel_th_2x,256 },257 {258 /* Elkhart Lake CPU */259 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529),260 .driver_data = (kernel_ulong_t)&intel_th_2x,261 },262 {263 /* Elkhart Lake */264 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26),265 .driver_data = (kernel_ulong_t)&intel_th_2x,266 },267 {268 /* Emmitsburg PCH */269 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc),270 .driver_data = (kernel_ulong_t)&intel_th_2x,271 },272 {273 /* Alder Lake */274 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7aa6),275 .driver_data = (kernel_ulong_t)&intel_th_2x,276 },277 {278 /* Alder Lake-P */279 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6),280 .driver_data = (kernel_ulong_t)&intel_th_2x,281 },282 {283 /* Alder Lake-M */284 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6),285 .driver_data = (kernel_ulong_t)&intel_th_2x,286 },287 {288 /* Meteor Lake-P */289 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7e24),290 .driver_data = (kernel_ulong_t)&intel_th_2x,291 },292 {293 /* Meteor Lake-S */294 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7f26),295 .driver_data = (kernel_ulong_t)&intel_th_2x,296 },297 {298 /* Meteor Lake-S CPU */299 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24),300 .driver_data = (kernel_ulong_t)&intel_th_2x,301 },302 {303 /* Raptor Lake-S */304 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26),305 .driver_data = (kernel_ulong_t)&intel_th_2x,306 },307 {308 /* Raptor Lake-S CPU */309 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa76f),310 .driver_data = (kernel_ulong_t)&intel_th_2x,311 },312 {313 /* Granite Rapids */314 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0963),315 .driver_data = (kernel_ulong_t)&intel_th_2x,316 },317 {318 /* Granite Rapids SOC */319 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3256),320 .driver_data = (kernel_ulong_t)&intel_th_2x,321 },322 {323 /* Sapphire Rapids SOC */324 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3456),325 .driver_data = (kernel_ulong_t)&intel_th_2x,326 },327 {328 /* Lunar Lake */329 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824),330 .driver_data = (kernel_ulong_t)&intel_th_2x,331 },332 {333 /* Alder Lake CPU */334 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),335 .driver_data = (kernel_ulong_t)&intel_th_2x,336 },337 {338 /* Rocket Lake CPU */339 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19),340 .driver_data = (kernel_ulong_t)&intel_th_2x,341 },342 { 0 },343};344 345MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table);346 347static struct pci_driver intel_th_pci_driver = {348 .name = DRIVER_NAME,349 .id_table = intel_th_pci_id_table,350 .probe = intel_th_pci_probe,351 .remove = intel_th_pci_remove,352};353 354module_pci_driver(intel_th_pci_driver);355 356MODULE_LICENSE("GPL v2");357MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver");358MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");359