Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Driver Header File for FPGA Device Feature List (DFL) Support
0004  *
0005  * Copyright (C) 2017-2018 Intel Corporation, Inc.
0006  *
0007  * Authors:
0008  *   Kang Luwei <luwei.kang@intel.com>
0009  *   Zhang Yi <yi.z.zhang@intel.com>
0010  *   Wu Hao <hao.wu@intel.com>
0011  *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
0012  */
0013 
0014 #ifndef __FPGA_DFL_H
0015 #define __FPGA_DFL_H
0016 
0017 #include <linux/bitfield.h>
0018 #include <linux/cdev.h>
0019 #include <linux/delay.h>
0020 #include <linux/eventfd.h>
0021 #include <linux/fs.h>
0022 #include <linux/interrupt.h>
0023 #include <linux/iopoll.h>
0024 #include <linux/io-64-nonatomic-lo-hi.h>
0025 #include <linux/mod_devicetable.h>
0026 #include <linux/platform_device.h>
0027 #include <linux/slab.h>
0028 #include <linux/uuid.h>
0029 #include <linux/fpga/fpga-region.h>
0030 
0031 /* maximum supported number of ports */
0032 #define MAX_DFL_FPGA_PORT_NUM 4
0033 /* plus one for fme device */
0034 #define MAX_DFL_FEATURE_DEV_NUM    (MAX_DFL_FPGA_PORT_NUM + 1)
0035 
0036 /* Reserved 0xfe for Header Group Register and 0xff for AFU */
0037 #define FEATURE_ID_FIU_HEADER       0xfe
0038 #define FEATURE_ID_AFU          0xff
0039 
0040 #define FME_FEATURE_ID_HEADER       FEATURE_ID_FIU_HEADER
0041 #define FME_FEATURE_ID_THERMAL_MGMT 0x1
0042 #define FME_FEATURE_ID_POWER_MGMT   0x2
0043 #define FME_FEATURE_ID_GLOBAL_IPERF 0x3
0044 #define FME_FEATURE_ID_GLOBAL_ERR   0x4
0045 #define FME_FEATURE_ID_PR_MGMT      0x5
0046 #define FME_FEATURE_ID_HSSI     0x6
0047 #define FME_FEATURE_ID_GLOBAL_DPERF 0x7
0048 
0049 #define PORT_FEATURE_ID_HEADER      FEATURE_ID_FIU_HEADER
0050 #define PORT_FEATURE_ID_AFU     FEATURE_ID_AFU
0051 #define PORT_FEATURE_ID_ERROR       0x10
0052 #define PORT_FEATURE_ID_UMSG        0x11
0053 #define PORT_FEATURE_ID_UINT        0x12
0054 #define PORT_FEATURE_ID_STP     0x13
0055 
0056 /*
0057  * Device Feature Header Register Set
0058  *
0059  * For FIUs, they all have DFH + GUID + NEXT_AFU as common header registers.
0060  * For AFUs, they have DFH + GUID as common header registers.
0061  * For private features, they only have DFH register as common header.
0062  */
0063 #define DFH         0x0
0064 #define GUID_L          0x8
0065 #define GUID_H          0x10
0066 #define NEXT_AFU        0x18
0067 
0068 #define DFH_SIZE        0x8
0069 
0070 /* Device Feature Header Register Bitfield */
0071 #define DFH_ID          GENMASK_ULL(11, 0)  /* Feature ID */
0072 #define DFH_ID_FIU_FME      0
0073 #define DFH_ID_FIU_PORT     1
0074 #define DFH_REVISION        GENMASK_ULL(15, 12) /* Feature revision */
0075 #define DFH_NEXT_HDR_OFST   GENMASK_ULL(39, 16) /* Offset to next DFH */
0076 #define DFH_EOL         BIT_ULL(40)     /* End of list */
0077 #define DFH_TYPE        GENMASK_ULL(63, 60) /* Feature type */
0078 #define DFH_TYPE_AFU        1
0079 #define DFH_TYPE_PRIVATE    3
0080 #define DFH_TYPE_FIU        4
0081 
0082 /* Next AFU Register Bitfield */
0083 #define NEXT_AFU_NEXT_DFH_OFST  GENMASK_ULL(23, 0)  /* Offset to next AFU */
0084 
0085 /* FME Header Register Set */
0086 #define FME_HDR_DFH     DFH
0087 #define FME_HDR_GUID_L      GUID_L
0088 #define FME_HDR_GUID_H      GUID_H
0089 #define FME_HDR_NEXT_AFU    NEXT_AFU
0090 #define FME_HDR_CAP     0x30
0091 #define FME_HDR_PORT_OFST(n)    (0x38 + ((n) * 0x8))
0092 #define FME_PORT_OFST_BAR_SKIP  7
0093 #define FME_HDR_BITSTREAM_ID    0x60
0094 #define FME_HDR_BITSTREAM_MD    0x68
0095 
0096 /* FME Fab Capability Register Bitfield */
0097 #define FME_CAP_FABRIC_VERID    GENMASK_ULL(7, 0)   /* Fabric version ID */
0098 #define FME_CAP_SOCKET_ID   BIT_ULL(8)      /* Socket ID */
0099 #define FME_CAP_PCIE0_LINK_AVL  BIT_ULL(12)     /* PCIE0 Link */
0100 #define FME_CAP_PCIE1_LINK_AVL  BIT_ULL(13)     /* PCIE1 Link */
0101 #define FME_CAP_COHR_LINK_AVL   BIT_ULL(14)     /* Coherent Link */
0102 #define FME_CAP_IOMMU_AVL   BIT_ULL(16)     /* IOMMU available */
0103 #define FME_CAP_NUM_PORTS   GENMASK_ULL(19, 17) /* Number of ports */
0104 #define FME_CAP_ADDR_WIDTH  GENMASK_ULL(29, 24) /* Address bus width */
0105 #define FME_CAP_CACHE_SIZE  GENMASK_ULL(43, 32) /* cache size in KB */
0106 #define FME_CAP_CACHE_ASSOC GENMASK_ULL(47, 44) /* Associativity */
0107 
0108 /* FME Port Offset Register Bitfield */
0109 /* Offset to port device feature header */
0110 #define FME_PORT_OFST_DFH_OFST  GENMASK_ULL(23, 0)
0111 /* PCI Bar ID for this port */
0112 #define FME_PORT_OFST_BAR_ID    GENMASK_ULL(34, 32)
0113 /* AFU MMIO access permission. 1 - VF, 0 - PF. */
0114 #define FME_PORT_OFST_ACC_CTRL  BIT_ULL(55)
0115 #define FME_PORT_OFST_ACC_PF    0
0116 #define FME_PORT_OFST_ACC_VF    1
0117 #define FME_PORT_OFST_IMP   BIT_ULL(60)
0118 
0119 /* FME Error Capability Register */
0120 #define FME_ERROR_CAP       0x70
0121 
0122 /* FME Error Capability Register Bitfield */
0123 #define FME_ERROR_CAP_SUPP_INT  BIT_ULL(0)      /* Interrupt Support */
0124 #define FME_ERROR_CAP_INT_VECT  GENMASK_ULL(12, 1)  /* Interrupt vector */
0125 
0126 /* PORT Header Register Set */
0127 #define PORT_HDR_DFH        DFH
0128 #define PORT_HDR_GUID_L     GUID_L
0129 #define PORT_HDR_GUID_H     GUID_H
0130 #define PORT_HDR_NEXT_AFU   NEXT_AFU
0131 #define PORT_HDR_CAP        0x30
0132 #define PORT_HDR_CTRL       0x38
0133 #define PORT_HDR_STS        0x40
0134 #define PORT_HDR_USRCLK_CMD0    0x50
0135 #define PORT_HDR_USRCLK_CMD1    0x58
0136 #define PORT_HDR_USRCLK_STS0    0x60
0137 #define PORT_HDR_USRCLK_STS1    0x68
0138 
0139 /* Port Capability Register Bitfield */
0140 #define PORT_CAP_PORT_NUM   GENMASK_ULL(1, 0)   /* ID of this port */
0141 #define PORT_CAP_MMIO_SIZE  GENMASK_ULL(23, 8)  /* MMIO size in KB */
0142 #define PORT_CAP_SUPP_INT_NUM   GENMASK_ULL(35, 32) /* Interrupts num */
0143 
0144 /* Port Control Register Bitfield */
0145 #define PORT_CTRL_SFTRST    BIT_ULL(0)      /* Port soft reset */
0146 /* Latency tolerance reporting. '1' >= 40us, '0' < 40us.*/
0147 #define PORT_CTRL_LATENCY   BIT_ULL(2)
0148 #define PORT_CTRL_SFTRST_ACK    BIT_ULL(4)      /* HW ack for reset */
0149 
0150 /* Port Status Register Bitfield */
0151 #define PORT_STS_AP2_EVT    BIT_ULL(13)     /* AP2 event detected */
0152 #define PORT_STS_AP1_EVT    BIT_ULL(12)     /* AP1 event detected */
0153 #define PORT_STS_PWR_STATE  GENMASK_ULL(11, 8)  /* AFU power states */
0154 #define PORT_STS_PWR_STATE_NORM 0
0155 #define PORT_STS_PWR_STATE_AP1  1           /* 50% throttling */
0156 #define PORT_STS_PWR_STATE_AP2  2           /* 90% throttling */
0157 #define PORT_STS_PWR_STATE_AP6  6           /* 100% throttling */
0158 
0159 /* Port Error Capability Register */
0160 #define PORT_ERROR_CAP      0x38
0161 
0162 /* Port Error Capability Register Bitfield */
0163 #define PORT_ERROR_CAP_SUPP_INT BIT_ULL(0)      /* Interrupt Support */
0164 #define PORT_ERROR_CAP_INT_VECT GENMASK_ULL(12, 1)  /* Interrupt vector */
0165 
0166 /* Port Uint Capability Register */
0167 #define PORT_UINT_CAP       0x8
0168 
0169 /* Port Uint Capability Register Bitfield */
0170 #define PORT_UINT_CAP_INT_NUM   GENMASK_ULL(11, 0)  /* Interrupts num */
0171 #define PORT_UINT_CAP_FST_VECT  GENMASK_ULL(23, 12) /* First Vector */
0172 
0173 /**
0174  * struct dfl_fpga_port_ops - port ops
0175  *
0176  * @name: name of this port ops, to match with port platform device.
0177  * @owner: pointer to the module which owns this port ops.
0178  * @node: node to link port ops to global list.
0179  * @get_id: get port id from hardware.
0180  * @enable_set: enable/disable the port.
0181  */
0182 struct dfl_fpga_port_ops {
0183     const char *name;
0184     struct module *owner;
0185     struct list_head node;
0186     int (*get_id)(struct platform_device *pdev);
0187     int (*enable_set)(struct platform_device *pdev, bool enable);
0188 };
0189 
0190 void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops);
0191 void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops);
0192 struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev);
0193 void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops);
0194 int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id);
0195 
0196 /**
0197  * struct dfl_feature_id - dfl private feature id
0198  *
0199  * @id: unique dfl private feature id.
0200  */
0201 struct dfl_feature_id {
0202     u16 id;
0203 };
0204 
0205 /**
0206  * struct dfl_feature_driver - dfl private feature driver
0207  *
0208  * @id_table: id_table for dfl private features supported by this driver.
0209  * @ops: ops of this dfl private feature driver.
0210  */
0211 struct dfl_feature_driver {
0212     const struct dfl_feature_id *id_table;
0213     const struct dfl_feature_ops *ops;
0214 };
0215 
0216 /**
0217  * struct dfl_feature_irq_ctx - dfl private feature interrupt context
0218  *
0219  * @irq: Linux IRQ number of this interrupt.
0220  * @trigger: eventfd context to signal when interrupt happens.
0221  * @name: irq name needed when requesting irq.
0222  */
0223 struct dfl_feature_irq_ctx {
0224     int irq;
0225     struct eventfd_ctx *trigger;
0226     char *name;
0227 };
0228 
0229 /**
0230  * struct dfl_feature - sub feature of the feature devices
0231  *
0232  * @dev: ptr to pdev of the feature device which has the sub feature.
0233  * @id: sub feature id.
0234  * @resource_index: each sub feature has one mmio resource for its registers.
0235  *          this index is used to find its mmio resource from the
0236  *          feature dev (platform device)'s resources.
0237  * @ioaddr: mapped mmio resource address.
0238  * @irq_ctx: interrupt context list.
0239  * @nr_irqs: number of interrupt contexts.
0240  * @ops: ops of this sub feature.
0241  * @ddev: ptr to the dfl device of this sub feature.
0242  * @priv: priv data of this feature.
0243  */
0244 struct dfl_feature {
0245     struct platform_device *dev;
0246     u16 id;
0247     u8 revision;
0248     int resource_index;
0249     void __iomem *ioaddr;
0250     struct dfl_feature_irq_ctx *irq_ctx;
0251     unsigned int nr_irqs;
0252     const struct dfl_feature_ops *ops;
0253     struct dfl_device *ddev;
0254     void *priv;
0255 };
0256 
0257 #define FEATURE_DEV_ID_UNUSED   (-1)
0258 
0259 /**
0260  * struct dfl_feature_platform_data - platform data for feature devices
0261  *
0262  * @node: node to link feature devs to container device's port_dev_list.
0263  * @lock: mutex to protect platform data.
0264  * @cdev: cdev of feature dev.
0265  * @dev: ptr to platform device linked with this platform data.
0266  * @dfl_cdev: ptr to container device.
0267  * @id: id used for this feature device.
0268  * @disable_count: count for port disable.
0269  * @excl_open: set on feature device exclusive open.
0270  * @open_count: count for feature device open.
0271  * @num: number for sub features.
0272  * @private: ptr to feature dev private data.
0273  * @features: sub features of this feature dev.
0274  */
0275 struct dfl_feature_platform_data {
0276     struct list_head node;
0277     struct mutex lock;
0278     struct cdev cdev;
0279     struct platform_device *dev;
0280     struct dfl_fpga_cdev *dfl_cdev;
0281     int id;
0282     unsigned int disable_count;
0283     bool excl_open;
0284     int open_count;
0285     void *private;
0286     int num;
0287     struct dfl_feature features[];
0288 };
0289 
0290 static inline
0291 int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata,
0292                   bool excl)
0293 {
0294     if (pdata->excl_open)
0295         return -EBUSY;
0296 
0297     if (excl) {
0298         if (pdata->open_count)
0299             return -EBUSY;
0300 
0301         pdata->excl_open = true;
0302     }
0303     pdata->open_count++;
0304 
0305     return 0;
0306 }
0307 
0308 static inline
0309 void dfl_feature_dev_use_end(struct dfl_feature_platform_data *pdata)
0310 {
0311     pdata->excl_open = false;
0312 
0313     if (WARN_ON(pdata->open_count <= 0))
0314         return;
0315 
0316     pdata->open_count--;
0317 }
0318 
0319 static inline
0320 int dfl_feature_dev_use_count(struct dfl_feature_platform_data *pdata)
0321 {
0322     return pdata->open_count;
0323 }
0324 
0325 static inline
0326 void dfl_fpga_pdata_set_private(struct dfl_feature_platform_data *pdata,
0327                 void *private)
0328 {
0329     pdata->private = private;
0330 }
0331 
0332 static inline
0333 void *dfl_fpga_pdata_get_private(struct dfl_feature_platform_data *pdata)
0334 {
0335     return pdata->private;
0336 }
0337 
0338 struct dfl_feature_ops {
0339     int (*init)(struct platform_device *pdev, struct dfl_feature *feature);
0340     void (*uinit)(struct platform_device *pdev,
0341               struct dfl_feature *feature);
0342     long (*ioctl)(struct platform_device *pdev, struct dfl_feature *feature,
0343               unsigned int cmd, unsigned long arg);
0344 };
0345 
0346 #define DFL_FPGA_FEATURE_DEV_FME        "dfl-fme"
0347 #define DFL_FPGA_FEATURE_DEV_PORT       "dfl-port"
0348 
0349 void dfl_fpga_dev_feature_uinit(struct platform_device *pdev);
0350 int dfl_fpga_dev_feature_init(struct platform_device *pdev,
0351                   struct dfl_feature_driver *feature_drvs);
0352 
0353 int dfl_fpga_dev_ops_register(struct platform_device *pdev,
0354                   const struct file_operations *fops,
0355                   struct module *owner);
0356 void dfl_fpga_dev_ops_unregister(struct platform_device *pdev);
0357 
0358 static inline
0359 struct platform_device *dfl_fpga_inode_to_feature_dev(struct inode *inode)
0360 {
0361     struct dfl_feature_platform_data *pdata;
0362 
0363     pdata = container_of(inode->i_cdev, struct dfl_feature_platform_data,
0364                  cdev);
0365     return pdata->dev;
0366 }
0367 
0368 #define dfl_fpga_dev_for_each_feature(pdata, feature)               \
0369     for ((feature) = (pdata)->features;                 \
0370        (feature) < (pdata)->features + (pdata)->num; (feature)++)
0371 
0372 static inline
0373 struct dfl_feature *dfl_get_feature_by_id(struct device *dev, u16 id)
0374 {
0375     struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
0376     struct dfl_feature *feature;
0377 
0378     dfl_fpga_dev_for_each_feature(pdata, feature)
0379         if (feature->id == id)
0380             return feature;
0381 
0382     return NULL;
0383 }
0384 
0385 static inline
0386 void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u16 id)
0387 {
0388     struct dfl_feature *feature = dfl_get_feature_by_id(dev, id);
0389 
0390     if (feature && feature->ioaddr)
0391         return feature->ioaddr;
0392 
0393     WARN_ON(1);
0394     return NULL;
0395 }
0396 
0397 static inline bool is_dfl_feature_present(struct device *dev, u16 id)
0398 {
0399     return !!dfl_get_feature_ioaddr_by_id(dev, id);
0400 }
0401 
0402 static inline
0403 struct device *dfl_fpga_pdata_to_parent(struct dfl_feature_platform_data *pdata)
0404 {
0405     return pdata->dev->dev.parent->parent;
0406 }
0407 
0408 static inline bool dfl_feature_is_fme(void __iomem *base)
0409 {
0410     u64 v = readq(base + DFH);
0411 
0412     return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) &&
0413         (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_FME);
0414 }
0415 
0416 static inline bool dfl_feature_is_port(void __iomem *base)
0417 {
0418     u64 v = readq(base + DFH);
0419 
0420     return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) &&
0421         (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_PORT);
0422 }
0423 
0424 static inline u8 dfl_feature_revision(void __iomem *base)
0425 {
0426     return (u8)FIELD_GET(DFH_REVISION, readq(base + DFH));
0427 }
0428 
0429 /**
0430  * struct dfl_fpga_enum_info - DFL FPGA enumeration information
0431  *
0432  * @dev: parent device.
0433  * @dfls: list of device feature lists.
0434  * @nr_irqs: number of irqs for all feature devices.
0435  * @irq_table: Linux IRQ numbers for all irqs, indexed by hw irq numbers.
0436  */
0437 struct dfl_fpga_enum_info {
0438     struct device *dev;
0439     struct list_head dfls;
0440     unsigned int nr_irqs;
0441     int *irq_table;
0442 };
0443 
0444 /**
0445  * struct dfl_fpga_enum_dfl - DFL FPGA enumeration device feature list info
0446  *
0447  * @start: base address of this device feature list.
0448  * @len: size of this device feature list.
0449  * @node: node in list of device feature lists.
0450  */
0451 struct dfl_fpga_enum_dfl {
0452     resource_size_t start;
0453     resource_size_t len;
0454     struct list_head node;
0455 };
0456 
0457 struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev);
0458 int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
0459                    resource_size_t start, resource_size_t len);
0460 int dfl_fpga_enum_info_add_irq(struct dfl_fpga_enum_info *info,
0461                    unsigned int nr_irqs, int *irq_table);
0462 void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info);
0463 
0464 /**
0465  * struct dfl_fpga_cdev - container device of DFL based FPGA
0466  *
0467  * @parent: parent device of this container device.
0468  * @region: base fpga region.
0469  * @fme_dev: FME feature device under this container device.
0470  * @lock: mutex lock to protect the port device list.
0471  * @port_dev_list: list of all port feature devices under this container device.
0472  * @released_port_num: released port number under this container device.
0473  */
0474 struct dfl_fpga_cdev {
0475     struct device *parent;
0476     struct fpga_region *region;
0477     struct device *fme_dev;
0478     struct mutex lock;
0479     struct list_head port_dev_list;
0480     int released_port_num;
0481 };
0482 
0483 struct dfl_fpga_cdev *
0484 dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info);
0485 void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev);
0486 
0487 /*
0488  * need to drop the device reference with put_device() after use port platform
0489  * device returned by __dfl_fpga_cdev_find_port and dfl_fpga_cdev_find_port
0490  * functions.
0491  */
0492 struct platform_device *
0493 __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
0494               int (*match)(struct platform_device *, void *));
0495 
0496 static inline struct platform_device *
0497 dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
0498             int (*match)(struct platform_device *, void *))
0499 {
0500     struct platform_device *pdev;
0501 
0502     mutex_lock(&cdev->lock);
0503     pdev = __dfl_fpga_cdev_find_port(cdev, data, match);
0504     mutex_unlock(&cdev->lock);
0505 
0506     return pdev;
0507 }
0508 
0509 int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id);
0510 int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id);
0511 void dfl_fpga_cdev_config_ports_pf(struct dfl_fpga_cdev *cdev);
0512 int dfl_fpga_cdev_config_ports_vf(struct dfl_fpga_cdev *cdev, int num_vf);
0513 int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start,
0514                   unsigned int count, int32_t *fds);
0515 long dfl_feature_ioctl_get_num_irqs(struct platform_device *pdev,
0516                     struct dfl_feature *feature,
0517                     unsigned long arg);
0518 long dfl_feature_ioctl_set_irq(struct platform_device *pdev,
0519                    struct dfl_feature *feature,
0520                    unsigned long arg);
0521 
0522 #endif /* __FPGA_DFL_H */