Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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 */