^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver Header File for FPGA Device Feature List (DFL) Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2017-2018 Intel Corporation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Kang Luwei <luwei.kang@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Zhang Yi <yi.z.zhang@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Wu Hao <hao.wu@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Xiao Guangrong <guangrong.xiao@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #ifndef __FPGA_DFL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define __FPGA_DFL_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/cdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/eventfd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/io-64-nonatomic-lo-hi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/uuid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/fpga/fpga-region.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* maximum supported number of ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define MAX_DFL_FPGA_PORT_NUM 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* plus one for fme device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define MAX_DFL_FEATURE_DEV_NUM (MAX_DFL_FPGA_PORT_NUM + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Reserved 0xfe for Header Group Register and 0xff for AFU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define FEATURE_ID_FIU_HEADER 0xfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define FEATURE_ID_AFU 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define FME_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FME_FEATURE_ID_THERMAL_MGMT 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FME_FEATURE_ID_POWER_MGMT 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FME_FEATURE_ID_GLOBAL_IPERF 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define FME_FEATURE_ID_GLOBAL_ERR 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define FME_FEATURE_ID_PR_MGMT 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define FME_FEATURE_ID_HSSI 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define FME_FEATURE_ID_GLOBAL_DPERF 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define PORT_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define PORT_FEATURE_ID_AFU FEATURE_ID_AFU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define PORT_FEATURE_ID_ERROR 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define PORT_FEATURE_ID_UMSG 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define PORT_FEATURE_ID_UINT 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define PORT_FEATURE_ID_STP 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Device Feature Header Register Set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * For FIUs, they all have DFH + GUID + NEXT_AFU as common header registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * For AFUs, they have DFH + GUID as common header registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * For private features, they only have DFH register as common header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DFH 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define GUID_L 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define GUID_H 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define NEXT_AFU 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define DFH_SIZE 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Device Feature Header Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define DFH_ID GENMASK_ULL(11, 0) /* Feature ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define DFH_ID_FIU_FME 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define DFH_ID_FIU_PORT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define DFH_REVISION GENMASK_ULL(15, 12) /* Feature revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define DFH_NEXT_HDR_OFST GENMASK_ULL(39, 16) /* Offset to next DFH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define DFH_EOL BIT_ULL(40) /* End of list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define DFH_TYPE GENMASK_ULL(63, 60) /* Feature type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define DFH_TYPE_AFU 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define DFH_TYPE_PRIVATE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define DFH_TYPE_FIU 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Next AFU Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define NEXT_AFU_NEXT_DFH_OFST GENMASK_ULL(23, 0) /* Offset to next AFU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* FME Header Register Set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define FME_HDR_DFH DFH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FME_HDR_GUID_L GUID_L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FME_HDR_GUID_H GUID_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define FME_HDR_NEXT_AFU NEXT_AFU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define FME_HDR_CAP 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define FME_HDR_PORT_OFST(n) (0x38 + ((n) * 0x8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define FME_HDR_BITSTREAM_ID 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define FME_HDR_BITSTREAM_MD 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* FME Fab Capability Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define FME_CAP_FABRIC_VERID GENMASK_ULL(7, 0) /* Fabric version ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define FME_CAP_SOCKET_ID BIT_ULL(8) /* Socket ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define FME_CAP_PCIE0_LINK_AVL BIT_ULL(12) /* PCIE0 Link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define FME_CAP_PCIE1_LINK_AVL BIT_ULL(13) /* PCIE1 Link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define FME_CAP_COHR_LINK_AVL BIT_ULL(14) /* Coherent Link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define FME_CAP_IOMMU_AVL BIT_ULL(16) /* IOMMU available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define FME_CAP_NUM_PORTS GENMASK_ULL(19, 17) /* Number of ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define FME_CAP_ADDR_WIDTH GENMASK_ULL(29, 24) /* Address bus width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define FME_CAP_CACHE_SIZE GENMASK_ULL(43, 32) /* cache size in KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define FME_CAP_CACHE_ASSOC GENMASK_ULL(47, 44) /* Associativity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* FME Port Offset Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Offset to port device feature header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define FME_PORT_OFST_DFH_OFST GENMASK_ULL(23, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* PCI Bar ID for this port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define FME_PORT_OFST_BAR_ID GENMASK_ULL(34, 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* AFU MMIO access permission. 1 - VF, 0 - PF. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define FME_PORT_OFST_ACC_CTRL BIT_ULL(55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define FME_PORT_OFST_ACC_PF 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define FME_PORT_OFST_ACC_VF 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define FME_PORT_OFST_IMP BIT_ULL(60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* FME Error Capability Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define FME_ERROR_CAP 0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* FME Error Capability Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define FME_ERROR_CAP_SUPP_INT BIT_ULL(0) /* Interrupt Support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define FME_ERROR_CAP_INT_VECT GENMASK_ULL(12, 1) /* Interrupt vector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* PORT Header Register Set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define PORT_HDR_DFH DFH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define PORT_HDR_GUID_L GUID_L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define PORT_HDR_GUID_H GUID_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define PORT_HDR_NEXT_AFU NEXT_AFU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define PORT_HDR_CAP 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define PORT_HDR_CTRL 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define PORT_HDR_STS 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define PORT_HDR_USRCLK_CMD0 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define PORT_HDR_USRCLK_CMD1 0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define PORT_HDR_USRCLK_STS0 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define PORT_HDR_USRCLK_STS1 0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* Port Capability Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define PORT_CAP_PORT_NUM GENMASK_ULL(1, 0) /* ID of this port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define PORT_CAP_MMIO_SIZE GENMASK_ULL(23, 8) /* MMIO size in KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define PORT_CAP_SUPP_INT_NUM GENMASK_ULL(35, 32) /* Interrupts num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Port Control Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define PORT_CTRL_SFTRST BIT_ULL(0) /* Port soft reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Latency tolerance reporting. '1' >= 40us, '0' < 40us.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define PORT_CTRL_LATENCY BIT_ULL(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define PORT_CTRL_SFTRST_ACK BIT_ULL(4) /* HW ack for reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Port Status Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define PORT_STS_AP2_EVT BIT_ULL(13) /* AP2 event detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define PORT_STS_AP1_EVT BIT_ULL(12) /* AP1 event detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define PORT_STS_PWR_STATE GENMASK_ULL(11, 8) /* AFU power states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define PORT_STS_PWR_STATE_NORM 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define PORT_STS_PWR_STATE_AP1 1 /* 50% throttling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define PORT_STS_PWR_STATE_AP2 2 /* 90% throttling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define PORT_STS_PWR_STATE_AP6 6 /* 100% throttling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /* Port Error Capability Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define PORT_ERROR_CAP 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Port Error Capability Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define PORT_ERROR_CAP_SUPP_INT BIT_ULL(0) /* Interrupt Support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define PORT_ERROR_CAP_INT_VECT GENMASK_ULL(12, 1) /* Interrupt vector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* Port Uint Capability Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define PORT_UINT_CAP 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Port Uint Capability Register Bitfield */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define PORT_UINT_CAP_INT_NUM GENMASK_ULL(11, 0) /* Interrupts num */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define PORT_UINT_CAP_FST_VECT GENMASK_ULL(23, 12) /* First Vector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * struct dfl_fpga_port_ops - port ops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @name: name of this port ops, to match with port platform device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * @owner: pointer to the module which owns this port ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @node: node to link port ops to global list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * @get_id: get port id from hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * @enable_set: enable/disable the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct dfl_fpga_port_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct module *owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int (*get_id)(struct platform_device *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int (*enable_set)(struct platform_device *pdev, bool enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * struct dfl_feature_id - dfl private feature id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * @id: unique dfl private feature id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct dfl_feature_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * struct dfl_feature_driver - dfl private feature driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * @id_table: id_table for dfl private features supported by this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * @ops: ops of this dfl private feature driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct dfl_feature_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) const struct dfl_feature_id *id_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) const struct dfl_feature_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * struct dfl_feature_irq_ctx - dfl private feature interrupt context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * @irq: Linux IRQ number of this interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * @trigger: eventfd context to signal when interrupt happens.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * @name: irq name needed when requesting irq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct dfl_feature_irq_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct eventfd_ctx *trigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * struct dfl_feature - sub feature of the feature devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * @dev: ptr to pdev of the feature device which has the sub feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * @id: sub feature id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * @resource_index: each sub feature has one mmio resource for its registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * this index is used to find its mmio resource from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * feature dev (platform device)'s reources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * @ioaddr: mapped mmio resource address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @irq_ctx: interrupt context list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @nr_irqs: number of interrupt contexts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * @ops: ops of this sub feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * @ddev: ptr to the dfl device of this sub feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * @priv: priv data of this feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct dfl_feature {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct platform_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u16 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int resource_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void __iomem *ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct dfl_feature_irq_ctx *irq_ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned int nr_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) const struct dfl_feature_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct dfl_device *ddev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) void *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define FEATURE_DEV_ID_UNUSED (-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * struct dfl_feature_platform_data - platform data for feature devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * @node: node to link feature devs to container device's port_dev_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @lock: mutex to protect platform data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * @cdev: cdev of feature dev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * @dev: ptr to platform device linked with this platform data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * @dfl_cdev: ptr to container device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * @id: id used for this feature device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * @disable_count: count for port disable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * @excl_open: set on feature device exclusive open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * @open_count: count for feature device open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * @num: number for sub features.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * @private: ptr to feature dev private data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @features: sub features of this feature dev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct dfl_feature_platform_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct cdev cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct platform_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct dfl_fpga_cdev *dfl_cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) unsigned int disable_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) bool excl_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int open_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) void *private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct dfl_feature features[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (pdata->excl_open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (excl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (pdata->open_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pdata->excl_open = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pdata->open_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) void dfl_feature_dev_use_end(struct dfl_feature_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) pdata->excl_open = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (WARN_ON(pdata->open_count <= 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) pdata->open_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int dfl_feature_dev_use_count(struct dfl_feature_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return pdata->open_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) void dfl_fpga_pdata_set_private(struct dfl_feature_platform_data *pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pdata->private = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) void *dfl_fpga_pdata_get_private(struct dfl_feature_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return pdata->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct dfl_feature_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int (*init)(struct platform_device *pdev, struct dfl_feature *feature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) void (*uinit)(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct dfl_feature *feature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) long (*ioctl)(struct platform_device *pdev, struct dfl_feature *feature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) unsigned int cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #define DFL_FPGA_FEATURE_DEV_FME "dfl-fme"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #define DFL_FPGA_FEATURE_DEV_PORT "dfl-port"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) void dfl_fpga_dev_feature_uinit(struct platform_device *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int dfl_fpga_dev_feature_init(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct dfl_feature_driver *feature_drvs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int dfl_fpga_dev_ops_register(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) const struct file_operations *fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct module *owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) void dfl_fpga_dev_ops_unregister(struct platform_device *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct platform_device *dfl_fpga_inode_to_feature_dev(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct dfl_feature_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) pdata = container_of(inode->i_cdev, struct dfl_feature_platform_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return pdata->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #define dfl_fpga_dev_for_each_feature(pdata, feature) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) for ((feature) = (pdata)->features; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) (feature) < (pdata)->features + (pdata)->num; (feature)++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct dfl_feature *dfl_get_feature_by_id(struct device *dev, u16 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct dfl_feature *feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) dfl_fpga_dev_for_each_feature(pdata, feature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (feature->id == id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return feature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u16 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct dfl_feature *feature = dfl_get_feature_by_id(dev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (feature && feature->ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return feature->ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static inline bool is_dfl_feature_present(struct device *dev, u16 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return !!dfl_get_feature_ioaddr_by_id(dev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct device *dfl_fpga_pdata_to_parent(struct dfl_feature_platform_data *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return pdata->dev->dev.parent->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static inline bool dfl_feature_is_fme(void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u64 v = readq(base + DFH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_FME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static inline bool dfl_feature_is_port(void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) u64 v = readq(base + DFH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static inline u8 dfl_feature_revision(void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return (u8)FIELD_GET(DFH_REVISION, readq(base + DFH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * struct dfl_fpga_enum_info - DFL FPGA enumeration information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * @dev: parent device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * @dfls: list of device feature lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * @nr_irqs: number of irqs for all feature devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * @irq_table: Linux IRQ numbers for all irqs, indexed by hw irq numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct dfl_fpga_enum_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct list_head dfls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned int nr_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) int *irq_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * struct dfl_fpga_enum_dfl - DFL FPGA enumeration device feature list info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * @start: base address of this device feature list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * @len: size of this device feature list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * @node: node in list of device feature lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct dfl_fpga_enum_dfl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) resource_size_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) resource_size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) resource_size_t start, resource_size_t len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int dfl_fpga_enum_info_add_irq(struct dfl_fpga_enum_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) unsigned int nr_irqs, int *irq_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * struct dfl_fpga_cdev - container device of DFL based FPGA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * @parent: parent device of this container device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * @region: base fpga region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * @fme_dev: FME feature device under this container device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * @lock: mutex lock to protect the port device list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * @port_dev_list: list of all port feature devices under this container device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * @released_port_num: released port number under this container device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct dfl_fpga_cdev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct device *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct fpga_region *region;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct device *fme_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct list_head port_dev_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) int released_port_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct dfl_fpga_cdev *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * need to drop the device reference with put_device() after use port platform
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * device returned by __dfl_fpga_cdev_find_port and dfl_fpga_cdev_find_port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct platform_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int (*match)(struct platform_device *, void *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static inline struct platform_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int (*match)(struct platform_device *, void *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) mutex_lock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) pdev = __dfl_fpga_cdev_find_port(cdev, data, match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) mutex_unlock(&cdev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) void dfl_fpga_cdev_config_ports_pf(struct dfl_fpga_cdev *cdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) int dfl_fpga_cdev_config_ports_vf(struct dfl_fpga_cdev *cdev, int num_vf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) unsigned int count, int32_t *fds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) long dfl_feature_ioctl_get_num_irqs(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct dfl_feature *feature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) long dfl_feature_ioctl_set_irq(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct dfl_feature *feature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * enum dfl_id_type - define the DFL FIU types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) enum dfl_id_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) FME_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) PORT_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) DFL_ID_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * struct dfl_device_id - dfl device identifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * @type: contains 4 bits DFL FIU type of the device. See enum dfl_id_type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * @feature_id: contains 12 bits feature identifier local to its DFL FIU type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * @driver_data: driver specific data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct dfl_device_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) u16 feature_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) unsigned long driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * struct dfl_device - represent an dfl device on dfl bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * @dev: generic device interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * @id: id of the dfl device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * @type: type of DFL FIU of the device. See enum dfl_id_type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * @feature_id: 16 bits feature identifier local to its DFL FIU type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * @mmio_res: mmio resource of this dfl device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * @irqs: list of Linux IRQ numbers of this dfl device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * @num_irqs: number of IRQs supported by this dfl device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * @cdev: pointer to DFL FPGA container device this dfl device belongs to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * @id_entry: matched id entry in dfl driver's id table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct dfl_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) u16 feature_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct resource mmio_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) int *irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) unsigned int num_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct dfl_fpga_cdev *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) const struct dfl_device_id *id_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * struct dfl_driver - represent an dfl device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * @drv: driver model structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * @id_table: pointer to table of device IDs the driver is interested in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * { } member terminated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * @probe: mandatory callback for device binding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * @remove: callback for device unbinding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct dfl_driver {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct device_driver drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) const struct dfl_device_id *id_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int (*probe)(struct dfl_device *dfl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) void (*remove)(struct dfl_device *dfl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) #define to_dfl_dev(d) container_of(d, struct dfl_device, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) #define to_dfl_drv(d) container_of(d, struct dfl_driver, drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * use a macro to avoid include chaining to get THIS_MODULE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) #define dfl_driver_register(drv) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) __dfl_driver_register(drv, THIS_MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int __dfl_driver_register(struct dfl_driver *dfl_drv, struct module *owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) void dfl_driver_unregister(struct dfl_driver *dfl_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * module_dfl_driver() - Helper macro for drivers that don't do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * anything special in module init/exit. This eliminates a lot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * boilerplate. Each module may only use this macro once, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * calling it replaces module_init() and module_exit().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) #define module_dfl_driver(__dfl_driver) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) module_driver(__dfl_driver, dfl_driver_register, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) dfl_driver_unregister)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) #endif /* __FPGA_DFL_H */