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 intel_th_pci_activate(struct intel_th * th)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 intel_th_pci_deactivate(struct intel_th * th)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 intel_th_pci_probe(struct pci_dev * pdev,const struct pci_device_id * id)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 intel_th_pci_remove(struct pci_dev * pdev)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 /* Lewisburg PCH */ 145 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226), 146 .driver_data = (kernel_ulong_t)0, 147 }, 148 { 149 /* Gemini Lake */ 150 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), 151 .driver_data = (kernel_ulong_t)&intel_th_2x, 152 }, 153 { 154 /* Cannon Lake H */ 155 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), 156 .driver_data = (kernel_ulong_t)&intel_th_2x, 157 }, 158 { 159 /* Cannon Lake LP */ 160 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), 161 .driver_data = (kernel_ulong_t)&intel_th_2x, 162 }, 163 { 164 /* Cedar Fork PCH */ 165 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1), 166 .driver_data = (kernel_ulong_t)&intel_th_2x, 167 }, 168 { 169 /* Ice Lake PCH */ 170 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6), 171 .driver_data = (kernel_ulong_t)&intel_th_2x, 172 }, 173 { 174 /* Comet Lake */ 175 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6), 176 .driver_data = (kernel_ulong_t)&intel_th_2x, 177 }, 178 { 179 /* Comet Lake PCH */ 180 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6), 181 .driver_data = (kernel_ulong_t)&intel_th_2x, 182 }, 183 { 184 /* Comet Lake PCH-V */ 185 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6), 186 .driver_data = (kernel_ulong_t)&intel_th_2x, 187 }, 188 { 189 /* Ice Lake NNPI */ 190 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5), 191 .driver_data = (kernel_ulong_t)&intel_th_2x, 192 }, 193 { 194 /* Ice Lake CPU */ 195 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29), 196 .driver_data = (kernel_ulong_t)&intel_th_2x, 197 }, 198 { 199 /* Tiger Lake CPU */ 200 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33), 201 .driver_data = (kernel_ulong_t)&intel_th_2x, 202 }, 203 { 204 /* Tiger Lake PCH */ 205 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), 206 .driver_data = (kernel_ulong_t)&intel_th_2x, 207 }, 208 { 209 /* Tiger Lake PCH-H */ 210 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6), 211 .driver_data = (kernel_ulong_t)&intel_th_2x, 212 }, 213 { 214 /* Jasper Lake PCH */ 215 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), 216 .driver_data = (kernel_ulong_t)&intel_th_2x, 217 }, 218 { 219 /* Jasper Lake CPU */ 220 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29), 221 .driver_data = (kernel_ulong_t)&intel_th_2x, 222 }, 223 { 224 /* Elkhart Lake CPU */ 225 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529), 226 .driver_data = (kernel_ulong_t)&intel_th_2x, 227 }, 228 { 229 /* Elkhart Lake */ 230 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), 231 .driver_data = (kernel_ulong_t)&intel_th_2x, 232 }, 233 { 234 /* Emmitsburg PCH */ 235 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc), 236 .driver_data = (kernel_ulong_t)&intel_th_2x, 237 }, 238 { 0 }, 239 }; 240 241 MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table); 242 243 static struct pci_driver intel_th_pci_driver = { 244 .name = DRIVER_NAME, 245 .id_table = intel_th_pci_id_table, 246 .probe = intel_th_pci_probe, 247 .remove = intel_th_pci_remove, 248 }; 249 250 module_pci_driver(intel_th_pci_driver); 251 252 MODULE_LICENSE("GPL v2"); 253 MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver"); 254 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>"); 255