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 { 164 /* Ice Lake PCH */ 165 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6), 166 .driver_data = (kernel_ulong_t)&intel_th_2x, 167 }, 168 { 0 }, 169 }; 170 171 MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table); 172 173 static struct pci_driver intel_th_pci_driver = { 174 .name = DRIVER_NAME, 175 .id_table = intel_th_pci_id_table, 176 .probe = intel_th_pci_probe, 177 .remove = intel_th_pci_remove, 178 }; 179 180 module_pci_driver(intel_th_pci_driver); 181 182 MODULE_LICENSE("GPL v2"); 183 MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver"); 184 MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>"); 185