blob: 1cf6290d643555d1cd9edfd114f2756b66d1b4bb [file] [log] [blame]
Alexander Shishkin50352fa2018-03-28 18:46:15 +03001// SPDX-License-Identifier: GPL-2.0
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +03002/*
3 * Intel(R) Trace Hub pci driver
4 *
5 * Copyright (C) 2014-2015 Intel Corporation.
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +03006 */
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
Alexander Shishkina0e7df32017-02-24 16:09:40 +020022#define PCI_REG_NPKDSC 0x80
23#define NPKDSC_TSACT BIT(5)
24
25static 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
46static 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
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +030065static int intel_th_pci_probe(struct pci_dev *pdev,
66 const struct pci_device_id *id)
67{
Alexander Shishkin33213712017-08-18 17:57:35 +030068 struct intel_th_drvdata *drvdata = (void *)id->driver_data;
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +030069 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
Alexander Shishkin33213712017-08-18 17:57:35 +030080 th = intel_th_alloc(&pdev->dev, drvdata, pdev->resource,
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +030081 DEVICE_COUNT_RESOURCE, pdev->irq);
82 if (IS_ERR(th))
83 return PTR_ERR(th);
84
Alexander Shishkina0e7df32017-02-24 16:09:40 +020085 th->activate = intel_th_pci_activate;
86 th->deactivate = intel_th_pci_deactivate;
87
Alexander Shishkine9b2b3e2017-08-10 11:10:58 +030088 pci_set_master(pdev);
89
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +030090 return 0;
91}
92
93static 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
Alexander Shishkina0e7df32017-02-24 16:09:40 +0200100static const struct intel_th_drvdata intel_th_2x = {
101 .tscu_enable = 1,
102};
103
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +0300104static 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 },
Alexander Shishkin6396b912015-12-22 17:25:22 +0200113 {
114 /* Apollo Lake */
115 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e),
116 .driver_data = (kernel_ulong_t)0,
117 },
Alexander Shishkin3f040882015-12-22 17:25:23 +0200118 {
119 /* Broxton */
120 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),
121 .driver_data = (kernel_ulong_t)0,
122 },
Alexander Shishkinaaa3ca82016-04-08 18:26:52 +0300123 {
124 /* Broxton B-step */
125 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e),
126 .driver_data = (kernel_ulong_t)0,
127 },
Alexander Shishkin7a1a47c2016-06-28 18:55:23 +0300128 {
129 /* Kaby Lake PCH-H */
130 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
131 .driver_data = (kernel_ulong_t)0,
132 },
Alexander Shishkin5118ccd2015-09-08 14:03:55 +0300133 {
134 /* Denverton */
135 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1),
136 .driver_data = (kernel_ulong_t)0,
137 },
Alexander Shishkin340837f2016-06-30 16:10:51 +0300138 {
Alexander Shishkin24600842017-09-19 18:47:42 +0300139 /* Lewisburg PCH */
140 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6),
141 .driver_data = (kernel_ulong_t)0,
142 },
143 {
Alexander Shishkin340837f2016-06-30 16:10:51 +0300144 /* Gemini Lake */
145 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
Alexander Shishkina0e7df32017-02-24 16:09:40 +0200146 .driver_data = (kernel_ulong_t)&intel_th_2x,
Alexander Shishkin340837f2016-06-30 16:10:51 +0300147 },
Alexander Shishkin84331e12016-06-30 16:11:13 +0300148 {
149 /* Cannon Lake H */
150 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
Alexander Shishkina0e7df32017-02-24 16:09:40 +0200151 .driver_data = (kernel_ulong_t)&intel_th_2x,
Alexander Shishkin84331e12016-06-30 16:11:13 +0300152 },
Alexander Shishkinefb36692016-06-30 16:11:31 +0300153 {
154 /* Cannon Lake LP */
155 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
Alexander Shishkina0e7df32017-02-24 16:09:40 +0200156 .driver_data = (kernel_ulong_t)&intel_th_2x,
Alexander Shishkinefb36692016-06-30 16:11:31 +0300157 },
Alexander Shishkin920ce7c2017-09-19 18:47:41 +0300158 {
159 /* Cedar Fork PCH */
160 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
161 .driver_data = (kernel_ulong_t)&intel_th_2x,
162 },
Alexander Shishkin59d08d002018-09-18 16:10:49 +0300163 {
164 /* Ice Lake PCH */
165 PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
166 .driver_data = (kernel_ulong_t)&intel_th_2x,
167 },
Alexander Shishkin2b0b16d2015-09-22 15:47:15 +0300168 { 0 },
169};
170
171MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table);
172
173static 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
180module_pci_driver(intel_th_pci_driver);
181
182MODULE_LICENSE("GPL v2");
183MODULE_DESCRIPTION("Intel(R) Trace Hub PCI controller driver");
184MODULE_AUTHOR("Alexander Shishkin <alexander.shishkin@intel.com>");