xref: /OK3568_Linux_fs/kernel/include/misc/ocxl.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun // Copyright 2017 IBM Corp.
3*4882a593Smuzhiyun #ifndef _MISC_OCXL_H_
4*4882a593Smuzhiyun #define _MISC_OCXL_H_
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/pci.h>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun  * Opencapi drivers all need some common facilities, like parsing the
10*4882a593Smuzhiyun  * device configuration space, adding a Process Element to the Shared
11*4882a593Smuzhiyun  * Process Area, etc...
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * The ocxl module provides a kernel API, to allow other drivers to
14*4882a593Smuzhiyun  * reuse common code. A bit like a in-kernel library.
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define OCXL_AFU_NAME_SZ      (24+1)  /* add 1 for NULL termination */
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun struct ocxl_afu_config {
21*4882a593Smuzhiyun 	u8 idx;
22*4882a593Smuzhiyun 	int dvsec_afu_control_pos; /* offset of AFU control DVSEC */
23*4882a593Smuzhiyun 	char name[OCXL_AFU_NAME_SZ];
24*4882a593Smuzhiyun 	u8 version_major;
25*4882a593Smuzhiyun 	u8 version_minor;
26*4882a593Smuzhiyun 	u8 afuc_type;
27*4882a593Smuzhiyun 	u8 afum_type;
28*4882a593Smuzhiyun 	u8 profile;
29*4882a593Smuzhiyun 	u8 global_mmio_bar;     /* global MMIO area */
30*4882a593Smuzhiyun 	u64 global_mmio_offset;
31*4882a593Smuzhiyun 	u32 global_mmio_size;
32*4882a593Smuzhiyun 	u8 pp_mmio_bar;         /* per-process MMIO area */
33*4882a593Smuzhiyun 	u64 pp_mmio_offset;
34*4882a593Smuzhiyun 	u32 pp_mmio_stride;
35*4882a593Smuzhiyun 	u64 lpc_mem_offset;
36*4882a593Smuzhiyun 	u64 lpc_mem_size;
37*4882a593Smuzhiyun 	u64 special_purpose_mem_offset;
38*4882a593Smuzhiyun 	u64 special_purpose_mem_size;
39*4882a593Smuzhiyun 	u8 pasid_supported_log;
40*4882a593Smuzhiyun 	u16 actag_supported;
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun struct ocxl_fn_config {
44*4882a593Smuzhiyun 	int dvsec_tl_pos;       /* offset of the Transaction Layer DVSEC */
45*4882a593Smuzhiyun 	int dvsec_function_pos; /* offset of the Function DVSEC */
46*4882a593Smuzhiyun 	int dvsec_afu_info_pos; /* offset of the AFU information DVSEC */
47*4882a593Smuzhiyun 	s8 max_pasid_log;
48*4882a593Smuzhiyun 	s8 max_afu_index;
49*4882a593Smuzhiyun };
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun enum ocxl_endian {
52*4882a593Smuzhiyun 	OCXL_BIG_ENDIAN = 0,    /**< AFU data is big-endian */
53*4882a593Smuzhiyun 	OCXL_LITTLE_ENDIAN = 1, /**< AFU data is little-endian */
54*4882a593Smuzhiyun 	OCXL_HOST_ENDIAN = 2,   /**< AFU data is the same endianness as the host */
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun // These are opaque outside the ocxl driver
58*4882a593Smuzhiyun struct ocxl_afu;
59*4882a593Smuzhiyun struct ocxl_fn;
60*4882a593Smuzhiyun struct ocxl_context;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun // Device detection & initialisation
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun /**
65*4882a593Smuzhiyun  * ocxl_function_open() - Open an OpenCAPI function on an OpenCAPI device
66*4882a593Smuzhiyun  * @dev: The PCI device that contains the function
67*4882a593Smuzhiyun  *
68*4882a593Smuzhiyun  * Returns an opaque pointer to the function, or an error pointer (check with IS_ERR)
69*4882a593Smuzhiyun  */
70*4882a593Smuzhiyun struct ocxl_fn *ocxl_function_open(struct pci_dev *dev);
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun /**
73*4882a593Smuzhiyun  * ocxl_function_afu_list() - Get the list of AFUs associated with a PCI function device
74*4882a593Smuzhiyun  * Returns a list of struct ocxl_afu *
75*4882a593Smuzhiyun  *
76*4882a593Smuzhiyun  * @fn: The OpenCAPI function containing the AFUs
77*4882a593Smuzhiyun  */
78*4882a593Smuzhiyun struct list_head *ocxl_function_afu_list(struct ocxl_fn *fn);
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /**
81*4882a593Smuzhiyun  * ocxl_function_fetch_afu() - Fetch an AFU instance from an OpenCAPI function
82*4882a593Smuzhiyun  * @fn: The OpenCAPI function to get the AFU from
83*4882a593Smuzhiyun  * @afu_idx: The index of the AFU to get
84*4882a593Smuzhiyun  *
85*4882a593Smuzhiyun  * If successful, the AFU should be released with ocxl_afu_put()
86*4882a593Smuzhiyun  *
87*4882a593Smuzhiyun  * Returns a pointer to the AFU, or NULL on error
88*4882a593Smuzhiyun  */
89*4882a593Smuzhiyun struct ocxl_afu *ocxl_function_fetch_afu(struct ocxl_fn *fn, u8 afu_idx);
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /**
92*4882a593Smuzhiyun  * ocxl_afu_get() - Take a reference to an AFU
93*4882a593Smuzhiyun  * @afu: The AFU to increment the reference count on
94*4882a593Smuzhiyun  */
95*4882a593Smuzhiyun void ocxl_afu_get(struct ocxl_afu *afu);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun /**
98*4882a593Smuzhiyun  * ocxl_afu_put() - Release a reference to an AFU
99*4882a593Smuzhiyun  * @afu: The AFU to decrement the reference count on
100*4882a593Smuzhiyun  */
101*4882a593Smuzhiyun void ocxl_afu_put(struct ocxl_afu *afu);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun /**
105*4882a593Smuzhiyun  * ocxl_function_config() - Get the configuration information for an OpenCAPI function
106*4882a593Smuzhiyun  * @fn: The OpenCAPI function to get the config for
107*4882a593Smuzhiyun  *
108*4882a593Smuzhiyun  * Returns the function config, or NULL on error
109*4882a593Smuzhiyun  */
110*4882a593Smuzhiyun const struct ocxl_fn_config *ocxl_function_config(struct ocxl_fn *fn);
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun /**
113*4882a593Smuzhiyun  * ocxl_function_close() - Close an OpenCAPI function
114*4882a593Smuzhiyun  * This will free any AFUs previously retrieved from the function, and
115*4882a593Smuzhiyun  * detach and associated contexts. The contexts must by freed by the caller.
116*4882a593Smuzhiyun  *
117*4882a593Smuzhiyun  * @fn: The OpenCAPI function to close
118*4882a593Smuzhiyun  *
119*4882a593Smuzhiyun  */
120*4882a593Smuzhiyun void ocxl_function_close(struct ocxl_fn *fn);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun // Context allocation
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun /**
125*4882a593Smuzhiyun  * ocxl_context_alloc() - Allocate an OpenCAPI context
126*4882a593Smuzhiyun  * @context: The OpenCAPI context to allocate, must be freed with ocxl_context_free
127*4882a593Smuzhiyun  * @afu: The AFU the context belongs to
128*4882a593Smuzhiyun  * @mapping: The mapping to unmap when the context is closed (may be NULL)
129*4882a593Smuzhiyun  */
130*4882a593Smuzhiyun int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu,
131*4882a593Smuzhiyun 			struct address_space *mapping);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun /**
134*4882a593Smuzhiyun  * ocxl_context_free() - Free an OpenCAPI context
135*4882a593Smuzhiyun  * @ctx: The OpenCAPI context to free
136*4882a593Smuzhiyun  */
137*4882a593Smuzhiyun void ocxl_context_free(struct ocxl_context *ctx);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /**
140*4882a593Smuzhiyun  * ocxl_context_attach() - Grant access to an MM to an OpenCAPI context
141*4882a593Smuzhiyun  * @ctx: The OpenCAPI context to attach
142*4882a593Smuzhiyun  * @amr: The value of the AMR register to restrict access
143*4882a593Smuzhiyun  * @mm: The mm to attach to the context
144*4882a593Smuzhiyun  *
145*4882a593Smuzhiyun  * Returns 0 on success, negative on failure
146*4882a593Smuzhiyun  */
147*4882a593Smuzhiyun int ocxl_context_attach(struct ocxl_context *ctx, u64 amr,
148*4882a593Smuzhiyun 				struct mm_struct *mm);
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun /**
151*4882a593Smuzhiyun  * ocxl_context_detach() - Detach an MM from an OpenCAPI context
152*4882a593Smuzhiyun  * @ctx: The OpenCAPI context to attach
153*4882a593Smuzhiyun  *
154*4882a593Smuzhiyun  * Returns 0 on success, negative on failure
155*4882a593Smuzhiyun  */
156*4882a593Smuzhiyun int ocxl_context_detach(struct ocxl_context *ctx);
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun // AFU IRQs
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /**
161*4882a593Smuzhiyun  * ocxl_afu_irq_alloc() - Allocate an IRQ associated with an AFU context
162*4882a593Smuzhiyun  * @ctx: the AFU context
163*4882a593Smuzhiyun  * @irq_id: out, the IRQ ID
164*4882a593Smuzhiyun  *
165*4882a593Smuzhiyun  * Returns 0 on success, negative on failure
166*4882a593Smuzhiyun  */
167*4882a593Smuzhiyun int ocxl_afu_irq_alloc(struct ocxl_context *ctx, int *irq_id);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun /**
170*4882a593Smuzhiyun  * ocxl_afu_irq_free() - Frees an IRQ associated with an AFU context
171*4882a593Smuzhiyun  * @ctx: the AFU context
172*4882a593Smuzhiyun  * @irq_id: the IRQ ID
173*4882a593Smuzhiyun  *
174*4882a593Smuzhiyun  * Returns 0 on success, negative on failure
175*4882a593Smuzhiyun  */
176*4882a593Smuzhiyun int ocxl_afu_irq_free(struct ocxl_context *ctx, int irq_id);
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /**
179*4882a593Smuzhiyun  * ocxl_afu_irq_get_addr() - Gets the address of the trigger page for an IRQ
180*4882a593Smuzhiyun  * This can then be provided to an AFU which will write to that
181*4882a593Smuzhiyun  * page to trigger the IRQ.
182*4882a593Smuzhiyun  * @ctx: The AFU context that the IRQ is associated with
183*4882a593Smuzhiyun  * @irq_id: The IRQ ID
184*4882a593Smuzhiyun  *
185*4882a593Smuzhiyun  * returns the trigger page address, or 0 if the IRQ is not valid
186*4882a593Smuzhiyun  */
187*4882a593Smuzhiyun u64 ocxl_afu_irq_get_addr(struct ocxl_context *ctx, int irq_id);
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun /**
190*4882a593Smuzhiyun  * ocxl_irq_set_handler() - Provide a callback to be called when an IRQ is triggered
191*4882a593Smuzhiyun  * @ctx: The AFU context that the IRQ is associated with
192*4882a593Smuzhiyun  * @irq_id: The IRQ ID
193*4882a593Smuzhiyun  * @handler: the callback to be called when the IRQ is triggered
194*4882a593Smuzhiyun  * @free_private: the callback to be called when the IRQ is freed (may be NULL)
195*4882a593Smuzhiyun  * @private: Private data to be passed to the callbacks
196*4882a593Smuzhiyun  *
197*4882a593Smuzhiyun  * Returns 0 on success, negative on failure
198*4882a593Smuzhiyun  */
199*4882a593Smuzhiyun int ocxl_irq_set_handler(struct ocxl_context *ctx, int irq_id,
200*4882a593Smuzhiyun 		irqreturn_t (*handler)(void *private),
201*4882a593Smuzhiyun 		void (*free_private)(void *private),
202*4882a593Smuzhiyun 		void *private);
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun // AFU Metadata
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun /**
207*4882a593Smuzhiyun  * ocxl_afu_config() - Get a pointer to the config for an AFU
208*4882a593Smuzhiyun  * @afu: a pointer to the AFU to get the config for
209*4882a593Smuzhiyun  *
210*4882a593Smuzhiyun  * Returns a pointer to the AFU config
211*4882a593Smuzhiyun  */
212*4882a593Smuzhiyun struct ocxl_afu_config *ocxl_afu_config(struct ocxl_afu *afu);
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun /**
215*4882a593Smuzhiyun  * ocxl_afu_set_private() - Assign opaque hardware specific information to an OpenCAPI AFU.
216*4882a593Smuzhiyun  * @afu: The OpenCAPI AFU
217*4882a593Smuzhiyun  * @private: the opaque hardware specific information to assign to the driver
218*4882a593Smuzhiyun  */
219*4882a593Smuzhiyun void ocxl_afu_set_private(struct ocxl_afu *afu, void *private);
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /**
222*4882a593Smuzhiyun  * ocxl_afu_get_private() - Fetch the hardware specific information associated with
223*4882a593Smuzhiyun  * an external OpenCAPI AFU. This may be consumed by an external OpenCAPI driver.
224*4882a593Smuzhiyun  * @afu: The OpenCAPI AFU
225*4882a593Smuzhiyun  *
226*4882a593Smuzhiyun  * Returns the opaque pointer associated with the device, or NULL if not set
227*4882a593Smuzhiyun  */
228*4882a593Smuzhiyun void *ocxl_afu_get_private(struct ocxl_afu *afu);
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun // Global MMIO
231*4882a593Smuzhiyun /**
232*4882a593Smuzhiyun  * ocxl_global_mmio_read32() - Read a 32 bit value from global MMIO
233*4882a593Smuzhiyun  * @afu: The AFU
234*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
235*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
236*4882a593Smuzhiyun  * @val: returns the value
237*4882a593Smuzhiyun  *
238*4882a593Smuzhiyun  * Returns 0 for success, negative on error
239*4882a593Smuzhiyun  */
240*4882a593Smuzhiyun int ocxl_global_mmio_read32(struct ocxl_afu *afu, size_t offset,
241*4882a593Smuzhiyun 			    enum ocxl_endian endian, u32 *val);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun /**
244*4882a593Smuzhiyun  * ocxl_global_mmio_read64() - Read a 64 bit value from global MMIO
245*4882a593Smuzhiyun  * @afu: The AFU
246*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
247*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
248*4882a593Smuzhiyun  * @val: returns the value
249*4882a593Smuzhiyun  *
250*4882a593Smuzhiyun  * Returns 0 for success, negative on error
251*4882a593Smuzhiyun  */
252*4882a593Smuzhiyun int ocxl_global_mmio_read64(struct ocxl_afu *afu, size_t offset,
253*4882a593Smuzhiyun 			    enum ocxl_endian endian, u64 *val);
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun /**
256*4882a593Smuzhiyun  * ocxl_global_mmio_write32() - Write a 32 bit value to global MMIO
257*4882a593Smuzhiyun  * @afu: The AFU
258*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
259*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
260*4882a593Smuzhiyun  * @val: The value to write
261*4882a593Smuzhiyun  *
262*4882a593Smuzhiyun  * Returns 0 for success, negative on error
263*4882a593Smuzhiyun  */
264*4882a593Smuzhiyun int ocxl_global_mmio_write32(struct ocxl_afu *afu, size_t offset,
265*4882a593Smuzhiyun 			     enum ocxl_endian endian, u32 val);
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun /**
268*4882a593Smuzhiyun  * ocxl_global_mmio_write64() - Write a 64 bit value to global MMIO
269*4882a593Smuzhiyun  * @afu: The AFU
270*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
271*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
272*4882a593Smuzhiyun  * @val: The value to write
273*4882a593Smuzhiyun  *
274*4882a593Smuzhiyun  * Returns 0 for success, negative on error
275*4882a593Smuzhiyun  */
276*4882a593Smuzhiyun int ocxl_global_mmio_write64(struct ocxl_afu *afu, size_t offset,
277*4882a593Smuzhiyun 			     enum ocxl_endian endian, u64 val);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun /**
280*4882a593Smuzhiyun  * ocxl_global_mmio_set32() - Set bits in a 32 bit global MMIO register
281*4882a593Smuzhiyun  * @afu: The AFU
282*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
283*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
284*4882a593Smuzhiyun  * @mask: a mask of the bits to set
285*4882a593Smuzhiyun  *
286*4882a593Smuzhiyun  * Returns 0 for success, negative on error
287*4882a593Smuzhiyun  */
288*4882a593Smuzhiyun int ocxl_global_mmio_set32(struct ocxl_afu *afu, size_t offset,
289*4882a593Smuzhiyun 			   enum ocxl_endian endian, u32 mask);
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun /**
292*4882a593Smuzhiyun  * ocxl_global_mmio_set64() - Set bits in a 64 bit global MMIO register
293*4882a593Smuzhiyun  * @afu: The AFU
294*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
295*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
296*4882a593Smuzhiyun  * @mask: a mask of the bits to set
297*4882a593Smuzhiyun  *
298*4882a593Smuzhiyun  * Returns 0 for success, negative on error
299*4882a593Smuzhiyun  */
300*4882a593Smuzhiyun int ocxl_global_mmio_set64(struct ocxl_afu *afu, size_t offset,
301*4882a593Smuzhiyun 			   enum ocxl_endian endian, u64 mask);
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun /**
304*4882a593Smuzhiyun  * ocxl_global_mmio_clear32() - Set bits in a 32 bit global MMIO register
305*4882a593Smuzhiyun  * @afu: The AFU
306*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
307*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
308*4882a593Smuzhiyun  * @mask: a mask of the bits to set
309*4882a593Smuzhiyun  *
310*4882a593Smuzhiyun  * Returns 0 for success, negative on error
311*4882a593Smuzhiyun  */
312*4882a593Smuzhiyun int ocxl_global_mmio_clear32(struct ocxl_afu *afu, size_t offset,
313*4882a593Smuzhiyun 			     enum ocxl_endian endian, u32 mask);
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun /**
316*4882a593Smuzhiyun  * ocxl_global_mmio_clear64() - Set bits in a 64 bit global MMIO register
317*4882a593Smuzhiyun  * @afu: The AFU
318*4882a593Smuzhiyun  * @offset: The Offset from the start of MMIO
319*4882a593Smuzhiyun  * @endian: the endianness that the MMIO data is in
320*4882a593Smuzhiyun  * @mask: a mask of the bits to set
321*4882a593Smuzhiyun  *
322*4882a593Smuzhiyun  * Returns 0 for success, negative on error
323*4882a593Smuzhiyun  */
324*4882a593Smuzhiyun int ocxl_global_mmio_clear64(struct ocxl_afu *afu, size_t offset,
325*4882a593Smuzhiyun 			     enum ocxl_endian endian, u64 mask);
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun // Functions left here are for compatibility with the cxlflash driver
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun /*
330*4882a593Smuzhiyun  * Read the configuration space of a function for the AFU specified by
331*4882a593Smuzhiyun  * the index 'afu_idx'. Fills in a ocxl_afu_config structure
332*4882a593Smuzhiyun  */
333*4882a593Smuzhiyun int ocxl_config_read_afu(struct pci_dev *dev,
334*4882a593Smuzhiyun 				struct ocxl_fn_config *fn,
335*4882a593Smuzhiyun 				struct ocxl_afu_config *afu,
336*4882a593Smuzhiyun 				u8 afu_idx);
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun /*
339*4882a593Smuzhiyun  * Tell an AFU, by writing in the configuration space, the PASIDs that
340*4882a593Smuzhiyun  * it can use. Range starts at 'pasid_base' and its size is a multiple
341*4882a593Smuzhiyun  * of 2
342*4882a593Smuzhiyun  *
343*4882a593Smuzhiyun  * 'afu_control_offset' is the offset of the AFU control DVSEC which
344*4882a593Smuzhiyun  * can be found in the function configuration
345*4882a593Smuzhiyun  */
346*4882a593Smuzhiyun void ocxl_config_set_afu_pasid(struct pci_dev *dev,
347*4882a593Smuzhiyun 				int afu_control_offset,
348*4882a593Smuzhiyun 				int pasid_base, u32 pasid_count_log);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun /*
351*4882a593Smuzhiyun  * Get the actag configuration for the function:
352*4882a593Smuzhiyun  * 'base' is the first actag value that can be used.
353*4882a593Smuzhiyun  * 'enabled' it the number of actags available, starting from base.
354*4882a593Smuzhiyun  * 'supported' is the total number of actags desired by all the AFUs
355*4882a593Smuzhiyun  *             of the function.
356*4882a593Smuzhiyun  */
357*4882a593Smuzhiyun int ocxl_config_get_actag_info(struct pci_dev *dev,
358*4882a593Smuzhiyun 				u16 *base, u16 *enabled, u16 *supported);
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun /*
361*4882a593Smuzhiyun  * Tell a function, by writing in the configuration space, the actags
362*4882a593Smuzhiyun  * it can use.
363*4882a593Smuzhiyun  *
364*4882a593Smuzhiyun  * 'func_offset' is the offset of the Function DVSEC that can found in
365*4882a593Smuzhiyun  * the function configuration
366*4882a593Smuzhiyun  */
367*4882a593Smuzhiyun void ocxl_config_set_actag(struct pci_dev *dev, int func_offset,
368*4882a593Smuzhiyun 				u32 actag_base, u32 actag_count);
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun /*
371*4882a593Smuzhiyun  * Tell an AFU, by writing in the configuration space, the actags it
372*4882a593Smuzhiyun  * can use.
373*4882a593Smuzhiyun  *
374*4882a593Smuzhiyun  * 'afu_control_offset' is the offset of the AFU control DVSEC for the
375*4882a593Smuzhiyun  * desired AFU. It can be found in the AFU configuration
376*4882a593Smuzhiyun  */
377*4882a593Smuzhiyun void ocxl_config_set_afu_actag(struct pci_dev *dev,
378*4882a593Smuzhiyun 				int afu_control_offset,
379*4882a593Smuzhiyun 				int actag_base, int actag_count);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun /*
382*4882a593Smuzhiyun  * Enable/disable an AFU, by writing in the configuration space.
383*4882a593Smuzhiyun  *
384*4882a593Smuzhiyun  * 'afu_control_offset' is the offset of the AFU control DVSEC for the
385*4882a593Smuzhiyun  * desired AFU. It can be found in the AFU configuration
386*4882a593Smuzhiyun  */
387*4882a593Smuzhiyun void ocxl_config_set_afu_state(struct pci_dev *dev,
388*4882a593Smuzhiyun 				int afu_control_offset, int enable);
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun /*
391*4882a593Smuzhiyun  * Set the Transaction Layer configuration in the configuration space.
392*4882a593Smuzhiyun  * Only needed for function 0.
393*4882a593Smuzhiyun  *
394*4882a593Smuzhiyun  * It queries the host TL capabilities, find some common ground
395*4882a593Smuzhiyun  * between the host and device, and set the Transaction Layer on both
396*4882a593Smuzhiyun  * accordingly.
397*4882a593Smuzhiyun  */
398*4882a593Smuzhiyun int ocxl_config_set_TL(struct pci_dev *dev, int tl_dvsec);
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun /*
401*4882a593Smuzhiyun  * Request an AFU to terminate a PASID.
402*4882a593Smuzhiyun  * Will return once the AFU has acked the request, or an error in case
403*4882a593Smuzhiyun  * of timeout.
404*4882a593Smuzhiyun  *
405*4882a593Smuzhiyun  * The hardware can only terminate one PASID at a time, so caller must
406*4882a593Smuzhiyun  * guarantee some kind of serialization.
407*4882a593Smuzhiyun  *
408*4882a593Smuzhiyun  * 'afu_control_offset' is the offset of the AFU control DVSEC for the
409*4882a593Smuzhiyun  * desired AFU. It can be found in the AFU configuration
410*4882a593Smuzhiyun  */
411*4882a593Smuzhiyun int ocxl_config_terminate_pasid(struct pci_dev *dev,
412*4882a593Smuzhiyun 				int afu_control_offset, int pasid);
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun /*
415*4882a593Smuzhiyun  * Read the configuration space of a function and fill in a
416*4882a593Smuzhiyun  * ocxl_fn_config structure with all the function details
417*4882a593Smuzhiyun  */
418*4882a593Smuzhiyun int ocxl_config_read_function(struct pci_dev *dev,
419*4882a593Smuzhiyun 				struct ocxl_fn_config *fn);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun /*
422*4882a593Smuzhiyun  * Set up the opencapi link for the function.
423*4882a593Smuzhiyun  *
424*4882a593Smuzhiyun  * When called for the first time for a link, it sets up the Shared
425*4882a593Smuzhiyun  * Process Area for the link and the interrupt handler to process
426*4882a593Smuzhiyun  * translation faults.
427*4882a593Smuzhiyun  *
428*4882a593Smuzhiyun  * Returns a 'link handle' that should be used for further calls for
429*4882a593Smuzhiyun  * the link
430*4882a593Smuzhiyun  */
431*4882a593Smuzhiyun int ocxl_link_setup(struct pci_dev *dev, int PE_mask,
432*4882a593Smuzhiyun 			void **link_handle);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun /*
435*4882a593Smuzhiyun  * Remove the association between the function and its link.
436*4882a593Smuzhiyun  */
437*4882a593Smuzhiyun void ocxl_link_release(struct pci_dev *dev, void *link_handle);
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun /*
440*4882a593Smuzhiyun  * Add a Process Element to the Shared Process Area for a link.
441*4882a593Smuzhiyun  * The process is defined by its PASID, pid, tid and its mm_struct.
442*4882a593Smuzhiyun  *
443*4882a593Smuzhiyun  * 'xsl_err_cb' is an optional callback if the driver wants to be
444*4882a593Smuzhiyun  * notified when the translation fault interrupt handler detects an
445*4882a593Smuzhiyun  * address error.
446*4882a593Smuzhiyun  * 'xsl_err_data' is an argument passed to the above callback, if
447*4882a593Smuzhiyun  * defined
448*4882a593Smuzhiyun  */
449*4882a593Smuzhiyun int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr,
450*4882a593Smuzhiyun 		u64 amr, struct mm_struct *mm,
451*4882a593Smuzhiyun 		void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr),
452*4882a593Smuzhiyun 		void *xsl_err_data);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun /*
455*4882a593Smuzhiyun  * Remove a Process Element from the Shared Process Area for a link
456*4882a593Smuzhiyun  */
457*4882a593Smuzhiyun int ocxl_link_remove_pe(void *link_handle, int pasid);
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun /*
460*4882a593Smuzhiyun  * Allocate an AFU interrupt associated to the link.
461*4882a593Smuzhiyun  *
462*4882a593Smuzhiyun  * 'hw_irq' is the hardware interrupt number
463*4882a593Smuzhiyun  */
464*4882a593Smuzhiyun int ocxl_link_irq_alloc(void *link_handle, int *hw_irq);
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun /*
467*4882a593Smuzhiyun  * Free a previously allocated AFU interrupt
468*4882a593Smuzhiyun  */
469*4882a593Smuzhiyun void ocxl_link_free_irq(void *link_handle, int hw_irq);
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun #endif /* _MISC_OCXL_H_ */
472