hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/drivers/fpga/dfl.h
....@@ -17,7 +17,9 @@
1717 #include <linux/bitfield.h>
1818 #include <linux/cdev.h>
1919 #include <linux/delay.h>
20
+#include <linux/eventfd.h>
2021 #include <linux/fs.h>
22
+#include <linux/interrupt.h>
2123 #include <linux/iopoll.h>
2224 #include <linux/io-64-nonatomic-lo-hi.h>
2325 #include <linux/platform_device.h>
....@@ -30,8 +32,8 @@
3032 /* plus one for fme device */
3133 #define MAX_DFL_FEATURE_DEV_NUM (MAX_DFL_FPGA_PORT_NUM + 1)
3234
33
-/* Reserved 0x0 for Header Group Register and 0xff for AFU */
34
-#define FEATURE_ID_FIU_HEADER 0x0
35
+/* Reserved 0xfe for Header Group Register and 0xff for AFU */
36
+#define FEATURE_ID_FIU_HEADER 0xfe
3537 #define FEATURE_ID_AFU 0xff
3638
3739 #define FME_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER
....@@ -112,6 +114,13 @@
112114 #define FME_PORT_OFST_ACC_VF 1
113115 #define FME_PORT_OFST_IMP BIT_ULL(60)
114116
117
+/* FME Error Capability Register */
118
+#define FME_ERROR_CAP 0x70
119
+
120
+/* FME Error Capability Register Bitfield */
121
+#define FME_ERROR_CAP_SUPP_INT BIT_ULL(0) /* Interrupt Support */
122
+#define FME_ERROR_CAP_INT_VECT GENMASK_ULL(12, 1) /* Interrupt vector */
123
+
115124 /* PORT Header Register Set */
116125 #define PORT_HDR_DFH DFH
117126 #define PORT_HDR_GUID_L GUID_L
....@@ -119,6 +128,11 @@
119128 #define PORT_HDR_NEXT_AFU NEXT_AFU
120129 #define PORT_HDR_CAP 0x30
121130 #define PORT_HDR_CTRL 0x38
131
+#define PORT_HDR_STS 0x40
132
+#define PORT_HDR_USRCLK_CMD0 0x50
133
+#define PORT_HDR_USRCLK_CMD1 0x58
134
+#define PORT_HDR_USRCLK_STS0 0x60
135
+#define PORT_HDR_USRCLK_STS1 0x68
122136
123137 /* Port Capability Register Bitfield */
124138 #define PORT_CAP_PORT_NUM GENMASK_ULL(1, 0) /* ID of this port */
....@@ -130,6 +144,30 @@
130144 /* Latency tolerance reporting. '1' >= 40us, '0' < 40us.*/
131145 #define PORT_CTRL_LATENCY BIT_ULL(2)
132146 #define PORT_CTRL_SFTRST_ACK BIT_ULL(4) /* HW ack for reset */
147
+
148
+/* Port Status Register Bitfield */
149
+#define PORT_STS_AP2_EVT BIT_ULL(13) /* AP2 event detected */
150
+#define PORT_STS_AP1_EVT BIT_ULL(12) /* AP1 event detected */
151
+#define PORT_STS_PWR_STATE GENMASK_ULL(11, 8) /* AFU power states */
152
+#define PORT_STS_PWR_STATE_NORM 0
153
+#define PORT_STS_PWR_STATE_AP1 1 /* 50% throttling */
154
+#define PORT_STS_PWR_STATE_AP2 2 /* 90% throttling */
155
+#define PORT_STS_PWR_STATE_AP6 6 /* 100% throttling */
156
+
157
+/* Port Error Capability Register */
158
+#define PORT_ERROR_CAP 0x38
159
+
160
+/* Port Error Capability Register Bitfield */
161
+#define PORT_ERROR_CAP_SUPP_INT BIT_ULL(0) /* Interrupt Support */
162
+#define PORT_ERROR_CAP_INT_VECT GENMASK_ULL(12, 1) /* Interrupt vector */
163
+
164
+/* Port Uint Capability Register */
165
+#define PORT_UINT_CAP 0x8
166
+
167
+/* Port Uint Capability Register Bitfield */
168
+#define PORT_UINT_CAP_INT_NUM GENMASK_ULL(11, 0) /* Interrupts num */
169
+#define PORT_UINT_CAP_FST_VECT GENMASK_ULL(23, 12) /* First Vector */
170
+
133171 /**
134172 * struct dfl_fpga_port_ops - port ops
135173 *
....@@ -154,34 +192,66 @@
154192 int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id);
155193
156194 /**
157
- * struct dfl_feature_driver - sub feature's driver
195
+ * struct dfl_feature_id - dfl private feature id
158196 *
159
- * @id: sub feature id.
160
- * @ops: ops of this sub feature.
197
+ * @id: unique dfl private feature id.
198
+ */
199
+struct dfl_feature_id {
200
+ u16 id;
201
+};
202
+
203
+/**
204
+ * struct dfl_feature_driver - dfl private feature driver
205
+ *
206
+ * @id_table: id_table for dfl private features supported by this driver.
207
+ * @ops: ops of this dfl private feature driver.
161208 */
162209 struct dfl_feature_driver {
163
- u64 id;
210
+ const struct dfl_feature_id *id_table;
164211 const struct dfl_feature_ops *ops;
212
+};
213
+
214
+/**
215
+ * struct dfl_feature_irq_ctx - dfl private feature interrupt context
216
+ *
217
+ * @irq: Linux IRQ number of this interrupt.
218
+ * @trigger: eventfd context to signal when interrupt happens.
219
+ * @name: irq name needed when requesting irq.
220
+ */
221
+struct dfl_feature_irq_ctx {
222
+ int irq;
223
+ struct eventfd_ctx *trigger;
224
+ char *name;
165225 };
166226
167227 /**
168228 * struct dfl_feature - sub feature of the feature devices
169229 *
230
+ * @dev: ptr to pdev of the feature device which has the sub feature.
170231 * @id: sub feature id.
171232 * @resource_index: each sub feature has one mmio resource for its registers.
172233 * this index is used to find its mmio resource from the
173234 * feature dev (platform device)'s reources.
174235 * @ioaddr: mapped mmio resource address.
236
+ * @irq_ctx: interrupt context list.
237
+ * @nr_irqs: number of interrupt contexts.
175238 * @ops: ops of this sub feature.
239
+ * @ddev: ptr to the dfl device of this sub feature.
240
+ * @priv: priv data of this feature.
176241 */
177242 struct dfl_feature {
178
- u64 id;
243
+ struct platform_device *dev;
244
+ u16 id;
179245 int resource_index;
180246 void __iomem *ioaddr;
247
+ struct dfl_feature_irq_ctx *irq_ctx;
248
+ unsigned int nr_irqs;
181249 const struct dfl_feature_ops *ops;
250
+ struct dfl_device *ddev;
251
+ void *priv;
182252 };
183253
184
-#define DEV_STATUS_IN_USE 0
254
+#define FEATURE_DEV_ID_UNUSED (-1)
185255
186256 /**
187257 * struct dfl_feature_platform_data - platform data for feature devices
....@@ -191,9 +261,11 @@
191261 * @cdev: cdev of feature dev.
192262 * @dev: ptr to platform device linked with this platform data.
193263 * @dfl_cdev: ptr to container device.
264
+ * @id: id used for this feature device.
194265 * @disable_count: count for port disable.
266
+ * @excl_open: set on feature device exclusive open.
267
+ * @open_count: count for feature device open.
195268 * @num: number for sub features.
196
- * @dev_status: dev status (e.g. DEV_STATUS_IN_USE).
197269 * @private: ptr to feature dev private data.
198270 * @features: sub features of this feature dev.
199271 */
....@@ -203,19 +275,29 @@
203275 struct cdev cdev;
204276 struct platform_device *dev;
205277 struct dfl_fpga_cdev *dfl_cdev;
278
+ int id;
206279 unsigned int disable_count;
207
- unsigned long dev_status;
280
+ bool excl_open;
281
+ int open_count;
208282 void *private;
209283 int num;
210
- struct dfl_feature features[0];
284
+ struct dfl_feature features[];
211285 };
212286
213287 static inline
214
-int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata)
288
+int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata,
289
+ bool excl)
215290 {
216
- /* Test and set IN_USE flags to ensure file is exclusively used */
217
- if (test_and_set_bit_lock(DEV_STATUS_IN_USE, &pdata->dev_status))
291
+ if (pdata->excl_open)
218292 return -EBUSY;
293
+
294
+ if (excl) {
295
+ if (pdata->open_count)
296
+ return -EBUSY;
297
+
298
+ pdata->excl_open = true;
299
+ }
300
+ pdata->open_count++;
219301
220302 return 0;
221303 }
....@@ -223,7 +305,18 @@
223305 static inline
224306 void dfl_feature_dev_use_end(struct dfl_feature_platform_data *pdata)
225307 {
226
- clear_bit_unlock(DEV_STATUS_IN_USE, &pdata->dev_status);
308
+ pdata->excl_open = false;
309
+
310
+ if (WARN_ON(pdata->open_count <= 0))
311
+ return;
312
+
313
+ pdata->open_count--;
314
+}
315
+
316
+static inline
317
+int dfl_feature_dev_use_count(struct dfl_feature_platform_data *pdata)
318
+{
319
+ return pdata->open_count;
227320 }
228321
229322 static inline
....@@ -250,12 +343,6 @@
250343 #define DFL_FPGA_FEATURE_DEV_FME "dfl-fme"
251344 #define DFL_FPGA_FEATURE_DEV_PORT "dfl-port"
252345
253
-static inline int dfl_feature_platform_data_size(const int num)
254
-{
255
- return sizeof(struct dfl_feature_platform_data) +
256
- num * sizeof(struct dfl_feature);
257
-}
258
-
259346 void dfl_fpga_dev_feature_uinit(struct platform_device *pdev);
260347 int dfl_fpga_dev_feature_init(struct platform_device *pdev,
261348 struct dfl_feature_driver *feature_drvs);
....@@ -280,7 +367,7 @@
280367 (feature) < (pdata)->features + (pdata)->num; (feature)++)
281368
282369 static inline
283
-struct dfl_feature *dfl_get_feature_by_id(struct device *dev, u64 id)
370
+struct dfl_feature *dfl_get_feature_by_id(struct device *dev, u16 id)
284371 {
285372 struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
286373 struct dfl_feature *feature;
....@@ -293,7 +380,7 @@
293380 }
294381
295382 static inline
296
-void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u64 id)
383
+void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u16 id)
297384 {
298385 struct dfl_feature *feature = dfl_get_feature_by_id(dev, id);
299386
....@@ -304,7 +391,7 @@
304391 return NULL;
305392 }
306393
307
-static inline bool is_dfl_feature_present(struct device *dev, u64 id)
394
+static inline bool is_dfl_feature_present(struct device *dev, u16 id)
308395 {
309396 return !!dfl_get_feature_ioaddr_by_id(dev, id);
310397 }
....@@ -331,15 +418,24 @@
331418 (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_PORT);
332419 }
333420
421
+static inline u8 dfl_feature_revision(void __iomem *base)
422
+{
423
+ return (u8)FIELD_GET(DFH_REVISION, readq(base + DFH));
424
+}
425
+
334426 /**
335427 * struct dfl_fpga_enum_info - DFL FPGA enumeration information
336428 *
337429 * @dev: parent device.
338430 * @dfls: list of device feature lists.
431
+ * @nr_irqs: number of irqs for all feature devices.
432
+ * @irq_table: Linux IRQ numbers for all irqs, indexed by hw irq numbers.
339433 */
340434 struct dfl_fpga_enum_info {
341435 struct device *dev;
342436 struct list_head dfls;
437
+ unsigned int nr_irqs;
438
+ int *irq_table;
343439 };
344440
345441 /**
....@@ -347,22 +443,19 @@
347443 *
348444 * @start: base address of this device feature list.
349445 * @len: size of this device feature list.
350
- * @ioaddr: mapped base address of this device feature list.
351446 * @node: node in list of device feature lists.
352447 */
353448 struct dfl_fpga_enum_dfl {
354449 resource_size_t start;
355450 resource_size_t len;
356
-
357
- void __iomem *ioaddr;
358
-
359451 struct list_head node;
360452 };
361453
362454 struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev);
363455 int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
364
- resource_size_t start, resource_size_t len,
365
- void __iomem *ioaddr);
456
+ resource_size_t start, resource_size_t len);
457
+int dfl_fpga_enum_info_add_irq(struct dfl_fpga_enum_info *info,
458
+ unsigned int nr_irqs, int *irq_table);
366459 void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info);
367460
368461 /**
....@@ -373,6 +466,7 @@
373466 * @fme_dev: FME feature device under this container device.
374467 * @lock: mutex lock to protect the port device list.
375468 * @port_dev_list: list of all port feature devices under this container device.
469
+ * @released_port_num: released port number under this container device.
376470 */
377471 struct dfl_fpga_cdev {
378472 struct device *parent;
....@@ -380,6 +474,7 @@
380474 struct device *fme_dev;
381475 struct mutex lock;
382476 struct list_head port_dev_list;
477
+ int released_port_num;
383478 };
384479
385480 struct dfl_fpga_cdev *
....@@ -407,4 +502,102 @@
407502
408503 return pdev;
409504 }
505
+
506
+int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id);
507
+int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id);
508
+void dfl_fpga_cdev_config_ports_pf(struct dfl_fpga_cdev *cdev);
509
+int dfl_fpga_cdev_config_ports_vf(struct dfl_fpga_cdev *cdev, int num_vf);
510
+int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start,
511
+ unsigned int count, int32_t *fds);
512
+long dfl_feature_ioctl_get_num_irqs(struct platform_device *pdev,
513
+ struct dfl_feature *feature,
514
+ unsigned long arg);
515
+long dfl_feature_ioctl_set_irq(struct platform_device *pdev,
516
+ struct dfl_feature *feature,
517
+ unsigned long arg);
518
+
519
+/**
520
+ * enum dfl_id_type - define the DFL FIU types
521
+ */
522
+enum dfl_id_type {
523
+ FME_ID,
524
+ PORT_ID,
525
+ DFL_ID_MAX,
526
+};
527
+
528
+/**
529
+ * struct dfl_device_id - dfl device identifier
530
+ * @type: contains 4 bits DFL FIU type of the device. See enum dfl_id_type.
531
+ * @feature_id: contains 12 bits feature identifier local to its DFL FIU type.
532
+ * @driver_data: driver specific data.
533
+ */
534
+struct dfl_device_id {
535
+ u8 type;
536
+ u16 feature_id;
537
+ unsigned long driver_data;
538
+};
539
+
540
+/**
541
+ * struct dfl_device - represent an dfl device on dfl bus
542
+ *
543
+ * @dev: generic device interface.
544
+ * @id: id of the dfl device.
545
+ * @type: type of DFL FIU of the device. See enum dfl_id_type.
546
+ * @feature_id: 16 bits feature identifier local to its DFL FIU type.
547
+ * @mmio_res: mmio resource of this dfl device.
548
+ * @irqs: list of Linux IRQ numbers of this dfl device.
549
+ * @num_irqs: number of IRQs supported by this dfl device.
550
+ * @cdev: pointer to DFL FPGA container device this dfl device belongs to.
551
+ * @id_entry: matched id entry in dfl driver's id table.
552
+ */
553
+struct dfl_device {
554
+ struct device dev;
555
+ int id;
556
+ u8 type;
557
+ u16 feature_id;
558
+ struct resource mmio_res;
559
+ int *irqs;
560
+ unsigned int num_irqs;
561
+ struct dfl_fpga_cdev *cdev;
562
+ const struct dfl_device_id *id_entry;
563
+};
564
+
565
+/**
566
+ * struct dfl_driver - represent an dfl device driver
567
+ *
568
+ * @drv: driver model structure.
569
+ * @id_table: pointer to table of device IDs the driver is interested in.
570
+ * { } member terminated.
571
+ * @probe: mandatory callback for device binding.
572
+ * @remove: callback for device unbinding.
573
+ */
574
+struct dfl_driver {
575
+ struct device_driver drv;
576
+ const struct dfl_device_id *id_table;
577
+
578
+ int (*probe)(struct dfl_device *dfl_dev);
579
+ void (*remove)(struct dfl_device *dfl_dev);
580
+};
581
+
582
+#define to_dfl_dev(d) container_of(d, struct dfl_device, dev)
583
+#define to_dfl_drv(d) container_of(d, struct dfl_driver, drv)
584
+
585
+/*
586
+ * use a macro to avoid include chaining to get THIS_MODULE.
587
+ */
588
+#define dfl_driver_register(drv) \
589
+ __dfl_driver_register(drv, THIS_MODULE)
590
+int __dfl_driver_register(struct dfl_driver *dfl_drv, struct module *owner);
591
+void dfl_driver_unregister(struct dfl_driver *dfl_drv);
592
+
593
+/*
594
+ * module_dfl_driver() - Helper macro for drivers that don't do
595
+ * anything special in module init/exit. This eliminates a lot of
596
+ * boilerplate. Each module may only use this macro once, and
597
+ * calling it replaces module_init() and module_exit().
598
+ */
599
+#define module_dfl_driver(__dfl_driver) \
600
+ module_driver(__dfl_driver, dfl_driver_register, \
601
+ dfl_driver_unregister)
602
+
410603 #endif /* __FPGA_DFL_H */