forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/drivers/fpga/dfl-pci.c
....@@ -31,22 +31,46 @@
3131 struct dfl_fpga_cdev *cdev; /* container device */
3232 };
3333
34
-static void __iomem *cci_pci_ioremap_bar(struct pci_dev *pcidev, int bar)
34
+static void __iomem *cci_pci_ioremap_bar0(struct pci_dev *pcidev)
3535 {
36
- if (pcim_iomap_regions(pcidev, BIT(bar), DRV_NAME))
36
+ if (pcim_iomap_regions(pcidev, BIT(0), DRV_NAME))
3737 return NULL;
3838
39
- return pcim_iomap_table(pcidev)[bar];
39
+ return pcim_iomap_table(pcidev)[0];
40
+}
41
+
42
+static int cci_pci_alloc_irq(struct pci_dev *pcidev)
43
+{
44
+ int ret, nvec = pci_msix_vec_count(pcidev);
45
+
46
+ if (nvec <= 0) {
47
+ dev_dbg(&pcidev->dev, "fpga interrupt not supported\n");
48
+ return 0;
49
+ }
50
+
51
+ ret = pci_alloc_irq_vectors(pcidev, nvec, nvec, PCI_IRQ_MSIX);
52
+ if (ret < 0)
53
+ return ret;
54
+
55
+ return nvec;
56
+}
57
+
58
+static void cci_pci_free_irq(struct pci_dev *pcidev)
59
+{
60
+ pci_free_irq_vectors(pcidev);
4061 }
4162
4263 /* PCI Device ID */
43
-#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
44
-#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
45
-#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
64
+#define PCIE_DEVICE_ID_PF_INT_5_X 0xBCBD
65
+#define PCIE_DEVICE_ID_PF_INT_6_X 0xBCC0
66
+#define PCIE_DEVICE_ID_PF_DSC_1_X 0x09C4
67
+#define PCIE_DEVICE_ID_INTEL_PAC_N3000 0x0B30
68
+#define PCIE_DEVICE_ID_INTEL_PAC_D5005 0x0B2B
4669 /* VF Device */
47
-#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
48
-#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
49
-#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
70
+#define PCIE_DEVICE_ID_VF_INT_5_X 0xBCBF
71
+#define PCIE_DEVICE_ID_VF_INT_6_X 0xBCC1
72
+#define PCIE_DEVICE_ID_VF_DSC_1_X 0x09C5
73
+#define PCIE_DEVICE_ID_INTEL_PAC_D5005_VF 0x0B2C
5074
5175 static struct pci_device_id cci_pcie_id_tbl[] = {
5276 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_INT_5_X),},
....@@ -55,6 +79,9 @@
5579 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_INT_6_X),},
5680 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_PF_DSC_1_X),},
5781 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_VF_DSC_1_X),},
82
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_N3000),},
83
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005),},
84
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_PAC_D5005_VF),},
5885 {0,}
5986 };
6087 MODULE_DEVICE_TABLE(pci, cci_pcie_id_tbl);
....@@ -78,17 +105,34 @@
78105
79106 /* remove all children feature devices */
80107 dfl_fpga_feature_devs_remove(drvdata->cdev);
108
+ cci_pci_free_irq(pcidev);
109
+}
110
+
111
+static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec)
112
+{
113
+ unsigned int i;
114
+ int *table;
115
+
116
+ table = kcalloc(nvec, sizeof(int), GFP_KERNEL);
117
+ if (!table)
118
+ return table;
119
+
120
+ for (i = 0; i < nvec; i++)
121
+ table[i] = pci_irq_vector(pcidev, i);
122
+
123
+ return table;
81124 }
82125
83126 /* enumerate feature devices under pci device */
84127 static int cci_enumerate_feature_devs(struct pci_dev *pcidev)
85128 {
86129 struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
130
+ int port_num, bar, i, nvec, ret = 0;
87131 struct dfl_fpga_enum_info *info;
88132 struct dfl_fpga_cdev *cdev;
89133 resource_size_t start, len;
90
- int port_num, bar, i, ret = 0;
91134 void __iomem *base;
135
+ int *irq_table;
92136 u32 offset;
93137 u64 v;
94138
....@@ -97,11 +141,30 @@
97141 if (!info)
98142 return -ENOMEM;
99143
100
- /* start to find Device Feature List from Bar 0 */
101
- base = cci_pci_ioremap_bar(pcidev, 0);
144
+ /* add irq info for enumeration if the device support irq */
145
+ nvec = cci_pci_alloc_irq(pcidev);
146
+ if (nvec < 0) {
147
+ dev_err(&pcidev->dev, "Fail to alloc irq %d.\n", nvec);
148
+ ret = nvec;
149
+ goto enum_info_free_exit;
150
+ } else if (nvec) {
151
+ irq_table = cci_pci_create_irq_table(pcidev, nvec);
152
+ if (!irq_table) {
153
+ ret = -ENOMEM;
154
+ goto irq_free_exit;
155
+ }
156
+
157
+ ret = dfl_fpga_enum_info_add_irq(info, nvec, irq_table);
158
+ kfree(irq_table);
159
+ if (ret)
160
+ goto irq_free_exit;
161
+ }
162
+
163
+ /* start to find Device Feature List in Bar 0 */
164
+ base = cci_pci_ioremap_bar0(pcidev);
102165 if (!base) {
103166 ret = -ENOMEM;
104
- goto enum_info_free_exit;
167
+ goto irq_free_exit;
105168 }
106169
107170 /*
....@@ -113,7 +176,7 @@
113176 start = pci_resource_start(pcidev, 0);
114177 len = pci_resource_len(pcidev, 0);
115178
116
- dfl_fpga_enum_info_add_dfl(info, start, len, base);
179
+ dfl_fpga_enum_info_add_dfl(info, start, len);
117180
118181 /*
119182 * find more Device Feature Lists (e.g. Ports) per information
....@@ -137,36 +200,37 @@
137200 */
138201 bar = FIELD_GET(FME_PORT_OFST_BAR_ID, v);
139202 offset = FIELD_GET(FME_PORT_OFST_DFH_OFST, v);
140
- base = cci_pci_ioremap_bar(pcidev, bar);
141
- if (!base)
142
- continue;
143
-
144203 start = pci_resource_start(pcidev, bar) + offset;
145204 len = pci_resource_len(pcidev, bar) - offset;
146205
147
- dfl_fpga_enum_info_add_dfl(info, start, len,
148
- base + offset);
206
+ dfl_fpga_enum_info_add_dfl(info, start, len);
149207 }
150208 } else if (dfl_feature_is_port(base)) {
151209 start = pci_resource_start(pcidev, 0);
152210 len = pci_resource_len(pcidev, 0);
153211
154
- dfl_fpga_enum_info_add_dfl(info, start, len, base);
212
+ dfl_fpga_enum_info_add_dfl(info, start, len);
155213 } else {
156214 ret = -ENODEV;
157
- goto enum_info_free_exit;
215
+ goto irq_free_exit;
158216 }
217
+
218
+ /* release I/O mappings for next step enumeration */
219
+ pcim_iounmap_regions(pcidev, BIT(0));
159220
160221 /* start enumeration with prepared enumeration information */
161222 cdev = dfl_fpga_feature_devs_enumerate(info);
162223 if (IS_ERR(cdev)) {
163224 dev_err(&pcidev->dev, "Enumeration failure\n");
164225 ret = PTR_ERR(cdev);
165
- goto enum_info_free_exit;
226
+ goto irq_free_exit;
166227 }
167228
168229 drvdata->cdev = cdev;
169230
231
+irq_free_exit:
232
+ if (ret)
233
+ cci_pci_free_irq(pcidev);
170234 enum_info_free_exit:
171235 dfl_fpga_enum_info_free(info);
172236
....@@ -211,20 +275,56 @@
211275 }
212276
213277 ret = cci_enumerate_feature_devs(pcidev);
214
- if (ret) {
215
- dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
216
- goto disable_error_report_exit;
217
- }
278
+ if (!ret)
279
+ return ret;
218280
219
- return ret;
281
+ dev_err(&pcidev->dev, "enumeration failure %d.\n", ret);
220282
221283 disable_error_report_exit:
222284 pci_disable_pcie_error_reporting(pcidev);
223285 return ret;
224286 }
225287
288
+static int cci_pci_sriov_configure(struct pci_dev *pcidev, int num_vfs)
289
+{
290
+ struct cci_drvdata *drvdata = pci_get_drvdata(pcidev);
291
+ struct dfl_fpga_cdev *cdev = drvdata->cdev;
292
+
293
+ if (!num_vfs) {
294
+ /*
295
+ * disable SRIOV and then put released ports back to default
296
+ * PF access mode.
297
+ */
298
+ pci_disable_sriov(pcidev);
299
+
300
+ dfl_fpga_cdev_config_ports_pf(cdev);
301
+
302
+ } else {
303
+ int ret;
304
+
305
+ /*
306
+ * before enable SRIOV, put released ports into VF access mode
307
+ * first of all.
308
+ */
309
+ ret = dfl_fpga_cdev_config_ports_vf(cdev, num_vfs);
310
+ if (ret)
311
+ return ret;
312
+
313
+ ret = pci_enable_sriov(pcidev, num_vfs);
314
+ if (ret) {
315
+ dfl_fpga_cdev_config_ports_pf(cdev);
316
+ return ret;
317
+ }
318
+ }
319
+
320
+ return num_vfs;
321
+}
322
+
226323 static void cci_pci_remove(struct pci_dev *pcidev)
227324 {
325
+ if (dev_is_pf(&pcidev->dev))
326
+ cci_pci_sriov_configure(pcidev, 0);
327
+
228328 cci_remove_feature_devs(pcidev);
229329 pci_disable_pcie_error_reporting(pcidev);
230330 }
....@@ -234,6 +334,7 @@
234334 .id_table = cci_pcie_id_tbl,
235335 .probe = cci_pci_probe,
236336 .remove = cci_pci_remove,
337
+ .sriov_configure = cci_pci_sriov_configure,
237338 };
238339
239340 module_pci_driver(cci_pci_driver);