pci.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  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. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  8. #include <linux/types.h>
  9. #include <linux/module.h>
  10. #include <linux/device.h>
  11. #include <linux/sysfs.h>
  12. #include <linux/pci.h>
  13. #include "intel_th.h"
  14. #define DRIVER_NAME "intel_th_pci"
  15. enum {
  16. TH_PCI_CONFIG_BAR = 0,
  17. TH_PCI_STH_SW_BAR = 2,
  18. TH_PCI_RTIT_BAR = 4,
  19. };
  20. #define BAR_MASK (BIT(TH_PCI_CONFIG_BAR) | BIT(TH_PCI_STH_SW_BAR))
  21. #define PCI_REG_NPKDSC 0x80
  22. #define NPKDSC_TSACT BIT(5)
  23. static int intel_th_pci_activate(struct intel_th *th)
  24. {
  25. struct pci_dev *pdev = to_pci_dev(th->dev);
  26. u32 npkdsc;
  27. int err;
  28. if (!INTEL_TH_CAP(th, tscu_enable))
  29. return 0;
  30. err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
  31. if (!err) {
  32. npkdsc |= NPKDSC_TSACT;
  33. err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
  34. }
  35. if (err)
  36. dev_err(&pdev->dev, "failed to read NPKDSC register\n");
  37. return err;
  38. }
  39. static void intel_th_pci_deactivate(struct intel_th *th)
  40. {
  41. struct pci_dev *pdev = to_pci_dev(th->dev);
  42. u32 npkdsc;
  43. int err;
  44. if (!INTEL_TH_CAP(th, tscu_enable))
  45. return;
  46. err = pci_read_config_dword(pdev, PCI_REG_NPKDSC, &npkdsc);
  47. if (!err) {
  48. npkdsc |= NPKDSC_TSACT;
  49. err = pci_write_config_dword(pdev, PCI_REG_NPKDSC, npkdsc);
  50. }
  51. if (err)
  52. dev_err(&pdev->dev, "failed to read NPKDSC register\n");
  53. }
  54. static int intel_th_pci_probe(struct pci_dev *pdev,
  55. const struct pci_device_id *id)
  56. {
  57. const struct intel_th_drvdata *drvdata = (void *)id->driver_data;
  58. struct resource resource[TH_MMIO_END + TH_NVEC_MAX] = {
  59. [TH_MMIO_CONFIG] = pdev->resource[TH_PCI_CONFIG_BAR],
  60. [TH_MMIO_SW] = pdev->resource[TH_PCI_STH_SW_BAR],
  61. };
  62. int err, r = TH_MMIO_SW + 1, i;
  63. struct intel_th *th;
  64. err = pcim_enable_device(pdev);
  65. if (err)
  66. return err;
  67. err = pcim_iomap_regions_request_all(pdev, BAR_MASK, DRIVER_NAME);
  68. if (err)
  69. return err;
  70. if (pdev->resource[TH_PCI_RTIT_BAR].start) {
  71. resource[TH_MMIO_RTIT] = pdev->resource[TH_PCI_RTIT_BAR];
  72. r++;
  73. }
  74. err = pci_alloc_irq_vectors(pdev, 1, 8, PCI_IRQ_ALL_TYPES);
  75. if (err > 0)
  76. for (i = 0; i < err; i++, r++) {
  77. resource[r].flags = IORESOURCE_IRQ;
  78. resource[r].start = pci_irq_vector(pdev, i);
  79. }
  80. th = intel_th_alloc(&pdev->dev, drvdata, resource, r);
  81. if (IS_ERR(th)) {
  82. err = PTR_ERR(th);
  83. goto err_free_irq;
  84. }
  85. th->activate = intel_th_pci_activate;
  86. th->deactivate = intel_th_pci_deactivate;
  87. pci_set_master(pdev);
  88. return 0;
  89. err_free_irq:
  90. pci_free_irq_vectors(pdev);
  91. return err;
  92. }
  93. static void intel_th_pci_remove(struct pci_dev *pdev)
  94. {
  95. struct intel_th *th = pci_get_drvdata(pdev);
  96. intel_th_free(th);
  97. pci_free_irq_vectors(pdev);
  98. }
  99. static const struct intel_th_drvdata intel_th_1x_multi_is_broken = {
  100. .multi_is_broken = 1,
  101. };
  102. static const struct intel_th_drvdata intel_th_2x = {
  103. .tscu_enable = 1,
  104. .has_mintctl = 1,
  105. };
  106. static const struct pci_device_id intel_th_pci_id_table[] = {
  107. {
  108. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26),
  109. .driver_data = (kernel_ulong_t)0,
  110. },
  111. {
  112. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126),
  113. .driver_data = (kernel_ulong_t)0,
  114. },
  115. {
  116. /* Apollo Lake */
  117. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e),
  118. .driver_data = (kernel_ulong_t)0,
  119. },
  120. {
  121. /* Broxton */
  122. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),
  123. .driver_data = (kernel_ulong_t)0,
  124. },
  125. {
  126. /* Broxton B-step */
  127. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e),
  128. .driver_data = (kernel_ulong_t)0,
  129. },
  130. {
  131. /* Kaby Lake PCH-H */
  132. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
  133. .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
  134. },
  135. {
  136. /* Denverton */
  137. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),
  138. .driver_data = (kernel_ulong_t)0,
  139. },
  140. {
  141. /* Lewisburg PCH */
  142. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6),
  143. .driver_data = (kernel_ulong_t)0,
  144. },
  145. {
  146. /* Lewisburg PCH */
  147. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226),
  148. .driver_data = (kernel_ulong_t)0,
  149. },
  150. {
  151. /* Gemini Lake */
  152. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
  153. .driver_data = (kernel_ulong_t)&intel_th_2x,
  154. },
  155. {
  156. /* Cannon Lake H */
  157. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
  158. .driver_data = (kernel_ulong_t)&intel_th_2x,
  159. },
  160. {
  161. /* Cannon Lake LP */
  162. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
  163. .driver_data = (kernel_ulong_t)&intel_th_2x,
  164. },
  165. {
  166. /* Cedar Fork PCH */
  167. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
  168. .driver_data = (kernel_ulong_t)&intel_th_2x,
  169. },
  170. {
  171. /* Ice Lake PCH */
  172. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
  173. .driver_data = (kernel_ulong_t)&intel_th_2x,
  174. },
  175. {
  176. /* Comet Lake */
  177. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6),
  178. .driver_data = (kernel_ulong_t)&intel_th_2x,
  179. },
  180. {
  181. /* Comet Lake PCH */
  182. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6),
  183. .driver_data = (kernel_ulong_t)&intel_th_2x,
  184. },
  185. {
  186. /* Comet Lake PCH-V */
  187. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6),
  188. .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken,
  189. },
  190. {
  191. /* Ice Lake NNPI */
  192. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),
  193. .driver_data = (kernel_ulong_t)&intel_th_2x,
  194. },
  195. {
  196. /* Ice Lake CPU */
  197. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29),
  198. .driver_data = (kernel_ulong_t)&intel_th_2x,
  199. },
  200. {
  201. /* Tiger Lake CPU */
  202. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33),
  203. .driver_data = (kernel_ulong_t)&intel_th_2x,
  204. },
  205. {
  206. /* Tiger Lake PCH */
  207. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
  208. .driver_data = (kernel_ulong_t)&intel_th_2x,
  209. },
  210. {
  211. /* Tiger Lake PCH-H */
  212. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6),
  213. .driver_data = (kernel_ulong_t)&intel_th_2x,
  214. },
  215. {
  216. /* Jasper Lake PCH */
  217. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6),
  218. .driver_data = (kernel_ulong_t)&intel_th_2x,
  219. },
  220. {
  221. /* Jasper Lake CPU */
  222. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29),
  223. .driver_data = (kernel_ulong_t)&intel_th_2x,
  224. },
  225. {
  226. /* Elkhart Lake CPU */
  227. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529),
  228. .driver_data = (kernel_ulong_t)&intel_th_2x,
  229. },
  230. {
  231. /* Elkhart Lake */
  232. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26),
  233. .driver_data = (kernel_ulong_t)&intel_th_2x,
  234. },
  235. {
  236. /* Emmitsburg PCH */
  237. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc),
  238. .driver_data = (kernel_ulong_t)&intel_th_2x,
  239. },
  240. {
  241. /* Alder Lake */
  242. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7aa6),
  243. .driver_data = (kernel_ulong_t)&intel_th_2x,
  244. },
  245. {
  246. /* Alder Lake-P */
  247. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6),
  248. .driver_data = (kernel_ulong_t)&intel_th_2x,
  249. },
  250. {
  251. /* Alder Lake-M */
  252. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6),
  253. .driver_data = (kernel_ulong_t)&intel_th_2x,
  254. },
  255. {
  256. /* Meteor Lake-P */
  257. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7e24),
  258. .driver_data = (kernel_ulong_t)&intel_th_2x,
  259. },
  260. {
  261. /* Meteor Lake-S */
  262. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7f26),
  263. .driver_data = (kernel_ulong_t)&intel_th_2x,
  264. },
  265. {
  266. /* Meteor Lake-S CPU */
  267. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24),
  268. .driver_data = (kernel_ulong_t)&intel_th_2x,
  269. },
  270. {
  271. /* Raptor Lake-S */
  272. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26),
  273. .driver_data = (kernel_ulong_t)&intel_th_2x,
  274. },
  275. {
  276. /* Raptor Lake-S CPU */
  277. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa76f),
  278. .driver_data = (kernel_ulong_t)&intel_th_2x,
  279. },
  280. {
  281. /* Granite Rapids */
  282. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0963),
  283. .driver_data = (kernel_ulong_t)&intel_th_2x,
  284. },
  285. {
  286. /* Granite Rapids SOC */
  287. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3256),
  288. .driver_data = (kernel_ulong_t)&intel_th_2x,
  289. },
  290. {
  291. /* Sapphire Rapids SOC */
  292. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3456),
  293. .driver_data = (kernel_ulong_t)&intel_th_2x,
  294. },
  295. {
  296. /* Lunar Lake */
  297. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824),
  298. .driver_data = (kernel_ulong_t)&intel_th_2x,
  299. },
  300. {
  301. /* Arrow Lake */
  302. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7724),
  303. .driver_data = (kernel_ulong_t)&intel_th_2x,
  304. },
  305. {
  306. /* Panther Lake-H */
  307. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe324),
  308. .driver_data = (kernel_ulong_t)&intel_th_2x,
  309. },
  310. {
  311. /* Panther Lake-P/U */
  312. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe424),
  313. .driver_data = (kernel_ulong_t)&intel_th_2x,
  314. },
  315. {
  316. /* Alder Lake CPU */
  317. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
  318. .driver_data = (kernel_ulong_t)&intel_th_2x,
  319. },
  320. {
  321. /* Rocket Lake CPU */
  322. PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19),
  323. .driver_data = (kernel_ulong_t)&intel_th_2x,
  324. },
  325. { 0 },
  326. };
  327. MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table);
  328. static struct pci_driver intel_th_pci_driver = {
  329. .name = DRIVER_NAME,
  330. .id_table = intel_th_pci_id_table,
  331. .probe = intel_th_pci_probe,
  332. .remove = intel_th_pci_remove,
  333. };
  334. module_pci_driver(intel_th_pci_driver);
  335. MODULE_LICENSE("GPL v2");
  336. MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver");
  337. MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");